CakePHP calculation not correct - php

I have a small script that generates quotes. I can add items with related discount or tax values, however the calculation does not seem to be correct as it's not subtracting the discount value. Based upon the screenshot I will attach the item subtotal should amount to 155,584.00
Please refer to my script below as well as a screenshot
foreach ($items as $item) {
$itemSubTotal = $item['quantity'] * $item['unit_price'];
$discount_rate=$item['discount_rate'];
$unit_price=$item['unit_price'];
$subTotal += $itemSubTotal;
$itemDiscount=$itemSubTotal*$discount_rate/100;
$discount+=$itemDiscount;
$itemTax = $itemSubTotal * ($item['tax_rate'] / 100);
$tax += $itemTax;
$itemSubTotal = number_format($itemSubTotal, 2, '.', ',');
$y+=5;
$pdf->setXY(5, $y);
$pdf->MultiCell(10, 5, $i++, 0, 'L');
$pdf->setXY(15, $y);
$pdf->Cell(30, 5, $item['title'], 0, 2, 'L');
$pdf->setXY(45, $y);
$pdf->Cell(30, 5, $item['details'], 0, 2, 'L');
$pdf->setXY(125, $y);
$pdf->MultiCell(20, 5, $item['quantity'], 0, 'R');
$pdf->setXY(145, $y);
$pdf->MultiCell(15, 5, number_format($unit_price, 2, '.', ','), 0, 'R');
$pdf->setXY(160, $y);
$pdf->MultiCell(20, 5, number_format($discount_rate, 2, '.', ','), 0, 'R');
$pdf->setXY(180, $y);
$pdf->MultiCell(25, 5, $itemSubTotal, 0, 'R');
How can I get this fixed? Some expert advise would be greatly appreciated

You haven't modified the $itemSubTotal variable with the discount. you should do this before printing it:
$itemSubTotal = $itemSubTotal*($discount_rate/100);
also, according to my calculation, the item subtotal would be 83,776.00

Related

Word wrap in a cell in FPDF using PHP?

I am trying to print some words in a cell but wordwrap in not working in a cell, what should i do?
$pdf->setXY(124, 36 + ($i * 5.1));
$pdf->SetFillColor(238, 236, 225);
$pdf->SetFont('Arial', '', 8);
$pdf->Cell(40, 6, $resultArrayIndex['pubtitle'], 0, 0, 'L', True);
Here is my output -
and here what i am trying to achieve - trying to wrap word within a cell. (Any help or hint is appreciated)
Edited after comments and sugggestions
After all u suggesting me use Multicell, I used it but it's still not helpful
not equal gap with each multicell and even sometimes it's uneven size text and gap
My code after your suggestion and i am using it in for-loop
$pdf->setXY(17, 36+($i * 6.9));
$pdf->SetFillColor(255,255,255);
$pdf->SetFont('Arial', '', 8);
$pdf->MultiCell(19, 4.6, formatPubDate($resultArrayIndex['pubdate']), 1);
$pdf->setXY(42, 36 + ($i * 6.9));
$pdf->SetFont('Arial', '', 8);
$pdf->MultiCell(50.5, 4.6, ($resultArrayIndex['title']), 1);
$pdf->setXY(124, 33.7 + ($i * 9.0));
$pdf->SetFont('Arial', '', 8);
$pdf-> MultiCell(27, 2.9 , $resultArrayIndex['pubtitle'],1);

sort in cakephp / fpdf

I have a small script created in CakePHP where I can generate quotes, however the quote items seem to be sorted in a non specific way on my PDF. What is the best way to have this sorted by ID in an ascending order ?
Find below my related code snippet which will list all items on my quote:
foreach ($items as $item) {
$itemSubTotal = $item['quantity'] * $item['unit_price'];
$discount_rate=$item['discount_rate'];
$unit_price=$item['unit_price'];
$subTotal += $itemSubTotal;
$itemDiscount=$itemSubTotal*$discount_rate/100;
$discount+=$itemDiscount;
//$itemTax = $itemSubTotal * ($item['tax_rate'] / 100);
$itemTax = ($itemSubTotal - $itemDiscount) * ($item['tax_rate'] / 100);
$tax += $itemTax;
$itemSubTotal = $itemSubTotal*((100-$discount_rate) / 100);
$itemSubTotal = number_format($itemSubTotal, 2, '.', ',');
$y+=5;
$pdf->setXY(5, $y);
$pdf->MultiCell(10, 5, $i++, 0, 'L');
$pdf->setXY(15, $y);
//$pdf->MultiCell(30, 5, $item['title'], 0, 'L');
$pdf->Cell(30, 5, $item['title'], 0, 2, 'L');
$pdf->setXY(45, $y);
//$pdf->MultiCell(80, 5, $item['details'], 0, 'L');
$pdf->Cell(30, 5, $item['details'], 0, 2, 'L');
$pdf->setXY(125, $y);
$pdf->MultiCell(20, 5, $item['quantity'], 0, 'R');
$pdf->setXY(145, $y);
$pdf->MultiCell(15, 5, number_format($unit_price, 2, '.', ','), 0, 'R');
$pdf->setXY(160, $y);
$pdf->MultiCell(20, 5, number_format($discount_rate, 2, '.', ','), 0, 'R');
$pdf->setXY(180, $y);
$pdf->MultiCell(25, 5, $itemSubTotal, 0, 'R');
}
Some expert help would be greatly appreciated, thank you
I have not tried this, but it should work. Have a look at cake 3 collections and specifically sortBy
If you wrap your $items in a collection, then sort them, then iterate through them you will achieve your goal.
Something like:
use Cake\Collection\Collection;
$collection = new Collection($items);
$sortedByField = $collection->sortBy('field')
If this doesn't work have a play with the other methods like groupBy

how to increase width according to value count

First of all i am really sorry for my english. I try to explain my wanted. I use fpdf to make dynamic invoice in pdf. I have more than one product to add one invoice and i must list them sub-bottom. But products counts change in all invoices. Some invoice has 5 products but some invoice has 2 products. My problem is i use code below but all lines overrided.
$invoices_query = mysql_query("SELECT * FROM invoice_bookings WHERE invoice_code = '$invoice_code'");
while ($invoices = mysql_fetch_array($invoices_query)) {
$customers_name = $invoices['customer_name'];
$pdf->Ln(0);
$pdf->Cell(21,123,$invoice_number,0,0,'L',0); // empty cell with left,top, and right borders
$pdf->Cell(30,123,$customers_name,0,0,'L',0);
$pdf->Cell(20,123,$date,0,0,'L',0);
$pdf->Cell(20,123,$time,0,0,'L',0);
$pdf->Cell(30,123,$suburb_from,0,0,'L',0);
$pdf->Cell(34,123,$suburb_to,0,0,'L',0);
$pdf->Cell(10,123,'% ' . $tax_percent,0,0,'L',0);
$pdf->Cell(25,123,'$ ' . $invoice_price,0,0,'R',0);
}
You can see value of margin. It's 123 as you can see. I must increase this value to 132 for example. And for other product 142 i must make. For example there are 5 products in this invoice i must make like this ;
first 123
second 133
third 143
fourth 153
fifth 163
but i really don't know how can i do this.
As this. Add a counter, initialize it, and always incrase with 10.
$cnt = 123; //Init the counter
while ($invoices = mysql_fetch_array($invoices_query)) {
$customers_name = $invoices['customer_name'];
$pdf->Ln(0);
$pdf->Cell(21, $cnt, $invoice_number, 0, 0, 'L', 0); // empty cell with left,top, and right borders
$pdf->Cell(30, $cnt, $customers_name, 0, 0, 'L', 0);
$pdf->Cell(20, $cnt, $date, 0, 0, 'L', 0);
$pdf->Cell(20, $cnt, $time, 0, 0, 'L', 0);
$pdf->Cell(30, $cnt, $suburb_from, 0, 0, 'L', 0);
$pdf->Cell(34, $cnt, $suburb_to, 0, 0, 'L', 0);
$pdf->Cell(10, $cnt, '% ' . $tax_percent, 0, 0, 'L', 0);
$pdf->Cell(25, $cnt, '$ ' . $invoice_price, 0, 0, 'R', 0);
$cnt = $cnt + 10; //Incrase it in the loop.
}
NOTE
Do not use mysql functions, they are deprecated. Use mysqli or PDO instead.
Avoid sql injections by escaping your variables comes from outside, or use prepared statements.

php gd - multicolor imagettftext

I'm trying to put multicolor text through imagettftext.
I tried drawing letter by letter but the spacing is horrible.
Here's my code:
$usrname_split = str_split("MarioErmando");
$onecharwidth = imagefontwidth((int)$font)*(12/8);
foreach($usrname_split as $key=>$letter){
if($key == 0){
// first letter
imagettftext($im, 12, 0, $xusrname, 15, $blue, $font, $letter);
$oldletters = "$letter";
}else{
$posarr=imageftbbox(12, 0 ,$font, $oldletters);
$posx = $posarr["2"];
imagefttext($im, 12, 0, $posx, 15, $red, $font, $letter);
$oldletters .= "$letter";
}
}
The output:
Note that the text is dynamic.
Is it possible to achieve multicolor text through imagettftext without horrible spacing?
Regards, MarioErmando.
in order to test, replace your code by this one:
$string="Mario Ermando";
$last_string= substr( $string, 1 );
imagettftext($im, 12, 0, $xusrname, 20, $blue, $font, $string[0]); //first letter "M"
imagefttext($im, 12, 0, 12, 20, $red, $font, $last_string);
i think the problem is when you write every letter separately

PHP Normalise percentage values across range

I have an array of numbers and the ammount of properties in the array cannot be determined.
example:
array(30, 30, 10, 20, 60);
array(2, 53, 71, 22);
array(88, 22, 8);
etc...
Now normally, the sum of all the array values will be 100 or less.
What I want to do is, when they are over 100, reduce them all to make it equal to 100. Normally i would just divide the difference and then take away but for example, the first array adds up to 150, and if I divide the difference (50) evenly, i would end up with:
array(20, 20, 0, 10, 50);
But i want the numbers to be subtracted according to their size, so 30 would have a larger chunk taken out then 10.
The way I would do it is divide each value by (total_sum / 100), and that works perfectly. Now what I need to do is be able to select one value which becomes dominant and cannot be subtracted from then subtract all other values until sum is 100. Example below:
array(20, 20, 80); // 80 is the dominant number
After normalising, the array would be:
array(10, 10, 80);
Example 2:
array(20, 20, 40, 60); // 40 is dominant number
after normalising:
array(10, 10, 40, 20) // maybe it wouldnt be those exact values bhut just to show how different size numbers get reduced according to size. But now total sum is 100
Example 3:
array(23, 43, 100, 32) // 100 is dominant
normalise
array(0, 0, 100, 0);
I have tried so many things but nothing seems to work. How would i accomplish this?
Thanks
If I understand your problem correctly, you're just about done. Just remove the dominant value from your input array, reduce the 100 by that value, and do the rest like before:
function helper($values, $sum) {
$f = array_sum($values) / $sum;
return array_map(function ($v) use($f) {
return $v / $f;
}, $values);
}
// input
$a = array(20, 20, 40, 60);
// remove the dominant value (index: 2)
$b = array_splice($a, 2, 1);
// `normalize` the remaining values using `100 - dominant value` instead of `100`
$c = helper($a, 100 - $b[0]);
// re-inject the dominant value
array_splice($c, 2, 0, $b);
// output
print_r($c); // => [12, 12, 40, 36]
Try this?
function normalise_array($array_to_work_on,$upper_limit){
$current_total = array_sum($array_to_work_on);
$reduce_total_by = $current_total - $upper_limit;
$percentage_to_reduce_by = floor(($reduce_total_by / $current_total) * 100);
$i = 0;
$new_array;
foreach($array_to_work_on as $item){
$reduce = ($item / 100) * $percentage_to_reduce_by;
$new_array[$i] = floor($item - $reduce);
$i ++;
echo $new_array[$i];
}
return($new_array);
}
$numbers1 = array(30, 30, 10, 20, 89);
print_r(normalise_array($numbers1,20));
echo "<br />";
echo "<br />First array total: ".array_sum(normalise_array($numbers1,20));
echo "<br /><br/ >";
$numbers2 = array(234, 30, 10, 20, 60);
print_r(normalise_array($numbers2,100));
echo "<br />First array total: ".array_sum(normalise_array($numbers2,100));

Categories