PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php

https://bitbucket.org/speedealing/speedealing
PHP | 967 lines | 643 code | 158 blank | 166 comment | 82 complexity | 42abd8441e40e4e9a9db411d188edcfd MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, GPL-3.0, MIT
  1. <?php
  2. /* Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
  3. * Copyright (C) 2010-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. * or see http://www.gnu.org/
  18. */
  19. /**
  20. * \file htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php
  21. * \ingroup fournisseur
  22. * \brief Class file to generate the supplier invoices with the canelle model
  23. */
  24. require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_invoice/modules_facturefournisseur.php';
  25. require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
  26. require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
  27. require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
  28. require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
  29. /**
  30. * Class to generate the supplier invoices with the canelle model
  31. */
  32. class pdf_canelle extends ModelePDFSuppliersInvoices
  33. {
  34. var $db;
  35. var $name;
  36. var $description;
  37. var $type;
  38. var $phpmin = array(4,3,0); // Minimum version of PHP required by module
  39. var $version = 'dolibarr';
  40. var $page_largeur;
  41. var $page_hauteur;
  42. var $format;
  43. var $marge_gauche;
  44. var $marge_droite;
  45. var $marge_haute;
  46. var $marge_basse;
  47. var $emetteur; // Objet societe qui emet
  48. /**
  49. * Constructor
  50. *
  51. * @param DoliDB $db Database handler
  52. * @param Societe $object Supplier invoice
  53. */
  54. function __construct($db,$object)
  55. {
  56. global $conf,$langs,$mysoc;
  57. $langs->load("main");
  58. $langs->load("bills");
  59. $this->db = $db;
  60. $this->name = "canelle";
  61. $this->description = $langs->trans('SuppliersInvoiceModel');
  62. // Dimension page pour format A4
  63. $this->type = 'pdf';
  64. $formatarray=pdf_getFormat();
  65. $this->page_largeur = $formatarray['width'];
  66. $this->page_hauteur = $formatarray['height'];
  67. $this->format = array($this->page_largeur,$this->page_hauteur);
  68. $this->marge_gauche=10;
  69. $this->marge_droite=10;
  70. $this->marge_haute=10;
  71. $this->marge_basse=10;
  72. $this->option_logo = 1; // Affiche logo
  73. $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION
  74. $this->option_modereg = 1; // Affiche mode reglement
  75. $this->option_condreg = 1; // Affiche conditions reglement
  76. $this->option_codeproduitservice = 1; // Affiche code produit-service
  77. $this->option_multilang = 1; // Dispo en plusieurs langues
  78. $this->franchise=!$mysoc->tva_assuj;
  79. // Get source company
  80. if (! is_object($object->thirdparty)) $object->fetch_thirdparty();
  81. $this->emetteur=$object->thirdparty;
  82. if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined
  83. // Defini position des colonnes
  84. $this->posxdesc=$this->marge_gauche+1;
  85. $this->posxtva=111;
  86. $this->posxup=126;
  87. $this->posxqty=145;
  88. $this->posxdiscount=162;
  89. $this->postotalht=174;
  90. $this->tva=array();
  91. $this->localtax1=array();
  92. $this->localtax2=array();
  93. $this->atleastoneratenotnull=0;
  94. $this->atleastonediscount=0;
  95. }
  96. /**
  97. * Function to build pdf onto disk
  98. *
  99. * @param int $object Id of object to generate
  100. * @param object $outputlangs Lang output object
  101. * @param string $srctemplatepath Full path of source filename for generator using a template file
  102. * @param int $hidedetails Do not show line details
  103. * @param int $hidedesc Do not show desc
  104. * @param int $hideref Do not show ref
  105. * @return int 1=OK, 0=KO
  106. */
  107. function write_file($object,$outputlangs='',$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
  108. {
  109. global $user, $langs, $conf, $mysoc, $hookmanager;
  110. if (! is_object($outputlangs)) $outputlangs=$langs;
  111. // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
  112. if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
  113. $outputlangs->load("main");
  114. $outputlangs->load("dict");
  115. $outputlangs->load("companies");
  116. $outputlangs->load("bills");
  117. $outputlangs->load("products");
  118. $default_font_size = pdf_getPDFFontSize($outputlangs);
  119. if ($conf->fournisseur->dir_output.'/facture')
  120. {
  121. $object->fetch_thirdparty();
  122. $deja_regle = $object->getSommePaiement();
  123. //$amount_credit_notes_included = $object->getSumCreditNotesUsed();
  124. //$amount_deposits_included = $object->getSumDepositsUsed();
  125. // Definition of $dir and $file
  126. if ($object->specimen)
  127. {
  128. $dir = $conf->fournisseur->facture->dir_output;
  129. $file = $dir . "/SPECIMEN.pdf";
  130. }
  131. else
  132. {
  133. $objectref = dol_sanitizeFileName($object->ref);
  134. $dir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($object->id,2).$objectref;
  135. $file = $dir . "/" . $objectref . ".pdf";
  136. }
  137. if (! file_exists($dir))
  138. {
  139. if (dol_mkdir($dir) < 0)
  140. {
  141. $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
  142. return 0;
  143. }
  144. }
  145. if (file_exists($dir))
  146. {
  147. $nblignes = count($object->lines);
  148. $pdf=pdf_getInstance($this->format);
  149. $heightforinfotot = 50; // Height reserved to output the info and total part
  150. $heightforfooter = 25; // Height reserved to output the footer (value include bottom margin)
  151. $pdf->SetAutoPageBreak(1,0);
  152. if (class_exists('TCPDF'))
  153. {
  154. $pdf->setPrintHeader(false);
  155. $pdf->setPrintFooter(false);
  156. }
  157. $pdf->SetFont(pdf_getPDFFont($outputlangs));
  158. // Set path to the background PDF File
  159. if (empty($conf->global->MAIN_DISABLE_FPDI) && ! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
  160. {
  161. $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
  162. $tplidx = $pdf->importPage(1);
  163. }
  164. $pdf->Open();
  165. $pagenb=0;
  166. $pdf->SetDrawColor(128,128,128);
  167. $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
  168. $pdf->SetSubject($outputlangs->transnoentities("Invoice"));
  169. $pdf->SetCreator("Speedealing ".DOL_VERSION);
  170. $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
  171. $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Order"));
  172. if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
  173. $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
  174. // Positionne $this->atleastonediscount si on a au moins une remise
  175. for ($i = 0 ; $i < $nblignes ; $i++)
  176. {
  177. if ($object->lines[$i]->remise_percent)
  178. {
  179. $this->atleastonediscount++;
  180. }
  181. }
  182. // New page
  183. $pdf->AddPage();
  184. if (! empty($tplidx)) $pdf->useTemplate($tplidx);
  185. $pagenb++;
  186. $this->_pagehead($pdf, $object, 1, $outputlangs);
  187. $pdf->SetFont('','', $default_font_size - 1);
  188. $pdf->MultiCell(0, 3, ''); // Set interline to 3
  189. $pdf->SetTextColor(0,0,0);
  190. $tab_top = 90;
  191. $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42:10);
  192. $tab_height = 130;
  193. $tab_height_newpage = 150;
  194. // Affiche notes
  195. if (! empty($object->note_public))
  196. {
  197. $tab_top = 88;
  198. $pdf->SetFont('','', $default_font_size - 1);
  199. $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($object->note_public), 0, 1);
  200. $nexY = $pdf->GetY();
  201. $height_note=$nexY-$tab_top;
  202. // Rect prend une longueur en 3eme param
  203. $pdf->SetDrawColor(192,192,192);
  204. $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_note+1);
  205. $tab_height = $tab_height - $height_note;
  206. $tab_top = $nexY+6;
  207. }
  208. else
  209. {
  210. $height_note=0;
  211. }
  212. $iniY = $tab_top + 7;
  213. $curY = $tab_top + 7;
  214. $nexY = $tab_top + 7;
  215. // Loop on each lines
  216. for ($i = 0 ; $i < $nblignes ; $i++)
  217. {
  218. $curY = $nexY;
  219. $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage
  220. $pdf->SetTextColor(0,0,0);
  221. $pdf->setTopMargin($tab_top_newpage);
  222. $pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot); // The only function to edit the bottom margin of current page to set it.
  223. $pageposbefore=$pdf->getPage();
  224. // Description of product line
  225. $curX = $this->posxdesc-1;
  226. pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxtva-$curX,3,$curX,$curY,$hideref,$hidedesc,1);
  227. $nexY = $pdf->GetY();
  228. $pageposafter=$pdf->getPage();
  229. $pdf->setPage($pageposbefore);
  230. $pdf->setTopMargin($this->marge_haute);
  231. $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
  232. // We suppose that a too long description is moved completely on next page
  233. if ($pageposafter > $pageposbefore) {
  234. $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
  235. }
  236. $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut
  237. // VAT Rate
  238. if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
  239. {
  240. $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
  241. $pdf->SetXY($this->posxtva, $curY);
  242. $pdf->MultiCell($this->posxup-$this->posxtva-1, 3, $vat_rate, 0, 'R');
  243. }
  244. // Unit price before discount
  245. $pdf->SetXY($this->posxup, $curY);
  246. $pdf->MultiCell($this->posxqty-$this->posxup-1, 3, price($object->lines[$i]->pu_ht), 0, 'R', 0);
  247. // Quantity
  248. $pdf->SetXY($this->posxqty, $curY);
  249. $pdf->MultiCell($this->posxdiscount-$this->posxqty-1, 3, $object->lines[$i]->qty, 0, 'R');
  250. // Discount on line
  251. $pdf->SetXY($this->posxdiscount, $curY);
  252. if ($object->lines[$i]->remise_percent)
  253. {
  254. $pdf->MultiCell($this->postotalht-$this->posxdiscount-1, 3, $object->lines[$i]->remise_percent."%", 0, 'R');
  255. }
  256. // Total HT line
  257. $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs);
  258. $pdf->SetXY($this->postotalht, $curY);
  259. $pdf->MultiCell(26, 3, $total_excl_tax, 0, 'R', 0);
  260. // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
  261. $tvaligne=$object->lines[$i]->total_tva;
  262. $localtax1ligne=$object->lines[$i]->total_localtax1;
  263. $localtax2ligne=$object->lines[$i]->total_localtax2;
  264. if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
  265. $vatrate=(string) $object->lines[$i]->tva_tx;
  266. $localtax1rate=(string) $object->lines[$i]->localtax1_tx;
  267. $localtax2rate=(string) $object->lines[$i]->localtax2_tx;
  268. if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
  269. $this->tva[$vatrate] += $tvaligne;
  270. $this->localtax1[$localtax1rate]+=$localtax1ligne;
  271. $this->localtax2[$localtax2rate]+=$localtax2ligne;
  272. $nexY+=2; // Passe espace entre les lignes
  273. // Detect if some page were added automatically and output _tableau for past pages
  274. while ($pagenb < $pageposafter)
  275. {
  276. $pdf->setPage($pagenb);
  277. if ($pagenb == 1)
  278. {
  279. $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
  280. }
  281. else
  282. {
  283. $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
  284. }
  285. $this->_pagefoot($pdf,$object,$outputlangs);
  286. $pagenb++;
  287. $pdf->setPage($pagenb);
  288. $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
  289. }
  290. if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
  291. {
  292. if ($pagenb == 1)
  293. {
  294. $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
  295. }
  296. else
  297. {
  298. $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
  299. }
  300. $this->_pagefoot($pdf,$object,$outputlangs);
  301. // New page
  302. $pdf->AddPage();
  303. if (! empty($tplidx)) $pdf->useTemplate($tplidx);
  304. $pagenb++;
  305. }
  306. }
  307. // Show square
  308. if ($pagenb == 1)
  309. {
  310. $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfooter, 0, $outputlangs, 0, 0);
  311. $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfooter + 1;
  312. }
  313. else
  314. {
  315. $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfooter, 0, $outputlangs, 1, 0);
  316. $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfooter + 1;
  317. }
  318. // Affiche zone totaux
  319. $posy=$this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
  320. $amount_credit_notes_included=0;
  321. $amount_deposits_included=0;
  322. if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included)
  323. {
  324. $posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs);
  325. }
  326. // Pied de page
  327. $this->_pagefoot($pdf, $object, $outputlangs);
  328. $pdf->AliasNbPages();
  329. $pdf->Close();
  330. $pdf->Output($file,'F');
  331. // Add pdfgeneration hook
  332. $hookmanager->initHooks(array('pdfgeneration'));
  333. $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
  334. global $action;
  335. $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
  336. if (! empty($conf->global->MAIN_UMASK))
  337. @chmod($file, octdec($conf->global->MAIN_UMASK));
  338. return 1; // Pas d'erreur
  339. }
  340. else
  341. {
  342. $this->error=$langs->trans("ErrorCanNotCreateDir",$dir);
  343. return 0;
  344. }
  345. }
  346. else
  347. {
  348. $this->error=$langs->trans("ErrorConstantNotDefined","SUPPLIER_OUTPUTDIR");
  349. return 0;
  350. }
  351. $this->error=$langs->trans("ErrorUnknown");
  352. return 0; // Erreur par defaut
  353. }
  354. /**
  355. * Show total to pay
  356. *
  357. * @param PDF &$pdf Object PDF
  358. * @param Facture $object Object invoice
  359. * @param int $deja_regle Montant deja regle
  360. * @param int $posy Position depart
  361. * @param Translate $outputlangs Objet langs
  362. * @return int Position pour suite
  363. */
  364. function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
  365. {
  366. global $conf,$mysoc;
  367. $default_font_size = pdf_getPDFFontSize($outputlangs);
  368. $tab2_top = $posy;
  369. $tab2_hl = 4;
  370. $pdf->SetFont('','', $default_font_size - 1);
  371. $pdf->SetXY($this->marge_gauche, $tab2_top + 0);
  372. // If France, show VAT mention if not applicable
  373. if ($this->emetteur->country_code == 'FR' && $this->franchise == 1)
  374. {
  375. $pdf->MultiCell(100, $tab2_hl, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
  376. }
  377. // Tableau total
  378. $col1x = 120; $col2x = 170; $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
  379. $index=0;
  380. // Total HT
  381. $pdf->SetFillColor(255,255,255);
  382. $pdf->SetXY($col1x, $tab2_top + 0);
  383. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
  384. $pdf->SetXY($col2x, $tab2_top + 0);
  385. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ht + $object->remise), 0, 'R', 1);
  386. // Show VAT by rates and total
  387. $pdf->SetFillColor(248,248,248);
  388. foreach( $this->tva as $tvakey => $tvaval )
  389. {
  390. if ($tvakey > 0) // On affiche pas taux 0
  391. {
  392. $this->atleastoneratenotnull++;
  393. $index++;
  394. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  395. $tvacompl='';
  396. if (preg_match('/\*/',$tvakey))
  397. {
  398. $tvakey=str_replace('*','',$tvakey);
  399. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  400. }
  401. $totalvat =$outputlangs->transnoentities("TotalVAT").' ';
  402. $totalvat.=vatrate($tvakey,1).$tvacompl;
  403. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  404. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  405. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
  406. }
  407. }
  408. if (! $this->atleastoneratenotnull) // If no vat at all
  409. {
  410. $index++;
  411. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  412. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalVAT"), 0, 'L', 1);
  413. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  414. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_tva), 0, 'R', 1);
  415. // Total LocalTax1
  416. if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on' && $object->total_localtax1>0)
  417. {
  418. $index++;
  419. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  420. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalLT1".$mysoc->country_code), 0, 'L', 1);
  421. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  422. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax1), 0, 'R', 1);
  423. }
  424. // Total LocalTax2
  425. if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on' && $object->total_localtax2>0)
  426. {
  427. $index++;
  428. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  429. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalLT2".$mysoc->country_code), 0, 'L', 1);
  430. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  431. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax2), 0, 'R', 1);
  432. }
  433. }
  434. else
  435. {
  436. if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
  437. {
  438. //Local tax 1
  439. foreach( $this->localtax1 as $tvakey => $tvaval )
  440. {
  441. if ($tvakey>0) // On affiche pas taux 0
  442. {
  443. //$this->atleastoneratenotnull++;
  444. $index++;
  445. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  446. $tvacompl='';
  447. if (preg_match('/\*/',$tvakey))
  448. {
  449. $tvakey=str_replace('*','',$tvakey);
  450. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  451. }
  452. $totalvat =$outputlangs->transnoentities("TotalLT1".$mysoc->country_code).' ';
  453. $totalvat.=vatrate($tvakey,1).$tvacompl;
  454. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  455. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  456. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
  457. }
  458. }
  459. }
  460. if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
  461. {
  462. //Local tax 2
  463. foreach( $this->localtax2 as $tvakey => $tvaval )
  464. {
  465. if ($tvakey>0) // On affiche pas taux 0
  466. {
  467. //$this->atleastoneratenotnull++;
  468. $index++;
  469. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  470. $tvacompl='';
  471. if (preg_match('/\*/',$tvakey))
  472. {
  473. $tvakey=str_replace('*','',$tvakey);
  474. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  475. }
  476. $totalvat =$outputlangs->transnoentities("TotalLT2".$mysoc->pays_code).' ';
  477. $totalvat.=vatrate($tvakey,1).$tvacompl;
  478. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  479. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  480. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
  481. }
  482. }
  483. }
  484. }
  485. $useborder=0;
  486. $index++;
  487. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  488. $pdf->SetTextColor(0,0,60);
  489. $pdf->SetFillColor(224,224,224);
  490. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
  491. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  492. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc), $useborder, 'R', 1);
  493. if ($deja_regle > 0)
  494. {
  495. $index++;
  496. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  497. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
  498. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  499. $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle), 0, 'R', 0);
  500. $index++;
  501. $pdf->SetTextColor(0,0,60);
  502. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  503. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
  504. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  505. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle), $useborder, 'R', 1);
  506. $pdf->SetFont('','', $default_font_size - 1);
  507. $pdf->SetTextColor(0,0,0);
  508. }
  509. $index++;
  510. return ($tab2_top + ($tab2_hl * $index));
  511. }
  512. /**
  513. * Show table for lines
  514. *
  515. * @param PDF &$pdf Object PDF
  516. * @param string $tab_top Top position of table
  517. * @param string $tab_height Height of table (rectangle)
  518. * @param int $nexY Y (not used)
  519. * @param Translate $outputlangs Langs object
  520. * @param int $hidetop Hide top bar of array
  521. * @param int $hidebottom Hide bottom bar of array
  522. * @return void
  523. */
  524. function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
  525. {
  526. global $conf;
  527. // Force to disable hidetop and hidebottom
  528. $hidebottom=0;
  529. if ($hidetop) $hidetop=-1;
  530. $default_font_size = pdf_getPDFFontSize($outputlangs);
  531. // Amount in (at tab_top - 1)
  532. $pdf->SetTextColor(0,0,0);
  533. $pdf->SetFont('','',$default_font_size - 2);
  534. if (empty($hidetop))
  535. {
  536. $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$conf->currency));
  537. $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
  538. $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
  539. }
  540. $pdf->SetDrawColor(128,128,128);
  541. $pdf->SetFont('','', $default_font_size - 1);
  542. // Output Rect
  543. $this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect prend une longueur en 3eme param et 4eme param
  544. if (empty($hidetop))
  545. {
  546. $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); // line prend une position y en 2eme param et 4eme param
  547. $pdf->SetXY($this->posxdesc-1, $tab_top+1);
  548. $pdf->MultiCell(108,2, $outputlangs->transnoentities("Designation"),'','L');
  549. }
  550. if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
  551. {
  552. $pdf->line($this->posxtva-1, $tab_top, $this->posxtva-1, $tab_top + $tab_height);
  553. if (empty($hidetop))
  554. {
  555. $pdf->SetXY($this->posxtva-3, $tab_top+1);
  556. $pdf->MultiCell($this->posxup-$this->posxtva+3,2, $outputlangs->transnoentities("VAT"),'','C');
  557. }
  558. }
  559. $pdf->line($this->posxup-1, $tab_top, $this->posxup-1, $tab_top + $tab_height);
  560. if (empty($hidetop))
  561. {
  562. $pdf->SetXY($this->posxup-1, $tab_top+1);
  563. $pdf->MultiCell($this->posxqty-$this->posxup-1,2, $outputlangs->transnoentities("PriceUHT"),'','C');
  564. }
  565. $pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height);
  566. if (empty($hidetop))
  567. {
  568. $pdf->SetXY($this->posxqty-1, $tab_top+1);
  569. $pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C');
  570. }
  571. $pdf->line($this->posxdiscount-1, $tab_top, $this->posxdiscount-1, $tab_top + $tab_height);
  572. if (empty($hidetop))
  573. {
  574. if ($this->atleastonediscount)
  575. {
  576. $pdf->SetXY($this->posxdiscount-1, $tab_top+1);
  577. $pdf->MultiCell($this->postotalht-$this->posxdiscount+1,2, $outputlangs->transnoentities("ReductionShort"),'','C');
  578. }
  579. }
  580. if ($this->atleastonediscount)
  581. {
  582. $pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
  583. }
  584. if (empty($hidetop))
  585. {
  586. $pdf->SetXY($this->postotalht-1, $tab_top+1);
  587. $pdf->MultiCell(30,2, $outputlangs->transnoentities("TotalHTShort"),'','C');
  588. }
  589. }
  590. /**
  591. * Show payments table
  592. *
  593. * @param PDF &$pdf Object PDF
  594. * @param Object $object Object invoice
  595. * @param int $posy Position y in PDF
  596. * @param Translate $outputlangs Object langs for output
  597. * @return int <0 if KO, >0 if OK
  598. */
  599. function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
  600. {
  601. $tab3_posx = 120;
  602. $tab3_top = $posy + 8;
  603. $tab3_width = 80;
  604. $tab3_height = 4;
  605. $default_font_size = pdf_getPDFFontSize($outputlangs);
  606. $pdf->SetFont('','', $default_font_size - 2);
  607. $pdf->SetXY($tab3_posx, $tab3_top - 5);
  608. $pdf->MultiCell(60, 5, $outputlangs->transnoentities("PaymentsAlreadyDone"), 0, 'L', 0);
  609. $pdf->line($tab3_posx, $tab3_top-1+$tab3_height, $tab3_posx+$tab3_width, $tab3_top-1+$tab3_height);
  610. $pdf->SetFont('','', $default_font_size - 4);
  611. $pdf->SetXY($tab3_posx, $tab3_top);
  612. $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Payment"), 0, 'L', 0);
  613. $pdf->SetXY($tab3_posx+21, $tab3_top);
  614. $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Amount"), 0, 'L', 0);
  615. $pdf->SetXY($tab3_posx+40, $tab3_top);
  616. $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Type"), 0, 'L', 0);
  617. $pdf->SetXY($tab3_posx+58, $tab3_top);
  618. $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Num"), 0, 'L', 0);
  619. $y=0;
  620. $pdf->SetFont('','', $default_font_size - 4);
  621. // Loop on each payment
  622. $sql = "SELECT p.datep as date, p.fk_paiement as type, p.num_paiement as num, pf.amount as amount,";
  623. $sql.= " cp.code";
  624. $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf, ".MAIN_DB_PREFIX."paiementfourn as p";
  625. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id";
  626. $sql.= " WHERE pf.fk_paiementfourn = p.rowid and pf.fk_facturefourn = ".$object->id;
  627. $sql.= " ORDER BY p.datep";
  628. $resql=$this->db->query($sql);
  629. if ($resql)
  630. {
  631. $num = $this->db->num_rows($resql);
  632. $i=0;
  633. while ($i < $num) {
  634. $y+=3;
  635. $row = $this->db->fetch_object($resql);
  636. $pdf->SetXY($tab3_posx, $tab3_top+$y);
  637. $pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($row->date),'day',false,$outputlangs,true), 0, 'L', 0);
  638. $pdf->SetXY($tab3_posx+21, $tab3_top+$y);
  639. $pdf->MultiCell(20, 3, price($row->amount), 0, 'L', 0);
  640. $pdf->SetXY($tab3_posx+40, $tab3_top+$y);
  641. $oper = $outputlangs->transnoentitiesnoconv("PaymentTypeShort" . $row->code);
  642. $pdf->MultiCell(20, 3, $oper, 0, 'L', 0);
  643. $pdf->SetXY($tab3_posx+58, $tab3_top+$y);
  644. $pdf->MultiCell(30, 3, $row->num, 0, 'L', 0);
  645. $pdf->line($tab3_posx, $tab3_top+$y+3, $tab3_posx+$tab3_width, $tab3_top+$y+3);
  646. $i++;
  647. }
  648. }
  649. else
  650. {
  651. $this->error=$this->db->lasterror();
  652. dol_syslog($this->db,$this->error, LOG_ERR);
  653. return -1;
  654. }
  655. }
  656. /**
  657. * Show top header of page.
  658. *
  659. * @param PDF &$pdf Object PDF
  660. * @param Object $object Object to show
  661. * @param int $showaddress 0=no, 1=yes
  662. * @param Translate $outputlangs Object lang for output
  663. * @return void
  664. */
  665. function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
  666. {
  667. global $langs,$conf,$mysoc;
  668. $outputlangs->load("main");
  669. $outputlangs->load("bills");
  670. $outputlangs->load("orders");
  671. $outputlangs->load("companies");
  672. $default_font_size = pdf_getPDFFontSize($outputlangs);
  673. // Do not add the BACKGROUND as this is for suppliers
  674. //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
  675. $pdf->SetTextColor(0,0,60);
  676. $pdf->SetFont('','B', $default_font_size + 3);
  677. $posy=$this->marge_haute;
  678. $posx=$this->page_largeur-$this->marge_droite-100;
  679. $pdf->SetXY($this->marge_gauche,$posy);
  680. // Logo
  681. /*
  682. $logo=$conf->mycompany->dir_output.'/logos/'.$mysoc->logo;
  683. if ($mysoc->logo)
  684. {
  685. if (is_readable($logo))
  686. {
  687. $height=pdf_getHeightForLogo($logo);
  688. $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
  689. }
  690. else
  691. {
  692. $pdf->SetTextColor(200,0,0);
  693. $pdf->SetFont('','B', $default_font_size - 2);
  694. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
  695. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToModuleSetup"), 0, 'L');
  696. }
  697. }
  698. else
  699. {*/
  700. $text=$this->emetteur->name;
  701. $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
  702. //}
  703. $pdf->SetFont('','B', $default_font_size + 3);
  704. $pdf->SetXY($posx,$posy);
  705. $pdf->SetTextColor(0,0,60);
  706. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("SupplierInvoice")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R');
  707. $pdf->SetFont('','B', $default_font_size);
  708. if ($object->ref_supplier)
  709. {
  710. $posy+=5;
  711. $pdf->SetXY($posx,$posy);
  712. $pdf->SetTextColor(0,0,60);
  713. $pdf->MultiCell(100, 4, $outputlangs->transnoentities("RefSupplier")." : " . $object->ref_supplier, '', 'R');
  714. }
  715. $posy+=1;
  716. $pdf->SetFont('','', $default_font_size - 1);
  717. $posy+=5;
  718. $pdf->SetXY($posx,$posy);
  719. if ($object->date)
  720. {
  721. $pdf->SetTextColor(0,0,60);
  722. $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Date")." : " . dol_print_date($object->date,"day",false,$outputlangs,true), '', 'R');
  723. }
  724. else
  725. {
  726. $pdf->SetTextColor(255,0,0);
  727. $pdf->MultiCell(100, 4, strtolower($outputlangs->transnoentities("OrderToProcess")), '', 'R');
  728. }
  729. if ($showaddress)
  730. {
  731. // Sender properties
  732. $carac_emetteur = pdf_build_address($outputlangs,$this->emetteur);
  733. // Show sender
  734. $posy=42;
  735. $posx=$this->marge_gauche;
  736. if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
  737. $hautcadre=40;
  738. // Show sender frame
  739. $pdf->SetTextColor(0,0,0);
  740. $pdf->SetFont('','', $default_font_size - 2);
  741. $pdf->SetXY($posx,$posy-5);
  742. $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
  743. $pdf->SetXY($posx,$posy);
  744. $pdf->SetFillColor(230,230,230);
  745. $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
  746. $pdf->SetTextColor(0,0,60);
  747. // Show sender name
  748. $pdf->SetXY($posx+2,$posy+3);
  749. $pdf->SetFont('','B', $default_font_size);
  750. $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
  751. // Show sender information
  752. $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($this->emetteur->name,44)*4));
  753. $pdf->SetFont('','', $default_font_size - 1);
  754. $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
  755. // If BILLING contact defined on invoice, we use it
  756. $usecontact=false;
  757. $arrayidcontact=$object->getIdContact('internal','BILLING');
  758. if (count($arrayidcontact) > 0)
  759. {
  760. $usecontact=true;
  761. $result=$object->fetch_contact($arrayidcontact[0]);
  762. }
  763. // Recipient name
  764. if (! empty($usecontact))
  765. {
  766. // On peut utiliser le nom de la societe du contact
  767. if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socname = $object->contact->socname;
  768. else $socname = $mysoc->nom;
  769. $carac_client_name=$outputlangs->convToOutputCharset($socname);
  770. }
  771. else
  772. {
  773. $carac_client_name=$outputlangs->convToOutputCharset($mysoc->nom);
  774. }
  775. $carac_client=pdf_build_address($outputlangs,$this->emetteur,$mysoc,$object->contact,$usecontact,'target');
  776. // Show recipient
  777. $posy=42;
  778. $posx=$this->page_largeur-$this->marge_droite-100;
  779. if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
  780. // Show recipient frame
  781. $pdf->SetTextColor(0,0,0);
  782. $pdf->SetFont('','', $default_font_size - 2);
  783. $pdf->SetXY($posx+2,$posy-5);
  784. $pdf->MultiCell(80,5, $outputlangs->transnoentities("BillTo").":",0,'L');
  785. $pdf->Rect($posx, $posy, 100, $hautcadre);
  786. // Show recipient name
  787. $pdf->SetXY($posx+2,$posy+3);
  788. $pdf->SetFont('','B', $default_font_size);
  789. $pdf->MultiCell(96,4, $carac_client_name, 0, 'L');
  790. // Show recipient information
  791. $pdf->SetFont('','', $default_font_size - 1);
  792. $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4));
  793. $pdf->MultiCell(86,4, $carac_client, 0, 'L');
  794. }
  795. }
  796. /**
  797. * Show footer of page. Need this->emetteur object
  798. *
  799. * @param PDF &$pdf PDF
  800. * @param Object $object Object to show
  801. * @param Translate $outputlangs Object lang for output
  802. * @return int Return height of bottom margin including footer text
  803. */
  804. function _pagefoot(&$pdf, $object, $outputlangs)
  805. {
  806. return pdf_pagefoot($pdf,$outputlangs,'SUPPLIER_INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object);
  807. }
  808. }
  809. ?>