dolibarr  13.0.2
pdf_sponge.modules.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2008 Raphael Bertrand <raphael.bertrand@resultic.fr>
5  * Copyright (C) 2010-2014 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
7  * Copyright (C) 2012 Cédric Salvador <csalvador@gpcsolutions.fr>
8  * Copyright (C) 2012-2014 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
9  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
10  * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
11  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <https://www.gnu.org/licenses/>.
25  * or see https://www.gnu.org/
26  */
27 
34 require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
35 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
39 
40 
45 {
49  public $db;
50 
54  public $name;
55 
59  public $description;
60 
64  public $update_main_doc_field;
65 
69  public $type;
70 
75  public $phpmin = array(5, 6);
76 
81  public $version = 'dolibarr';
82 
86  public $page_largeur;
87 
91  public $page_hauteur;
92 
96  public $format;
97 
101  public $marge_gauche;
102 
106  public $marge_droite;
107 
111  public $marge_haute;
112 
116  public $marge_basse;
117 
122  public $emetteur;
123 
127  public $situationinvoice;
128 
129 
133  public $cols;
134 
135 
141  public function __construct($db)
142  {
143  global $conf, $langs, $mysoc;
144 
145  // Translations
146  $langs->loadLangs(array("main", "bills"));
147 
148  $this->db = $db;
149  $this->name = "sponge";
150  $this->description = $langs->trans('PDFSpongeDescription');
151  $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
152 
153  // Dimension page
154  $this->type = 'pdf';
155  $formatarray = pdf_getFormat();
156  $this->page_largeur = $formatarray['width'];
157  $this->page_hauteur = $formatarray['height'];
158  $this->format = array($this->page_largeur, $this->page_hauteur);
159  $this->marge_gauche = isset($conf->global->MAIN_PDF_MARGIN_LEFT) ? $conf->global->MAIN_PDF_MARGIN_LEFT : 10;
160  $this->marge_droite = isset($conf->global->MAIN_PDF_MARGIN_RIGHT) ? $conf->global->MAIN_PDF_MARGIN_RIGHT : 10;
161  $this->marge_haute = isset($conf->global->MAIN_PDF_MARGIN_TOP) ? $conf->global->MAIN_PDF_MARGIN_TOP : 10;
162  $this->marge_basse = isset($conf->global->MAIN_PDF_MARGIN_BOTTOM) ? $conf->global->MAIN_PDF_MARGIN_BOTTOM : 10;
163 
164  $this->option_logo = 1; // Display logo
165  $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
166  $this->option_modereg = 1; // Display payment mode
167  $this->option_condreg = 1; // Display payment terms
168  $this->option_codeproduitservice = 1; // Display product-service code
169  $this->option_multilang = 1; // Available in several languages
170  $this->option_escompte = 1; // Displays if there has been a discount
171  $this->option_credit_note = 1; // Support credit notes
172  $this->option_freetext = 1; // Support add of a personalised text
173  $this->option_draft_watermark = 1; // Support add of a watermark on drafts
174 
175  // Get source company
176  $this->emetteur = $mysoc;
177  if (empty($this->emetteur->country_code)) $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
178 
179  // Define position of columns
180  $this->posxdesc = $this->marge_gauche + 1; // used for notes ans other stuff
181 
182 
183  $this->tabTitleHeight = 5; // default height
184 
185  // Use new system for position of columns, view $this->defineColumnField()
186 
187  $this->tva = array();
188  $this->localtax1 = array();
189  $this->localtax2 = array();
190  $this->atleastoneratenotnull = 0;
191  $this->atleastonediscount = 0;
192  $this->situationinvoice = false;
193  }
194 
195 
196  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
208  public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
209  {
210  // phpcs:enable
211  global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
212 
213  dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null'));
214 
215  if (!is_object($outputlangs)) $outputlangs = $langs;
216  // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
217  if (!empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output = 'ISO-8859-1';
218 
219  // Load translation files required by the page
220  $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
221 
222  global $outputlangsbis;
223  $outputlangsbis = null;
224  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
225  $outputlangsbis = new Translate('', $conf);
226  $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
227  $outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies"));
228  }
229 
230  $nblines = count($object->lines);
231 
232  $hidetop = 0;
233  if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) {
234  $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE;
235  }
236 
237  // Loop on each lines to detect if there is at least one image to show
238  $realpatharray = array();
239  $this->atleastonephoto = false;
240  if (!empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE))
241  {
242  $objphoto = new Product($this->db);
243 
244  for ($i = 0; $i < $nblines; $i++)
245  {
246  if (empty($object->lines[$i]->fk_product)) continue;
247 
248  $objphoto->fetch($object->lines[$i]->fk_product);
249  //var_dump($objphoto->ref);exit;
250  if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
251  {
252  $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
253  $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
254  } else {
255  $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; // default
256  $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
257  }
258 
259  $arephoto = false;
260  foreach ($pdir as $midir)
261  {
262  if (!$arephoto)
263  {
264  if ($conf->product->entity != $objphoto->entity) {
265  $dir = $conf->product->multidir_output[$objphoto->entity].'/'.$midir; //Check repertories of current entities
266  } else {
267  $dir = $conf->product->dir_output.'/'.$midir; //Check repertory of the current product
268  }
269 
270  foreach ($objphoto->liste_photos($dir, 1) as $key => $obj)
271  {
272  if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
273  {
274  if ($obj['photo_vignette'])
275  {
276  $filename = $obj['photo_vignette'];
277  } else {
278  $filename = $obj['photo'];
279  }
280  } else {
281  $filename = $obj['photo'];
282  }
283 
284  $realpath = $dir.$filename;
285  $arephoto = true;
286  $this->atleastonephoto = true;
287  }
288  }
289  }
290 
291  if ($realpath && $arephoto) $realpatharray[$i] = $realpath;
292  }
293  }
294 
295  //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
296 
297  if ($conf->facture->multidir_output[$conf->entity])
298  {
299  $object->fetch_thirdparty();
300 
301  $deja_regle = $object->getSommePaiement((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? 1 : 0);
302  $amount_credit_notes_included = $object->getSumCreditNotesUsed((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? 1 : 0);
303  $amount_deposits_included = $object->getSumDepositsUsed((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? 1 : 0);
304 
305  // Definition of $dir and $file
306  if ($object->specimen)
307  {
308  $dir = $conf->facture->multidir_output[$conf->entity];
309  $file = $dir."/SPECIMEN.pdf";
310  } else {
311  $objectref = dol_sanitizeFileName($object->ref);
312  $dir = $conf->facture->multidir_output[$object->entity]."/".$objectref;
313  $file = $dir."/".$objectref.".pdf";
314  }
315  if (!file_exists($dir))
316  {
317  if (dol_mkdir($dir) < 0)
318  {
319  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
320  return 0;
321  }
322  }
323 
324  if (file_exists($dir))
325  {
326  // Add pdfgeneration hook
327  if (!is_object($hookmanager))
328  {
329  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
330  $hookmanager = new HookManager($this->db);
331  }
332  $hookmanager->initHooks(array('pdfgeneration'));
333  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
334  global $action;
335  $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
336 
337  // Set nblines with the new facture lines content after hook
338  $nblines = count($object->lines);
339  $nbpayments = count($object->getListOfPayments());
340 
341  // Create pdf instance
342  $pdf = pdf_getInstance($this->format);
343  $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
344  $pdf->SetAutoPageBreak(1, 0);
345 
346  $heightforinfotot = 50 + (4 * $nbpayments); // Height reserved to output the info and total part and payment part
347  $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page
348  $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin)
349 
350  if (class_exists('TCPDF'))
351  {
352  $pdf->setPrintHeader(false);
353  $pdf->setPrintFooter(false);
354  }
355  $pdf->SetFont(pdf_getPDFFont($outputlangs));
356 
357  // Set path to the background PDF File
358  if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
359  {
360  $pagecount = $pdf->setSourceFile($conf->mycompany->multidir_output[$object->entity].'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
361  $tplidx = $pdf->importPage(1);
362  }
363 
364  $pdf->Open();
365  $pagenb = 0;
366  $pdf->SetDrawColor(128, 128, 128);
367 
368  $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
369  $pdf->SetSubject($outputlangs->transnoentities("PdfInvoiceTitle"));
370  $pdf->SetCreator("Dolibarr ".DOL_VERSION);
371  $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
372  $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfInvoiceTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
373  if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
374 
375  // Set certificate
376  $cert = empty($user->conf->CERTIFICATE_CRT) ? '' : $user->conf->CERTIFICATE_CRT;
377  // If user has no certificate, we try to take the company one
378  if (!$cert) {
379  $cert = empty($conf->global->CERTIFICATE_CRT) ? '' : $conf->global->CERTIFICATE_CRT;
380  }
381  // If a certificate is found
382  if ($cert) {
383  $info = array(
384  'Name' => $this->emetteur->name,
385  'Location' => getCountry($this->emetteur->country_code, 0),
386  'Reason' => 'INVOICE',
387  'ContactInfo' => $this->emetteur->email
388  );
389  $pdf->setSignature($cert, $cert, $this->emetteur->name, '', 2, $info);
390  }
391 
392  $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
393 
394  // Set $this->atleastonediscount if you have at least one discount
395  for ($i = 0; $i < $nblines; $i++)
396  {
397  if ($object->lines[$i]->remise_percent)
398  {
399  $this->atleastonediscount++;
400  }
401  }
402 
403 
404  // Situation invoice handling
405  if ($object->situation_cycle_ref)
406  {
407  $this->situationinvoice = true;
408  }
409 
410  // New page
411  $pdf->AddPage();
412  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
413  $pagenb++;
414 
415  $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis);
416  $pdf->SetFont('', '', $default_font_size - 1);
417  $pdf->MultiCell(0, 3, ''); // Set interline to 3
418  $pdf->SetTextColor(0, 0, 0);
419 
420  $tab_top = 90 + $top_shift;
421  $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10);
422  $tab_height = 130 - $top_shift;
423  $tab_height_newpage = 150;
424  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift;
425 
426  $nexY = $tab_top - 1;
427 
428  // Incoterm
429  $height_incoterms = 0;
430  if (!empty($conf->incoterm->enabled))
431  {
432  $desc_incoterms = $object->getIncotermsForPDF();
433  if ($desc_incoterms)
434  {
435  $tab_top -= 2;
436 
437  $pdf->SetFont('', '', $default_font_size - 1);
438  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
439  $nexY = max($pdf->GetY(), $nexY);
440  $height_incoterms = $nexY - $tab_top;
441 
442  // Rect takes a length in 3rd parameter
443  $pdf->SetDrawColor(192, 192, 192);
444  $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1);
445 
446  $tab_top = $nexY + 6;
447  $height_incoterms += 4;
448  }
449  }
450 
451  // Displays notes
452  $notetoshow = empty($object->note_public) ? '' : $object->note_public;
453  if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
454  {
455  // Get first sale rep
456  if (is_object($object->thirdparty))
457  {
458  $salereparray = $object->thirdparty->getSalesRepresentatives($user);
459  $salerepobj = new User($this->db);
460  $salerepobj->fetch($salereparray[0]['id']);
461  if (!empty($salerepobj->signature)) $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
462  }
463  }
464 
465  // Extrafields in note
466  $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
467  if (!empty($extranote)) {
468  $notetoshow = dol_concatdesc($notetoshow, $extranote);
469  }
470 
471  $pagenb = $pdf->getPage();
472  if ($notetoshow)
473  {
474  $tab_top -= 2;
475 
476  $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
477  $pageposbeforenote = $pagenb;
478 
479  $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
480  complete_substitutions_array($substitutionarray, $outputlangs, $object);
481  $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
482  $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
483 
484  $pdf->startTransaction();
485 
486  $pdf->SetFont('', '', $default_font_size - 1);
487  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
488  // Description
489  $pageposafternote = $pdf->getPage();
490  $posyafter = $pdf->GetY();
491 
492  if ($pageposafternote > $pageposbeforenote)
493  {
494  $pdf->rollbackTransaction(true);
495 
496  // prepare pages to receive notes
497  while ($pagenb < $pageposafternote) {
498  $pdf->AddPage();
499  $pagenb++;
500  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
501  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
502  // $this->_pagefoot($pdf,$object,$outputlangs,1);
503  $pdf->setTopMargin($tab_top_newpage);
504  // The only function to edit the bottom margin of current page to set it.
505  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
506  }
507 
508  // back to start
509  $pdf->setPage($pageposbeforenote);
510  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
511  $pdf->SetFont('', '', $default_font_size - 1);
512  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
513  $pageposafternote = $pdf->getPage();
514 
515  $posyafter = $pdf->GetY();
516 
517  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) // There is no space left for total+free text
518  {
519  $pdf->AddPage('', '', true);
520  $pagenb++;
521  $pageposafternote++;
522  $pdf->setPage($pageposafternote);
523  $pdf->setTopMargin($tab_top_newpage);
524  // The only function to edit the bottom margin of current page to set it.
525  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
526  //$posyafter = $tab_top_newpage;
527  }
528 
529 
530  // apply note frame to previous pages
531  $i = $pageposbeforenote;
532  while ($i < $pageposafternote) {
533  $pdf->setPage($i);
534 
535 
536  $pdf->SetDrawColor(128, 128, 128);
537  // Draw note frame
538  if ($i > $pageposbeforenote) {
539  $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
540  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
541  } else {
542  $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
543  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
544  }
545 
546  // Add footer
547  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
548  $this->_pagefoot($pdf, $object, $outputlangs, 1);
549 
550  $i++;
551  }
552 
553  // apply note frame to last page
554  $pdf->setPage($pageposafternote);
555  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
556  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
557  $height_note = $posyafter - $tab_top_newpage;
558  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
559  } else // No pagebreak
560  {
561  $pdf->commitTransaction();
562  $posyafter = $pdf->GetY();
563  $height_note = $posyafter - $tab_top;
564  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
565 
566 
567  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20)))
568  {
569  // not enough space, need to add page
570  $pdf->AddPage('', '', true);
571  $pagenb++;
572  $pageposafternote++;
573  $pdf->setPage($pageposafternote);
574  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
575  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
576 
577  $posyafter = $tab_top_newpage;
578  }
579  }
580 
581  $tab_height = $tab_height - $height_note;
582  $tab_top = $posyafter + 6;
583  } else {
584  $height_note = 0;
585  }
586 
587  // Use new auto column system
588  $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
589 
590  // Table simulation to know the height of the title line
591  $pdf->startTransaction();
592  $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
593  $pdf->rollbackTransaction(true);
594 
595  $nexY = $tab_top + $this->tabTitleHeight;
596 
597  // Loop on each lines
598  $pageposbeforeprintlines = $pdf->getPage();
599  $pagenb = $pageposbeforeprintlines;
600  for ($i = 0; $i < $nblines; $i++)
601  {
602  $curY = $nexY;
603  $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
604  $pdf->SetTextColor(0, 0, 0);
605 
606  // Define size of image if we need it
607  $imglinesize = array();
608  if (!empty($realpatharray[$i])) $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
609 
610  $pdf->setTopMargin($tab_top_newpage);
611  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
612  $pageposbefore = $pdf->getPage();
613 
614  $showpricebeforepagebreak = 1;
615  $posYAfterImage = 0;
616  $posYAfterDescription = 0;
617 
618  if ($this->getColumnStatus('photo'))
619  {
620  // We start with Photo of product line
621  if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // If photo too high, we moved completely on new page
622  {
623  $pdf->AddPage('', '', true);
624  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
625  $pdf->setPage($pageposbefore + 1);
626 
627  $curY = $tab_top_newpage;
628 
629  // Allows data in the first page if description is long enough to break in multiples pages
630  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
631  $showpricebeforepagebreak = 1;
632  else $showpricebeforepagebreak = 0;
633  }
634 
635  if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
636  {
637  $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
638  // $pdf->Image does not increase value return by getY, so we save it manually
639  $posYAfterImage = $curY + $imglinesize['height'];
640  }
641  }
642 
643  // Description of product line
644  if ($this->getColumnStatus('desc'))
645  {
646  $pdf->startTransaction();
647 
648  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
649  $pageposafter = $pdf->getPage();
650 
651  if ($pageposafter > $pageposbefore) // There is a pagebreak
652  {
653  $pdf->rollbackTransaction(true);
654  $pageposafter = $pageposbefore;
655  $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
656 
657  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
658 
659  $pageposafter = $pdf->getPage();
660  $posyafter = $pdf->GetY();
661  //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
662  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text
663  {
664  if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page
665  {
666  $pdf->AddPage('', '', true);
667  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
668  $pdf->setPage($pageposafter + 1);
669  }
670  } else {
671  // We found a page break
672  // Allows data in the first page if description is long enough to break in multiples pages
673  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
674  $showpricebeforepagebreak = 1;
675  else $showpricebeforepagebreak = 0;
676  }
677  } else // No pagebreak
678  {
679  $pdf->commitTransaction();
680  }
681  $posYAfterDescription = $pdf->GetY();
682  }
683 
684  $nexY = max($pdf->GetY(), $posYAfterImage, $posYAfterDescription);
685 
686  $pageposafter = $pdf->getPage();
687  $pdf->setPage($pageposbefore);
688  $pdf->setTopMargin($this->marge_haute);
689  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
690 
691  // We suppose that a too long description or photo were moved completely on next page
692  if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
693  $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
694  }
695 
696  $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font
697 
698  // VAT Rate
699  if ($this->getColumnStatus('vat'))
700  {
701  $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
702  $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
703  $nexY = max($pdf->GetY(), $nexY);
704  }
705 
706  // Unit price before discount
707  if ($this->getColumnStatus('subprice'))
708  {
709  $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
710  $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
711  $nexY = max($pdf->GetY(), $nexY);
712  }
713 
714  // Quantity
715  // Enough for 6 chars
716  if ($this->getColumnStatus('qty'))
717  {
718  $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
719  $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
720  $nexY = max($pdf->GetY(), $nexY);
721  }
722 
723  // Situation progress
724  if ($this->getColumnStatus('progress'))
725  {
726  $progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails);
727  $this->printStdColumnContent($pdf, $curY, 'progress', $progress);
728  $nexY = max($pdf->GetY(), $nexY);
729  }
730 
731  // Unit
732  if ($this->getColumnStatus('unit'))
733  {
734  $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
735  $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
736  $nexY = max($pdf->GetY(), $nexY);
737  }
738 
739  // Discount on line
740  if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
741  {
742  $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
743  $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
744  $nexY = max($pdf->GetY(), $nexY);
745  }
746 
747  // Total excl tax line (HT)
748  if ($this->getColumnStatus('totalexcltax'))
749  {
750  $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
751  $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
752  $nexY = max($pdf->GetY(), $nexY);
753  }
754 
755  // Total with tax line (TTC)
756  if ($this->getColumnStatus('totalincltax'))
757  {
758  $total_incl_tax = pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails);
759  $this->printStdColumnContent($pdf, $curY, 'totalincltax', $total_incl_tax);
760  $nexY = max($pdf->GetY(), $nexY);
761  }
762 
763  // Extrafields
764  if (!empty($object->lines[$i]->array_options)) {
765  foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
766  if ($this->getColumnStatus($extrafieldColKey))
767  {
768  $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey);
769  $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
770  $nexY = max($pdf->GetY(), $nexY);
771  }
772  }
773  }
774 
775 
776  $parameters = array(
777  'object' => $object,
778  'i' => $i,
779  'pdf' =>& $pdf,
780  'curY' =>& $curY,
781  'nexY' =>& $nexY,
782  'outputlangs' => $outputlangs,
783  'hidedetails' => $hidedetails
784  );
785  $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook
786 
787 
788  $sign = 1;
789  if (isset($object->type) && $object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign = -1;
790  // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
791  $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
792  if ($prev_progress > 0 && !empty($object->lines[$i]->situation_percent)) // Compute progress from previous situation
793  {
794  if (!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
795  else $tvaligne = $sign * $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
796  } else {
797  if (!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva;
798  else $tvaligne = $sign * $object->lines[$i]->total_tva;
799  }
800 
801  $localtax1ligne = $object->lines[$i]->total_localtax1;
802  $localtax2ligne = $object->lines[$i]->total_localtax2;
803  $localtax1_rate = $object->lines[$i]->localtax1_tx;
804  $localtax2_rate = $object->lines[$i]->localtax2_tx;
805  $localtax1_type = $object->lines[$i]->localtax1_type;
806  $localtax2_type = $object->lines[$i]->localtax2_type;
807 
808  if ($object->remise_percent) $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
809  if ($object->remise_percent) $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
810  if ($object->remise_percent) $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
811 
812  $vatrate = (string) $object->lines[$i]->tva_tx;
813 
814  // Retrieve type from database for backward compatibility with old records
815  if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
816  && (!empty($localtax1_rate) || !empty($localtax2_rate))) // and there is local tax
817  {
818  $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
819  $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
820  $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
821  }
822 
823  // retrieve global local tax
824  if ($localtax1_type && $localtax1ligne != 0) {
825  $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
826  }
827  if ($localtax2_type && $localtax2ligne != 0) {
828  $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
829  }
830 
831  if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate .= '*';
832  if (!isset($this->tva[$vatrate])) $this->tva[$vatrate] = 0;
833  $this->tva[$vatrate] += $tvaligne;
834 
835  $nexY = max($nexY, $posYAfterImage);
836 
837  // Add line
838  if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) {
839  $pdf->setPage($pageposafter);
840  $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
841  //$pdf->SetDrawColor(190,190,200);
842  $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
843  $pdf->SetLineStyle(array('dash'=>0));
844  }
845 
846  // Detect if some page were added automatically and output _tableau for past pages
847  while ($pagenb < $pageposafter) {
848  $pdf->setPage($pagenb);
849  if ($pagenb == $pageposbeforeprintlines) {
850  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
851  } else {
852  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
853  }
854  $this->_pagefoot($pdf, $object, $outputlangs, 1);
855  $pagenb++;
856  $pdf->setPage($pagenb);
857  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
858  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
859  }
860 
861  if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
862  if ($pagenb == $pageposafter) {
863  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
864  } else {
865  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
866  }
867  $this->_pagefoot($pdf, $object, $outputlangs, 1);
868  // New page
869  $pdf->AddPage();
870  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
871  $pagenb++;
872  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
873  }
874  }
875 
876  // Show square
877  if ($pagenb == $pageposbeforeprintlines)
878  {
879  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis);
880  $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
881  } else {
882  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis);
883  $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
884  }
885 
886  // Display infos area
887  $posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
888 
889  // Display total zone
890  $posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
891 
892  // Display payment area
893  if (($deja_regle || $amount_credit_notes_included || $amount_deposits_included) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
894  {
895  $posy = $this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
896  }
897 
898  // Pagefoot
899  $this->_pagefoot($pdf, $object, $outputlangs);
900  if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages();
901 
902  $pdf->Close();
903 
904  $pdf->Output($file, 'F');
905 
906  // Add pdfgeneration hook
907  $hookmanager->initHooks(array('pdfgeneration'));
908  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
909  global $action;
910  $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
911  if ($reshook < 0)
912  {
913  $this->error = $hookmanager->error;
914  $this->errors = $hookmanager->errors;
915  }
916 
917  if (!empty($conf->global->MAIN_UMASK))
918  @chmod($file, octdec($conf->global->MAIN_UMASK));
919 
920  $this->result = array('fullpath'=>$file);
921 
922  return 1; // No error
923  } else {
924  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
925  return 0;
926  }
927  } else {
928  $this->error = $langs->transnoentities("ErrorConstantNotDefined", "FAC_OUTPUTDIR");
929  return 0;
930  }
931  }
932 
933 
943  public function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
944  {
945  global $conf;
946 
947  $sign = 1;
948  if ($object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign = -1;
949 
950  $tab3_posx = 120;
951  $tab3_top = $posy + 8;
952  $tab3_width = 80;
953  $tab3_height = 4;
954  if ($this->page_largeur < 210) // To work with US executive format
955  {
956  $tab3_posx -= 20;
957  }
958 
959  $default_font_size = pdf_getPDFFontSize($outputlangs);
960 
961  $title = $outputlangs->transnoentities("PaymentsAlreadyDone");
962  if ($object->type == 2) $title = $outputlangs->transnoentities("PaymentsBackAlreadyDone");
963 
964  $pdf->SetFont('', '', $default_font_size - 3);
965  $pdf->SetXY($tab3_posx, $tab3_top - 4);
966  $pdf->MultiCell(60, 3, $title, 0, 'L', 0);
967 
968  $pdf->line($tab3_posx, $tab3_top, $tab3_posx + $tab3_width, $tab3_top);
969 
970  $pdf->SetFont('', '', $default_font_size - 4);
971  $pdf->SetXY($tab3_posx, $tab3_top);
972  $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Payment"), 0, 'L', 0);
973  $pdf->SetXY($tab3_posx + 21, $tab3_top);
974  $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Amount"), 0, 'L', 0);
975  $pdf->SetXY($tab3_posx + 40, $tab3_top);
976  $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Type"), 0, 'L', 0);
977  $pdf->SetXY($tab3_posx + 58, $tab3_top);
978  $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Num"), 0, 'L', 0);
979 
980  $pdf->line($tab3_posx, $tab3_top - 1 + $tab3_height, $tab3_posx + $tab3_width, $tab3_top - 1 + $tab3_height);
981 
982  $y = 0;
983 
984  $pdf->SetFont('', '', $default_font_size - 4);
985 
986 
987  // Loop on each discount available (deposits and credit notes and excess of payment included)
988  $sql = "SELECT re.rowid, re.amount_ht, re.multicurrency_amount_ht, re.amount_tva, re.multicurrency_amount_tva, re.amount_ttc, re.multicurrency_amount_ttc,";
989  $sql .= " re.description, re.fk_facture_source,";
990  $sql .= " f.type, f.datef";
991  $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re, ".MAIN_DB_PREFIX."facture as f";
992  $sql .= " WHERE re.fk_facture_source = f.rowid AND re.fk_facture = ".$object->id;
993  $resql = $this->db->query($sql);
994  if ($resql)
995  {
996  $num = $this->db->num_rows($resql);
997  $i = 0;
998  $invoice = new Facture($this->db);
999  while ($i < $num)
1000  {
1001  $y += 3;
1002  $obj = $this->db->fetch_object($resql);
1003 
1004  if ($obj->type == 2) $text = $outputlangs->transnoentities("CreditNote");
1005  elseif ($obj->type == 3) $text = $outputlangs->transnoentities("Deposit");
1006  elseif ($obj->type == 0) $text = $outputlangs->transnoentities("ExcessReceived");
1007  else $text = $outputlangs->transnoentities("UnknownType");
1008 
1009  $invoice->fetch($obj->fk_facture_source);
1010 
1011  $pdf->SetXY($tab3_posx, $tab3_top + $y);
1012  $pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($obj->datef), 'day', false, $outputlangs, true), 0, 'L', 0);
1013  $pdf->SetXY($tab3_posx + 21, $tab3_top + $y);
1014  $pdf->MultiCell(20, 3, price((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? $obj->multicurrency_amount_ttc : $obj->amount_ttc, 0, $outputlangs), 0, 'L', 0);
1015  $pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1016  $pdf->MultiCell(20, 3, $text, 0, 'L', 0);
1017  $pdf->SetXY($tab3_posx + 58, $tab3_top + $y);
1018  $pdf->MultiCell(20, 3, $invoice->ref, 0, 'L', 0);
1019 
1020  $pdf->line($tab3_posx, $tab3_top + $y + 3, $tab3_posx + $tab3_width, $tab3_top + $y + 3);
1021 
1022  $i++;
1023  }
1024  } else {
1025  $this->error = $this->db->lasterror();
1026  return -1;
1027  }
1028 
1029  // Loop on each payment
1030  // TODO Call getListOfPaymentsgetListOfPayments instead of hard coded sql
1031  $sql = "SELECT p.datep as date, p.fk_paiement, p.num_paiement as num, pf.amount as amount, pf.multicurrency_amount,";
1032  $sql .= " cp.code";
1033  $sql .= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p";
1034  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id";
1035  $sql .= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = ".$object->id;
1036  //$sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = 1";
1037  $sql .= " ORDER BY p.datep";
1038 
1039  $resql = $this->db->query($sql);
1040  if ($resql)
1041  {
1042  $num = $this->db->num_rows($resql);
1043  $i = 0;
1044  while ($i < $num) {
1045  $y += 3;
1046  $row = $this->db->fetch_object($resql);
1047 
1048  $pdf->SetXY($tab3_posx, $tab3_top + $y);
1049  $pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($row->date), 'day', false, $outputlangs, true), 0, 'L', 0);
1050  $pdf->SetXY($tab3_posx + 21, $tab3_top + $y);
1051  $pdf->MultiCell(20, 3, price($sign * ((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? $row->multicurrency_amount : $row->amount), 0, $outputlangs), 0, 'L', 0);
1052  $pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1053  $oper = $outputlangs->transnoentitiesnoconv("PaymentTypeShort".$row->code);
1054 
1055  $pdf->MultiCell(20, 3, $oper, 0, 'L', 0);
1056  $pdf->SetXY($tab3_posx + 58, $tab3_top + $y);
1057  $pdf->MultiCell(30, 3, $row->num, 0, 'L', 0);
1058 
1059  $pdf->line($tab3_posx, $tab3_top + $y + 3, $tab3_posx + $tab3_width, $tab3_top + $y + 3);
1060 
1061  $i++;
1062  }
1063 
1064  return $tab3_top + $y + 3;
1065  } else {
1066  $this->error = $this->db->lasterror();
1067  return -1;
1068  }
1069  }
1070 
1071 
1081  protected function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
1082  {
1083  global $conf, $mysoc;
1084 
1085  $default_font_size = pdf_getPDFFontSize($outputlangs);
1086 
1087  $pdf->SetFont('', '', $default_font_size - 1);
1088 
1089  // If France, show VAT mention if not applicable
1090  if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj))
1091  {
1092  $pdf->SetFont('', 'B', $default_font_size - 2);
1093  $pdf->SetXY($this->marge_gauche, $posy);
1094  $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
1095 
1096  $posy = $pdf->GetY() + 4;
1097  }
1098 
1099  $posxval = 52;
1100 
1101  // Show payments conditions
1102  if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement))
1103  {
1104  $pdf->SetFont('', 'B', $default_font_size - 2);
1105  $pdf->SetXY($this->marge_gauche, $posy);
1106  $titre = $outputlangs->transnoentities("PaymentConditions").':';
1107  $pdf->MultiCell(43, 4, $titre, 0, 'L');
1108 
1109  $pdf->SetFont('', '', $default_font_size - 2);
1110  $pdf->SetXY($posxval, $posy);
1111  $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement_label);
1112  $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
1113  $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
1114 
1115  $posy = $pdf->GetY() + 3;
1116  }
1117 
1118  if ($object->type != 2)
1119  {
1120  // Check a payment mode is defined
1121  if (empty($object->mode_reglement_code)
1122  && empty($conf->global->FACTURE_CHQ_NUMBER)
1123  && empty($conf->global->FACTURE_RIB_NUMBER))
1124  {
1125  $this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured");
1126  }
1127  // Avoid having any valid PDF with setup that is not complete
1128  elseif (($object->mode_reglement_code == 'CHQ' && empty($conf->global->FACTURE_CHQ_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))
1129  || ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank)))
1130  {
1131  $outputlangs->load("errors");
1132 
1133  $pdf->SetXY($this->marge_gauche, $posy);
1134  $pdf->SetTextColor(200, 0, 0);
1135  $pdf->SetFont('', 'B', $default_font_size - 2);
1136  $this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup", $object->mode_reglement_code);
1137  $pdf->MultiCell(80, 3, $this->error, 0, 'L', 0);
1138  $pdf->SetTextColor(0, 0, 0);
1139 
1140  $posy = $pdf->GetY() + 1;
1141  }
1142 
1143  // Show payment mode
1144  if ($object->mode_reglement_code
1145  && $object->mode_reglement_code != 'CHQ'
1146  && $object->mode_reglement_code != 'VIR')
1147  {
1148  $pdf->SetFont('', 'B', $default_font_size - 2);
1149  $pdf->SetXY($this->marge_gauche, $posy);
1150  $titre = $outputlangs->transnoentities("PaymentMode").':';
1151  $pdf->MultiCell(80, 5, $titre, 0, 'L');
1152 
1153  $pdf->SetFont('', '', $default_font_size - 2);
1154  $pdf->SetXY($posxval, $posy);
1155  $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement);
1156  $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
1157 
1158  // Show online payment link
1159  $useonlinepayment = ((!empty($conf->paypal->enabled) || !empty($conf->stripe->enabled) || !empty($conf->paybox->enabled)) && !empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT));
1160  if (($object->mode_reglement_code == 'CB' || $object->mode_reglement_code == 'VAD') && $object->statut != Facture::STATUS_DRAFT && $useonlinepayment) {
1161  require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
1162  global $langs;
1163 
1164  $langs->loadLangs(array('payment', 'paybox'));
1165  $servicename = $langs->transnoentities('Online');
1166  $paiement_url = getOnlinePaymentUrl('', 'invoice', $object->ref, '', '', '');
1167  $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' <a href="'.$paiement_url.'">'.$outputlangs->transnoentities("ClickHere").'</a>';
1168 
1169  $pdf->writeHTMLCell(80, 10, '', '', dol_htmlentitiesbr($linktopay), 0, 1);
1170  }
1171 
1172  $posy = $pdf->GetY() + 2;
1173  }
1174 
1175  // Show payment mode CHQ
1176  if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
1177  {
1178  // If payment mode unregulated or payment mode forced to CHQ
1179  if (!empty($conf->global->FACTURE_CHQ_NUMBER))
1180  {
1181  $diffsizetitle = (empty($conf->global->PDF_DIFFSIZE_TITLE) ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
1182 
1183  if ($conf->global->FACTURE_CHQ_NUMBER > 0)
1184  {
1185  $account = new Account($this->db);
1186  $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
1187 
1188  $pdf->SetXY($this->marge_gauche, $posy);
1189  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1190  $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0);
1191  $posy = $pdf->GetY() + 1;
1192 
1193  if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
1194  {
1195  $pdf->SetXY($this->marge_gauche, $posy);
1196  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1197  $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
1198  $posy = $pdf->GetY() + 2;
1199  }
1200  }
1201  if ($conf->global->FACTURE_CHQ_NUMBER == -1)
1202  {
1203  $pdf->SetXY($this->marge_gauche, $posy);
1204  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1205  $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
1206  $posy = $pdf->GetY() + 1;
1207 
1208  if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
1209  {
1210  $pdf->SetXY($this->marge_gauche, $posy);
1211  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1212  $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
1213  $posy = $pdf->GetY() + 2;
1214  }
1215  }
1216  }
1217  }
1218 
1219  // If payment mode not forced or forced to VIR, show payment with BAN
1220  if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
1221  {
1222  if ($object->fk_account > 0 || $object->fk_bank > 0 || !empty($conf->global->FACTURE_RIB_NUMBER)) {
1223  $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
1224  if ($object->fk_bank > 0) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
1225  $account = new Account($this->db);
1226  $account->fetch($bankid);
1227 
1228  $curx = $this->marge_gauche;
1229  $cury = $posy;
1230 
1231  $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
1232 
1233  $posy += 2;
1234  }
1235  }
1236  }
1237 
1238  return $posy;
1239  }
1240 
1241 
1252  protected function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
1253  {
1254  global $conf, $mysoc, $hookmanager;
1255 
1256  $sign = 1;
1257  if ($object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign = -1;
1258 
1259  $default_font_size = pdf_getPDFFontSize($outputlangs);
1260 
1261  $outputlangsbis = null;
1262  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
1263  $outputlangsbis = new Translate('', $conf);
1264  $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
1265  $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
1266  $default_font_size--;
1267  }
1268 
1269  $tab2_top = $posy;
1270  $tab2_hl = 4;
1271  $pdf->SetFont('', '', $default_font_size - 1);
1272 
1273  // Total table
1274  $col1x = 120; $col2x = 170;
1275  if ($this->page_largeur < 210) // To work with US executive format
1276  {
1277  $col2x -= 20;
1278  }
1279  $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
1280 
1281  $useborder = 0;
1282  $index = 0;
1283 
1284  // Add trigger to allow to edit $object
1285  $parameters = array(
1286  'object' => &$object,
1287  'outputlangs' => $outputlangs,
1288  );
1289  $hookmanager->executeHooks('beforePercentCalculation', $parameters, $this); // Note that $object may have been modified by hook
1290 
1291  // overall percentage of advancement
1292  $percent = 0;
1293  $i = 0;
1294  foreach ($object->lines as $line)
1295  {
1296  $percent += $line->situation_percent;
1297  $i++;
1298  }
1299 
1300  if (!empty($i)) {
1301  $avancementGlobal = $percent / $i;
1302  } else {
1303  $avancementGlobal = 0;
1304  }
1305 
1306  $object->fetchPreviousNextSituationInvoice();
1307  $TPreviousIncoice = $object->tab_previous_situation_invoice;
1308 
1309  $total_a_payer = 0;
1310  $total_a_payer_ttc = 0;
1311  foreach ($TPreviousIncoice as &$fac) {
1312  $total_a_payer += $fac->total_ht;
1313  $total_a_payer_ttc += $fac->total_ttc;
1314  }
1315  $total_a_payer += $object->total_ht;
1316  $total_a_payer_ttc += $object->total_ttc;
1317 
1318  if (!empty($avancementGlobal)) {
1319  $total_a_payer = $total_a_payer * 100 / $avancementGlobal;
1320  $total_a_payer_ttc = $total_a_payer_ttc * 100 / $avancementGlobal;
1321  } else {
1322  $total_a_payer = 0;
1323  $total_a_payer_ttc = 0;
1324  }
1325 
1326  $i = 1;
1327  if (!empty($TPreviousIncoice)) {
1328  $pdf->setY($tab2_top);
1329  $posy = $pdf->GetY();
1330 
1331  foreach ($TPreviousIncoice as &$fac) {
1332  if ($posy > $this->page_hauteur - 4) {
1333  $this->_pagefoot($pdf, $object, $outputlangs, 1);
1334  $pdf->addPage();
1335  $pdf->setY($this->marge_haute);
1336  $posy = $pdf->GetY();
1337  }
1338 
1339  // cumul TVA précédent
1340  $index++;
1341  $pdf->SetFillColor(255, 255, 255);
1342  $pdf->SetXY($col1x, $posy);
1343  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("PDFSituationTitle", $fac->situation_counter).' '.$outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
1344 
1345  $pdf->SetXY($col2x, $posy);
1346 
1347  $facSign = '';
1348  if ($i > 1) {
1349  $facSign = $fac->total_ht >= 0 ? '+' : '';
1350  }
1351 
1352  $displayAmount = ' '.$facSign.' '.price($fac->total_ht, 0, $outputlangs);
1353 
1354  $pdf->MultiCell($largcol2, $tab2_hl, $displayAmount, 0, 'R', 1);
1355 
1356  $i++;
1357  $posy += $tab2_hl;
1358 
1359  $pdf->setY($posy);
1360  }
1361 
1362  // Display current total
1363  $pdf->SetFillColor(255, 255, 255);
1364  $pdf->SetXY($col1x, $posy);
1365  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("PDFSituationTitle", $object->situation_counter).' '.$outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
1366 
1367  $pdf->SetXY($col2x, $posy);
1368  $facSign = '';
1369  if ($i > 1) {
1370  $facSign = $object->total_ht >= 0 ? '+' : ''; // management of a particular customer case
1371  }
1372 
1373  if ($fac->type === facture::TYPE_CREDIT_NOTE) {
1374  $facSign = '-'; // les avoirs
1375  }
1376 
1377 
1378  $displayAmount = ' '.$facSign.' '.price($object->total_ht, 0, $outputlangs);
1379  $pdf->MultiCell($largcol2, $tab2_hl, $displayAmount, 0, 'R', 1);
1380 
1381  $posy += $tab2_hl;
1382 
1383  // Display all total
1384  $pdf->SetFont('', '', $default_font_size - 1);
1385  $pdf->SetFillColor(255, 255, 255);
1386  $pdf->SetXY($col1x, $posy);
1387  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("SituationTotalProgress", $avancementGlobal), 0, 'L', 1);
1388 
1389  $pdf->SetXY($col2x, $posy);
1390  $pdf->MultiCell($largcol2, $tab2_hl, price($total_a_payer * $avancementGlobal / 100, 0, $outputlangs), 0, 'R', 1);
1391  $pdf->SetFont('', '', $default_font_size - 2);
1392 
1393  $posy += $tab2_hl;
1394 
1395  if ($posy > $this->page_hauteur - 4) {
1396  $pdf->addPage();
1397  $pdf->setY($this->marge_haute);
1398  $posy = $pdf->GetY();
1399  }
1400 
1401  $tab2_top = $posy;
1402  $index = 0;
1403  }
1404 
1405  $tab2_top += 3;
1406 
1407  // Get Total HT
1408  $total_ht = (!empty($conf->multicurrency->enabled) && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
1409 
1410  // Total remise
1411  $total_line_remise = 0;
1412  foreach ($object->lines as $i => $line) {
1413  $total_line_remise += pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, 2); // TODO: add this methode to core/lib/pdf.lib
1414  // Gestion remise sous forme de ligne négative
1415  if ($line->total_ht < 0) $total_line_remise += -$line->total_ht;
1416  }
1417  if ($total_line_remise > 0) {
1418  if (!empty($conf->global->MAIN_SHOW_AMOUNT_DISCOUNT)) {
1419  $pdf->SetFillColor(255, 255, 255);
1420  $pdf->SetXY($col1x, $tab2_top + $tab2_hl);
1421  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalDiscount").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalDiscount") : ''), 0, 'L', 1);
1422  $pdf->SetXY($col2x, $tab2_top + $tab2_hl);
1423  $pdf->MultiCell($largcol2, $tab2_hl, price($total_line_remise, 0, $outputlangs), 0, 'R', 1);
1424 
1425  $index++;
1426  }
1427  // Show total NET before discount
1428  if (!empty($conf->global->MAIN_SHOW_AMOUNT_BEFORE_DISCOUNT)) {
1429  $pdf->SetFillColor(255, 255, 255);
1430  $pdf->SetXY($col1x, $tab2_top + 0);
1431  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHTBeforeDiscount").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHTBeforeDiscount") : ''), 0, 'L', 1);
1432  $pdf->SetXY($col2x, $tab2_top + 0);
1433  $pdf->MultiCell($largcol2, $tab2_hl, price($total_line_remise + $total_ht, 0, $outputlangs), 0, 'R', 1);
1434 
1435  $index++;
1436  }
1437  }
1438 
1439  // Total HT
1440  $pdf->SetFillColor(255, 255, 255);
1441  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1442  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1);
1443 
1444  $total_ht = ((!empty($conf->multicurrency->enabled) && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
1445  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1446  $pdf->MultiCell($largcol2, $tab2_hl, price($sign * ($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, $outputlangs), 0, 'R', 1);
1447 
1448  // Show VAT by rates and total
1449  $pdf->SetFillColor(248, 248, 248);
1450 
1451  $total_ttc = (!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
1452 
1453  $this->atleastoneratenotnull = 0;
1454  if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
1455  {
1456  $tvaisnull = ((!empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
1457  if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull)
1458  {
1459  // Nothing to do
1460  } else {
1461  // FIXME amount of vat not supported with multicurrency
1462 
1463  //Local tax 1 before VAT
1464  //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1465  //{
1466  foreach ($this->localtax1 as $localtax_type => $localtax_rate)
1467  {
1468  if (in_array((string) $localtax_type, array('1', '3', '5'))) continue;
1469 
1470  foreach ($localtax_rate as $tvakey => $tvaval)
1471  {
1472  if ($tvakey != 0) // On affiche pas taux 0
1473  {
1474  //$this->atleastoneratenotnull++;
1475 
1476  $index++;
1477  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1478 
1479  $tvacompl = '';
1480  if (preg_match('/\*/', $tvakey))
1481  {
1482  $tvakey = str_replace('*', '', $tvakey);
1483  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1484  }
1485 
1486  $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1487  $totalvat .= ' ';
1488  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1489  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1490 
1491  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1492  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1493  }
1494  }
1495  }
1496  //}
1497  //Local tax 2 before VAT
1498  //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1499  //{
1500  foreach ($this->localtax2 as $localtax_type => $localtax_rate)
1501  {
1502  if (in_array((string) $localtax_type, array('1', '3', '5'))) continue;
1503 
1504  foreach ($localtax_rate as $tvakey => $tvaval)
1505  {
1506  if ($tvakey != 0) // On affiche pas taux 0
1507  {
1508  //$this->atleastoneratenotnull++;
1509 
1510  $index++;
1511  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1512 
1513  $tvacompl = '';
1514  if (preg_match('/\*/', $tvakey))
1515  {
1516  $tvakey = str_replace('*', '', $tvakey);
1517  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1518  }
1519  $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1520  $totalvat .= ' ';
1521  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1522  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1523 
1524  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1525  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1526  }
1527  }
1528  }
1529  //}
1530 
1531  // VAT
1532  // Situations totals migth be wrong on huge amounts
1533  if ($object->situation_cycle_ref && $object->situation_counter > 1) {
1534  $sum_pdf_tva = 0;
1535  foreach ($this->tva as $tvakey => $tvaval) {
1536  $sum_pdf_tva += $tvaval; // sum VAT amounts to compare to object
1537  }
1538 
1539  if ($sum_pdf_tva != $object->total_tva) { // apply coef to recover the VAT object amount (the good one)
1540  if (!empty($sum_pdf_tva))
1541  {
1542  $coef_fix_tva = $object->total_tva / $sum_pdf_tva;
1543  } else {
1544  $coef_fix_tva = 1;
1545  }
1546 
1547 
1548  foreach ($this->tva as $tvakey => $tvaval) {
1549  $this->tva[$tvakey] = $tvaval * $coef_fix_tva;
1550  }
1551  }
1552  }
1553 
1554  foreach ($this->tva as $tvakey => $tvaval)
1555  {
1556  if ($tvakey != 0) // On affiche pas taux 0
1557  {
1558  $this->atleastoneratenotnull++;
1559 
1560  $index++;
1561  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1562 
1563  $tvacompl = '';
1564  if (preg_match('/\*/', $tvakey))
1565  {
1566  $tvakey = str_replace('*', '', $tvakey);
1567  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1568  }
1569  $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
1570  $totalvat .= ' ';
1571  $totalvat .= vatrate($tvakey, 1).$tvacompl;
1572  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1573 
1574  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1575  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1576  }
1577  }
1578 
1579  //Local tax 1 after VAT
1580  //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1581  //{
1582  foreach ($this->localtax1 as $localtax_type => $localtax_rate)
1583  {
1584  if (in_array((string) $localtax_type, array('2', '4', '6'))) continue;
1585 
1586  foreach ($localtax_rate as $tvakey => $tvaval)
1587  {
1588  if ($tvakey != 0) // On affiche pas taux 0
1589  {
1590  //$this->atleastoneratenotnull++;
1591 
1592  $index++;
1593  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1594 
1595  $tvacompl = '';
1596  if (preg_match('/\*/', $tvakey))
1597  {
1598  $tvakey = str_replace('*', '', $tvakey);
1599  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1600  }
1601  $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1602  $totalvat .= ' ';
1603  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1604 
1605  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1606  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1607  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1608  }
1609  }
1610  }
1611  //}
1612  //Local tax 2 after VAT
1613  //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1614  //{
1615  foreach ($this->localtax2 as $localtax_type => $localtax_rate)
1616  {
1617  if (in_array((string) $localtax_type, array('2', '4', '6'))) continue;
1618 
1619  foreach ($localtax_rate as $tvakey => $tvaval)
1620  {
1621  // retrieve global local tax
1622  if ($tvakey != 0) // On affiche pas taux 0
1623  {
1624  //$this->atleastoneratenotnull++;
1625 
1626  $index++;
1627  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1628 
1629  $tvacompl = '';
1630  if (preg_match('/\*/', $tvakey))
1631  {
1632  $tvakey = str_replace('*', '', $tvakey);
1633  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1634  }
1635  $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1636  $totalvat .= ' ';
1637 
1638  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1639  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1640 
1641  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1642  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1643  }
1644  }
1645  }
1646 
1647 
1648  // Revenue stamp
1649  if (price2num($object->revenuestamp) != 0)
1650  {
1651  $index++;
1652  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1653  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RevenueStamp").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RevenueStamp", $mysoc->country_code) : ''), $useborder, 'L', 1);
1654 
1655  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1656  $pdf->MultiCell($largcol2, $tab2_hl, price($sign * $object->revenuestamp), $useborder, 'R', 1);
1657  }
1658 
1659  // Total TTC
1660  $index++;
1661  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1662  $pdf->SetTextColor(0, 0, 60);
1663  $pdf->SetFillColor(224, 224, 224);
1664  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalTTC") : ''), $useborder, 'L', 1);
1665 
1666  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1667  $pdf->MultiCell($largcol2, $tab2_hl, price($sign * $total_ttc, 0, $outputlangs), $useborder, 'R', 1);
1668 
1669 
1670  // Retained warranty
1671  if ($object->displayRetainedWarranty())
1672  {
1673  $pdf->SetTextColor(40, 40, 40);
1674  $pdf->SetFillColor(255, 255, 255);
1675 
1676  $retainedWarranty = $object->getRetainedWarrantyAmount();
1677  $billedWithRetainedWarranty = $object->total_ttc - $retainedWarranty;
1678 
1679  // Billed - retained warranty
1680  $index++;
1681  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1682  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("ToPayOn", dol_print_date($object->date_lim_reglement, 'day')), $useborder, 'L', 1);
1683 
1684  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1685  $pdf->MultiCell($largcol2, $tab2_hl, price($billedWithRetainedWarranty), $useborder, 'R', 1);
1686 
1687  // retained warranty
1688  $index++;
1689  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1690 
1691  $retainedWarrantyToPayOn = $outputlangs->transnoentities("RetainedWarranty").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RetainedWarranty") : '').' ('.$object->retained_warranty.'%)';
1692  $retainedWarrantyToPayOn .= !empty($object->retained_warranty_date_limit) ? ' '.$outputlangs->transnoentities("toPayOn", dol_print_date($object->retained_warranty_date_limit, 'day')) : '';
1693 
1694  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $retainedWarrantyToPayOn, $useborder, 'L', 1);
1695  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1696  $pdf->MultiCell($largcol2, $tab2_hl, price($retainedWarranty), $useborder, 'R', 1);
1697  }
1698  }
1699  }
1700 
1701  $pdf->SetTextColor(0, 0, 0);
1702 
1703  $creditnoteamount = $object->getSumCreditNotesUsed((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? 1 : 0); // Warning, this also include excess received
1704  $depositsamount = $object->getSumDepositsUsed((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? 1 : 0);
1705 
1706  $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
1707  if (!empty($object->paye)) $resteapayer = 0;
1708 
1709  if (($deja_regle > 0 || $creditnoteamount > 0 || $depositsamount > 0) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
1710  {
1711  // Already paid + Deposits
1712  $index++;
1713  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1714  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Paid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("Paid") : ''), 0, 'L', 0);
1715  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1716  $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle + $depositsamount, 0, $outputlangs), 0, 'R', 0);
1717 
1718  // Credit note
1719  if ($creditnoteamount)
1720  {
1721  $labeltouse = ($outputlangs->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangs->transnoentities("CreditNotesOrExcessReceived") : $outputlangs->transnoentities("CreditNotes");
1722  $labeltouse .= (is_object($outputlangsbis) ? ' / '.($outputlangsbis->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangsbis->transnoentities("CreditNotesOrExcessReceived") : $outputlangsbis->transnoentities("CreditNotes") : '');
1723  $index++;
1724  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1725  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $labeltouse, 0, 'L', 0);
1726  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1727  $pdf->MultiCell($largcol2, $tab2_hl, price($creditnoteamount, 0, $outputlangs), 0, 'R', 0);
1728  }
1729 
1730  /*
1731  if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT)
1732  {
1733  $index++;
1734  $pdf->SetFillColor(255, 255, 255);
1735 
1736  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1737  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("EscompteOfferedShort") : ''), $useborder, 'L', 1);
1738  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1739  $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1);
1740 
1741  $resteapayer = 0;
1742  }
1743  */
1744 
1745  $index++;
1746  $pdf->SetTextColor(0, 0, 60);
1747  $pdf->SetFillColor(224, 224, 224);
1748  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1749  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RemainderToPay") : ''), $useborder, 'L', 1);
1750  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1751  $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
1752 
1753  $pdf->SetFont('', '', $default_font_size - 1);
1754  $pdf->SetTextColor(0, 0, 0);
1755  }
1756 
1757  $index++;
1758  return ($tab2_top + ($tab2_hl * $index));
1759  }
1760 
1761  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1769  public static function liste_modeles($db, $maxfilenamelength = 0)
1770  {
1771  // phpcs:enable
1772  return parent::liste_modeles($db, $maxfilenamelength); // TODO: Change the autogenerated stub
1773  }
1774 
1775  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1790  protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
1791  {
1792  global $conf;
1793 
1794  // Force to disable hidetop and hidebottom
1795  $hidebottom = 0;
1796  if ($hidetop) $hidetop = -1;
1797 
1798  $currency = !empty($currency) ? $currency : $conf->currency;
1799  $default_font_size = pdf_getPDFFontSize($outputlangs);
1800 
1801  // Amount in (at tab_top - 1)
1802  $pdf->SetTextColor(0, 0, 0);
1803  $pdf->SetFont('', '', $default_font_size - 2);
1804 
1805  if (empty($hidetop))
1806  {
1807  $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1808  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
1809  $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency));
1810  }
1811 
1812  $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1813  $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1814 
1815  //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1816  if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) {
1817  $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, 'F', null, explode(',', $conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
1818  }
1819  }
1820 
1821  $pdf->SetDrawColor(128, 128, 128);
1822  $pdf->SetFont('', '', $default_font_size - 1);
1823 
1824  // Output Rect
1825  $this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect takes a length in 3rd parameter and 4th parameter
1826 
1827 
1828  $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
1829 
1830  if (empty($hidetop)) {
1831  $pdf->line($this->marge_gauche, $tab_top + $this->tabTitleHeight, $this->page_largeur - $this->marge_droite, $tab_top + $this->tabTitleHeight); // line takes a position y in 2nd parameter and 4th parameter
1832  }
1833  }
1834 
1835  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1846  protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null)
1847  {
1848  global $conf, $langs;
1849 
1850  // Load traductions files required by page
1851  $outputlangs->loadLangs(array("main", "bills", "propal", "companies"));
1852 
1853  $default_font_size = pdf_getPDFFontSize($outputlangs);
1854 
1855  pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
1856 
1857  // Show Draft Watermark
1858  if ($object->statut == $object::STATUS_DRAFT && (!empty($conf->global->FACTURE_DRAFT_WATERMARK)))
1859  {
1860  pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK);
1861  }
1862 
1863  $pdf->SetTextColor(0, 0, 60);
1864  $pdf->SetFont('', 'B', $default_font_size + 3);
1865 
1866  $w = 110;
1867 
1868  $posy = $this->marge_haute;
1869  $posx = $this->page_largeur - $this->marge_droite - $w;
1870 
1871  $pdf->SetXY($this->marge_gauche, $posy);
1872 
1873  // Logo
1874  if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
1875  {
1876  if ($this->emetteur->logo)
1877  {
1878  $logodir = $conf->mycompany->dir_output;
1879  if (!empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity];
1880  if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO))
1881  {
1882  $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1883  } else {
1884  $logo = $logodir.'/logos/'.$this->emetteur->logo;
1885  }
1886  if (is_readable($logo)) {
1887  $height = pdf_getHeightForLogo($logo);
1888  $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1889  } else {
1890  $pdf->SetTextColor(200, 0, 0);
1891  $pdf->SetFont('', 'B', $default_font_size - 2);
1892  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1893  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1894  }
1895  } else {
1896  $text = $this->emetteur->name;
1897  $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
1898  }
1899  }
1900 
1901  $pdf->SetFont('', 'B', $default_font_size + 3);
1902  $pdf->SetXY($posx, $posy);
1903  $pdf->SetTextColor(0, 0, 60);
1904  $title = $outputlangs->transnoentities("PdfInvoiceTitle");
1905  if ($object->type == 1) $title = $outputlangs->transnoentities("InvoiceReplacement");
1906  if ($object->type == 2) $title = $outputlangs->transnoentities("InvoiceAvoir");
1907  if ($object->type == 3) $title = $outputlangs->transnoentities("InvoiceDeposit");
1908  if ($object->type == 4) $title = $outputlangs->transnoentities("InvoiceProForma");
1909  if ($this->situationinvoice) $title = $outputlangs->transnoentities("PDFInvoiceSituation");
1910  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
1911  $title .= ' - ';
1912  if ($object->type == 0) {
1913  if ($this->situationinvoice) $title .= $outputlangsbis->transnoentities("PDFInvoiceSituation");
1914  $title .= $outputlangsbis->transnoentities("PdfInvoiceTitle");
1915  } elseif ($object->type == 1) $title .= $outputlangsbis->transnoentities("InvoiceReplacement");
1916  elseif ($object->type == 2) $title .= $outputlangsbis->transnoentities("InvoiceAvoir");
1917  elseif ($object->type == 3) $title .= $outputlangsbis->transnoentities("InvoiceDeposit");
1918  elseif ($object->type == 4) $title .= $outputlangsbis->transnoentities("InvoiceProForma");
1919  }
1920  $pdf->MultiCell($w, 3, $title, '', 'R');
1921 
1922  $pdf->SetFont('', 'B', $default_font_size);
1923 
1924  $posy += 5;
1925  $pdf->SetXY($posx, $posy);
1926  $pdf->SetTextColor(0, 0, 60);
1927  $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref);
1928  if ($object->statut == $object::STATUS_DRAFT)
1929  {
1930  $pdf->SetTextColor(128, 0, 0);
1931  $textref .= ' - '.$outputlangs->transnoentities("NotValidated");
1932  }
1933  $pdf->MultiCell($w, 4, $textref, '', 'R');
1934 
1935  $posy += 1;
1936  $pdf->SetFont('', '', $default_font_size - 2);
1937 
1938  if ($object->ref_client)
1939  {
1940  $posy += 4;
1941  $pdf->SetXY($posx, $posy);
1942  $pdf->SetTextColor(0, 0, 60);
1943  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R');
1944  }
1945 
1946  if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE))
1947  {
1948  $object->fetch_projet();
1949  if (!empty($object->project->ref))
1950  {
1951  $posy += 3;
1952  $pdf->SetXY($posx, $posy);
1953  $pdf->SetTextColor(0, 0, 60);
1954  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R');
1955  }
1956  }
1957 
1958  if (!empty($conf->global->PDF_SHOW_PROJECT))
1959  {
1960  $object->fetch_projet();
1961  if (!empty($object->project->ref))
1962  {
1963  $posy += 3;
1964  $pdf->SetXY($posx, $posy);
1965  $pdf->SetTextColor(0, 0, 60);
1966  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R');
1967  }
1968  }
1969 
1970  $objectidnext = $object->getIdReplacingInvoice('validated');
1971  if ($object->type == 0 && $objectidnext)
1972  {
1973  $objectreplacing = new Facture($this->db);
1974  $objectreplacing->fetch($objectidnext);
1975 
1976  $posy += 3;
1977  $pdf->SetXY($posx, $posy);
1978  $pdf->SetTextColor(0, 0, 60);
1979  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementByInvoice").' : '.$outputlangs->convToOutputCharset($objectreplacing->ref), '', 'R');
1980  }
1981  if ($object->type == 1)
1982  {
1983  $objectreplaced = new Facture($this->db);
1984  $objectreplaced->fetch($object->fk_facture_source);
1985 
1986  $posy += 4;
1987  $pdf->SetXY($posx, $posy);
1988  $pdf->SetTextColor(0, 0, 60);
1989  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
1990  }
1991  if ($object->type == 2 && !empty($object->fk_facture_source))
1992  {
1993  $objectreplaced = new Facture($this->db);
1994  $objectreplaced->fetch($object->fk_facture_source);
1995 
1996  $posy += 3;
1997  $pdf->SetXY($posx, $posy);
1998  $pdf->SetTextColor(0, 0, 60);
1999  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CorrectionInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
2000  }
2001 
2002  $posy += 4;
2003  $pdf->SetXY($posx, $posy);
2004  $pdf->SetTextColor(0, 0, 60);
2005 
2006  $title = $outputlangs->transnoentities("DateInvoice");
2007  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
2008  $title .= ' - '.$outputlangsbis->transnoentities("DateInvoice");
2009  }
2010  $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date, "day", false, $outputlangs, true), '', 'R');
2011 
2012  if (!empty($conf->global->INVOICE_POINTOFTAX_DATE))
2013  {
2014  $posy += 4;
2015  $pdf->SetXY($posx, $posy);
2016  $pdf->SetTextColor(0, 0, 60);
2017  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DatePointOfTax")." : ".dol_print_date($object->date_pointoftax, "day", false, $outputlangs), '', 'R');
2018  }
2019 
2020  if ($object->type != 2)
2021  {
2022  $posy += 3;
2023  $pdf->SetXY($posx, $posy);
2024  $pdf->SetTextColor(0, 0, 60);
2025  $title = $outputlangs->transnoentities("DateDue");
2026  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
2027  $title .= ' - '.$outputlangsbis->transnoentities("DateDue");
2028  }
2029  $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date_lim_reglement, "day", false, $outputlangs, true), '', 'R');
2030  }
2031 
2032  if ($object->thirdparty->code_client)
2033  {
2034  $posy += 3;
2035  $pdf->SetXY($posx, $posy);
2036  $pdf->SetTextColor(0, 0, 60);
2037  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
2038  }
2039 
2040  // Get contact
2041  if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
2042  {
2043  $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
2044  if (count($arrayidcontact) > 0)
2045  {
2046  $usertmp = new User($this->db);
2047  $usertmp->fetch($arrayidcontact[0]);
2048  $posy += 4;
2049  $pdf->SetXY($posx, $posy);
2050  $pdf->SetTextColor(0, 0, 60);
2051  $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
2052  }
2053  }
2054 
2055  $posy += 1;
2056 
2057  $top_shift = 0;
2058  // Show list of linked objects
2059  $current_y = $pdf->getY();
2060  $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
2061  if ($current_y < $pdf->getY())
2062  {
2063  $top_shift = $pdf->getY() - $current_y;
2064  }
2065 
2066  if ($showaddress)
2067  {
2068  // Sender properties
2069  $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
2070 
2071  // Show sender
2072  $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
2073  $posy += $top_shift;
2074  $posx = $this->marge_gauche;
2075  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->page_largeur - $this->marge_droite - 80;
2076 
2077  $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
2078  $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
2079 
2080 
2081  // Show sender frame
2082  $pdf->SetTextColor(0, 0, 0);
2083  $pdf->SetFont('', '', $default_font_size - 2);
2084  $pdf->SetXY($posx, $posy - 5);
2085  $pdf->MultiCell(66, 5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
2086  $pdf->SetXY($posx, $posy);
2087  $pdf->SetFillColor(230, 230, 230);
2088  $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
2089  $pdf->SetTextColor(0, 0, 60);
2090 
2091  // Show sender name
2092  $pdf->SetXY($posx + 2, $posy + 3);
2093  $pdf->SetFont('', 'B', $default_font_size);
2094  $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
2095  $posy = $pdf->getY();
2096 
2097  // Show sender information
2098  $pdf->SetXY($posx + 2, $posy);
2099  $pdf->SetFont('', '', $default_font_size - 1);
2100  $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, 'L');
2101 
2102  // If BILLING contact defined, we use it
2103  $usecontact = false;
2104  $arrayidcontact = $object->getIdContact('external', 'BILLING');
2105  if (count($arrayidcontact) > 0)
2106  {
2107  $usecontact = true;
2108  $result = $object->fetch_contact($arrayidcontact[0]);
2109  }
2110 
2111  // Recipient name
2112  if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) {
2113  $thirdparty = $object->contact;
2114  } else {
2115  $thirdparty = $object->thirdparty;
2116  }
2117 
2118  $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
2119 
2120  $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object);
2121 
2122  // Show recipient
2123  $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
2124  if ($this->page_largeur < 210) $widthrecbox = 84; // To work with US executive format
2125  $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
2126  $posy += $top_shift;
2127  $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
2128  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->marge_gauche;
2129 
2130  // Show recipient frame
2131  $pdf->SetTextColor(0, 0, 0);
2132  $pdf->SetFont('', '', $default_font_size - 2);
2133  $pdf->SetXY($posx + 2, $posy - 5);
2134  $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":", 0, 'L');
2135  $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
2136 
2137  // Show recipient name
2138  $pdf->SetXY($posx + 2, $posy + 3);
2139  $pdf->SetFont('', 'B', $default_font_size);
2140  $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L');
2141 
2142  $posy = $pdf->getY();
2143 
2144  // Show recipient information
2145  $pdf->SetFont('', '', $default_font_size - 1);
2146  $pdf->SetXY($posx + 2, $posy);
2147  $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
2148  }
2149 
2150  $pdf->SetTextColor(0, 0, 0);
2151  return $top_shift;
2152  }
2153 
2154  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2164  protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
2165  {
2166  global $conf;
2167  $showdetails = empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 0 : $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
2168  return pdf_pagefoot($pdf, $outputlangs, 'INVOICE_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
2169  }
2170 
2181  public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
2182  {
2183  global $conf, $hookmanager;
2184 
2185  // Default field style for content
2186  $this->defaultContentsFieldsStyle = array(
2187  'align' => 'R', // R,C,L
2188  'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2189  );
2190 
2191  // Default field style for content
2192  $this->defaultTitlesFieldsStyle = array(
2193  'align' => 'C', // R,C,L
2194  'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2195  );
2196 
2197  /*
2198  * For exemple
2199  $this->cols['theColKey'] = array(
2200  'rank' => $rank, // int : use for ordering columns
2201  'width' => 20, // the column width in mm
2202  'title' => array(
2203  'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
2204  'label' => ' ', // the final label : used fore final generated text
2205  'align' => 'L', // text alignement : R,C,L
2206  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2207  ),
2208  'content' => array(
2209  'align' => 'L', // text alignement : R,C,L
2210  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2211  ),
2212  );
2213  */
2214 
2215  $rank = 0; // do not use negative rank
2216  $this->cols['desc'] = array(
2217  'rank' => $rank,
2218  'width' => false, // only for desc
2219  'status' => true,
2220  'title' => array(
2221  'textkey' => 'Designation', // use lang key is usefull in somme case with module
2222  'align' => 'L',
2223  // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
2224  // 'label' => ' ', // the final label
2225  'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2226  ),
2227  'content' => array(
2228  'align' => 'L',
2229  'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2230  ),
2231  );
2232 
2233  // Image of product
2234  $rank = $rank + 10;
2235  $this->cols['photo'] = array(
2236  'rank' => $rank,
2237  'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
2238  'status' => false,
2239  'title' => array(
2240  'textkey' => 'Photo',
2241  'label' => ' '
2242  ),
2243  'content' => array(
2244  'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2245  ),
2246  'border-left' => false, // remove left line separator
2247  );
2248 
2249  if (!empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto))
2250  {
2251  $this->cols['photo']['status'] = true;
2252  }
2253 
2254 
2255  $rank = $rank + 10;
2256  $this->cols['vat'] = array(
2257  'rank' => $rank,
2258  'status' => false,
2259  'width' => 16, // in mm
2260  'title' => array(
2261  'textkey' => 'VAT'
2262  ),
2263  'border-left' => true, // add left line separator
2264  );
2265 
2266  if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
2267  {
2268  $this->cols['vat']['status'] = true;
2269  }
2270 
2271  $rank = $rank + 10;
2272  $this->cols['subprice'] = array(
2273  'rank' => $rank,
2274  'width' => 19, // in mm
2275  'status' => true,
2276  'title' => array(
2277  'textkey' => 'PriceUHT'
2278  ),
2279  'border-left' => true, // add left line separator
2280  );
2281 
2282  // Adapt dynamically the width of subprice, if text is too long.
2283  $tmpwidth = 0;
2284  $nblines = count($object->lines);
2285  for ($i = 0; $i < $nblines; $i++) {
2286  $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails)));
2287  $tmpwidth = max($tmpwidth, $tmpwidth2);
2288  }
2289  if ($tmpwidth > 10) {
2290  $this->cols['subprice']['width'] += (2 * ($tmpwidth - 10));
2291  }
2292 
2293  $rank = $rank + 10;
2294  $this->cols['qty'] = array(
2295  'rank' => $rank,
2296  'width' => 16, // in mm
2297  'status' => true,
2298  'title' => array(
2299  'textkey' => 'Qty'
2300  ),
2301  'border-left' => true, // add left line separator
2302  );
2303 
2304  $rank = $rank + 10;
2305  $this->cols['progress'] = array(
2306  'rank' => $rank,
2307  'width' => 19, // in mm
2308  'status' => false,
2309  'title' => array(
2310  'textkey' => 'Progress'
2311  ),
2312  'border-left' => true, // add left line separator
2313  );
2314 
2315  if ($this->situationinvoice)
2316  {
2317  $this->cols['progress']['status'] = true;
2318  }
2319 
2320  $rank = $rank + 10;
2321  $this->cols['unit'] = array(
2322  'rank' => $rank,
2323  'width' => 11, // in mm
2324  'status' => false,
2325  'title' => array(
2326  'textkey' => 'Unit'
2327  ),
2328  'border-left' => true, // add left line separator
2329  );
2330  if (!empty($conf->global->PRODUCT_USE_UNITS)) {
2331  $this->cols['unit']['status'] = true;
2332  }
2333 
2334  $rank = $rank + 10;
2335  $this->cols['discount'] = array(
2336  'rank' => $rank,
2337  'width' => 13, // in mm
2338  'status' => false,
2339  'title' => array(
2340  'textkey' => 'ReductionShort'
2341  ),
2342  'border-left' => true, // add left line separator
2343  );
2344  if ($this->atleastonediscount) {
2345  $this->cols['discount']['status'] = true;
2346  }
2347 
2348  $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
2349  $this->cols['totalexcltax'] = array(
2350  'rank' => $rank,
2351  'width' => 26, // in mm
2352  'status' => empty($conf->global->PDF_PROPAL_HIDE_PRICE_EXCL_TAX) ? true : false,
2353  'title' => array(
2354  'textkey' => 'TotalHT'
2355  ),
2356  'border-left' => true, // add left line separator
2357  );
2358 
2359  $rank = $rank + 1010; // add a big offset to be sure is the last col because default extrafield rank is 100
2360  $this->cols['totalincltax'] = array(
2361  'rank' => $rank,
2362  'width' => 26, // in mm
2363  'status' => empty($conf->global->PDF_PROPAL_SHOW_PRICE_INCL_TAX) ? false : true,
2364  'title' => array(
2365  'textkey' => 'TotalTTC'
2366  ),
2367  'border-left' => true, // add left line separator
2368  );
2369 
2370  // Add extrafields cols
2371  if (!empty($object->lines)) {
2372  $line = reset($object->lines);
2373  $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
2374  }
2375 
2376  $parameters = array(
2377  'object' => $object,
2378  'outputlangs' => $outputlangs,
2379  'hidedetails' => $hidedetails,
2380  'hidedesc' => $hidedesc,
2381  'hideref' => $hideref
2382  );
2383 
2384  $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
2385  if ($reshook < 0)
2386  {
2387  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2388  } elseif (empty($reshook))
2389  {
2390  $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
2391  } else {
2392  $this->cols = $hookmanager->resArray;
2393  }
2394  }
2395 }
pdf_getFormat(Translate $outputlangs=null, $mode= 'setup')
Return array with format properties of default PDF format.
Definition: pdf.lib.php:45
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank informations for PDF generation.
Definition: pdf.lib.php:712
getExtrafieldContent($object, $extrafieldKey)
get extrafield content for pdf writeHtmlCell compatibility usage for PDF line columns and object note...
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto= 'UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition: pdf.lib.php:342
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition: pdf.lib.php:620
pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition: pdf.lib.php:663
prepareArrayColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Prepare Array Column Field.
</td > param sortfield sortorder printFieldListOption< tdclass="liste_titremaxwidthsearchright"></td ></tr >< trclass="liste_titre">< inputtype="checkbox"onClick="toggle(this)"/> Ref p ref Label p label Duration p duration center DesiredStock p desiredstock right StockLimitShort p seuil_stock_alerte right stock_physique right stock_real_warehouse right Ordered right StockToBuy right SupplierRef right param sortfield sortorder printFieldListTitle warehouseinternal SELECT description FROM product_lang WHERE qty< br > qty qty qty StockTooLow StockTooLow help help help< trclass="oddeven">< td >< inputtype="checkbox"class="check"name="choose'.$i.'"></td >< tdclass="nowrap"> stock</td >< td >< inputtype="hidden"name="desc'.$i.'"value="'.dol_escape_htmltag($objp-> description
Only used if Module[ID]Desc translation string is not found.
Definition: replenish.php:750
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition: pdf.lib.php:245
Class to manage products or services.
printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref=0, $hidedesc=0, $issupplierline=0)
print description column content
Class to manage Dolibarr users.
Definition: user.class.php:44
defineColumnExtrafield($object, $outputlangs, $hidedetails=0)
Define Array Column Field for extrafields.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom= 'UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
printStdColumnContent($pdf, &$curY, $colKey, $columnText= '')
print standard column content
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition: pdf.lib.php:222
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0, $hookmanager=false)
Return line unit.
Definition: pdf.lib.php:1828
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:108
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
$conf db
API class for accounts.
Definition: inc.php:54
Class to manage bank accounts.
price($amount, $form=0, $outlangs= '', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code= '')
Function to format a value into an amount for visual output Function used into PDF and HTML pages...
drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
Show payments table.
getColumnStatus($colKey)
get column status from column key
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition: pdf.lib.php:1952
Class to manage hooks.
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition: pdf.lib.php:1556
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition: pdf.lib.php:1691
pdfTabTitles(&$pdf, $tab_top, $tab_height, $outputlangs, $hidetop=0)
Print standard column content.
pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails=0, $hidefreetext=0)
Show footer of page for PDF generation.
Definition: pdf.lib.php:887
dol_strlen($string, $stringencoding= 'UTF-8')
Make a strlen call.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition: pdf.lib.php:1615
Parent class of invoice document generators.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
const STATUS_DRAFT
Draft status.
getColumnContentXStart($colKey)
get column content X (abscissa) left position from column key
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart= '')
Return a path to have a the directory according to object where files are stored. ...
pdf_getSizeForImage($realpath)
Return dimensions to use for images onto PDF checking that width and height are not higher than maxim...
Definition: pdf.lib.php:2221
pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails=0)
Return line total amount discount.
Definition: pdf.lib.php:2253
Class to manage translations.
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition: pdf.lib.php:1869
printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
Rect pdf.
pdf_getlineprogress($object, $i, $outputlangs, $hidedetails=0, $hookmanager=null)
Return line percent.
Definition: pdf.lib.php:1906
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition: pdf.lib.php:270
convertBackOfficeMediasLinksToPublicLinks($notetoshow)
Convert links to local wrapper to medias files into a string into a public external URL readable on i...
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages...
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition: pdf.lib.php:1135
pdf_getSubstitutionArray($outputlangs, $exclude=null, $object=null, $onlykey=0)
Return array of possible substitutions for PDF content (without external module substitutions).
Definition: pdf.lib.php:643
pdf_getInstance($format= '', $metric= 'mm', $pagetype= 'P')
Return a PDF instance object.
Definition: pdf.lib.php:88
drawInfoTable(&$pdf, $object, $posy, $outputlangs)
Show miscellaneous information (payment mode, payment term, ...)
pdf_build_address($outputlangs, $sourcecompany, $targetcompany= '', $targetcontact= '', $usecontact=0, $mode= 'source', $object=null)
Return a string with full address formated for output on documents.
Definition: pdf.lib.php:376
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1232
write_file($object, $outputlangs, $srctemplatepath= '', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
make_substitutions($text, $substitutionarray, $outputlangs=null)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=&gt;newva...
Class to manage invoices.
Class to manage PDF invoice template sponge.
__construct($db)
Constructor.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
if(!defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN'
Draft customers invoices.
_pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis=null)
Show top header of page.
drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
Show total to pay.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:105
getCountry($searchkey, $withcode= '', $dbtouse=0, $outputlangs= '', $entconv=1, $searchlabel= '')
Return country label, code or id from an id, code or label.
dol_mkdir($dir, $dataroot= '', $newmask=null)
Creation of a directory (this can create recursive subdir)
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the &quot;subst...
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency= '', $outputlangsbis=null)
Show table for lines.
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition: pdf.lib.php:2009