[Vtigercrm-developers] Rounding numbers in PDF invoice

Holbok István holbok at gmail.com
Fri Nov 25 09:41:44 PST 2011


Hi All,

Here is a small modification of *....\include\fields\CurrencyField.php*

It would be useful, if the parameter $numberOfDecimal could be set up 
from settings panel.

Due to actual state of economics and inflation in Hungary we are not 
using anymore cents only whole Forints. Even now we are using only 0 or 
5 end integers for the prices and currency values because so we should 
round all prices:
Numbers with end ...xxx1 , ...xxx2, ...xxx8  and ...xxx9 to the   ..xxx0 
and
numbers with end ...xxx3 , ...xxx4, ...xxx6  and ...xxx7 to the   ..xxx5

There are a var $numberOfDecimal = 3; in this file.

If this var set *$numberOfDecimal = 0;*

and adding and/or changing the blue lines in the *function 
*_formatCurrencyValue($value), the numbers will round well in the PDF 
Invoice.

     /**
      * Function that formats the Number based on the User configured 
Pattern, Currency separator and Decimal separator
      * @param Number $value
      * @return Formatted Currency
      */
     private function _formatCurrencyValue($value) {

         $currencyPattern = $this->currencyFormat;
         $currencySeparator = $this->currencySeparator;
         $decimalSeparator  = $this->decimalSeparator;
         if(empty($currencySeparator)) $currencySeparator = ' ';
         if(empty($decimalSeparator)) $decimalSeparator = ' ';
*        // Rounding value to the given decimals
         $value = round($value, $this->numberOfDecimal);*

         if($currencyPattern == $this->CURRENCY_PATTERN_PLAIN) {
             // Replace '.' with Decimal Separator
             $number = str_replace('.', $decimalSeparator, $value);
             return $number;
         }
         if($currencyPattern == $this->CURRENCY_PATTERN_SINGLE_GROUPING) {
             // Separate the numeric and decimal parts
             $numericParts = explode('.', $value);
             $wholeNumber = $numericParts[0];
             // First part of the number which remains intact
             if(strlen($wholeNumber) > 3) {
                 $wholeNumberFirstPart = 
substr($wholeNumber,0,strlen($wholeNumber)-3);
             }
             // Second Part of the number (last 3 digits) which should 
be separated from the First part using Currency Separator
             $wholeNumberLastPart = substr($wholeNumber,-3);
             // Re-create the whole number with user's configured 
currency separator
             if(!empty($wholeNumberFirstPart)) {
                 $numericParts[0] = 
$wholeNumberFirstPart.$currencySeparator.$wholeNumberLastPart;
             } else {
                 $numericParts[0] = $wholeNumberLastPart;
             }
*            // Handling number rounding
             if ( $this->numberOfDecimal == 0) {
                 //No decimal parts: No $decimalSeparator and No 
$numericParts[1]
                 // Re-create the currency value combining the whole 
number and the decimal part using Decimal separator
                 $number = $numericParts[0];
             }
             else {
                 // Re-create the currency value combining the whole 
number and the decimal part using Decimal separator
                 $number = implode($decimalSeparator, $numericParts);
             }*
             return $number;
         }
         if($currencyPattern == $this->CURRENCY_PATTERN_THOUSAND_GROUPING) {
             // Separate the numeric and decimal parts
             $numericParts = explode('.', $value);
             $wholeNumber = $numericParts[0];
             // Pad the rest of the length in the number string with 
Leading 0, to get it to the multiples of 3
             $numberLength = strlen($wholeNumber);
             // First grouping digits length
             $OddGroupLength = $numberLength%3;
             $gapsToBeFilled = 0;
             if($OddGroupLength > 0) $gapsToBeFilled = 3 - $OddGroupLength;
             $wholeNumber = str_pad($wholeNumber, 
$numberLength+$gapsToBeFilled, '0', STR_PAD_LEFT);
             // Split the whole number into chunks of 3 digits
             $wholeNumberParts = str_split($wholeNumber,3);
             // Re-create the whole number with user's configured 
currency separator
             $numericParts[0] = $wholeNumber = 
implode($currencySeparator, $wholeNumberParts);
             if($wholeNumber > 0) {
                 $numericParts[0] = ltrim($wholeNumber, '0');
             } else {
                 $numericParts[0] = 0;
             }
*            // Handling number rounding
             if ( $this->numberOfDecimal == 0) {
                 //No decimal parts: No $decimalSeparator and No 
$numericParts[1]
                 // Re-create the currency value combining the whole 
number and the decimal part using Decimal separator
                 $number = $numericParts[0];
             }
             else {
                 // Re-create the currency value combining the whole 
number and the decimal part using Decimal separator
                 $number = implode($decimalSeparator, $numericParts);
             }*
             return $number;
         }
         if($currencyPattern == $this->CURRENCY_PATTERN_MIXED_GROUPING) {
             // Separate the numeric and decimal parts
             $numericParts = explode('.', $value);
             $wholeNumber = $numericParts[0];
             // First part of the number which needs separate division
             if(strlen($wholeNumber) > 3) {
                 $wholeNumberFirstPart = 
substr($wholeNumber,0,strlen($wholeNumber)-3);
             }
             // Second Part of the number (last 3 digits) which should 
be separated from the First part using Currency Separator
             $wholeNumberLastPart = substr($wholeNumber,-3);
             if(!empty($wholeNumberFirstPart)) {
                 // Pad the rest of the length in the number string with 
Leading 0, to get it to the multiples of 2
                 $numberLength = strlen($wholeNumberFirstPart);
                 // First grouping digits length
                 $OddGroupLength = $numberLength%2;
                 $gapsToBeFilled = 0;
                 if($OddGroupLength > 0) $gapsToBeFilled = 2 - 
$OddGroupLength;
                 $wholeNumberFirstPart = str_pad($wholeNumberFirstPart, 
$numberLength+$gapsToBeFilled, '0', STR_PAD_LEFT);
                 // Split the first part of tne number into chunks of 2 
digits
                 $wholeNumberFirstPartElements = 
str_split($wholeNumberFirstPart,2);
                 $wholeNumberFirstPart = 
ltrim(implode($currencySeparator, $wholeNumberFirstPartElements), '0');
                 $wholeNumberFirstPart = implode($currencySeparator, 
$wholeNumberFirstPartElements);
                 if($wholeNumberFirstPart > 0) {
                     $wholeNumberFirstPart = 
ltrim($wholeNumberFirstPart, '0');
                 } else {
                     $wholeNumberFirstPart = 0;
                 }
                 // Re-create the whole number with user's configured 
currency separator
                 $numericParts[0] = 
$wholeNumberFirstPart.$currencySeparator.$wholeNumberLastPart;
             } else {
                 $numericParts[0] = $wholeNumberLastPart;
             }
*            // Handling number rounding
             if ( $this->numberOfDecimal == 0) {
                 //No decimal parts: No $decimalSeparator and No 
$numericParts[1]
                 // Re-create the currency value combining the whole 
number and the decimal part using Decimal separator
                 $number = $numericParts[0];
             }
             else {
                 // Re-create the currency value combining the whole 
number and the decimal part using Decimal separator
                 $number = implode($decimalSeparator, $numericParts);
             }*
             return $number;
         }
         return $number;
     }

---------------------------------------------------
Plus we should change the *....\include\InventoryPDFController.php* a 
little also.

About line 135 - 140:

Change:
             $contentModel->set('Quantity', $quantity);
Into:
*$contentModel->set('Quantity', round($quantity,0));*

and

Change:
             $contentModel->set('Discount',  
$this->formatPrice($discount)."\n ($discountPercentage%)");
Into:
*$contentModel->set('Discount',  $this->formatPrice($discount)."\n 
(".round($discountPercentage,1)."%)");
*

Also should be changed 2 lines about lines: 210-214

         $summaryModel->set(getTranslatedString("Shipping & Handling 
Tax:", $this->moduleName)."($sh_tax_percent%)", 
$this->formatPrice($final_details['shtax_totalamount']));

         $summaryModel->set(getTranslatedString("Grand Total : (in 
$currencySymbol)", $this->moduleName), 
$this->formatPrice($final_details['grandTotal']));

Into the:
*
**        $summaryModel->set(getTranslatedString("Shipping & Handling 
Tax", $this->moduleName)." ($sh_tax_percent%):", 
$this->formatPrice($final_details['shtax_totalamount']));

         $summaryModel->set(getTranslatedString("Grand Total", 
$this->moduleName)." ($currencySymbol):", 
$this->formatPrice($final_details['grandTotal']));*

The first line for the better look, but the second line for the 
availability to translate.
The original version consists a variable in the 
getTranslatedString("*argument*", $this->moduleName) - so it very hard 
to translate.


Best regards:

-- 

Holbok István
telefon: +3670-342-0900
e-mail: holbok at gmail.com <mailto:holbok at gmail.com>



-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.vtigercrm.com/pipermail/vtigercrm-developers/attachments/20111125/f9ffe0c9/attachment-0002.html 


More information about the vtigercrm-developers mailing list