Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add FPDF totals to the last row of tables?

I have a set of tables categorized by their source e.g: "Client", "Stock", "Floorstock". They look like this:

List of Floor Stock orders

Each contain lists of prices, which need to be added up and totaled on the last row of the tables.

I'm having problems linking a "totals" array to the "tables" array - specifically displaying each total at the end of each table

So far, the totals of each table are generated in another function, where sourceTotals is an instance array:

public function setSourceTotalsArray($data)
{
    $this->sourceTotals = $data["source_totals"];
    return $this->sourceTotals;
}

This returns an array that looks like this:

array(4) { ["Floorstock"]=> int(0) ["Stock"]=> int(0) ["Client"]=> float(32.18)  } 

Here's where I define my $pdf object:

if($_SERVER["REQUEST_METHOD"] == "POST"){
$data = json_decode($_POST["printData"],true);
$pdf = new PDF();
// Column headings
$month = $pdf->getMonth($data['month']);
$year = $data['year'];
$pdf->SetFont('Arial','',10);
$pdf->AddPage();
$pdf>title(array('month'=>$month,'year'=>$year,'showroom'=>ucfirst($data['showroom_name'])));
$pdf->tableBody($data);

if(!empty($data["order_detail"])){
    $customerOrders = array();
    $stockOrders = array();
    $floorstockOrders = array();
    $otherOrders = array();

    foreach($data["order_detail"] as $o){
        switch($o["orderSource"]){
            case 'Client':
                $customerOrders[] = $o;
                break;
            case 'Stock':
                $stockOrders[] = $o;
                break;
            case 'Floorstock':
                $floorstockOrders[] = $o;
                break;

            default:
                $otherOrders[] = $o;
                break;
        }
    }

    if (!empty($customerOrders)) {
        $pdf->orderDetail($customerOrders, $data['currency'], 'Client');
    }

    if (!empty($stockOrders)) {
        $pdf->orderDetail($stockOrders, $data['currency'], 'Stock');
    }

    if (!empty($floorstockOrders)) {
        $pdf->orderDetail($floorstockOrders, $data['currency'], 'Floor Stock');
    }

    if (!empty($otherOrders)) {
        $pdf->orderDetail($otherOrders, $data['currency'], 'Client');
    }
}
$pdf->Output();

The orderDetail function is what structures the table within the $pdf object so that the table has cells that correspond to the correct column name:

function orderDetail($data,$currencyShortCode, $type){
    $this->orderType = $type;
    list($currencySymbol, $w_symbol, $cellHight) = $this->getOrderDetailHeader($currencyShortCode, $type);

    foreach ($data as $d){
        $commaValue = $this->addComma((float)$d['value']);
        $this->Cell(15,$cellHight,$d['order_no'],'LTB',0,'L');
        $this->Cell(20,$cellHight,substr($d['customer'],0,13),'TB',0,'L');
        $this->Cell(20,$cellHight,substr($d['company'],0,13),'TB',0,'L');
        $this->Cell(20,$cellHight,substr($d['ref'],0,13),'TB',0,'L');           
        $this->Cell(2,$cellHight,'','TB',0,'R');
        $this->Cell($w_symbol,$cellHight,$currencySymbol,'TB',0,'R');
        $this->Cell(16-$w_symbol,$cellHight,$commaValue,'TB',0,'R');
        $this->Cell(2,$cellHight,'','TB',0,'R');
        $this->Cell(10,$cellHight,$d['cat'],'TB',0,'L');
        $this->Cell(84,$cellHight,$d['description'],'RTB',0,'L');
        $this->Ln($cellHight);
    }
    //BOTTOM TOTAL
    $this->Cell(13,$cellHight,'TOTAL','LRTB',0,'L');
    $this->Cell(22,$cellHight,'','TB',0,'L');
    $this->Cell(20,$cellHight,'','TB',0,'L');
    $this->Cell(20,$cellHight,'','TB',0,'L');
    $this->Cell(4,$cellHight,$currencySymbol,'TB',0,'R');
    $this->Cell(14,$cellHight,$this->setSourceTotalsArray($data),'TB',0,'R'); //HERE
    $this->Cell(2,$cellHight,'','TB',0,'R');
    $this->Cell(10,$cellHight,'','TB',0,'L');
    $this->Cell(84,$cellHight,'','RTB',0,'L');
}

I'm just not sure how to pass setSourceTotalsArray into orderDetail, as my current attempt only returns null.

like image 977
hello world Avatar asked Oct 09 '17 11:10

hello world


2 Answers

Your setSourceTotalsArray method doesn't really do anything, so if it returns null that means $data does not have a source_totals node. (Suggestion/sidenote: set error reporting to E_ALL so PHP will warn you about this; then for live environments turn display_errors off and enable log_errors so you'll see the errors in the log but your visitors won't see them on the screen.) The reason source_totals does not exist in $data is that the $datavariable insideorderDetailis only a subset of$data` in the full script.

What I would do is add a $total argument to orderDetail. You the get something like this:

function orderDetail($data,$currencyShortCode, $type, $total) {
    ...
    $this->Cell(14,$cellHight, $total,'TB',0,'R'); //HERE
    ...
}

And

if (!empty($customerOrders)) {
    $pdf->orderDetail($customerOrders, $data['currency'], 'Client', $data['source_totals']['Client']);
}
// Also add the 4th argument for stock orders, floor orders and others.
like image 62
Jory Geerts Avatar answered Sep 28 '22 09:09

Jory Geerts


Another fantastic way to generate PDF is simply using the wkhtmltopdf binary.

if you already have a report, that generates html, you can use output buffering to generate html and then convert to pdf, it can run on most environments and you can control exactly the output you want, just like WebKit (Chrome, Safari, etc.) do it, using a familiar language (HTML).

HTH.

like image 45
Felipe Valdes Avatar answered Sep 28 '22 08:09

Felipe Valdes