Jump to content
Sign in to follow this  
Cartitarul

Help with invoice customization

Recommended Posts

Hi, i live in Romania and in our country is mandatory to have the total of the invoice in the local currency also for example if the total is 5 Euro, to display under the currency in RON also.

Plz help me configure this invoice so i can start my buissnes.

 

Share this post


Link to post
Share on other sites

For at least the invoice page, using the ClientAreaPageViewInvoice hook that calls GetCurrencies API, get the exchange rate for RON and do maths on the invoice total and then overwrites an existing template variable might do what you want.   For example, appending the total variable with the RON amount.   For the invoice PDF, editing the invoicepdf template file and basically doing the same thing would be needed.    

Share this post


Link to post
Share on other sites

You better read this before making changes.

In essence WHMCS doesn't keep historical currency rates and as we know rates fluctuate on a daily basis. On the invoice you must print the rate in effect on the date on which the invoice is issued. You can't do the math on the fly otherwise your numbers on invoices will fluctuate causing more than one billing error. In fact the same invoice will give different exchange rates depending on when customers download/view it.

There are third-party modules that bla bla bla... good luck.

Edited by Kian

Share this post


Link to post
Share on other sites

Ok so i tryed something, i edited the invoicepdf.tpl to this:

But as u can see i need Fixed Invoice Data Mod, i want to mention that i did NOT create this file, how do i install the mod and fix this code, here is a example of the error that it gives : image.png.9ce584face9eb5ffa0fd41532f443518.png

I want it to get the values on the left and convert it in RON, btw i have the conversion rate on top .image.png.0276490a6626eccaac2e7a9078fe89b7.png

<?php




##################################
# Use this only if you have installed Fixed Invoice Data Mod
###################################
# Begin Fixed Invoice Data Mod - uncoment if needed

$result = select_query("mod_invoicedata","",array("invoiceid"=>$invoiceid));
$data = mysql_fetch_array($result);
$match = $data[0];
if ($match) {
    $clientsdetails = unserialize($data[1]);
    $customfields = unserialize($data[2]);
}

# End Fixed Invoice Data Mod


# get the daily currency rate
$ron = select_query("tblcurrencies","rate","code='RON'");
$ron_data = mysql_fetch_array($ron);

$eur = select_query("tblcurrencies","rate","code='EUR'");
$eur_data = mysql_fetch_array($eur);

if ($currency[code] == "EUR" ) {
  $ron_data[0] = format_as_currency($ron_data[0]/$eur_data[0]);
}

# Logo - put it in [whmcs]/images/logo.png
if (file_exists(ROOTDIR.'/images/logo.png')) $pdf->Image(ROOTDIR.'/images/logo.png',16,5,75);
elseif (file_exists(ROOTDIR.'/images/logo.jpg')) $pdf->Image(ROOTDIR.'/images/logo.jpg',16,5,75);
else $pdf->Image(ROOTDIR.'/images/placeholder.png',16,5,75);

# Invoice Status
$statustext = $_LANG['invoices'.strtolower($status)];
$pdf->SetFillColor(223,85,74);
$pdf->SetDrawColor(171,49,43);
if ($status=="Paid") {
    $pdf->SetFillColor(151,223,74);
    $pdf->SetDrawColor(110,192,70);
} elseif ($status=="Cancelled") {
    $pdf->SetFillColor(200);
    $pdf->SetDrawColor(140);
} elseif ($status=="Refunded") {
    $pdf->SetFillColor(131,182,218);
    $pdf->SetDrawColor(91,136,182);
} elseif ($status=="Collections") {
    $pdf->SetFillColor(3,3,2);
    $pdf->SetDrawColor(127);
}
$pdf->SetXY(0,0);
$pdf->SetFont('freesans','B',28);
$pdf->SetTextColor(255);
$pdf->SetLineWidth(0.75);
$pdf->StartTransform();
$pdf->Rotate(-35,100,225);
$pdf->Cell(100,18,strtolower($statustext),'TB',0,'C','1');
$pdf->StopTransform();
$pdf->SetTextColor(0);

# Company Details
$pdf->SetXY(15,26);
$pdf->SetFont('freesans','',13);
$pdf->Cell(160,6,trim($companyaddress[0]),0,1,'R');
$pdf->SetFont('freesans','',9);
for ( $i = 1; $i <= ((count($companyaddress)>6) ? count($companyaddress) : 6); $i += 1) {
	$pdf->Cell(160,4,trim($companyaddress[$i]),0,1,'R');
}
$pdf->Ln(5);

# Header Bar
$invoiceprefix = $_LANG["invoicenumber"];
/*
** This code should be uncommented for EU companies using the sequential invoice numbering so that when unpaid it is shown as a proforma invoice **
** in this template we assume you are using the EU proforma / sequential numbering
*/
if ($status=="Unpaid") {
	$invoiceprefix = $_LANG["proformainvoicenumber"];
}
$ypos = $pdf->GetY();
$pdf->SetFont('freesans','B',15);
$pdf->SetFillColor(255);
$pdf->Cell(180,10,$invoiceprefix.$invoicenum,0,1,'L','1');
$pdf->SetXY(140,$ypos);
$pdf->SetFont('freesans','',9);
if ($status!="Paid") {
        $pdf->Cell(55,5,$_LANG["invoicesdatecreated"].': '.$datecreated.'',0,1,'R','1');
        $pdf->SetX(140);
        $pdf->Cell(55,5,$_LANG["invoicesdatedue"].': '.$duedate.'',0,1,'R','1');
} else {
        $pdf->Cell(55,5,$_LANG["invoicesdatecreated"].': '.$datepaid.'',0,1,'R','1');
        $pdf->SetX(140);
        $pdf->Cell(55,5,$_LANG["invoicerefnum"].': '.$invoiceid.'',0,1,'R','1');
}
$ypos = $pdf->GetY();
$pdf->SetXY(140,$ypos);
#$pdf->Cell(55,5,$_LANG["invoicesdatecreated"].': '.$datecreated.'',0,1,'R','1');
#$pdf->SetX(140);
#$pdf->Cell(55,5,$_LANG["invoicesdatedue"].': '.$duedate.'',0,1,'R','1');
$pdf->SetFillColor(255);
if ($currency["code"] != "RON") {
    $pdf->Cell(55,4,"1 ".$currency["code"]." = ".$ron_data["0"].' lei',0,1,'R','1');
} else {
$pdf->Ln(1);
}
$pdf->Ln(5);

$startpage = $pdf->GetPage();

# Customer Details
$addressypos = $pdf->GetY();
$pdf->SetFont('freesans','B',10);
$pdf->Cell(40,4,$_LANG["invoicesinvoicedto"],0,1);
$pdf->SetFont('freesans','B',9);
if ($clientsdetails["companyname"]) {
	$pdf->Cell(96,4,$clientsdetails["companyname"],0,0,'L');
	$pdf->Cell(0,4,$_LANG["invoicesattn"].": ".$clientsdetails["firstname"]." ".$clientsdetails["lastname"],0,1,'R');
} else {
	$pdf->Cell(0,4,$clientsdetails["firstname"]." ".$clientsdetails["lastname"],0,1,'L');
}
$pdf->SetFont('freesans','',8);
$pdf->Cell(0,4,$clientsdetails["address1"],0,1,'L');
if ($clientsdetails["address2"]) {
	$pdf->Cell(0,4,$clientsdetails["address2"],0,1,'L');
}
$pdf->Cell(0,4,$clientsdetails["city"].", ".$clientsdetails["state"].", ".$clientsdetails["postcode"],0,1,'L');
$pdf->Cell(0,4,$clientsdetails["country"],0,1,'L');
if ($customfields) {
    $pdf->Ln();
    foreach ($customfields AS $customfield) {
        $pdf->Cell(0,4,$customfield['fieldname'].': '.$customfield['value'],0,1,'L');
    }
}

$pdf->Ln(10);

# Invoice Items
$pdf->SetFont('freesans','',8);
### draw a simple table if customer uses RON currency ###
if ("RON" == $currency["code"]) {
$tblhtml = '<table width="100%" bgcolor="#ccc" cellspacing="1" cellpadding="2" border="0">
    <tr height="30" bgcolor="#e1e1e1" style="font-weight:bold;text-align:left;">
        <td width="80%">'.$_LANG['invoicesdescription'].'</td>
        <td width="20%" style="text-align:right;">'.$_LANG['quotelinetotal'].'</td>
    </tr>';
foreach ($invoiceitems AS $item) {
    $tblhtml .= '
    <tr bgcolor="#ffffff" style="border:1px solid #333;">
        <td align="left">'.nl2br($item['description']).'</td>
        <td align="right">'.$item['amount'].'</td>
    </tr>';
}
$tblhtml .= '
    <tr height="30" bgcolor="#fefefe" style="font-weight:bold;">
        <td align="right">'.$_LANG['invoicessubtotal'].'</td>
        <td align="right">'.$subtotal.'</td>
    </tr>';
if ($taxname) $tblhtml .= '
    <tr height="30" bgcolor="#fefefe" style="font-weight:bold;">
        <td align="right">'.$taxrate.'% '.$taxname.'</td>
        <td align="right">'.$tax.'</td>
    </tr>';
if ($taxname2) $tblhtml .= '
    <tr height="30" bgcolor="#fefefe" style="font-weight:bold;">
        <td align="right">'.$taxrate2.'% '.$taxname2.'</td>
        <td align="right">'.$tax2.'</td>
    </tr>';
$tblhtml .= '
    <tr height="30" bgcolor="#fefefe" style="font-weight:bold;">
        <td align="right">'.$_LANG['invoicescredit'].'</td>
        <td align="right">'.$credit.'</td>
    </tr>
    <tr height="30" bgcolor="#f9f9f9" style="font-weight:bold;">
        <td align="right">'.$_LANG['invoicestotal'].'</td>
        <td align="right">'.$total.'</td>
    </tr>
</table>';
} else {
$tblhtml = '<table width="100%" bgcolor="#ccc" cellspacing="1" cellpadding="2" border="0">
    <tr height="30" bgcolor="#efefef" style="font-weight:bold;text-align:center;">
        <td width="70%">'.$_LANG['invoicesdescription'].'</td>
        <td width="15%" style="text-align:right">'.$_LANG['quotelinetotal']." ".$currency["code"].'</td>
        <td width="15%" style="text-align:right">'.$_LANG['quotelinetotal']." RON".'</td>
    </tr>';
foreach ($invoiceitems AS $item) {
    $tblhtml .= '
    <tr bgcolor="#fff" style="border:1px solid #333;">
        <td align="left">'.nl2br($item['description']).'</td>
        <td align="right">'.$item['amount'].'</td>
        <td align="right">'.format_as_currency($ron_data["0"]*$item['amount'])." lei".'</td>
    </tr>';
}
$tblhtml .= '
    <tr height="30" bgcolor="#fefefe" style="text-align:right;font-weight:bold;">
        <td>'.$_LANG['invoicessubtotal'].'</td>
        <td>'.$subtotal.'</td>
        <td>'.format_as_currency($ron_data["0"]*$subtotal)." lei".'</td>
    </tr>';
if ($taxname) $tblhtml .= '
    <tr height="30" bgcolor="#fefefe" style="font-weight:bold;text-align:right;">
        <td>'.$taxrate.'% '.$taxname.'</td>
        <td>'.$tax.'</td>
        <td>'.format_as_currency($ron_data["0"]*$tax)." lei".'</td>
    </tr>';
if ($taxname2) $tblhtml .= '
    <tr height="30" bgcolor="#fefefe" style="font-weight:bold;text-align:right;">
        <td>'.$taxrate2.'% '.$taxname2.'</td>
        <td>'.$tax2.'</td>
        <td>'.format_as_currency($ron_data["0"]*$tax2)." lei".'</td>
    </tr>';
$tblhtml .= '
    <tr height="30" bgcolor="#fefefe" style="font-weight:bold;text-align:right;">
        <td>'.$_LANG['invoicescredit'].'</td>
        <td>'.$credit.'</td>
        <td>'.format_as_currency($ron_data["0"]*$credit)." lei".'</td>
    </tr>
    <tr height="30" bgcolor="#f9f9f9" style="font-weight:bold;text-align:right;">
        <td>'.$_LANG['invoicestotal'].'</td>
        <td>'.$total.'</td>
        <td>'.format_as_currency($ron_data["0"]*($subtotal+$tax+$tax2+$credit))." lei".'</td>
    </tr>
</table>';
}

$pdf->writeHTML($tblhtml, true, false, false, false, '');
$pdf->Ln(3);

# Transactions
$pdf->SetFont('freesans','B',9);
$pdf->Cell(0,4,$_LANG["invoicestransactions"],0,1);
$pdf->Ln(2);
$pdf->SetFont('freesans','',8);
$tblhtml = '<table width="100%" bgcolor="#ccc" cellspacing="1" cellpadding="2" border="0">
    <tr height="30" bgcolor="#efefef" style="font-weight:bold;text-align:center;">
        <td width="25%">'.$_LANG['invoicestransdate'].'</td>
        <td width="25%">'.$_LANG['invoicestransgateway'].'</td>
        <td width="30%">'.$_LANG['invoicestransid'].'</td>
        <td width="20%" style="text-align:right">'.$_LANG['invoicestransamount'].'</td>
    </tr>';

if (!count($transactions)) {
    $tblhtml .= '
    <tr bgcolor="#fff">
	<td colspan="4" align="center">'.$_LANG['invoicestransnonefound'].'</td>
    </tr>';
} else {
    foreach ($transactions AS $trans) {
        $tblhtml .= '
        <tr bgcolor="#fff">
    	<td align="center">'.$trans['date'].'</td>
    	<td align="center">'.$trans['gateway'].'</td>
    	<td align="center">'.$trans['transid'].'</td>';
        if ($currency["code"] != "RON") {
            $tblhtml .= '<td align="right">'.format_as_currency($ron_data["0"]*$trans['amount'])." lei".'</td>';
        } else {
		$tblhtml .= '<td align="right">'.$trans['amount']." lei".'</td>';
    	}
	$tblhtml .= '</tr>';
    }
}
$tblhtml .= '
    <tr height="30" bgcolor="#efefef" style="font-weight:bold;">
        <td colspan="3" align="right">'.$_LANG['invoicesbalance'].'</td>
        <td align="right">';
        if ($currency["code"] != "RON") {
            $tblhtml .= format_as_currency($ron_data["0"]*$balance)." lei".'</td>';
        } else {
	    $tblhtml .= $balance.'</td>';
    	}
$tblhtml .= '
    </tr>
</table>';

$pdf->writeHTML($tblhtml, true, false, false, false, '');

# Notes
if ($notes) {
    $pdf->Ln(2);
	$pdf->SetFont('freesans','',8);
	$pdf->MultiCell(170,5,$_LANG["invoicesnotes"].": $notes");
}

# Generation Date
$pdf->SetFont('freesans','',7);
$pdf->Ln(1);
$pdf->Cell(180,4,$_LANG['invoicepdfgenerated'].' '.getTodaysDate(1),'','','C');
?>

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Similar Content

    • By Marijo
      Hello,
      As some of you may know we in Croatia are obligated to have currency on HRK inside invoice, this makes stuff hard for me and my friend cause we're based on international marketplace and not only Croatia. Sadly we we're trying to come up with a solution and its been real pain in the ass trying to figure something out. As much as I know its not possible to use hooks inside php, so we have no idea how it would be possible to have currency exchange inside pdf that is being delivered by email. Really any help would be appreciated.
      We tried looking up on older posts but haven't found a solution yet, so please help 2 guys out :D
    • By Balram
      Hello,
      i am trying to add bank transfer details but having some problem.
      I am unable to add space after text below attaching screenshot for understanding.
      My issue-  https://prnt.sc/1x5pccy
      i found one website using same theme without this problem - https://prnt.sc/1x5p7zo
      here is how i have added details to whmcs admin area- https://prnt.sc/1x5pjhz
    • By Fany
      Hi friends,
      I tried to find an invoice template that would meet EU regulations. I didn't find it, maybe I'm looking wrong.
      According to EU rules, the type and amount of VAT must be specified for each item.
      I give an example of what an invoice should look like in the attachment.
      Can anyone solve this problem? Or do you know of a teplat that would meet these rules?
      Black texts: are firmly in the template
      Green texts: data generated from WHMCS
      Because I use the Czech language, the Czech names of the items are listed in the template
      I gave an example of generating products on an invoice.
      I am willing to evaluate the help financially. I need to change both the HTML and PDF invoice.

    • By Davor
      Hello,
      How to update the Credit Balance for a client after changing the Invoice and InvoiceItems?
      I'm using Paddle for processing my payments.
      When sending the invoice data to Paddle I send it without taxes. 
      Then Paddle handles the taxes and at the Subscription Payment Success webhook I get if there are any taxes.
      Then I change the Invoice Items and the Invoice.
      ((((Don't know if UpdateClientProduct autorecalc is not working in v8.2 or it is used for something else))))
      At the end I also update the Invoice with tax amount and the new total with taxes.
      I'm new with WHMCS (2 months now) and PHP (3 months).
      Now, I can't find the way how to update or trigger something to update the Credit Balance on the Summary for Client. It is still the old value that was before adding taxes to Invoices.
      Is there an API to update the Clients amounts, including Credit Balance and do I need to update something else after my changes to the Invoices?
       
      Here the part of the code that is doing this:
       
      $withoutTax = $fields['balance_fee'] + $fields['balance_earnings']; $taxAmount = $fields['balance_tax']; $withTax = $fields['balance_gross']; if ( $withoutTax <> 0 ) { $taxPercent = round(($taxAmount / $withoutTax) * 100, 2); } else { $taxPercent = 0; } if ( $taxPercent <> 0 ) { $itemTaxed = 1; } else { $itemTaxed = 0; } $command = 'GetInvoice'; $values = array( 'invoiceid' => $invoiceId, ); //$adminUsername = 'ADMIN_USERNAME'; // Optional for WHMCS 7.2 and later // Call the localAPI function $invoice = localAPI($command, $values, $adminUsername); logModuleCall('paddle_checkout_gateway_callback', 'UpdateInvoice_localAPI_invoice', $invoice, ""); if ($invoice['result'] == 'success') { foreach ($invoice['items']['item'] as $item) { //error_log($vars['invoiceid'].' item '.$item['id'].' has description of "'.$item['description'].'"'); $text = $item['description']; $updatedInfo = array( 'invoiceid' => $invoiceId, 'taxrate' => $taxPercent, 'itemdescription' => array($item['id'] => $text), 'itemamount' => array($item['id'] => $item['amount']), 'itemtaxed' => array($item['id'] => $itemTaxed) ); $updatedInvoice = localAPI('UpdateInvoice', $updatedInfo, $adminUsername); logModuleCall('paddle_checkout_gateway_callback', 'UpdateInvoice', $updatedInfo, $updatedInvoice); } } else { //echo "An Error Occurred: " . $results['result']; } // let's now trigger the recalculate of each hostingId from this updated invoiceid // I think that this is not working in v8.2 or the UpdateClientProduct autorecalc is used for something else $invoiceitems = Capsule::table('tblinvoiceitems') ->where('invoiceid', $invoiceId) ->where('type', 'Hosting')->get(); //->first(); foreach( $invoiceitems as $invoiceitem ){ //$invoiceitem->relid this is the id from the tblHosting table $resultOfAPI = localAPI('UpdateClientProduct', array('serviceid' => $invoiceitem->relid, 'autorecalc' => true), $adminUsername); logModuleCall('paddle_checkout_gateway_callback', 'recalculateProductItems', $invoiceitem->relid, $resultOfAPI); } // 20210927 maybe a bug in v8.2 // not updating the tax and the total amount of the invoice with UpdateClientProduct 'autorecalc' // manualy updating the table tblinvoices try { Capsule::table('tblinvoices') ->where('id', $invoiceId) ->update([ "tax" => $taxAmount, "total" => $withTax ]); } catch (\Exception $e) { logModuleCall('paddle_checkout_gateway_callback', 'recalculateProductItems_ERROR', "tax " .$taxAmount . " total " .$withtax ,$e); echo "Error in updating tblInvoices. {$e->getMessage()}"; }  
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated