Using FPDI to append third-party PDF documents to webERP system output PDF files


22nd Feb 2008 note this mod is now standard part of 3.09

25th Jan 08 - updated to reflect changes required from webERP v3.08.

This modification allows an option to append a pre-prepared PDF file, to the dynamically produced Invoice and Credit Note PDF files from webERP. For example, we can now append a materials handling sheet, or a product safety sheet, or a terms and conditions sheet, to an Invoice and Credit Note.

<Phil>I'm not sure if the document to append should be determined by reference to the customer or perhaps by the items on the invoice. - this implementation has a document selected per customer and it is sent with every customer</Phil> <emdee> This implementation actually has a PDF document per stock item, its attached only if the stock item is on the invoice. </emdee>

An appended PDF file can be either Landscape, or Portrait orientation, the resulting PDF can contain both a Landscape invoice, and a Portrait information sheet.

Installation


We require at least FPDF version 1.53. Make sure your includes/fpdf.php file is up-to-date. <emdee> The current 3.08 weberp package has an older version of FPDF, you need to overwrite with the latest versions. </emdee>

To retain compatibility with the other PDF documents, make this change to the new fpdf.php file,
line 994, replace:
function Output($name=,$dest=)
with
function Output($name='pdf',$dest='S')

We require at least FPDI version 1.2. Download FPDI package, unzip and move to fpdi directory under webERP installation root.

http://www.fpdf.org/
http://www.setasign.de/products/pdf-php-solutions/fpdi/

ALTER TABLE `stockmaster` ADD `appendfile` varchar(40) NOT NULL ;


The code below will check if a stockitem needs a PDF appended.

diff PrintCustTrans.php.3.08 PrintCustTrans.php.new
6a7,15
> error_reporting (E_ALL);
>
>
>
>
>
>
>
>
44c53,55
<
---
>       define('FPDF_FONTPATH','font/');
>       require('fpdi/fpdi.php');
>
69a81
>
342a355
>
419,420c432,433
<                       $FontSize=6;
<                       $LeftOvers = $pdf->addTextWrap($Left_Margin+300,$YPos-2,245,$FontSize,$_SESSION['RomalpaClause']);
---
>                       $FontSize=9;
>                       $LeftOvers = $pdf->addTextWrap($Left_Margin+300,$YPos-4,245,$FontSize,$_SESSION['RomalpaClause']);
422c435
<                               $YPos -=7;
---
>                               $YPos-=14;
424a438,442
>                       /* Add Images for Visa / Mastercard / Paypal */
>               $pdf->addJpegFromFile('companies/' . $_SESSION['DatabaseName'] . '/payment.jpg',$Page_Width/2 -280,$YPos-20,0,40);
>                       $pdf->addText($Page_Width-$Right_Margin-472, $YPos - ($line_height*3)+32,$FontSize, _('Bank Code: *** Bank Account: ***'));
>
>
435,436c453
<
<       $pdfcode = $pdf->output();
---
>       $pdfcode = $pdf->output("invoice.pdf", "F");
437a455,532
>
>
> // Start FPDI concatination to append PDF files conditionally to the invoice
> // This part taken from FPDI example page
> class concat_pdf extends FPDI {
>
>           var $files = array();
>
>           function setFiles($files) {
>               $this->files = $files;
>           }
>
>           function concat() {
>               foreach($this->files AS $file) {
>                   $pagecount = $this->setSourceFile($file);
>                   for ($i = 1; $i <= $pagecount; $i++) {
>                        $tplidx = $this->ImportPage($i);
>                        $s = $this->getTemplatesize($tplidx);
>                        $this->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
>                        $this->useTemplate($tplidx);
>                   }
>               }
>           }
>
>       }
>
>       $pdf =& new concat_pdf();
> // Have to get the TransNo again, not sure what happens if we have a series of trans nos
> if (isset($_GET['FromTransNo'])){
>       $FromTransNo = trim($_GET['FromTransNo']);
> } elseif (isset($_POST['FromTransNo'])){
>       $FromTransNo = trim($_POST['FromTransNo']);
> }
> // Check its an Invoice type again, then select appendfile filename
> //if ($InvOrCredit=='Invoice'){
>                        //$sql = 'SELECT stockmoves.stockid, stockmaster.appendfile
>                               //      FROM stockmoves,
>                                       //stockmaster
>                               //WHERE stockmoves.stockid = stockmaster.stockid
>                               //AND stockmoves.type=10
>                               //AND stockmoves.transno=' . $FromTransNo . '
>                               //AND stockmoves.show_on_inv_crds=1';
>               //};
>
>                        $sql = 'SELECT stockmoves.stockid, stockmaster.appendfile
>                                       FROM stockmoves,
>                                       stockmaster
>                               WHERE stockmoves.stockid = stockmaster.stockid
>                               AND stockmoves.type=10
>                               AND stockmoves.transno=' . $FromTransNo . '
>                               AND stockmoves.show_on_inv_crds=1';
>
>
>
>
>
>
>
>
>
>
> $result=DB_query($sql,$db);
> // Loop the result set and add appendfile if the field is not 0
> while ($row=DB_fetch_array($result)){
> if ($row['appendfile'] !='0') {
> $pdf->setFiles(array('invoice.pdf','pdf_append/' . $row['appendfile']));
> $pdf->concat();
> $pdf->Output('newpdf.pdf','I');
> exit;
> // If the appendfile field is empty, just print the invoice without any appended pages
> } else {
> $pdf->setFiles(array('invoice.pdf'));
> $pdf->concat();
> $pdf->Output('newpdf.pdf','D');
> exit;
> }
> }
> //End FPDI Concat
1013c1108
< ?>
\ No newline at end of file
---
> ?>


Then we modify Stocks.php, so that an item can have a PDF file attached to it.

You have to add the PDF files to a directory named "pdf_append" under your root weberp directory.

The drop down list is populated with all the PDF files within that directory. Under Item Maintenance, you can now choose which PDF file to attach, or choose 'none'.

NB I have added several "\n" line breaks to Stocks.php to aid HTML debugging.

diff Stocks.php.3.08 Stocks.php.new
30c30
< echo "<A HREF='" . $rootpath . '/SelectProduct.php?' . SID . "'>" . _('Back to Items') . '</A><BR>';
---
> echo "<A HREF='" . $rootpath . '/SelectProduct.php?' . SID . "'>" . _('Back to Items') . '</A><BR>' . "\n";
242c242,243
<                                                       decimalplaces=" . $_POST['DecimalPlaces'] . "
---
>                                                       decimalplaces=" . $_POST['DecimalPlaces'] . ",
>                                                       appendfile='" . $_POST['ItemPDF'] . "'
300c301,302
<                                                       decimalplaces)
---
>                                                       decimalplaces,
>                                                       appendfile)
316c318,319
<                                                       " . $_POST['DecimalPlaces']. "
---
>                                                       " . $_POST['DecimalPlaces']. ",
>                                                       '" . $_POST['ItemPDF']. "'
350a354
>                                               unset($_POST['ItemPDF']);
358c362
<               echo '<BR>';
---
>               echo '<BR>'. "\n";
464a469
>               unset($_POST['ItemPDF']);
475c480
<       <tr><td><table>'; //Nested table
---
>       <tr><td><table>'. "\n"; //Nested table
482c487
<       echo '<input type="hidden" name="New" value="1">';
---
>       echo '<input type="hidden" name="New" value="1">'. "\n";
484c489
<       echo '<TR><TD>'. _('Item Code'). ':</TD><TD><INPUT TYPE="TEXT" NAME="StockID" SIZE=21 MAXLENGTH=20></TD></TR>';
---
>       echo '<TR><TD>'. _('Item Code'). ':</TD><TD><INPUT TYPE="TEXT" NAME="StockID" SIZE=21 MAXLENGTH=20></TD></TR>'. "\n";
503c508,509
<                       decimalplaces
---
>                       decimalplaces,
>                       appendfile
512a519,521
>       // add PDF attachment code
>       $_POST['ItemPDF']  = $myrow['appendfile'];
>       // end PDF attachment code
526c535
<       echo '<TR><TD>' . _('Item Code') . ':</TD><TD>'.$StockID.'</TD></TR>';
---
>       echo '<TR><TD>' . _('Item Code') . ':</TD><TD>'.$StockID.'</TD></TR>'. "\n";
530,531c539,540
<       echo '<TR><TD>' . _('Item Code') . ':</TD><TD>'.$StockID.'</TD></TR>';
<       echo "<input type='Hidden' name='StockID' value='$StockID'>";
---
>       echo '<TR><TD>' . _('Item Code') . ':</TD><TD>'.$StockID.'</TD></TR>'. "\n";
>       echo "<input type='Hidden' name='StockID' value='$StockID'>". "\n";
535c544,546
< echo '<TR><TD>' . _('Part Description') . ' (' . _('short') . '):</TD><TD><input type="Text" name="Description" SIZE=52 MAXLENGTH=50 value="' . htmlentities($_POST['Description'],ENT_QUOTES,_('ISO-8859-1')) . '"></TD></TR>';
---
> echo '<TR><TD>' . _('Part Description') . ' (' . _('short') . '):</TD><TD><input type="Text" name="Description" SIZE=52 MAXLENGTH=50 value="' . htmlentities($_POST['Description'],ENT_QUOTES,_('ISO-8859-1')) . '"></TD></TR>'. "\n";
>
> echo '<TR><TD>' . _('Part Description') . ' (' . _('long') . '):</TD><TD><textarea name="LongDescription" cols=40 rows=4>' . htmlentities($_POST['LongDescription'],ENT_QUOTES,_('ISO-8859-1')) . '</textarea></TD></TR>'. "\n";
537c548,584
< echo '<TR><TD>' . _('Part Description') . ' (' . _('long') . '):</TD><TD><textarea name="LongDescription" cols=40 rows=4>' . htmlentities($_POST['LongDescription'],ENT_QUOTES,_('ISO-8859-1')) . '</textarea></TD></TR>';
---
> // Add PDF attachment upload for Items  - by Emdx
> if ($_POST['ItemPDF']=='' or !isset($_POST['ItemPDF'])){
>     $_POST['ItemPDF']="No PDF set";
> }
> // Generate selection drop down from pdf_append directory - by emdx, developed with examples from http://au2.php.net/manual/en/function.opendir.php
> function select_files($dir, $label = "", $select_name = "", $curr_val = "", $char_length = 60) {
>     $teller = 0;
>     if ($handle = opendir($dir)) {
>         $mydir = ($label != "") ? "<label for=\"".$select_name."\">".$label."</label>\n" : "";
>         $mydir .= "<select name=\"".$select_name."\">\n";
>         $curr_val = (isset($_REQUEST[$select_name])) ? $_REQUEST[$select_name] : $curr_val;
>         $mydir .= ($curr_val == "0") ? "  <option value=\"0\" selected>none\n" : "<option value=\"\">...\n";
>         while (false !== ($file = readdir($handle))) {
>             $files[] = $file;
>         }
>         closedir($handle);
>         sort($files);
>         foreach ($files as $val) {
>             if (is_file($dir.$val)) { // show only real files (ver. 1.01)
>                 $mydir .= "    <option value=\"".$val."\"";
>                 $mydir .= ($val == $curr_val) ? " selected>" : ">";
>                 $mydir .= (strlen($val) > $char_length) ? substr($val, 0, $char_length)."...\n" : $val."\n";
>                 $teller++;
>             }
>         }
>         $mydir .= "</select>";
>     }
>     if ($teller == 0) {
>         $mydir = "No files!";
>     } else {
>         return $mydir;
>     }
> }
>
> echo '<tr><td>' . _('PDF attachment (.pdf)') . ':</TD><TD>' . "\n" . select_files("companies/' . $_SESSION['DatabaseName'] .'/pdf_append/", "", "ItemPDF", $_POST['ItemPDF'], "60") . '</td></tr>'. "\n";
> //echo '<TR><TD>' . _('PDF attachment (.pdf) orig') . ':</TD><TD><input type="text" SIZE=20 MAXLENGTH=50 value="' . $_POST['ItemPDF'] . '" name="ItemPDF"> ' . $_POST['ItemPDF'] . '</TD></TR>'. "\n";
> // EOR Add Image upload for New Item  - by Emdx
540c587
< echo '<tr><td>'. _('Image File (.jpg)') . ':</td><td><input type="file" id="ItemPicture" name="ItemPicture"></td></tr>';
---
> echo '<tr><td>'. _('Image File (.jpg)') . ':</td><td><input type="file" id="ItemPicture" name="ItemPicture"></td></tr>'. "\n";
543c590
< echo '<tr><td>' . _('Category') . ':</td><td><select name="CategoryID" onChange="ReloadForm(this.form)">';
---
> echo '<tr><td>' . _('Category') . ':</td><td><select name="CategoryID" onChange="ReloadForm(this.form)">'. "\n";
552c599
<               echo '<OPTION SELECTED VALUE="'. $myrow['categoryid'] . '">' . $myrow['categorydescription'];
---
>               echo '<OPTION SELECTED VALUE="'. $myrow['categoryid'] . '">' . $myrow['categorydescription']. "\n";
554c601
<               echo '<OPTION VALUE="'. $myrow['categoryid'] . '">' . $myrow['categorydescription'];
---
>               echo '<OPTION VALUE="'. $myrow['categoryid'] . '">' . $myrow['categorydescription']. "\n";
585c632
< echo '<TR><TD>' . _('Economic Order Quantity') . ':</TD><TD><input type="Text" name="EOQ" SIZE=12 MAXLENGTH=10 Value="' . $_POST['EOQ'] . '"></TD></TR>';
---
> echo '<TR><TD>' . _('Economic Order Quantity') . ':</TD><TD><input type="Text" name="EOQ" SIZE=12 MAXLENGTH=10 Value="' . $_POST['EOQ'] . '"></TD></TR>'. "\n";
587c634
< echo '<TR><TD>' . _('Packaged Volume (metres cubed)') . ':</TD><TD><input type="Text" name="Volume" SIZE=12 MAXLENGTH=10 value="' . $_POST['Volume'] . '"></TD></TR>';
---
> echo '<TR><TD>' . _('Packaged Volume (metres cubed)') . ':</TD><TD><input type="Text" name="Volume" SIZE=12 MAXLENGTH=10 value="' . $_POST['Volume'] . '"></TD></TR>'. "\n";
589c636
< echo '<TR><TD>' . _('Packaged Weight (KGs)') . ':</TD><TD><input type="Text" name="KGS" SIZE=12 MAXLENGTH=10 value="' . $_POST['KGS'] . '"></TD></TR>';
---
> echo '<TR><TD>' . _('Packaged Weight (KGs)') . ':</TD><TD><input type="Text" name="KGS" SIZE=12 MAXLENGTH=10 value="' . $_POST['KGS'] . '"></TD></TR>'. "\n";
591c638
< echo '<TR><TD>' . _('Units of Measure') . ':</TD><TD><SELECT name="Units">';
---
> echo '<TR><TD>' . _('Units of Measure') . ':</TD><TD><SELECT name="Units">'. "\n";
599c646
<           echo "<OPTION SELECTED Value='" . $UOMrow['unitname'] . "'>" . $UOMrow['unitname'];
---
>           echo "<OPTION SELECTED Value='" . $UOMrow['unitname'] . "'>" . $UOMrow['unitname']. "\n";
601c648
<           echo "<OPTION Value='" . $UOMrow['unitname'] . "'>" . $UOMrow['unitname'];
---
>           echo "<OPTION Value='" . $UOMrow['unitname'] . "'>" . $UOMrow['unitname']. "\n";
605c652
< echo '</SELECT></TD></TR>';
---
> echo '</SELECT>' . "\n" . '</TD></TR>'. "\n";
607c654
< echo '<TR><TD>' . _('Make, Buy, Kit, Assembly or Service Part') . ':</TD><TD><SELECT name="MBFlag">';
---
> echo '<TR><TD>' . _('Make, Buy, Kit, Assembly or Service Part') . ':</TD><TD><SELECT name="MBFlag">'. "\n";
609c656
<       echo '<OPTION SELECTED VALUE="A">' . _('Assembly');
---
>       echo '<OPTION SELECTED VALUE="A">' . _('Assembly'). "\n";
611c658
<       echo '<OPTION VALUE="A">' . _('Assembly');
---
>       echo '<OPTION VALUE="A">' . _('Assembly'). "\n";
614c661
<       echo '<OPTION SELECTED VALUE="K">' . _('Kit');
---
>       echo '<OPTION SELECTED VALUE="K">' . _('Kit'). "\n";
616c663
<       echo '<OPTION VALUE="K">' . _('Kit');
---
>       echo '<OPTION VALUE="K">' . _('Kit'). "\n";
619c666
<       echo '<OPTION SELECTED VALUE="M">' . _('Manufactured');
---
>       echo '<OPTION SELECTED VALUE="M">' . _('Manufactured'). "\n";
621c668
<       echo '<OPTION VALUE="M">' . _('Manufactured');
---
>       echo '<OPTION VALUE="M">' . _('Manufactured'). "\n";
624c671
<       echo '<OPTION SELECTED VALUE="B">' . _('Purchased');
---
>       echo '<OPTION SELECTED VALUE="B">' . _('Purchased'). "\n";
626c673
<       echo '<OPTION VALUE="B">' . _('Purchased');
---
>       echo '<OPTION VALUE="B">' . _('Purchased'). "\n";
630c677
<       echo '<OPTION SELECTED VALUE="D">' . _('Service');
---
>       echo '<OPTION SELECTED VALUE="D">' . _('Service'). "\n";
632c679
<       echo '<OPTION VALUE="D">' . _('Service');
---
>       echo '<OPTION VALUE="D">' . _('Service'). "\n";
637c684
< echo '<TR><TD>' . _('Current or Obsolete') . ':</TD><TD><SELECT name="Discontinued">';
---
> echo '<TR><TD>' . _('Current or Obsolete') . ':</TD><TD><SELECT name="Discontinued">'. "\n";
639c686
<       echo '<OPTION SELECTED VALUE=0>' . _('Current');
---
>       echo '<OPTION SELECTED VALUE=0>' . _('Current'). "\n";
641c688
<       echo '<OPTION VALUE=0>' . _('Current');
---
>       echo '<OPTION VALUE=0>' . _('Current'). "\n";
644c691
<       echo '<OPTION SELECTED VALUE=1>' . _('Obsolete');
---
>       echo '<OPTION SELECTED VALUE=1>' . _('Obsolete'). "\n";
646c693
<       echo '<OPTION VALUE=1>' . _('Obsolete');
---
>       echo '<OPTION VALUE=1>' . _('Obsolete'). "\n";
650c697
< echo '<TR><TD>' . _('Batch, Serial or Lot Control') . ':</TD><TD><SELECT name="Controlled">';
---
> echo '<TR><TD>' . _('Batch, Serial or Lot Control') . ':</TD><TD><SELECT name="Controlled">'. "\n";
653c700
<       echo '<OPTION SELECTED VALUE=0>' . _('No Control');
---
>       echo '<OPTION SELECTED VALUE=0>' . _('No Control'). "\n";
655c702
<         echo '<OPTION VALUE=0>' . _('No Control');
---
>         echo '<OPTION VALUE=0>' . _('No Control'). "\n";
658c705
<       echo '<OPTION SELECTED VALUE=1>' . _('Controlled');
---
>       echo '<OPTION SELECTED VALUE=1>' . _('Controlled'). "\n";
660c707
<       echo "<OPTION VALUE=1>" . _('Controlled');
---
>       echo "<OPTION VALUE=1>" . _('Controlled'). "\n";
664c711
< echo '<TR><TD>' . _('Serialised') . ':</TD><TD><SELECT name="Serialised">';
---
> echo '<TR><TD>' . _('Serialised') . ':</TD><TD><SELECT name="Serialised">'. "\n";
667c714
<         echo '<OPTION SELECTED VALUE=0>' . _('No');
---
>         echo '<OPTION SELECTED VALUE=0>' . _('No'). "\n";
669c716
<         echo '<OPTION VALUE=0>' . _('No');
---
>         echo '<OPTION VALUE=0>' . _('No'). "\n";
672c719
<         echo '<OPTION SELECTED VALUE=1>' . _('Yes');
---
>         echo '<OPTION SELECTED VALUE=1>' . _('Yes'). "\n";
674c721
<         echo '<OPTION VALUE=1>' . _('Yes');
---
>         echo '<OPTION VALUE=1>' . _('Yes'). "\n";
676c723
< echo '</SELECT><i>' . _('Note') . ', ' . _('this has no effect if the item is not Controlled') . '</i></TD></TR>';
---
> echo '</SELECT><i>' . _('Note') . ', ' . _('this has no effect if the item is not Controlled') . '</i></TD></TR>'. "\n";
678c725
< echo '<TR><TD>' . _('Decimal Places to Display') . ':</TD><TD><input type="Text" name="DecimalPlaces" SIZE=1 MAXLENGTH=1 value="' . $_POST['DecimalPlaces'] . '"><TD></TR>';
---
> echo '<TR><TD>' . _('Decimal Places to Display') . ':</TD><TD><input type="Text" name="DecimalPlaces" SIZE=1 MAXLENGTH=1 value="' . $_POST['DecimalPlaces'] . '"><TD></TR>'. "\n";
680c727
< echo '<TR><TD>' . _('Bar Code') . ':</TD><TD><input type="Text" name="BarCode" SIZE=22 MAXLENGTH=20 value="' . $_POST['BarCode'] . '"></TD></TR>';
---
> echo '<TR><TD>' . _('Bar Code') . ':</TD><TD><input type="Text" name="BarCode" SIZE=22 MAXLENGTH=20 value="' . $_POST['BarCode'] . '"></TD></TR>'. "\n";
682c729
< echo '<TR><TD>' . _('Discount Category') . ':</TD><TD><input type="Text" name="DiscountCategory" SIZE=2 MAXLENGTH=2 value="' . $_POST['DiscountCategory'] . '"></TD></TR>';
---
> echo '<TR><TD>' . _('Discount Category') . ':</TD><TD><input type="Text" name="DiscountCategory" SIZE=2 MAXLENGTH=2 value="' . $_POST['DiscountCategory'] . '"></TD></TR>'. "\n";
684c731
< echo '<TR><TD>' . _('Tax Category') . ':</TD><TD><SELECT NAME="TaxCat">';
---
> echo '<TR><TD>' . _('Tax Category') . ':</TD><TD><SELECT NAME="TaxCat">'. "\n";
694c741
<               echo '<OPTION SELECTED VALUE=' . $myrow['taxcatid'] . '>' . $myrow['taxcatname'];
---
>               echo '<OPTION SELECTED VALUE=' . $myrow['taxcatid'] . '>' . $myrow['taxcatname']. "\n";
696c743
<               echo '<OPTION VALUE=' . $myrow['taxcatid'] . '>' . $myrow['taxcatname'];
---
>               echo '<OPTION VALUE=' . $myrow['taxcatid'] . '>' . $myrow['taxcatname']. "\n";
717c764
< echo '</table></td><td><center>' . _('Image') . '<br>'.$StockImgLink . '</center></td></tr></table><center>';
---
> echo '</table></td><td><center>' . _('Image') . '<br>'.$StockImgLink . '</center></td></tr></table><center>'. "\n";
721c768
<       echo '<input type="Submit" name="submit" value="' . _('Insert New Item') . '">';
---
>       echo '<input type="Submit" name="submit" value="' . _('Insert New Item') . '">'. "\n";
Valid XHTML :: Valid CSS: :: Powered by WikkaWikiGet webERP Accounting & Business Management at SourceForge.net. Fast, secure and Free Open Source software downloads