Topic: TCPDF Module - Override Any Existing FA Reports

I have made this module with TCPDF to over ride existing FA Reports with your own fancy report. Though you need basic PHP knowledge to make one.

No pre made reports has been provided with this module.

I have included Demo Rep107 as an example, get an idea from it.

See TCPDF examples here https://tcpdf.org/examples/

TCPDF Module Github https://github.com/impulse-solutions/FA-TCPDF

Regards

Mohsin Mujawar
Impulse Solutions

Re: TCPDF Module - Override Any Existing FA Reports

Provide screenshot of sample invoice.

TCPDF version used here is v6.3.2 - circa a year ago vintage.

What was sought to be achieved using the new TCPDF version?

Provide info on README.md as to which folder should be overwritten and what checks have been made to integrate with existing FrontAccounting Box report constructs.

Re: TCPDF Module - Override Any Existing FA Reports

I don't understand what is achieved with this version of TCPDF. This version is more than half a GB bigger than our current version, that is working perfectly.

Joe

4 (edited by dearmosin 09/28/2020 06:54:32 pm)

Re: TCPDF Module - Override Any Existing FA Reports

@apmuthu: Sorry for not pushing, README.md to repo. I will update it today with all details.

@joe: Thanks for your reply, you are correct new version is quite heavy and our current version is absolutely working fine and we can include existing TCPDF Class in this module.

FA TCPDF library used  4.0.027 (2008-09-19)
For example: QR Code (2D barcode) support was added from version 4.9.000

Since version 4.0.027 till 6.3.2 CHANGE LOG

I know we can create report placing repXXX.php in company/0/reporting but was stuck in some places eg: loading images, loading new ttf fonts etc. So came up with this.

Purpose of this module, is to overwrite existing FA reports with own template report - We can use existing older / newer or any other PDF library.

We have just pasted TCPDF library into module folder, and include to use it's class for creating pdf files. If we want to use some other library we can do that as well. 

Why this approach?
Changing core system file is not good idea, it may cause problem in updating software and troubleshoot problem.

Only those who need huge customization can you it

So here is what we are doing - First registering our module to enable hook.

define ('IMPULSE_TCPDF', 251<<8);

class hooks_TCPDF extends hooks {

    function __construct() {
        $this->module_name = 'TCPDF';
    }
    
    function install_access() {
        $security_sections[IMPULSE_TCPDF] =  _('TCPDF');
        $security_areas['PULSE_PDF'] = array(IMPULSE_TCPDF|1, _('Allow PDF Printing'));
        return array($security_areas, $security_sections);
    }
    
    function activate_extension($company, $check_only=true) {
        global $db_connections;
        
        $updates = array( 'update.sql' => array('TCPDF'));
 
        return $this->update_databases($company, $updates, $check_only);
    }
    
    function deactivate_extension($company, $check_only=true) {
        global $db_connections;

        $updates = array('remove.sql' => array('TCPDF'));

        return $this->update_databases($company, $updates, $check_only);
    }
    
}

Now when we activate this module and provide access, while printing reports reporting/reports_main.php will scan through each active module searching for module_folder/reporting/reports_custom.php to add report and register controls.

Suppose we want to print rep107 with our template invoice we created with TCPDF or other library. In module_folder/reporting/reports_custom.php

global $reports;

// Override Reports Here
// You Can Find This In reporting/reports_main.php

$reports->addReport(RC_CUSTOMER, 107, _('Print &Invoices'),
    array(    _('From') => 'INVOICE',
            _('To') => 'INVOICE',
            _('Currency Filter') => 'CURRENCY',
            _('email Customers') => 'YES_NO',
            _('Payment Link') => 'PAYMENT_LINK',
            _('Comments') => 'TEXTBOX',
            _('Customer') => 'CUSTOMERS_NO_FILTER',
            _('Orientation') => 'ORIENTATION',
            _('Copy') => 'INV_COPY'
));

// Example To Register Controls

function invoice_copy($name, $type) {
    if($type == 'INV_COPY')
        return "<select name = '".$name."'><option value='0'>"._('Original Copy For Recipient')."</option><option value='1'>"._('Duplicate Copy For Transporter ')."</option><option value='2'>"._('Triplicate Copy For Supplier')."</option></select>";
}

$reports->register_controls('invoice_copy');

We have changed $reports object for our module. With new field Copy in Customer -- Print Invoices, same way we can add field or remove field.

Note: Only Those Report Added here Will Be Replace, Other Reports Does Not Have Any Effect.

Now we need last file rep107.php in module_folder/reporting this is invoice template file

<?php
        // $page_security can be found in respective file in reporting folder
        $page_security = 'SA_SALESTRANSVIEW';
        ob_start();

        $path_to_root="..";

        include_once($path_to_root . "/includes/session.inc");
        include_once($path_to_root . "/includes/date_functions.inc");
        include_once($path_to_root . "/includes/data_checks.inc");
        include_once($path_to_root . "/sales/includes/sales_db.inc");
        include_once($path_to_root . "/gl/includes/db/gl_db_currencies.inc");
        include_once($path_to_root . "/inventory/includes/db/items_db.inc");
       // here you can write your own fuctions
        include_once($path_to_root."/modules/TCPDF/reporting/includes/db/rep107_db.php");
       // this can be any PDF Libarary
        require_once($path_to_root . "/modules/TCPDF/tcpdf.php");

// ---------------------------------------------------------
        $from = $_POST['PARAM_0'];
        $to = $_POST['PARAM_1'];
        $invoice_currency = $_POST['PARAM_2'];
        $email = $_POST['PARAM_3'];
        $pay_service = $_POST['PARAM_4'];
        $comments = $_POST['PARAM_5'];
        $customer = $_POST['PARAM_6'];
        $i = $_POST['PARAM_7'];

        if (!$from || !$to) return;

        $dec = user_price_dec();

        $fno = explode("-", $from);
        $tno = explode("-", $to);
        $from = min($fno[0], $tno[0]);
        $to = max($fno[0], $tno[0]);
        $range = get_invoice_range($from, $to);
        
        // Demo Invoice Starts
        // In this example HTML is used to create PDF file.
        $html = '
        <style>
        table, tr, td {
        padding: 15px;
        }
        </style>
        <table style="background-color: #222222; color: #fff">
        <tbody>
        <tr>
        <td><h1>INVOICE<strong> #21234</strong></h1></td>
        <td align="right">
        123 street, ABC Store<br/>
        Country, State, 00000
        <br/>
        <strong>+00-1234567890</strong> | <strong>abc@xyz</strong>
        </td>
        </tr>
        </tbody>
        </table>
        ';
        $html .= '
        <table>
        <tbody>
        <tr>
        <td>Invoice to<br/>
        <strong>Demo Customer</strong>
        <br/>
        123 street, ABC Store<br/>
        Country, State, 00000
        </td>
        <td align="right">
        <strong>Total Due: $ 23,442.00/strong><br/>
        Tax ID: ABCDEFGHIJ12345<br/>
        Invoice Date: '.date('d-m-Y').'
        </td>
        </tr>
        </tbody>
        </table>
        ';
        $html .= '
        <table>
        <thead>
        <tr style="font-weight:bold;">
        <th>Item name</th>
        <th>Price</th>
        <th>Quantity</th>
        <th>Total</th>
        </tr>
        </thead>
        <tbody>';
        $html .= '
        <tr>
        <td style="border-bottom: 1px solid #222">Demo Item</td>
        <td style="border-bottom: 1px solid #222">$23,422.00</td>
        <td style="border-bottom: 1px solid #222">1</td>
        <td style="border-bottom: 1px solid #222">$23,422.00</td>
        </tr>
        ';
        $html .='
        <tr align="right">
        <td colspan="4"><strong>Grand total: $23,422.00</strong></td>
        </tr>
        <tr>
        <td colspan="4">
        <h2>Thank you for your business.</h2><br/>
        <strong>Terms and conditions:<br/></strong>
        It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using Content here, content here, making it look like readable English.
        </td>
        </tr>
        </tbody>
        </table>';
        // create new PDF document
        $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
        // set default monospaced font
        // set margins
        $pdf->SetMargins(-1, 0, -1);
        // remove default header/footer
        $pdf->setPrintHeader(false);
        $pdf->setPrintFooter(false);
        // set auto page breaks
        $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
        // set image scale factor
        $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
        // Set font
        $pdf->SetFont('helvetica', '', 10);
        $pdf->AddPage();
        // Print text using writeHTMLCell()
        $pdf->writeHTMLCell(0, 0, '', '', $html, 0, 0, 0, true, '', true);
        // Demo Invoice Ends

        ob_end_clean();

        $filename = 'Invoice';


        $root_dir =  $_SERVER['DOCUMENT_ROOT'].substr(company_path(),3). '/pdf_files';
        $dir = company_path(). '/pdf_files';

        $fname = $root_dir.'/'.$filename.'.pdf';
        $pdf->Output($fname, 'F');


        if ($d = @opendir($dir)) {
        while (($file = readdir($d)) !== false) {
            if (!is_file($dir.'/'.$file) || $file == 'index.php') continue;
            $ftime = filemtime($dir.'/'.$file);
            if (time()-$ftime > 180){
                unlink($dir.'/'.$file);
            }
        }
        closedir($d);
        }

        global $Ajax;
        $Ajax->popup($dir.'/'.$filename.'.pdf'); 
        exit;

In the above example we included

       // here you can write your own fuctions for this template.
        include_once($path_to_root."/modules/TCPDF/reporting/includes/db/rep107_db.php");
       // this can be any PDF Libarary you are trying to print invoice with
        require_once($path_to_root . "/modules/TCPDF/tcpdf.php");

That's it now whenever user try to print invoice this report will print.

Here is sample Invoice Format I Created With TCPDF / dompdf in FrontAccountingERP

Invoice Template 1 - Rep107
Invoice Template 2  - Rep107
Invoice Template 3 - Rep107
Receipt Template 1 - Rep112

Your suggestion, thoughts and comment are appreciated.

Regards

Mohsin Mujawar
Impulse Solutions

Re: TCPDF Module - Override Any Existing FA Reports

hi dearmosin
can you guide me how to implement this? i dont understand the hooks thing in the first step to register module

Re: TCPDF Module - Override Any Existing FA Reports

I will soon update this module with some reports like Invoice Receipt, which will give you clear idea on how to use it. If you urgently need any help PM me.

Mohsin Mujawar
Impulse Solutions