dolibarr  18.0.6
pdf_eratosthene.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-2013 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
7  * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
8  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
9  * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
10  * Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program. If not, see <https://www.gnu.org/licenses/>.
24  * or see https://www.gnu.org/
25  */
26 
33 require_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
34 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
38 
39 
44 {
48  public $db;
49 
53  public $entity;
54 
58  public $name;
59 
63  public $description;
64 
68  public $update_main_doc_field;
69 
73  public $type;
74 
79  public $version = 'dolibarr';
80 
84  public $page_largeur;
85 
89  public $page_hauteur;
90 
94  public $format;
95 
99  public $marge_gauche;
100 
104  public $marge_droite;
105 
109  public $marge_haute;
110 
114  public $marge_basse;
115 
120  public $emetteur;
121 
125  public $cols;
126 
127 
133  public function __construct($db)
134  {
135  global $conf, $langs, $mysoc;
136 
137  // Translations
138  $langs->loadLangs(array("main", "bills", "products"));
139 
140  $this->db = $db;
141  $this->name = "eratosthene";
142  $this->description = $langs->trans('PDFEratostheneDescription');
143  $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
144 
145  // Dimension page
146  $this->type = 'pdf';
147  $formatarray = pdf_getFormat();
148  $this->page_largeur = $formatarray['width'];
149  $this->page_hauteur = $formatarray['height'];
150  $this->format = array($this->page_largeur, $this->page_hauteur);
151  $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
152  $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
153  $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
154  $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
155 
156  $this->option_logo = 1; // Display logo
157  $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
158  $this->option_modereg = 1; // Display payment mode
159  $this->option_condreg = 1; // Display payment terms
160  $this->option_multilang = 1; // Available in several languages
161  $this->option_escompte = 0; // Displays if there has been a discount
162  $this->option_credit_note = 0; // Support credit notes
163  $this->option_freetext = 1; // Support add of a personalised text
164  $this->option_draft_watermark = 1; // Support add of a watermark on drafts
165  $this->watermark = '';
166 
167  // Get source company
168  $this->emetteur = $mysoc;
169  if (empty($this->emetteur->country_code)) {
170  $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
171  }
172 
173  // Define position of columns
174  $this->posxdesc = $this->marge_gauche + 1; // used for notes ans other stuff
175 
176 
177  $this->tabTitleHeight = 5; // default height
178 
179  // Use new system for position of columns, view $this->defineColumnField()
180 
181  $this->tva = array();
182  $this->tva_array = array();
183  $this->localtax1 = array();
184  $this->localtax2 = array();
185  $this->atleastoneratenotnull = 0;
186  $this->atleastonediscount = 0;
187  }
188 
189  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
201  public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
202  {
203  // phpcs:enable
204  global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
205 
206  if (!is_object($outputlangs)) {
207  $outputlangs = $langs;
208  }
209  // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
210  if (!empty($conf->global->MAIN_USE_FPDF)) {
211  $outputlangs->charset_output = 'ISO-8859-1';
212  }
213 
214  // Load translation files required by the page
215  $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries"));
216 
217  // Show Draft Watermark
218  if ($object->statut == $object::STATUS_DRAFT && getDolGlobalString('COMMANDE_DRAFT_WATERMARK')) {
219  $this->watermark = getDolGlobalString('COMMANDE_DRAFT_WATERMARK');
220  }
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", "dict", "companies", "bills", "products", "orders", "deliveries"));
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_ORDERS_WITH_PICTURE)) {
241  $objphoto = new Product($this->db);
242 
243  for ($i = 0; $i < $nblines; $i++) {
244  if (empty($object->lines[$i]->fk_product)) {
245  continue;
246  }
247 
248  $objphoto->fetch($object->lines[$i]->fk_product);
249  //var_dump($objphoto->ref);exit;
250  if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
251  $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
252  $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
253  } else {
254  $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product'); // default
255  $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
256  }
257 
258  $arephoto = false;
259  foreach ($pdir as $midir) {
260  if (!$arephoto) {
261  if ($conf->entity != $objphoto->entity) {
262  $dir = $conf->product->multidir_output[$objphoto->entity].'/'.$midir; //Check repertories of current entities
263  } else {
264  $dir = $conf->product->dir_output.'/'.$midir; //Check repertory of the current product
265  }
266 
267  foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
268  if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES')) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
269  if ($obj['photo_vignette']) {
270  $filename = $obj['photo_vignette'];
271  } else {
272  $filename = $obj['photo'];
273  }
274  } else {
275  $filename = $obj['photo'];
276  }
277 
278  $realpath = $dir.$filename;
279  $arephoto = true;
280  $this->atleastonephoto = true;
281  }
282  }
283  }
284 
285  if ($realpath && $arephoto) {
286  $realpatharray[$i] = $realpath;
287  }
288  }
289  }
290 
291 
292 
293  if (getMultidirOutput($object)) {
294  $object->fetch_thirdparty();
295 
296  $deja_regle = 0;
297 
298  // Definition of $dir and $file
299  if ($object->specimen) {
300  $dir = getMultidirOutput($object);
301  $file = $dir."/SPECIMEN.pdf";
302  } else {
303  $objectref = dol_sanitizeFileName($object->ref);
304  $dir = getMultidirOutput($object)."/".$objectref;
305  $file = $dir."/".$objectref.".pdf";
306  }
307 
308  if (!file_exists($dir)) {
309  if (dol_mkdir($dir) < 0) {
310  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
311  return 0;
312  }
313  }
314 
315  if (file_exists($dir)) {
316  // Add pdfgeneration hook
317  if (!is_object($hookmanager)) {
318  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
319  $hookmanager = new HookManager($this->db);
320  }
321  $hookmanager->initHooks(array('pdfgeneration'));
322  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
323  global $action;
324  $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
325 
326  // Set nblines with the new command lines content after hook
327  $nblines = count($object->lines);
328 
329  // Create pdf instance
330  $pdf = pdf_getInstance($this->format);
331  $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
332  $pdf->SetAutoPageBreak(1, 0);
333 
334  $heightforinfotot = 40; // Height reserved to output the info and total part
335  $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
336  $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)
337 
338  if (class_exists('TCPDF')) {
339  $pdf->setPrintHeader(false);
340  $pdf->setPrintFooter(false);
341  }
342  $pdf->SetFont(pdf_getPDFFont($outputlangs));
343  // Set path to the background PDF File
344  if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) {
345  $logodir = $conf->mycompany->dir_output;
346  if (!empty($conf->mycompany->multidir_output[$object->entity])) {
347  $logodir = $conf->mycompany->multidir_output[$object->entity];
348  }
349  $pagecount = $pdf->setSourceFile($logodir.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
350  $tplidx = $pdf->importPage(1);
351  }
352 
353  $pdf->Open();
354  $pagenb = 0;
355  $pdf->SetDrawColor(128, 128, 128);
356 
357  $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
358  $pdf->SetSubject($outputlangs->transnoentities("PdfOrderTitle"));
359  $pdf->SetCreator("Dolibarr ".DOL_VERSION);
360  $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
361  $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfOrderTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
362  if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
363  $pdf->SetCompression(false);
364  }
365 
366  $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
367 
368  // Set $this->atleastonediscount if you have at least one discount
369  for ($i = 0; $i < $nblines; $i++) {
370  if ($object->lines[$i]->remise_percent) {
371  $this->atleastonediscount++;
372  }
373  }
374 
375 
376  // New page
377  $pdf->AddPage();
378  if (!empty($tplidx)) {
379  $pdf->useTemplate($tplidx);
380  }
381  $pagenb++;
382  $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis);
383  $pdf->SetFont('', '', $default_font_size - 1);
384  $pdf->MultiCell(0, 3, ''); // Set interline to 3
385  $pdf->SetTextColor(0, 0, 0);
386 
387 
388  $tab_top = 90 + $top_shift;
389  $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
390 
391  $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
392 
393  // Incoterm
394  $height_incoterms = 0;
395  if (isModEnabled('incoterm')) {
396  $desc_incoterms = $object->getIncotermsForPDF();
397  if ($desc_incoterms) {
398  $tab_top -= 2;
399 
400  $pdf->SetFont('', '', $default_font_size - 1);
401  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
402  $nexY = max($pdf->GetY(), $nexY);
403  $height_incoterms = $nexY - $tab_top;
404 
405  // Rect takes a length in 3rd parameter
406  $pdf->SetDrawColor(192, 192, 192);
407  $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1);
408 
409  $tab_top = $nexY + 6;
410  }
411  }
412 
413  // Displays notes
414  $notetoshow = empty($object->note_public) ? '' : $object->note_public;
415  if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) {
416  // Get first sale rep
417  if (is_object($object->thirdparty)) {
418  $salereparray = $object->thirdparty->getSalesRepresentatives($user);
419  $salerepobj = new User($this->db);
420  $salerepobj->fetch($salereparray[0]['id']);
421  if (!empty($salerepobj->signature)) {
422  $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
423  }
424  }
425  }
426 
427  // Extrafields in note
428  $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
429  if (!empty($extranote)) {
430  $notetoshow = dol_concatdesc($notetoshow, $extranote);
431  }
432 
433  $pagenb = $pdf->getPage();
434  if ($notetoshow) {
435  $tab_top -= 2;
436 
437  $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
438  $pageposbeforenote = $pagenb;
439 
440  $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
441  complete_substitutions_array($substitutionarray, $outputlangs, $object);
442  $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
443  $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
444 
445  $pdf->startTransaction();
446 
447  $pdf->SetFont('', '', $default_font_size - 1);
448  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
449  // Description
450  $pageposafternote = $pdf->getPage();
451  $posyafter = $pdf->GetY();
452 
453  if ($pageposafternote > $pageposbeforenote) {
454  $pdf->rollbackTransaction(true);
455 
456  // prepare pages to receive notes
457  while ($pagenb < $pageposafternote) {
458  $pdf->AddPage();
459  $pagenb++;
460  if (!empty($tplidx)) {
461  $pdf->useTemplate($tplidx);
462  }
463  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
464  $this->_pagehead($pdf, $object, 0, $outputlangs);
465  }
466  // $this->_pagefoot($pdf,$object,$outputlangs,1);
467  $pdf->setTopMargin($tab_top_newpage);
468  // The only function to edit the bottom margin of current page to set it.
469  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
470  }
471 
472  // back to start
473  $pdf->setPage($pageposbeforenote);
474  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
475  $pdf->SetFont('', '', $default_font_size - 1);
476  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
477  $pageposafternote = $pdf->getPage();
478 
479  $posyafter = $pdf->GetY();
480 
481  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text
482  $pdf->AddPage('', '', true);
483  $pagenb++;
484  $pageposafternote++;
485  $pdf->setPage($pageposafternote);
486  $pdf->setTopMargin($tab_top_newpage);
487  // The only function to edit the bottom margin of current page to set it.
488  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
489  //$posyafter = $tab_top_newpage;
490  }
491 
492 
493  // apply note frame to previous pages
494  $i = $pageposbeforenote;
495  while ($i < $pageposafternote) {
496  $pdf->setPage($i);
497 
498 
499  $pdf->SetDrawColor(128, 128, 128);
500  // Draw note frame
501  if ($i > $pageposbeforenote) {
502  $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
503  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
504  } else {
505  $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
506  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
507  }
508 
509  // Add footer
510  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
511  $this->_pagefoot($pdf, $object, $outputlangs, 1);
512 
513  $i++;
514  }
515 
516  // apply note frame to last page
517  $pdf->setPage($pageposafternote);
518  if (!empty($tplidx)) {
519  $pdf->useTemplate($tplidx);
520  }
521  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
522  $this->_pagehead($pdf, $object, 0, $outputlangs);
523  }
524  $height_note = $posyafter - $tab_top_newpage;
525  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
526  } else {
527  // No pagebreak
528  $pdf->commitTransaction();
529  $posyafter = $pdf->GetY();
530  $height_note = $posyafter - $tab_top;
531  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
532 
533 
534  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
535  // not enough space, need to add page
536  $pdf->AddPage('', '', true);
537  $pagenb++;
538  $pageposafternote++;
539  $pdf->setPage($pageposafternote);
540  if (!empty($tplidx)) {
541  $pdf->useTemplate($tplidx);
542  }
543  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
544  $this->_pagehead($pdf, $object, 0, $outputlangs);
545  }
546 
547  $posyafter = $tab_top_newpage;
548  }
549  }
550 
551  $tab_height = $tab_height - $height_note;
552  $tab_top = $posyafter + 6;
553  } else {
554  $height_note = 0;
555  }
556 
557 
558  // Use new auto column system
559  $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
560 
561  // Table simulation to know the height of the title line
562  $pdf->startTransaction();
563  $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
564  $pdf->rollbackTransaction(true);
565 
566  $nexY = $tab_top + $this->tabTitleHeight;
567 
568  // Loop on each lines
569  $pageposbeforeprintlines = $pdf->getPage();
570  $pagenb = $pageposbeforeprintlines;
571  for ($i = 0; $i < $nblines; $i++) {
572  $curY = $nexY;
573  $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
574  $pdf->SetTextColor(0, 0, 0);
575 
576  // Define size of image if we need it
577  $imglinesize = array();
578  if (!empty($realpatharray[$i])) {
579  $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
580  }
581 
582  $pdf->setTopMargin($tab_top_newpage);
583  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
584  $pageposbefore = $pdf->getPage();
585 
586 
587  $showpricebeforepagebreak = 1;
588  $posYAfterImage = 0;
589  $posYAfterDescription = 0;
590 
591  if ($this->getColumnStatus('photo')) {
592  // We start with Photo of product line
593  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
594  $pdf->AddPage('', '', true);
595  if (!empty($tplidx)) {
596  $pdf->useTemplate($tplidx);
597  }
598  $pdf->setPage($pageposbefore + 1);
599 
600  $curY = $tab_top_newpage;
601 
602  // Allows data in the first page if description is long enough to break in multiples pages
603  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
604  $showpricebeforepagebreak = 1;
605  } else {
606  $showpricebeforepagebreak = 0;
607  }
608  }
609 
610  if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) {
611  $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
612  // $pdf->Image does not increase value return by getY, so we save it manually
613  $posYAfterImage = $curY + $imglinesize['height'];
614  }
615  }
616 
617  // Description of product line
618  if ($this->getColumnStatus('desc')) {
619  $pdf->startTransaction();
620 
621  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
622  $pageposafter = $pdf->getPage();
623 
624  if ($pageposafter > $pageposbefore) { // There is a pagebreak
625  $pdf->rollbackTransaction(true);
626  $pageposafter = $pageposbefore;
627  //print $pageposafter.'-'.$pageposbefore;exit;
628  $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
629 
630  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
631  $pageposafter = $pdf->getPage();
632  $posyafter = $pdf->GetY();
633  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
634  if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
635  $pdf->AddPage('', '', true);
636  if (!empty($tplidx)) {
637  $pdf->useTemplate($tplidx);
638  }
639  //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
640  $pdf->setPage($pageposafter + 1);
641  }
642  } else {
643  // We found a page break
644  // Allows data in the first page if description is long enough to break in multiples pages
645  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
646  $showpricebeforepagebreak = 1;
647  } else {
648  $showpricebeforepagebreak = 0;
649  }
650  }
651  } else // No pagebreak
652  {
653  $pdf->commitTransaction();
654  }
655  $posYAfterDescription = $pdf->GetY();
656  }
657 
658 
659  $nexY = max($pdf->GetY(), $posYAfterImage);
660 
661 
662  $pageposafter = $pdf->getPage();
663 
664  $pdf->setPage($pageposbefore);
665  $pdf->setTopMargin($this->marge_haute);
666  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
667 
668  // We suppose that a too long description or photo were moved completely on next page
669  if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
670  $pdf->setPage($pageposafter);
671  $curY = $tab_top_newpage;
672  }
673 
674  $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font
675 
676  // VAT Rate
677  if ($this->getColumnStatus('vat')) {
678  $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
679  $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
680  $nexY = max($pdf->GetY(), $nexY);
681  }
682 
683  // Unit price before discount
684  if ($this->getColumnStatus('subprice')) {
685  $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
686  $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
687  $nexY = max($pdf->GetY(), $nexY);
688  }
689 
690  // Quantity
691  // Enough for 6 chars
692  if ($this->getColumnStatus('qty')) {
693  $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
694  $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
695  $nexY = max($pdf->GetY(), $nexY);
696  }
697 
698 
699  // Unit
700  if ($this->getColumnStatus('unit')) {
701  $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
702  $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
703  $nexY = max($pdf->GetY(), $nexY);
704  }
705 
706  // Discount on line
707  if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) {
708  $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
709  $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
710  $nexY = max($pdf->GetY(), $nexY);
711  }
712 
713  // Total excl tax line (HT)
714  if ($this->getColumnStatus('totalexcltax')) {
715  $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
716  $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
717  $nexY = max($pdf->GetY(), $nexY);
718  }
719 
720  // Total with tax line (TTC)
721  if ($this->getColumnStatus('totalincltax')) {
722  $total_incl_tax = pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails);
723  $this->printStdColumnContent($pdf, $curY, 'totalincltax', $total_incl_tax);
724  $nexY = max($pdf->GetY(), $nexY);
725  }
726 
727  // Extrafields
728  if (!empty($object->lines[$i]->array_options)) {
729  foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
730  if ($this->getColumnStatus($extrafieldColKey)) {
731  $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs);
732  $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
733  $nexY = max($pdf->GetY(), $nexY);
734  }
735  }
736  }
737 
738  $parameters = array(
739  'object' => $object,
740  'i' => $i,
741  'pdf' =>& $pdf,
742  'curY' =>& $curY,
743  'nexY' =>& $nexY,
744  'outputlangs' => $outputlangs,
745  'hidedetails' => $hidedetails
746  );
747  $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook
748 
749 
750  // Collection of totals by value of vat in $this->tva["rate"] = total_tva
751  if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) {
752  $tvaligne = $object->lines[$i]->multicurrency_total_tva;
753  } else {
754  $tvaligne = $object->lines[$i]->total_tva;
755  }
756 
757  $localtax1ligne = $object->lines[$i]->total_localtax1;
758  $localtax2ligne = $object->lines[$i]->total_localtax2;
759  $localtax1_rate = $object->lines[$i]->localtax1_tx;
760  $localtax2_rate = $object->lines[$i]->localtax2_tx;
761  $localtax1_type = $object->lines[$i]->localtax1_type;
762  $localtax2_type = $object->lines[$i]->localtax2_type;
763 
764  // TODO remise_percent is an obsolete field for object parent
765  /*if ($object->remise_percent) {
766  $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
767  }
768  if ($object->remise_percent) {
769  $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
770  }
771  if ($object->remise_percent) {
772  $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
773  }*/
774 
775  $vatrate = (string) $object->lines[$i]->tva_tx;
776 
777  // Retrieve type from database for backward compatibility with old records
778  if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
779  && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
780  $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
781  $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
782  $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
783  }
784 
785  // retrieve global local tax
786  if ($localtax1_type && $localtax1ligne != 0) {
787  if (empty($this->localtax1[$localtax1_type][$localtax1_rate])) {
788  $this->localtax1[$localtax1_type][$localtax1_rate] = $localtax1ligne;
789  } else {
790  $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
791  }
792  }
793  if ($localtax2_type && $localtax2ligne != 0) {
794  if (empty($this->localtax2[$localtax2_type][$localtax2_rate])) {
795  $this->localtax2[$localtax2_type][$localtax2_rate] = $localtax2ligne;
796  } else {
797  $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
798  }
799  }
800 
801  if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
802  $vatrate .= '*';
803  }
804 
805  // Fill $this->tva and $this->tva_array
806  if (!isset($this->tva[$vatrate])) {
807  $this->tva[$vatrate] = 0;
808  }
809  $this->tva[$vatrate] += $tvaligne;
810  $vatcode = $object->lines[$i]->vat_src_code;
811  if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
812  $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
813  }
814  $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate'=>$vatrate, 'vatcode'=>$vatcode, 'amount'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
815 
816  // Add line
817  if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) {
818  $pdf->setPage($pageposafter);
819  $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
820  //$pdf->SetDrawColor(190,190,200);
821  $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
822  $pdf->SetLineStyle(array('dash'=>0));
823  }
824 
825 
826  // Detect if some page were added automatically and output _tableau for past pages
827  while ($pagenb < $pageposafter) {
828  $pdf->setPage($pagenb);
829  if ($pagenb == $pageposbeforeprintlines) {
830  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
831  } else {
832  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
833  }
834  $this->_pagefoot($pdf, $object, $outputlangs, 1);
835  $pagenb++;
836  $pdf->setPage($pagenb);
837  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
838  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
839  $this->_pagehead($pdf, $object, 0, $outputlangs);
840  }
841  if (!empty($tplidx)) {
842  $pdf->useTemplate($tplidx);
843  }
844  }
845  if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
846  if ($pagenb == $pageposafter) {
847  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
848  } else {
849  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
850  }
851  $this->_pagefoot($pdf, $object, $outputlangs, 1);
852  // New page
853  $pdf->AddPage();
854  if (!empty($tplidx)) {
855  $pdf->useTemplate($tplidx);
856  }
857  $pagenb++;
858  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
859  $this->_pagehead($pdf, $object, 0, $outputlangs);
860  }
861  }
862  }
863 
864  // Show square
865  if ($pagenb == $pageposbeforeprintlines) {
866  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
867  } else {
868  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
869  }
870  $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
871 
872  // Display infos area
873  $posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
874 
875  // Display total zone
876  $posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
877 
878  // Affiche zone versements
879  /*
880  if ($deja_regle)
881  {
882  $posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
883  }
884  */
885 
886  // Pied de page
887  $this->_pagefoot($pdf, $object, $outputlangs);
888  if (method_exists($pdf, 'AliasNbPages')) {
889  $pdf->AliasNbPages();
890  }
891 
892  $pdf->Close();
893 
894  $pdf->Output($file, 'F');
895 
896  // Add pdfgeneration hook
897  $hookmanager->initHooks(array('pdfgeneration'));
898  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
899  global $action;
900  $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
901  if ($reshook < 0) {
902  $this->error = $hookmanager->error;
903  $this->errors = $hookmanager->errors;
904  }
905 
906  dolChmod($file);
907 
908  $this->result = array('fullpath'=>$file);
909 
910  return 1; // No error
911  } else {
912  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
913  return 0;
914  }
915  } else {
916  $this->error = $langs->transnoentities("ErrorConstantNotDefined", "COMMANDE_OUTPUTDIR");
917  return 0;
918  }
919  }
920 
930  protected function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
931  {
932  return 0;
933  }
934 
944  protected function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
945  {
946  global $conf, $mysoc;
947  $default_font_size = pdf_getPDFFontSize($outputlangs);
948 
949  $pdf->SetFont('', '', $default_font_size - 1);
950 
951  $diffsizetitle = (empty($conf->global->PDF_DIFFSIZE_TITLE) ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
952 
953  // If France, show VAT mention if not applicable
954  if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
955  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
956  $pdf->SetXY($this->marge_gauche, $posy);
957  $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
958 
959  $posy = $pdf->GetY() + 4;
960  }
961 
962  $posxval = 52;
963 
964  $diffsizetitle = (empty($conf->global->PDF_DIFFSIZE_TITLE) ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
965 
966  // Show payments conditions
967  if ($object->cond_reglement_code || $object->cond_reglement) {
968  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
969  $pdf->SetXY($this->marge_gauche, $posy);
970  $titre = $outputlangs->transnoentities("PaymentConditions").':';
971  $pdf->MultiCell(43, 4, $titre, 0, 'L');
972 
973  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
974  $pdf->SetXY($posxval, $posy);
975  $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);
976  $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
977  if ($object->deposit_percent > 0) {
978  $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', $object->deposit_percent, $lib_condition_paiement);
979  }
980  $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
981 
982  $posy = $pdf->GetY() + 3;
983  }
984 
985  // Check a payment mode is defined
986  /* Not used with orders
987  if (empty($object->mode_reglement_code)
988  && ! $conf->global->FACTURE_CHQ_NUMBER
989  && ! $conf->global->FACTURE_RIB_NUMBER)
990  {
991  $pdf->SetXY($this->marge_gauche, $posy);
992  $pdf->SetTextColor(200,0,0);
993  $pdf->SetFont('','B', $default_font_size - 2);
994  $pdf->MultiCell(80, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0);
995  $pdf->SetTextColor(0,0,0);
996 
997  $posy=$pdf->GetY()+1;
998  }
999  */
1000  /* TODO
1001  else if (!empty($object->availability_code))
1002  {
1003  $pdf->SetXY($this->marge_gauche, $posy);
1004  $pdf->SetTextColor(200,0,0);
1005  $pdf->SetFont('','B', $default_font_size - 2);
1006  $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0);
1007  $pdf->SetTextColor(0,0,0);
1008 
1009  $posy=$pdf->GetY()+1;
1010  }*/
1011 
1012  // Show planed date of delivery
1013  if (!empty($object->delivery_date)) {
1014  $outputlangs->load("sendings");
1015  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1016  $pdf->SetXY($this->marge_gauche, $posy);
1017  $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
1018  $pdf->MultiCell(80, 4, $titre, 0, 'L');
1019  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1020  $pdf->SetXY($posxval, $posy);
1021  $dlp = dol_print_date($object->delivery_date, "daytext", false, $outputlangs, true);
1022  $pdf->MultiCell(80, 4, $dlp, 0, 'L');
1023 
1024  $posy = $pdf->GetY() + 1;
1025  } elseif ($object->availability_code || $object->availability) { // Show availability conditions
1026  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1027  $pdf->SetXY($this->marge_gauche, $posy);
1028  $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
1029  $pdf->MultiCell(80, 4, $titre, 0, 'L');
1030  $pdf->SetTextColor(0, 0, 0);
1031  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1032  $pdf->SetXY($posxval, $posy);
1033  $lib_availability = $outputlangs->transnoentities("AvailabilityType".$object->availability_code) != ('AvailabilityType'.$object->availability_code) ? $outputlangs->transnoentities("AvailabilityType".$object->availability_code) : $outputlangs->convToOutputCharset(isset($object->availability) ? $object->availability : '');
1034  $lib_availability = str_replace('\n', "\n", $lib_availability);
1035  $pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
1036 
1037  $posy = $pdf->GetY() + 1;
1038  }
1039 
1040  // Show payment mode
1041  if ($object->mode_reglement_code
1042  && $object->mode_reglement_code != 'CHQ'
1043  && $object->mode_reglement_code != 'VIR') {
1044  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1045  $pdf->SetXY($this->marge_gauche, $posy);
1046  $titre = $outputlangs->transnoentities("PaymentMode").':';
1047  $pdf->MultiCell(80, 5, $titre, 0, 'L');
1048 
1049  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1050  $pdf->SetXY($posxval, $posy);
1051  $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);
1052  $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
1053 
1054  $posy = $pdf->GetY() + 2;
1055  }
1056 
1057  // Show payment mode CHQ
1058  if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') {
1059  // Si mode reglement non force ou si force a CHQ
1060  if (!empty($conf->global->FACTURE_CHQ_NUMBER)) {
1061  if ($conf->global->FACTURE_CHQ_NUMBER > 0) {
1062  $account = new Account($this->db);
1063  $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
1064 
1065  $pdf->SetXY($this->marge_gauche, $posy);
1066  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1067  $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0);
1068  $posy = $pdf->GetY() + 1;
1069 
1070  if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) {
1071  $pdf->SetXY($this->marge_gauche, $posy);
1072  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1073  $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
1074  $posy = $pdf->GetY() + 2;
1075  }
1076  }
1077  if ($conf->global->FACTURE_CHQ_NUMBER == -1) {
1078  $pdf->SetXY($this->marge_gauche, $posy);
1079  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1080  $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
1081  $posy = $pdf->GetY() + 1;
1082 
1083  if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) {
1084  $pdf->SetXY($this->marge_gauche, $posy);
1085  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1086  $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
1087  $posy = $pdf->GetY() + 2;
1088  }
1089  }
1090  }
1091  }
1092 
1093  // If payment mode not forced or forced to VIR, show payment with BAN
1094  if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') {
1095  if ($object->fk_account > 0 || $object->fk_bank > 0 || getDolGlobalInt('FACTURE_RIB_NUMBER')) {
1096  $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
1097  if ($object->fk_bank > 0) {
1098  $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
1099  }
1100  $account = new Account($this->db);
1101  $account->fetch($bankid);
1102 
1103  $curx = $this->marge_gauche;
1104  $cury = $posy;
1105 
1106  $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
1107 
1108  $posy += 2;
1109  }
1110  }
1111 
1112  return $posy;
1113  }
1114 
1115 
1127  protected function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis = null)
1128  {
1129  global $conf, $mysoc, $hookmanager;
1130 
1131  $default_font_size = pdf_getPDFFontSize($outputlangs);
1132 
1133  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
1134  $outputlangsbis = new Translate('', $conf);
1135  $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
1136  $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
1137  $default_font_size--;
1138  }
1139 
1140  $tab2_top = $posy;
1141  $tab2_hl = 4;
1142  $pdf->SetFont('', '', $default_font_size - 1);
1143 
1144  // Total table
1145  $col1x = 120;
1146  $col2x = 170;
1147  if ($this->page_largeur < 210) { // To work with US executive format
1148  $col2x -= 20;
1149  }
1150  $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
1151 
1152  $useborder = 0;
1153  $index = 0;
1154 
1155  // Total HT
1156  $pdf->SetFillColor(255, 255, 255);
1157  $pdf->SetXY($col1x, $tab2_top);
1158  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1);
1159  $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
1160  $pdf->SetXY($col2x, $tab2_top);
1161  $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0), 0, $outputlangs), 0, 'R', 1);
1162 
1163  // Show VAT by rates and total
1164  $pdf->SetFillColor(248, 248, 248);
1165 
1166  $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
1167 
1168  $this->atleastoneratenotnull = 0;
1169  if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) {
1170  $tvaisnull = ((!empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
1171  if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull) {
1172  // Nothing to do
1173  } else {
1174  //Local tax 1 before VAT
1175  //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1176  //{
1177  foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1178  if (in_array((string) $localtax_type, array('1', '3', '5'))) {
1179  continue;
1180  }
1181  foreach ($localtax_rate as $tvakey => $tvaval) {
1182  if ($tvakey != 0) { // On affiche pas taux 0
1183  //$this->atleastoneratenotnull++;
1184  $index++;
1185  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1186 
1187  $tvacompl = '';
1188  if (preg_match('/\*/', $tvakey)) {
1189  $tvakey = str_replace('*', '', $tvakey);
1190  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1191  }
1192  $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1193  $totalvat .= ' ';
1194  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1195  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1196 
1197  $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1198 
1199  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1200  $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1201  }
1202  }
1203  }
1204  //}
1205  //Local tax 2 before VAT
1206  //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1207  //{
1208  foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1209  if (in_array((string) $localtax_type, array('1', '3', '5'))) {
1210  continue;
1211  }
1212  foreach ($localtax_rate as $tvakey => $tvaval) {
1213  if ($tvakey != 0) { // On affiche pas taux 0
1214  //$this->atleastoneratenotnull++;
1215 
1216  $index++;
1217  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1218 
1219  $tvacompl = '';
1220  if (preg_match('/\*/', $tvakey)) {
1221  $tvakey = str_replace('*', '', $tvakey);
1222  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1223  }
1224  $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1225  $totalvat .= ' ';
1226  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1227  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1228 
1229  $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1230 
1231  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1232  $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1233  }
1234  }
1235  }
1236  //}
1237 
1238  // VAT
1239  foreach ($this->tva_array as $tvakey => $tvaval) {
1240  if ($tvakey != 0) { // On affiche pas taux 0
1241  $this->atleastoneratenotnull++;
1242 
1243  $index++;
1244  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1245 
1246  $tvacompl = '';
1247  if (preg_match('/\*/', $tvakey)) {
1248  $tvakey = str_replace('*', '', $tvakey);
1249  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1250  }
1251  $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
1252  $totalvat .= ' ';
1253  if (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'rateonly') {
1254  $totalvat .= vatrate($tvaval['vatrate'], 1).$tvacompl;
1255  } elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'codeonly') {
1256  $totalvat .= ($tvaval['vatcode'] ? $tvaval['vatcode'] : vatrate($tvaval['vatrate'], 1)).$tvacompl;
1257  } else {
1258  $totalvat .= vatrate($tvaval['vatrate'], 1).($tvaval['vatcode'] ? ' ('.$tvaval['vatcode'].')' : '').$tvacompl;
1259  }
1260  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1261 
1262  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1263  $pdf->MultiCell($largcol2, $tab2_hl, price(price2num($tvaval['amount'], 'MT'), 0, $outputlangs), 0, 'R', 1);
1264  }
1265  }
1266 
1267  //Local tax 1 after VAT
1268  //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1269  //{
1270  foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1271  if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1272  continue;
1273  }
1274 
1275  foreach ($localtax_rate as $tvakey => $tvaval) {
1276  if ($tvakey != 0) { // On affiche pas taux 0
1277  //$this->atleastoneratenotnull++;
1278 
1279  $index++;
1280  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1281 
1282  $tvacompl = '';
1283  if (preg_match('/\*/', $tvakey)) {
1284  $tvakey = str_replace('*', '', $tvakey);
1285  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1286  }
1287  $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1288  $totalvat .= ' ';
1289  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1290 
1291  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1292 
1293  $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1294 
1295  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1296  $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1297  }
1298  }
1299  }
1300  //}
1301  //Local tax 2 after VAT
1302  //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1303  //{
1304  foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1305  if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1306  continue;
1307  }
1308 
1309  foreach ($localtax_rate as $tvakey => $tvaval) {
1310  // retrieve global local tax
1311  if ($tvakey != 0) { // On affiche pas taux 0
1312  //$this->atleastoneratenotnull++;
1313 
1314  $index++;
1315  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1316 
1317  $tvacompl = '';
1318  if (preg_match('/\*/', $tvakey)) {
1319  $tvakey = str_replace('*', '', $tvakey);
1320  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1321  }
1322  $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1323  $totalvat .= ' ';
1324 
1325  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1326  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1327 
1328  $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1329 
1330  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1331  $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1332  }
1333  }
1334  }
1335  //}
1336 
1337  // Total TTC
1338  $index++;
1339  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1340  $pdf->SetTextColor(0, 0, 60);
1341  $pdf->SetFillColor(224, 224, 224);
1342  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalTTC", $mysoc->country_code) : ''), $useborder, 'L', 1);
1343 
1344  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1345  $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
1346  }
1347  }
1348 
1349  $pdf->SetTextColor(0, 0, 0);
1350 
1351  $creditnoteamount = 0;
1352  $depositsamount = 0;
1353  //$creditnoteamount=$object->getSumCreditNotesUsed();
1354  //$depositsamount=$object->getSumDepositsUsed();
1355  //print "x".$creditnoteamount."-".$depositsamount;exit;
1356  $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
1357  if (!empty($object->paye)) {
1358  $resteapayer = 0;
1359  }
1360 
1361  if ($deja_regle > 0) {
1362  // Already paid + Deposits
1363  $index++;
1364 
1365  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1366  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), 0, 'L', 0);
1367  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1368  $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
1369 
1370  $index++;
1371  $pdf->SetTextColor(0, 0, 60);
1372  $pdf->SetFillColor(224, 224, 224);
1373  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1374  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RemainderToPay") : ''), $useborder, 'L', 1);
1375 
1376  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1377  $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
1378 
1379  $pdf->SetFont('', '', $default_font_size - 1);
1380  $pdf->SetTextColor(0, 0, 0);
1381  }
1382 
1383  $index++;
1384  return ($tab2_top + ($tab2_hl * $index));
1385  }
1386 
1387  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1402  protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
1403  {
1404  global $conf;
1405 
1406  // Force to disable hidetop and hidebottom
1407  $hidebottom = 0;
1408  if ($hidetop) {
1409  $hidetop = -1;
1410  }
1411 
1412  $currency = !empty($currency) ? $currency : $conf->currency;
1413  $default_font_size = pdf_getPDFFontSize($outputlangs);
1414 
1415  // Amount in (at tab_top - 1)
1416  $pdf->SetTextColor(0, 0, 0);
1417  $pdf->SetFont('', '', $default_font_size - 2);
1418 
1419  if (empty($hidetop)) {
1420  $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1421  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
1422  $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency));
1423  }
1424 
1425  $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1426  $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1427 
1428  //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1429  if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) {
1430  $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));
1431  }
1432  }
1433 
1434  $pdf->SetDrawColor(128, 128, 128);
1435  $pdf->SetFont('', '', $default_font_size - 1);
1436 
1437  // Output Rect
1438  $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
1439 
1440 
1441  $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
1442 
1443  if (empty($hidetop)) {
1444  $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
1445  }
1446  }
1447 
1448  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1449  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1461  protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null, $titlekey = "PdfOrderTitle")
1462  {
1463  // phpcs:enable
1464  global $conf, $langs, $hookmanager, $mysoc;
1465 
1466  $ltrdirection = 'L';
1467  if ($outputlangs->trans("DIRECTION") == 'rtl') $ltrdirection = 'R';
1468 
1469  // Load traductions files required by page
1470  $outputlangs->loadLangs(array("main", "bills", "propal", "orders", "companies"));
1471 
1472  $default_font_size = pdf_getPDFFontSize($outputlangs);
1473 
1474  pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
1475 
1476  $pdf->SetTextColor(0, 0, 60);
1477  $pdf->SetFont('', 'B', $default_font_size + 3);
1478 
1479  $w = 100;
1480 
1481  $posy = $this->marge_haute;
1482  $posx = $this->page_largeur - $this->marge_droite - $w;
1483 
1484  $pdf->SetXY($this->marge_gauche, $posy);
1485 
1486  // Logo
1487  if (!getDolGlobalInt('PDF_DISABLE_MYCOMPANY_LOGO')) {
1488  if ($this->emetteur->logo) {
1489  $logodir = $conf->mycompany->dir_output;
1490  if (!empty(getMultidirOutput($mysoc, 'mycompany'))) {
1491  $logodir = getMultidirOutput($mysoc, 'mycompany');
1492  }
1493  if (!getDolGlobalInt('MAIN_PDF_USE_LARGE_LOGO')) {
1494  $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1495  } else {
1496  $logo = $logodir.'/logos/'.$this->emetteur->logo;
1497  }
1498  if (is_readable($logo)) {
1499  $height = pdf_getHeightForLogo($logo);
1500  $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1501  } else {
1502  $pdf->SetTextColor(200, 0, 0);
1503  $pdf->SetFont('', 'B', $default_font_size - 2);
1504  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1505  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1506  }
1507  } else {
1508  $text = $this->emetteur->name;
1509  $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
1510  }
1511  }
1512 
1513  $pdf->SetFont('', 'B', $default_font_size + 3);
1514  $pdf->SetXY($posx, $posy);
1515  $pdf->SetTextColor(0, 0, 60);
1516  $title = $outputlangs->transnoentities($titlekey);
1517  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
1518  $title .= ' - ';
1519  $title .= $outputlangsbis->transnoentities($titlekey);
1520  }
1521  $title .= ' '.$outputlangs->convToOutputCharset($object->ref);
1522  if ($object->statut == $object::STATUS_DRAFT) {
1523  $pdf->SetTextColor(128, 0, 0);
1524  $title .= ' - '.$outputlangs->transnoentities("NotValidated");
1525  }
1526 
1527  $pdf->MultiCell($w, 3, $title, '', 'R');
1528 
1529  $pdf->SetFont('', 'B', $default_font_size);
1530 
1531  /*
1532  $posy += 5;
1533  $pdf->SetXY($posx, $posy);
1534  $pdf->SetTextColor(0, 0, 60);
1535  $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref);
1536  if ($object->statut == $object::STATUS_DRAFT) {
1537  $pdf->SetTextColor(128, 0, 0);
1538  $textref .= ' - '.$outputlangs->transnoentities("NotValidated");
1539  }
1540  $pdf->MultiCell($w, 4, $textref, '', 'R');
1541  */
1542 
1543  $posy += 3;
1544  $pdf->SetFont('', '', $default_font_size - 2);
1545 
1546  if ($object->ref_client) {
1547  $posy += 4;
1548  $pdf->SetXY($posx, $posy);
1549  $pdf->SetTextColor(0, 0, 60);
1550  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".dol_trunc($outputlangs->convToOutputCharset($object->ref_client), 65), '', 'R');
1551  }
1552 
1553  if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) {
1554  $object->fetch_projet();
1555  if (!empty($object->project->ref)) {
1556  $posy += 3;
1557  $pdf->SetXY($posx, $posy);
1558  $pdf->SetTextColor(0, 0, 60);
1559  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1560  }
1561  }
1562 
1563  if (!empty($conf->global->PDF_SHOW_PROJECT)) {
1564  $object->fetch_projet();
1565  if (!empty($object->project->ref)) {
1566  $outputlangs->load("projects");
1567  $posy += 3;
1568  $pdf->SetXY($posx, $posy);
1569  $pdf->SetTextColor(0, 0, 60);
1570  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1571  }
1572  }
1573 
1574  $posy += 4;
1575 
1576  $pdf->SetXY($posx, $posy);
1577  $pdf->SetTextColor(0, 0, 60);
1578  $title = $outputlangs->transnoentities("OrderDate");
1579  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
1580  $title .= ' - '.$outputlangsbis->transnoentities("DateInvoice");
1581  }
1582  $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date, "day", false, $outputlangs, true), '', 'R');
1583 
1584  if (empty($conf->global->MAIN_PDF_HIDE_CUSTOMER_CODE) && !empty($object->thirdparty->code_client)) {
1585  $posy += 4;
1586  $pdf->SetXY($posx, $posy);
1587  $pdf->SetTextColor(0, 0, 60);
1588  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
1589  }
1590 
1591  // Get contact
1592  if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) {
1593  $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1594  if (count($arrayidcontact) > 0) {
1595  $usertmp = new User($this->db);
1596  $usertmp->fetch($arrayidcontact[0]);
1597  $posy += 4;
1598  $pdf->SetXY($posx, $posy);
1599  $pdf->SetTextColor(0, 0, 60);
1600  $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
1601  }
1602  }
1603 
1604  $posy += 2;
1605 
1606  $top_shift = 0;
1607  // Show list of linked objects
1608  $current_y = $pdf->getY();
1609  $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
1610  if ($current_y < $pdf->getY()) {
1611  $top_shift = $pdf->getY() - $current_y;
1612  }
1613 
1614  if ($showaddress) {
1615  // Sender properties
1616  $carac_emetteur = '';
1617  // Add internal contact of object if defined
1618  $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1619  if (count($arrayidcontact) > 0) {
1620  $object->fetch_user($arrayidcontact[0]);
1621  $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1622  $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1623  $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1624  $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1625  $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1626  $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1627  $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1628  $carac_emetteur .= "\n";
1629  }
1630 
1631  $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1632 
1633  // Show sender
1634  $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
1635  $posy += $top_shift;
1636  $posx = $this->marge_gauche;
1637  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
1638  $posx = $this->page_largeur - $this->marge_droite - 80;
1639  }
1640 
1641  $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
1642  $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
1643 
1644 
1645  // Show sender frame
1646  if (empty($conf->global->MAIN_PDF_NO_SENDER_FRAME)) {
1647  $pdf->SetTextColor(0, 0, 0);
1648  $pdf->SetFont('', '', $default_font_size - 2);
1649  $pdf->SetXY($posx, $posy - 5);
1650  $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1651  $pdf->SetXY($posx, $posy);
1652  $pdf->SetFillColor(230, 230, 230);
1653  $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
1654  $pdf->SetTextColor(0, 0, 60);
1655  }
1656 
1657  // Show sender name
1658  if (empty($conf->global->MAIN_PDF_HIDE_SENDER_NAME)) {
1659  $pdf->SetXY($posx + 2, $posy + 3);
1660  $pdf->SetFont('', 'B', $default_font_size);
1661  $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1662  $posy = $pdf->getY();
1663  }
1664 
1665  // Show sender information
1666  $pdf->SetXY($posx + 2, $posy);
1667  $pdf->SetFont('', '', $default_font_size - 1);
1668  $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, $ltrdirection);
1669 
1670  // If CUSTOMER contact defined, we use it
1671  $usecontact = false;
1672  $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1673  if (count($arrayidcontact) > 0) {
1674  $usecontact = true;
1675  $result = $object->fetch_contact($arrayidcontact[0]);
1676  }
1677 
1678  //Recipient name
1679  if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) {
1680  $thirdparty = $object->contact;
1681  } else {
1682  $thirdparty = $object->thirdparty;
1683  }
1684 
1685  $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1686 
1687  $mode = 'target';
1688  $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, $mode, $object);
1689 
1690  // Show recipient
1691  $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
1692  if ($this->page_largeur < 210) {
1693  $widthrecbox = 84; // To work with US executive format
1694  }
1695  $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
1696  $posy += $top_shift;
1697  $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1698  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
1699  $posx = $this->marge_gauche;
1700  }
1701 
1702  // Show recipient frame
1703  if (empty($conf->global->MAIN_PDF_NO_RECIPENT_FRAME)) {
1704  $pdf->SetTextColor(0, 0, 0);
1705  $pdf->SetFont('', '', $default_font_size - 2);
1706  $pdf->SetXY($posx + 2, $posy - 5);
1707  $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1708  $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
1709  }
1710 
1711  // Show recipient name
1712  $pdf->SetXY($posx + 2, $posy + 3);
1713  $pdf->SetFont('', 'B', $default_font_size);
1714  $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, $ltrdirection);
1715 
1716  $posy = $pdf->getY();
1717 
1718  // Show recipient information
1719  $pdf->SetFont('', '', $default_font_size - 1);
1720  $pdf->SetXY($posx + 2, $posy);
1721  $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1722  }
1723 
1724  $pdf->SetTextColor(0, 0, 0);
1725  return $top_shift;
1726  }
1727 
1728  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1729  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1739  protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1740  {
1741  // phpcs:enable
1742  $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1743  return pdf_pagefoot($pdf, $outputlangs, 'ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext, $this->page_largeur, $this->watermark);
1744  }
1745 
1746 
1747 
1758  public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1759  {
1760  global $conf, $hookmanager;
1761 
1762  // Default field style for content
1763  $this->defaultContentsFieldsStyle = array(
1764  'align' => 'R', // R,C,L
1765  'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1766  );
1767 
1768  // Default field style for content
1769  $this->defaultTitlesFieldsStyle = array(
1770  'align' => 'C', // R,C,L
1771  'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1772  );
1773 
1774  /*
1775  * For exemple
1776  $this->cols['theColKey'] = array(
1777  'rank' => $rank, // int : use for ordering columns
1778  'width' => 20, // the column width in mm
1779  'title' => array(
1780  'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1781  'label' => ' ', // the final label : used fore final generated text
1782  'align' => 'L', // text alignement : R,C,L
1783  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1784  ),
1785  'content' => array(
1786  'align' => 'L', // text alignement : R,C,L
1787  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1788  ),
1789  );
1790  */
1791 
1792  $rank = 0; // do not use negative rank
1793  $this->cols['desc'] = array(
1794  'rank' => $rank,
1795  'width' => false, // only for desc
1796  'status' => true,
1797  'title' => array(
1798  'textkey' => 'Designation', // use lang key is usefull in somme case with module
1799  'align' => 'L',
1800  // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1801  // 'label' => ' ', // the final label
1802  'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1803  ),
1804  'content' => array(
1805  'align' => 'L',
1806  'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1807  ),
1808  );
1809 
1810  // Image of product
1811  $rank = $rank + 10;
1812  $this->cols['photo'] = array(
1813  'rank' => $rank,
1814  'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
1815  'status' => false,
1816  'title' => array(
1817  'textkey' => 'Photo',
1818  'label' => ' '
1819  ),
1820  'content' => array(
1821  'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1822  ),
1823  'border-left' => false, // remove left line separator
1824  );
1825 
1826  if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE) && !empty($this->atleastonephoto)) {
1827  $this->cols['photo']['status'] = true;
1828  }
1829 
1830  $rank = $rank + 10;
1831  $this->cols['vat'] = array(
1832  'rank' => $rank,
1833  'status' => false,
1834  'width' => 16, // in mm
1835  'title' => array(
1836  'textkey' => 'VAT'
1837  ),
1838  'border-left' => true, // add left line separator
1839  );
1840 
1841  if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) {
1842  $this->cols['vat']['status'] = true;
1843  }
1844 
1845  $rank = $rank + 10;
1846  $this->cols['subprice'] = array(
1847  'rank' => $rank,
1848  'width' => 19, // in mm
1849  'status' => true,
1850  'title' => array(
1851  'textkey' => 'PriceUHT'
1852  ),
1853  'border-left' => true, // add left line separator
1854  );
1855 
1856  // Adapt dynamically the width of subprice, if text is too long.
1857  $tmpwidth = 0;
1858  $nblines = count($object->lines);
1859  for ($i = 0; $i < $nblines; $i++) {
1860  $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails)));
1861  $tmpwidth = max($tmpwidth, $tmpwidth2);
1862  }
1863  if ($tmpwidth > 10) {
1864  $this->cols['subprice']['width'] += (2 * ($tmpwidth - 10));
1865  }
1866 
1867  $rank = $rank + 10;
1868  $this->cols['qty'] = array(
1869  'rank' => $rank,
1870  'width' => 16, // in mm
1871  'status' => true,
1872  'title' => array(
1873  'textkey' => 'Qty'
1874  ),
1875  'border-left' => true, // add left line separator
1876  );
1877 
1878  $rank = $rank + 10;
1879  $this->cols['unit'] = array(
1880  'rank' => $rank,
1881  'width' => 11, // in mm
1882  'status' => false,
1883  'title' => array(
1884  'textkey' => 'Unit'
1885  ),
1886  'border-left' => true, // add left line separator
1887  );
1888  if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1889  $this->cols['unit']['status'] = true;
1890  }
1891 
1892  $rank = $rank + 10;
1893  $this->cols['discount'] = array(
1894  'rank' => $rank,
1895  'width' => 13, // in mm
1896  'status' => false,
1897  'title' => array(
1898  'textkey' => 'ReductionShort'
1899  ),
1900  'border-left' => true, // add left line separator
1901  );
1902  if ($this->atleastonediscount) {
1903  $this->cols['discount']['status'] = true;
1904  }
1905 
1906  $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
1907  $this->cols['totalexcltax'] = array(
1908  'rank' => $rank,
1909  'width' => 26, // in mm
1910  'status' => empty($conf->global->PDF_PROPAL_HIDE_PRICE_EXCL_TAX) ? true : false,
1911  'title' => array(
1912  'textkey' => 'TotalHTShort'
1913  ),
1914  'border-left' => true, // add left line separator
1915  );
1916 
1917  $rank = $rank + 1010; // add a big offset to be sure is the last col because default extrafield rank is 100
1918  $this->cols['totalincltax'] = array(
1919  'rank' => $rank,
1920  'width' => 26, // in mm
1921  'status' => empty($conf->global->PDF_PROPAL_SHOW_PRICE_INCL_TAX) ? false : true,
1922  'title' => array(
1923  'textkey' => 'TotalTTCShort'
1924  ),
1925  'border-left' => true, // add left line separator
1926  );
1927 
1928  // Add extrafields cols
1929  if (!empty($object->lines)) {
1930  $line = reset($object->lines);
1931  $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
1932  }
1933 
1934  $parameters = array(
1935  'object' => $object,
1936  'outputlangs' => $outputlangs,
1937  'hidedetails' => $hidedetails,
1938  'hidedesc' => $hidedesc,
1939  'hideref' => $hideref
1940  );
1941 
1942  $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
1943  if ($reshook < 0) {
1944  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1945  } elseif (empty($reshook)) {
1946  $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
1947  } else {
1948  $this->cols = $hookmanager->resArray;
1949  }
1950  }
1951 }
Class to manage bank accounts.
prepareArrayColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Prepare Array Column Field.
getColumnStatus($colKey)
get column status from column key
printStdColumnContent($pdf, &$curY, $colKey, $columnText='')
print standard column content
pdfTabTitles(&$pdf, $tab_top, $tab_height, $outputlangs, $hidetop=0)
Print standard column content.
printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref=0, $hidedesc=0, $issupplierline=0)
print description column content
getColumnContentXStart($colKey)
get column content X (abscissa) left position from column key
printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
Rect pdf.
getExtrafieldContent($object, $extrafieldKey, $outputlangs=null)
get extrafield content for pdf writeHtmlCell compatibility usage for PDF line columns and object note...
defineColumnExtrafield($object, $outputlangs, $hidedetails=0)
Define Array Column Field for extrafields.
Class to manage hooks.
Parent class for orders models.
Class to manage products or services.
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:48
Class to generate PDF orders with template Eratosthene.
__construct($db)
Constructor.
drawInfoTable(&$pdf, $object, $posy, $outputlangs)
Show miscellaneous information (payment mode, payment term, ...)
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='', $outputlangsbis=null)
Show table for lines.
drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
Show payments table.
_pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis=null, $titlekey="PdfOrderTitle")
Show top header of page.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis=null)
Show total to pay.
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!function_exists('dolEscapeXML')) 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, $html=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages.
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) if(!function_exists('str_starts_with')) if(!function_exists('str_ends_with')) if(!function_exists('str_contains')) getMultidirOutput($object, $module='')
Return the full path of the directory where a module (or an object of a module) stores its files.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
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.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
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...
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 "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
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...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
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:2529
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition: pdf.lib.php:2284
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition: pdf.lib.php:289
pdf_getFormat(Translate $outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition: pdf.lib.php:85
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition: pdf.lib.php:314
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition: pdf.lib.php:2340
pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails=0, $hidefreetext=0, $page_largeur=0, $watermark='')
Show footer of page for PDF generation.
Definition: pdf.lib.php:1010
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition: pdf.lib.php:1901
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition: pdf.lib.php:1839
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0, $hookmanager=false)
Return line unit.
Definition: pdf.lib.php:2147
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition: pdf.lib.php:726
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition: pdf.lib.php:1338
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank informations for PDF generation.
Definition: pdf.lib.php:833
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition: pdf.lib.php:266
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:435
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition: pdf.lib.php:2190
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition: pdf.lib.php:1986
pdf_getSubstitutionArray($outputlangs, $exclude=null, $object=null, $onlykey=0, $include=null)
Return array of possible substitutions for PDF content (without external module substitutions).
Definition: pdf.lib.php:758
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition: pdf.lib.php:127
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition: pdf.lib.php:387
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:120
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:123