dolibarr  18.0.6
pdf_cornas.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-2011 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
5  * Copyright (C) 2010-2014 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
7  * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
8  * Copyright (C) 2018-2022 Frédéric France <frederic.france@netlogic.fr>
9  * Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
23  * or see https://www.gnu.org/
24  */
25 
32 require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php';
33 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.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 $name;
54 
58  public $description;
59 
63  public $update_main_doc_field;
64 
68  public $type;
69 
74  public $version = 'dolibarr';
75 
79  public $page_largeur;
80 
84  public $page_hauteur;
85 
89  public $format;
90 
94  public $marge_gauche;
95 
99  public $marge_droite;
100 
104  public $marge_haute;
105 
109  public $marge_basse;
110 
115  public $emetteur;
116 
117 
123  public function __construct($db)
124  {
125  global $conf, $langs, $mysoc;
126 
127  // Load translation files required by the page
128  $langs->loadLangs(array("main", "bills"));
129 
130  $this->db = $db;
131  $this->name = "cornas";
132  $this->description = $langs->trans('SuppliersCommandModel');
133  $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
134 
135  // Page size for A4 format
136  $this->type = 'pdf';
137  $formatarray = pdf_getFormat();
138  $this->page_largeur = $formatarray['width'];
139  $this->page_hauteur = $formatarray['height'];
140  $this->format = array($this->page_largeur, $this->page_hauteur);
141  $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
142  $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
143  $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
144  $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
145 
146  $this->option_logo = 1; // Display logo
147  $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
148  $this->option_modereg = 1; // Display payment mode
149  $this->option_condreg = 1; // Display payment terms
150  $this->option_multilang = 1; //Available in several languages
151  $this->option_escompte = 0; // Displays if there has been a discount
152  $this->option_credit_note = 0; // Support credit notes
153  $this->option_freetext = 1; // Support add of a personalised text
154  $this->option_draft_watermark = 1; // Support add of a watermark on drafts
155 
156  // Get source company
157  $this->emetteur = $mysoc;
158  if (empty($this->emetteur->country_code)) {
159  $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
160  }
161 
162  // Define position of columns
163  $this->posxdesc = $this->marge_gauche + 1; // For module retrocompatibility support durring PDF transition: TODO remove this at the end
164 
165  $this->tva = array();
166  $this->tva_array = array();
167  $this->localtax1 = array();
168  $this->localtax2 = array();
169  $this->atleastoneratenotnull = 0;
170  $this->atleastonediscount = 0;
171  }
172 
173 
174  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
186  public function write_file($object, $outputlangs = '', $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
187  {
188  // phpcs:enable
189  global $user, $langs, $conf, $hookmanager, $mysoc, $nblines;
190 
191  if (!is_object($outputlangs)) {
192  $outputlangs = $langs;
193  }
194  // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
195  if (!empty($conf->global->MAIN_USE_FPDF)) {
196  $outputlangs->charset_output = 'ISO-8859-1';
197  }
198 
199  // Load translation files required by the page
200  $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "dict", "products"));
201 
202  global $outputlangsbis;
203  $outputlangsbis = null;
204  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
205  $outputlangsbis = new Translate('', $conf);
206  $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
207  $outputlangsbis->loadLangs(array("main", "orders", "companies", "bills", "dict", "products"));
208  }
209 
210  $nblines = count($object->lines);
211 
212  $hidetop = 0;
213  if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) {
214  $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE;
215  }
216 
217  // Loop on each lines to detect if there is at least one image to show
218  $realpatharray = array();
219  if (!empty($conf->global->MAIN_GENERATE_SUPPLIER_ORDER_WITH_PICTURE)) {
220  for ($i = 0; $i < $nblines; $i++) {
221  if (empty($object->lines[$i]->fk_product)) {
222  continue;
223  }
224 
225  $objphoto = new Product($this->db);
226  $objphoto->fetch($object->lines[$i]->fk_product);
227 
228  if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
229  $pdir = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$object->lines[$i]->fk_product."/photos/";
230  $dir = $conf->product->dir_output.'/'.$pdir;
231  } else {
232  $pdir = get_exdir($objphoto->id, 0, 0, 0, $objphoto, 'product');
233  $dir = $conf->product->dir_output.'/'.$pdir;
234  }
235 
236  $realpath = '';
237  foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
238  if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES')) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
239  if ($obj['photo_vignette']) {
240  $filename = $obj['photo_vignette'];
241  } else {
242  $filename = $obj['photo'];
243  }
244  } else {
245  $filename = $obj['photo'];
246  }
247  $realpath = $dir.$filename;
248  break;
249  }
250 
251  if ($realpath) {
252  $realpatharray[$i] = $realpath;
253  }
254  }
255  }
256  if (count($realpatharray) == 0) {
257  $this->posxpicture = $this->posxtva;
258  }
259 
260  if ($conf->fournisseur->commande->dir_output) {
261  $object->fetch_thirdparty();
262 
263  $deja_regle = 0;
264  $amount_credit_notes_included = 0;
265  $amount_deposits_included = 0;
266  //$amount_credit_notes_included = $object->getSumCreditNotesUsed();
267  //$amount_deposits_included = $object->getSumDepositsUsed();
268 
269  // Definition of $dir and $file
270  if ($object->specimen) {
271  $dir = $conf->fournisseur->commande->dir_output;
272  $file = $dir."/SPECIMEN.pdf";
273  } else {
274  $objectref = dol_sanitizeFileName($object->ref);
275  $objectrefsupplier = dol_sanitizeFileName($object->ref_supplier);
276  $dir = $conf->fournisseur->commande->dir_output.'/'.$objectref;
277  $file = $dir."/".$objectref.".pdf";
278  if (!empty($conf->global->SUPPLIER_REF_IN_NAME)) {
279  $file = $dir."/".$objectref.($objectrefsupplier ? "_".$objectrefsupplier : "").".pdf";
280  }
281  }
282 
283  if (!file_exists($dir)) {
284  if (dol_mkdir($dir) < 0) {
285  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
286  return 0;
287  }
288  }
289 
290  if (file_exists($dir)) {
291  // Add pdfgeneration hook
292  if (!is_object($hookmanager)) {
293  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
294  $hookmanager = new HookManager($this->db);
295  }
296  $hookmanager->initHooks(array('pdfgeneration'));
297  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
298  global $action;
299  $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
300 
301  $nblines = count($object->lines);
302 
303  $pdf = pdf_getInstance($this->format);
304  $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
305  $heightforinfotot = 50; // Height reserved to output the info and total part
306  $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
307  $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
308  if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)) {
309  $heightforfooter += 6;
310  }
311  $pdf->SetAutoPageBreak(1, 0);
312 
313  if (class_exists('TCPDF')) {
314  $pdf->setPrintHeader(false);
315  $pdf->setPrintFooter(false);
316  }
317  $pdf->SetFont(pdf_getPDFFont($outputlangs));
318  // Set path to the background PDF File
319  if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) {
320  $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
321  $tplidx = $pdf->importPage(1);
322  }
323 
324  $pdf->Open();
325  $pagenb = 0;
326  $pdf->SetDrawColor(128, 128, 128);
327 
328  $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
329  $pdf->SetSubject($outputlangs->transnoentities("Order"));
330  $pdf->SetCreator("Dolibarr ".DOL_VERSION);
331  $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
332  $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Order")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
333  if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
334  $pdf->SetCompression(false);
335  }
336 
337  $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
338 
339  // Does we have at least one line with discount $this->atleastonediscount
340  foreach ($object->lines as $line) {
341  if ($line->remise_percent) {
342  $this->atleastonediscount = true;
343  break;
344  }
345  }
346 
347  // New page
348  $pdf->AddPage();
349  if (!empty($tplidx)) {
350  $pdf->useTemplate($tplidx);
351  }
352  $pagenb++;
353  $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
354  $pdf->SetFont('', '', $default_font_size - 1);
355  $pdf->MultiCell(0, 3, ''); // Set interline to 3
356  $pdf->SetTextColor(0, 0, 0);
357 
358  $tab_top = 90 + $top_shift;
359  $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
360 
361  $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
362 
363  // Incoterm
364  if (isModEnabled('incoterm')) {
365  $desc_incoterms = $object->getIncotermsForPDF();
366  if ($desc_incoterms) {
367  $tab_top -= 2;
368 
369  $pdf->SetFont('', '', $default_font_size - 1);
370  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
371  $nexY = $pdf->GetY();
372  $height_incoterms = $nexY - $tab_top;
373 
374  // Rect takes a length in 3rd parameter
375  $pdf->SetDrawColor(192, 192, 192);
376  $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1);
377 
378  $tab_top = $nexY + 6;
379  }
380  }
381 
382  // Affiche notes
383  $notetoshow = empty($object->note_public) ? '' : $object->note_public;
384 
385  // Extrafields in note
386  $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
387  if (!empty($extranote)) {
388  $notetoshow = dol_concatdesc($notetoshow, $extranote);
389  }
390 
391  $pagenb = $pdf->getPage();
392  if ($notetoshow) {
393  $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
394  $pageposbeforenote = $pagenb;
395 
396  $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
397  complete_substitutions_array($substitutionarray, $outputlangs, $object);
398  $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
399  $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
400 
401  $tab_top -= 2;
402 
403  $pdf->startTransaction();
404 
405  $pdf->SetFont('', '', $default_font_size - 1);
406  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
407  // Description
408  $pageposafternote = $pdf->getPage();
409  $posyafter = $pdf->GetY();
410 
411  if ($pageposafternote > $pageposbeforenote) {
412  $pdf->rollbackTransaction(true);
413 
414  // prepar pages to receive notes
415  while ($pagenb < $pageposafternote) {
416  $pdf->AddPage();
417  $pagenb++;
418  if (!empty($tplidx)) {
419  $pdf->useTemplate($tplidx);
420  }
421  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
422  $this->_pagehead($pdf, $object, 0, $outputlangs);
423  }
424  // $this->_pagefoot($pdf,$object,$outputlangs,1);
425  $pdf->setTopMargin($tab_top_newpage);
426  // The only function to edit the bottom margin of current page to set it.
427  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
428  }
429 
430  // back to start
431  $pdf->setPage($pageposbeforenote);
432  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
433  $pdf->SetFont('', '', $default_font_size - 1);
434  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
435  $pageposafternote = $pdf->getPage();
436 
437  $posyafter = $pdf->GetY();
438 
439  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text
440  $pdf->AddPage('', '', true);
441  $pagenb++;
442  $pageposafternote++;
443  $pdf->setPage($pageposafternote);
444  $pdf->setTopMargin($tab_top_newpage);
445  // The only function to edit the bottom margin of current page to set it.
446  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
447  //$posyafter = $tab_top_newpage;
448  }
449 
450 
451  // apply note frame to previus pages
452  $i = $pageposbeforenote;
453  while ($i < $pageposafternote) {
454  $pdf->setPage($i);
455 
456 
457  $pdf->SetDrawColor(128, 128, 128);
458  // Draw note frame
459  if ($i > $pageposbeforenote) {
460  $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
461  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
462  } else {
463  $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
464  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
465  }
466 
467  // Add footer
468  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
469  $this->_pagefoot($pdf, $object, $outputlangs, 1);
470 
471  $i++;
472  }
473 
474  // apply note frame to last page
475  $pdf->setPage($pageposafternote);
476  if (!empty($tplidx)) {
477  $pdf->useTemplate($tplidx);
478  }
479  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
480  $this->_pagehead($pdf, $object, 0, $outputlangs);
481  }
482  $height_note = $posyafter - $tab_top_newpage;
483  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
484  } else {
485  // No pagebreak
486  $pdf->commitTransaction();
487  $posyafter = $pdf->GetY();
488  $height_note = $posyafter - $tab_top;
489  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
490 
491 
492  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
493  // not enough space, need to add page
494  $pdf->AddPage('', '', true);
495  $pagenb++;
496  $pageposafternote++;
497  $pdf->setPage($pageposafternote);
498  if (!empty($tplidx)) {
499  $pdf->useTemplate($tplidx);
500  }
501  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
502  $this->_pagehead($pdf, $object, 0, $outputlangs);
503  }
504 
505  $posyafter = $tab_top_newpage;
506  }
507  }
508 
509  $tab_height = $tab_height - $height_note;
510  $tab_top = $posyafter + 6;
511  } else {
512  $height_note = 0;
513  }
514 
515  $nexY = $tab_top + 5;
516 
517  // Use new auto collum system
518  $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
519 
520  // Loop on each lines
521  $pageposbeforeprintlines = $pdf->getPage();
522  $pagenb = $pageposbeforeprintlines;
523  for ($i = 0; $i < $nblines; $i++) {
524  $curY = $nexY;
525  $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
526  $pdf->SetTextColor(0, 0, 0);
527 
528  // Define size of image if we need it
529  $imglinesize = array();
530  if (!empty($realpatharray[$i])) {
531  $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
532  }
533 
534  $pdf->setTopMargin($tab_top_newpage);
535  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
536  $pageposbefore = $pdf->getPage();
537 
538  $showpricebeforepagebreak = 1;
539  $posYAfterImage = 0;
540  $posYAfterDescription = 0;
541 
542  // We start with Photo of product line
543  if ($this->getColumnStatus('photo')) {
544  // We start with Photo of product line
545  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
546  $pdf->AddPage('', '', true);
547  if (!empty($tplidx)) {
548  $pdf->useTemplate($tplidx);
549  }
550  $pdf->setPage($pageposbefore + 1);
551 
552  $curY = $tab_top_newpage;
553 
554  // Allows data in the first page if description is long enough to break in multiples pages
555  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
556  $showpricebeforepagebreak = 1;
557  } else {
558  $showpricebeforepagebreak = 0;
559  }
560  }
561 
562  if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) {
563  $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
564  // $pdf->Image does not increase value return by getY, so we save it manually
565  $posYAfterImage = $curY + $imglinesize['height'];
566  }
567  }
568  // Description of product line
569  $curX = $this->posxdesc - 1;
570  $showpricebeforepagebreak = 1;
571 
572  if ($this->getColumnStatus('desc')) {
573  $pdf->startTransaction();
574  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1);
575 
576  $pageposafter = $pdf->getPage();
577  if ($pageposafter > $pageposbefore) { // There is a pagebreak
578  $pdf->rollbackTransaction(true);
579 
580  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1);
581 
582  $pageposafter = $pdf->getPage();
583  $posyafter = $pdf->GetY();
584  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
585  if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
586  $pdf->AddPage('', '', true);
587  if (!empty($tplidx)) {
588  $pdf->useTemplate($tplidx);
589  }
590  //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
591  $pdf->setPage($pageposafter + 1);
592  }
593  } else {
594  // We found a page break
595  // Allows data in the first page if description is long enough to break in multiples pages
596  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
597  $showpricebeforepagebreak = 1;
598  } else {
599  $showpricebeforepagebreak = 0;
600  }
601  }
602  } else // No pagebreak
603  {
604  $pdf->commitTransaction();
605  }
606  $posYAfterDescription = $pdf->GetY();
607  }
608 
609  $nexY = $pdf->GetY();
610  $pageposafter = $pdf->getPage();
611  $pdf->setPage($pageposbefore);
612  $pdf->setTopMargin($this->marge_haute);
613  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
614 
615  // We suppose that a too long description is moved completely on next page
616  if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
617  $pdf->setPage($pageposafter);
618  $curY = $tab_top_newpage;
619  }
620 
621  $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut
622 
623  // VAT Rate
624  if ($this->getColumnStatus('vat')) {
625  $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
626  $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
627  $nexY = max($pdf->GetY(), $nexY);
628  }
629 
630  // Unit price before discount
631  if ($this->getColumnStatus('subprice')) {
632  $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
633  $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
634  $nexY = max($pdf->GetY(), $nexY);
635  }
636 
637  // Quantity
638  // Enough for 6 chars
639  if ($this->getColumnStatus('qty')) {
640  $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
641  $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
642  $nexY = max($pdf->GetY(), $nexY);
643  }
644 
645 
646  // Unit
647  if ($this->getColumnStatus('unit')) {
648  $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
649  $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
650  $nexY = max($pdf->GetY(), $nexY);
651  }
652 
653  // Discount on line
654  if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) {
655  $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
656  $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
657  $nexY = max($pdf->GetY(), $nexY);
658  }
659 
660  // Total HT line
661  if ($this->getColumnStatus('totalexcltax')) {
662  $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
663  $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
664  $nexY = max($pdf->GetY(), $nexY);
665  }
666 
667  // Extrafields
668  if (!empty($object->lines[$i]->array_options)) {
669  foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
670  if ($this->getColumnStatus($extrafieldColKey)) {
671  $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs);
672  $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
673  $nexY = max($pdf->GetY(), $nexY);
674  }
675  }
676  }
677 
678  $parameters = array(
679  'object' => $object,
680  'i' => $i,
681  'pdf' =>& $pdf,
682  'curY' =>& $curY,
683  'nexY' =>& $nexY,
684  'outputlangs' => $outputlangs,
685  'hidedetails' => $hidedetails
686  );
687  $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook
688 
689 
690  // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
691  if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) {
692  $tvaligne = $object->lines[$i]->multicurrency_total_tva;
693  } else {
694  $tvaligne = $object->lines[$i]->total_tva;
695  }
696 
697  $localtax1ligne = $object->lines[$i]->total_localtax1;
698  $localtax2ligne = $object->lines[$i]->total_localtax2;
699  $localtax1_rate = $object->lines[$i]->localtax1_tx;
700  $localtax2_rate = $object->lines[$i]->localtax2_tx;
701  $localtax1_type = $object->lines[$i]->localtax1_type;
702  $localtax2_type = $object->lines[$i]->localtax2_type;
703 
704  // TODO remise_percent is an obsolete field for object parent
705  /*if (!empty($object->remise_percent)) {
706  $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
707  }
708  if (!empty($object->remise_percent)) {
709  $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
710  }
711  if (!empty($object->remise_percent)) {
712  $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
713  }*/
714 
715  $vatrate = (string) $object->lines[$i]->tva_tx;
716 
717  // Retrieve type from database for backward compatibility with old records
718  if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
719  && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
720  $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $mysoc, $object->thirdparty);
721  $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
722  $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
723  }
724 
725  // retrieve global local tax
726  if ($localtax1_type && $localtax1ligne != 0) {
727  if (empty($this->localtax1[$localtax1_type][$localtax1_rate])) {
728  $this->localtax1[$localtax1_type][$localtax1_rate] = $localtax1ligne;
729  } else {
730  $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
731  }
732  }
733  if ($localtax2_type && $localtax2ligne != 0) {
734  if (empty($this->localtax2[$localtax2_type][$localtax2_rate])) {
735  $this->localtax2[$localtax2_type][$localtax2_rate] = $localtax2ligne;
736  } else {
737  $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
738  }
739  }
740 
741  if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
742  $vatrate .= '*';
743  }
744 
745  // Fill $this->tva and $this->tva_array
746  if (!isset($this->tva[$vatrate])) {
747  $this->tva[$vatrate] = 0;
748  }
749  $this->tva[$vatrate] += $tvaligne;
750  $vatcode = $object->lines[$i]->vat_src_code;
751  if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
752  $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
753  }
754  $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate'=>$vatrate, 'vatcode'=>$vatcode, 'amount'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
755 
756  if ($posYAfterImage > $posYAfterDescription) {
757  $nexY = $posYAfterImage;
758  }
759 
760  // Add line
761  if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) {
762  $pdf->setPage($pageposafter);
763  $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
764  //$pdf->SetDrawColor(190,190,200);
765  $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
766  $pdf->SetLineStyle(array('dash'=>0));
767  }
768 
769  // Detect if some page were added automatically and output _tableau for past pages
770  while ($pagenb < $pageposafter) {
771  $pdf->setPage($pagenb);
772  if ($pagenb == $pageposbeforeprintlines) {
773  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
774  } else {
775  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
776  }
777  $this->_pagefoot($pdf, $object, $outputlangs, 1);
778  $pagenb++;
779  $pdf->setPage($pagenb);
780  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
781  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
782  $this->_pagehead($pdf, $object, 0, $outputlangs);
783  }
784  if (!empty($tplidx)) {
785  $pdf->useTemplate($tplidx);
786  }
787  }
788  if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
789  if ($pagenb == $pageposafter) {
790  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
791  } else {
792  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
793  }
794  $this->_pagefoot($pdf, $object, $outputlangs, 1);
795  // New page
796  $pdf->AddPage();
797  if (!empty($tplidx)) {
798  $pdf->useTemplate($tplidx);
799  }
800  $pagenb++;
801  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
802  $this->_pagehead($pdf, $object, 0, $outputlangs);
803  }
804  }
805  }
806 
807  // Show square
808  if ($pagenb == $pageposbeforeprintlines) {
809  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
810  $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
811  } else {
812  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
813  $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
814  }
815 
816  // Affiche zone infos
817  $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
818 
819  // Affiche zone totaux
820  $posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
821 
822  // Affiche zone versements
823  if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) {
824  $posy = $this->_tableau_versements($pdf, $object, $posy, $outputlangs);
825  }
826 
827  // Pied de page
828  $this->_pagefoot($pdf, $object, $outputlangs);
829  if (method_exists($pdf, 'AliasNbPages')) {
830  $pdf->AliasNbPages();
831  }
832 
833  $pdf->Close();
834 
835  $pdf->Output($file, 'F');
836 
837  // Add pdfgeneration hook
838  $hookmanager->initHooks(array('pdfgeneration'));
839  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
840  global $action;
841  $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
842  if ($reshook < 0) {
843  $this->error = $hookmanager->error;
844  $this->errors = $hookmanager->errors;
845  }
846 
847  dolChmod($file);
848 
849  $this->result = array('fullpath'=>$file);
850 
851  return 1; // No error
852  } else {
853  $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
854  return 0;
855  }
856  } else {
857  $this->error = $langs->trans("ErrorConstantNotDefined", "SUPPLIER_OUTPUTDIR");
858  return 0;
859  }
860  }
861 
862  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
863  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
873  protected function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
874  {
875  // phpcs:enable
876  return 1;
877  }
878 
879  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
880  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
890  protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
891  {
892  // phpcs:enable
893  global $conf, $mysoc;
894  $default_font_size = pdf_getPDFFontSize($outputlangs);
895 
896  $diffsizetitle = (empty($conf->global->PDF_DIFFSIZE_TITLE) ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
897 
898  // If France, show VAT mention if not applicable
899  if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
900  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
901  $pdf->SetXY($this->marge_gauche, $posy);
902  $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
903 
904  $posy = $pdf->GetY() + 4;
905  }
906 
907  $posxval = 52;
908 
909  // Show payments conditions
910  if (!empty($object->cond_reglement_code) || $object->cond_reglement) {
911  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
912  $pdf->SetXY($this->marge_gauche, $posy);
913  $titre = $outputlangs->transnoentities("PaymentConditions").':';
914  $pdf->MultiCell(80, 4, $titre, 0, 'L');
915 
916  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
917  $pdf->SetXY($posxval, $posy);
918  $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);
919  $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
920  $pdf->MultiCell(80, 4, $lib_condition_paiement, 0, 'L');
921 
922  $posy = $pdf->GetY() + 3;
923  }
924 
925  // Show payment mode
926  if (!empty($object->mode_reglement_code)) {
927  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
928  $pdf->SetXY($this->marge_gauche, $posy);
929  $titre = $outputlangs->transnoentities("PaymentMode").':';
930  $pdf->MultiCell(80, 5, $titre, 0, 'L');
931 
932  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
933  $pdf->SetXY($posxval, $posy);
934  $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);
935  $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
936 
937  $posy = $pdf->GetY() + 2;
938  }
939 
940 
941  return $posy;
942  }
943 
944  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
945  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
956  protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
957  {
958  // phpcs:enable
959  global $conf, $mysoc;
960 
961  $default_font_size = pdf_getPDFFontSize($outputlangs);
962 
963  $tab2_top = $posy;
964  $tab2_hl = 4;
965  $pdf->SetFont('', '', $default_font_size - 1);
966 
967  // Tableau total
968  $col1x = 120;
969  $col2x = 170;
970  if ($this->page_largeur < 210) { // To work with US executive format
971  $col2x -= 20;
972  }
973  $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
974 
975  $useborder = 0;
976  $index = 0;
977 
978  // Total HT
979  $pdf->SetFillColor(255, 255, 255);
980  $pdf->SetXY($col1x, $tab2_top);
981  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
982 
983  $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
984  $pdf->SetXY($col2x, $tab2_top);
985  $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, 'R', 1);
986 
987  // Show VAT by rates and total
988  $pdf->SetFillColor(248, 248, 248);
989 
990  $this->atleastoneratenotnull = 0;
991  foreach ($this->tva as $tvakey => $tvaval) {
992  if ($tvakey > 0) { // On affiche pas taux 0
993  $this->atleastoneratenotnull++;
994 
995  $index++;
996  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
997 
998  $tvacompl = '';
999 
1000  if (preg_match('/\*/', $tvakey)) {
1001  $tvakey = str_replace('*', '', $tvakey);
1002  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1003  }
1004 
1005  $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).' ';
1006  $totalvat .= vatrate($tvakey, 1).$tvacompl;
1007  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1008 
1009  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1010  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
1011  }
1012  }
1013  if (!$this->atleastoneratenotnull) { // If no vat at all
1014  $index++;
1015  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1016  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code), 0, 'L', 1);
1017 
1018  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1019  $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_tva), 0, 'R', 1);
1020 
1021  // Total LocalTax1
1022  if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION == 'localtax1on' && $object->total_localtax1 > 0) {
1023  $index++;
1024  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1025  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code), 0, 'L', 1);
1026  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1027  $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax1), $useborder, 'R', 1);
1028  }
1029 
1030  // Total LocalTax2
1031  if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION == 'localtax2on' && $object->total_localtax2 > 0) {
1032  $index++;
1033  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1034  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code), 0, 'L', 1);
1035  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1036  $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax2), $useborder, 'R', 1);
1037  }
1038  } else {
1039  //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1040  //{
1041  //Local tax 1
1042  foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1043  if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1044  continue;
1045  }
1046 
1047  foreach ($localtax_rate as $tvakey => $tvaval) {
1048  if ($tvakey != 0) { // On affiche pas taux 0
1049  //$this->atleastoneratenotnull++;
1050 
1051  $index++;
1052  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1053 
1054  $tvacompl = '';
1055  if (preg_match('/\*/', $tvakey)) {
1056  $tvakey = str_replace('*', '', $tvakey);
1057  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1058  }
1059  $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
1060  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1061  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1062 
1063  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1064  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1065  }
1066  }
1067  }
1068 
1069  //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1070  //{
1071  //Local tax 2
1072  foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1073  if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1074  continue;
1075  }
1076 
1077  foreach ($localtax_rate as $tvakey => $tvaval) {
1078  if ($tvakey != 0) { // On affiche pas taux 0
1079  //$this->atleastoneratenotnull++;
1080 
1081  $index++;
1082  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1083 
1084  $tvacompl = '';
1085  if (preg_match('/\*/', $tvakey)) {
1086  $tvakey = str_replace('*', '', $tvakey);
1087  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1088  }
1089  $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
1090  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1091  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1092 
1093  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1094  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
1095  }
1096  }
1097  }
1098  }
1099 
1100  // Total TTC
1101  $index++;
1102  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1103  $pdf->SetTextColor(0, 0, 60);
1104  $pdf->SetFillColor(224, 224, 224);
1105  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
1106 
1107  $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
1108  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1109  $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc), $useborder, 'R', 1);
1110  $pdf->SetFont('', '', $default_font_size - 1);
1111  $pdf->SetTextColor(0, 0, 0);
1112 
1113  $creditnoteamount = 0;
1114  $depositsamount = 0;
1115  //$creditnoteamount=$object->getSumCreditNotesUsed();
1116  //$depositsamount=$object->getSumDepositsUsed();
1117  //print "x".$creditnoteamount."-".$depositsamount;exit;
1118  $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
1119  if (!empty($object->paye)) {
1120  $resteapayer = 0;
1121  }
1122 
1123  if ($deja_regle > 0) {
1124  // Already paid + Deposits
1125  $index++;
1126 
1127  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1128  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
1129  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1130  $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle), 0, 'R', 0);
1131 
1132  $index++;
1133  $pdf->SetTextColor(0, 0, 60);
1134  $pdf->SetFillColor(224, 224, 224);
1135  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1136  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
1137 
1138  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1139  $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer), $useborder, 'R', 1);
1140 
1141  $pdf->SetFont('', '', $default_font_size - 1);
1142  $pdf->SetTextColor(0, 0, 0);
1143  }
1144 
1145  $index++;
1146  return ($tab2_top + ($tab2_hl * $index));
1147  }
1148 
1149  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1163  protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
1164  {
1165  global $conf;
1166 
1167  // Force to disable hidetop and hidebottom
1168  $hidebottom = 0;
1169  if ($hidetop) {
1170  $hidetop = -1;
1171  }
1172 
1173  $currency = !empty($currency) ? $currency : $conf->currency;
1174  $default_font_size = pdf_getPDFFontSize($outputlangs);
1175 
1176  // Amount in (at tab_top - 1)
1177  $pdf->SetTextColor(0, 0, 0);
1178  $pdf->SetFont('', '', $default_font_size - 2);
1179 
1180  if (empty($hidetop)) {
1181  $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1182  $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1183  $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1184 
1185  //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1186  if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) {
1187  $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));
1188  }
1189  }
1190 
1191  $pdf->SetDrawColor(128, 128, 128);
1192  $pdf->SetFont('', '', $default_font_size - 1);
1193 
1194  // Output Rect
1195  $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
1196 
1197  foreach ($this->cols as $colKey => $colDef) {
1198  if (!$this->getColumnStatus($colKey)) {
1199  continue;
1200  }
1201 
1202  // get title label
1203  $colDef['title']['label'] = !empty($colDef['title']['label']) ? $colDef['title']['label'] : $outputlangs->transnoentities($colDef['title']['textkey']);
1204 
1205  // Add column separator
1206  if (!empty($colDef['border-left'])) {
1207  $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
1208  }
1209 
1210  if (empty($hidetop)) {
1211  $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0]);
1212 
1213  $textWidth = $colDef['width'] - $colDef['title']['padding'][3] - $colDef['title']['padding'][1];
1214  $pdf->MultiCell($textWidth, 2, $colDef['title']['label'], '', $colDef['title']['align']);
1215  }
1216  }
1217 
1218  if (empty($hidetop)) {
1219  $pdf->line($this->marge_gauche, $tab_top + 5, $this->page_largeur - $this->marge_droite, $tab_top + 5); // line takes a position y in 2nd parameter and 4th parameter
1220  }
1221  }
1222 
1223  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1233  protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
1234  {
1235  global $langs, $conf, $mysoc;
1236 
1237  $ltrdirection = 'L';
1238  if ($outputlangs->trans("DIRECTION") == 'rtl') $ltrdirection = 'R';
1239 
1240  // Load translation files required by the page
1241  $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "sendings"));
1242 
1243  $default_font_size = pdf_getPDFFontSize($outputlangs);
1244 
1245  // Do not add the BACKGROUND as this is for suppliers
1246  //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
1247 
1248  //Affiche le filigrane brouillon - Print Draft Watermark
1249  /*if($object->statut==0 && getDolGlobalString('COMMANDE_DRAFT_WATERMARK'))
1250  {
1251  pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',getDolGlobalString('COMMANDE_DRAFT_WATERMARK'));
1252  }*/
1253  //Print content
1254 
1255  $pdf->SetTextColor(0, 0, 60);
1256  $pdf->SetFont('', 'B', $default_font_size + 3);
1257 
1258  $w = 110;
1259 
1260  $posx = $this->page_largeur - $this->marge_droite - $w;
1261  $posy = $this->marge_haute;
1262 
1263  $pdf->SetXY($this->marge_gauche, $posy);
1264 
1265  // Logo
1266  if (!getDolGlobalInt('PDF_DISABLE_MYCOMPANY_LOGO')) {
1267  if ($this->emetteur->logo) {
1268  $logodir = $conf->mycompany->dir_output;
1269  if (!empty($conf->mycompany->multidir_output[$object->entity])) {
1270  $logodir = $conf->mycompany->multidir_output[$object->entity];
1271  }
1272  if (!getDolGlobalInt('MAIN_PDF_USE_LARGE_LOGO')) {
1273  $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1274  } else {
1275  $logo = $logodir.'/logos/'.$this->emetteur->logo;
1276  }
1277  if (is_readable($logo)) {
1278  $height = pdf_getHeightForLogo($logo);
1279  $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1280  } else {
1281  $pdf->SetTextColor(200, 0, 0);
1282  $pdf->SetFont('', 'B', $default_font_size - 2);
1283  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1284  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1285  }
1286  } else {
1287  $text = $this->emetteur->name;
1288  $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
1289  }
1290  }
1291 
1292  $pdf->SetFont('', 'B', $default_font_size + 3);
1293  $pdf->SetXY($posx, $posy);
1294  $pdf->SetTextColor(0, 0, 60);
1295  $title = $outputlangs->transnoentities("SupplierOrder")." ".$outputlangs->convToOutputCharset($object->ref);
1296  $pdf->MultiCell($w, 3, $title, '', 'R');
1297  $posy += 1;
1298 
1299  if ($object->ref_supplier) {
1300  $posy += 4;
1301  $pdf->SetFont('', 'B', $default_font_size);
1302  $pdf->SetXY($posx, $posy);
1303  $pdf->SetTextColor(0, 0, 60);
1304  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefSupplier")." : ".$outputlangs->convToOutputCharset($object->ref_supplier), '', 'R');
1305  $posy += 1;
1306  }
1307 
1308  $pdf->SetFont('', '', $default_font_size - 1);
1309 
1310  if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) {
1311  $object->fetch_projet();
1312  if (!empty($object->project->ref)) {
1313  $posy += 3;
1314  $pdf->SetXY($posx, $posy);
1315  $pdf->SetTextColor(0, 0, 60);
1316  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1317  }
1318  }
1319 
1320  if (!empty($conf->global->PDF_SHOW_PROJECT)) {
1321  $object->fetch_projet();
1322  if (!empty($object->project->ref)) {
1323  $outputlangs->load("projects");
1324  $posy += 4;
1325  $pdf->SetXY($posx, $posy);
1326  $langs->load("projects");
1327  $pdf->SetTextColor(0, 0, 60);
1328  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1329  }
1330  }
1331 
1332  if (!empty($object->date_commande)) {
1333  $posy += 5;
1334  $pdf->SetXY($posx, $posy);
1335  $pdf->SetTextColor(0, 0, 60);
1336  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("OrderDate")." : ".dol_print_date($object->date_commande, "day", false, $outputlangs, true), '', 'R');
1337  } else {
1338  $posy += 5;
1339  $pdf->SetXY($posx, $posy);
1340  $pdf->SetTextColor(255, 0, 0);
1341  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("OrderToProcess"), '', 'R');
1342  }
1343 
1344  $pdf->SetTextColor(0, 0, 60);
1345  $usehourmin = 'day';
1346  if (!empty($conf->global->SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE)) {
1347  $usehourmin = 'dayhour';
1348  }
1349  if (!empty($object->delivery_date)) {
1350  $posy += 4;
1351  $pdf->SetXY($posx - 90, $posy);
1352  $pdf->MultiCell(190, 3, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->delivery_date, $usehourmin, false, $outputlangs, true), '', 'R');
1353  }
1354 
1355  if ($object->thirdparty->code_fournisseur) {
1356  $posy += 4;
1357  $pdf->SetXY($posx, $posy);
1358  $pdf->SetTextColor(0, 0, 60);
1359  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("SupplierCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_fournisseur), '', 'R');
1360  }
1361 
1362  // Get contact
1363  if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) {
1364  $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1365  if (count($arrayidcontact) > 0) {
1366  $usertmp = new User($this->db);
1367  $usertmp->fetch($arrayidcontact[0]);
1368  $posy += 4;
1369  $pdf->SetXY($posx, $posy);
1370  $pdf->SetTextColor(0, 0, 60);
1371  $pdf->MultiCell($w, 3, $langs->trans("BuyerName")." : ".$usertmp->getFullName($langs), '', 'R');
1372  }
1373  }
1374 
1375  $posy += 1;
1376  $pdf->SetTextColor(0, 0, 60);
1377 
1378  $top_shift = 0;
1379  // Show list of linked objects
1380  $current_y = $pdf->getY();
1381  $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
1382  if ($current_y < $pdf->getY()) {
1383  $top_shift = $pdf->getY() - $current_y;
1384  }
1385 
1386  if ($showaddress) {
1387  // Sender properties
1388  $carac_emetteur = '';
1389  // Add internal contact of object if defined
1390  $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1391  if (count($arrayidcontact) > 0) {
1392  $object->fetch_user($arrayidcontact[0]);
1393  $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1394  $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname.": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1395  $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1396  $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1397  $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1398  $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1399  $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1400  $carac_emetteur .= "\n";
1401  }
1402 
1403  $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1404 
1405  // Show sender
1406  $posy = 42 + $top_shift;
1407  $posx = $this->marge_gauche;
1408  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
1409  $posx = $this->page_largeur - $this->marge_droite - 80;
1410  }
1411  $hautcadre = 40;
1412 
1413  // Show sender frame
1414  $pdf->SetTextColor(0, 0, 0);
1415  $pdf->SetFont('', '', $default_font_size - 2);
1416  $pdf->SetXY($posx, $posy - 5);
1417  $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1418  $pdf->SetXY($posx, $posy);
1419  $pdf->SetFillColor(230, 230, 230);
1420  $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
1421  $pdf->SetTextColor(0, 0, 60);
1422 
1423  // Show sender name
1424  $pdf->SetXY($posx + 2, $posy + 3);
1425  $pdf->SetFont('', 'B', $default_font_size);
1426  $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1427  $posy = $pdf->getY();
1428 
1429  // Show sender information
1430  $pdf->SetXY($posx + 2, $posy);
1431  $pdf->SetFont('', '', $default_font_size - 1);
1432  $pdf->MultiCell(80, 4, $carac_emetteur, 0, $ltrdirection);
1433 
1434 
1435 
1436  // If CUSTOMER contact defined on order, we use it. Note: Even if this is a supplier object, the code for external contat that follow order is 'CUSTOMER'
1437  $usecontact = false;
1438  $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1439  if (count($arrayidcontact) > 0) {
1440  $usecontact = true;
1441  $result = $object->fetch_contact($arrayidcontact[0]);
1442  }
1443 
1444  // Recipient name
1445  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)))) {
1446  $thirdparty = $object->contact;
1447  } else {
1448  $thirdparty = $object->thirdparty;
1449  }
1450 
1451  $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1452 
1453  $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object);
1454 
1455  // Show recipient
1456  $widthrecbox = 100;
1457  if ($this->page_largeur < 210) {
1458  $widthrecbox = 84; // To work with US executive format
1459  }
1460  $posy = 42 + $top_shift;
1461  $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1462  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
1463  $posx = $this->marge_gauche;
1464  }
1465 
1466  // Show recipient frame
1467  $pdf->SetTextColor(0, 0, 0);
1468  $pdf->SetFont('', '', $default_font_size - 2);
1469  $pdf->SetXY($posx + 2, $posy - 5);
1470  $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1471  $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
1472 
1473  // Show recipient name
1474  $pdf->SetXY($posx + 2, $posy + 3);
1475  $pdf->SetFont('', 'B', $default_font_size);
1476  $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, $ltrdirection);
1477 
1478  $posy = $pdf->getY();
1479 
1480  // Show recipient information
1481  $pdf->SetFont('', '', $default_font_size - 1);
1482  $pdf->SetXY($posx + 2, $posy);
1483  $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1484  }
1485 
1486  return $top_shift;
1487  }
1488 
1489  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1499  protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1500  {
1501  $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1502  return pdf_pagefoot($pdf, $outputlangs, 'SUPPLIER_ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1503  }
1504 
1505 
1506 
1517  public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1518  {
1519  global $conf, $hookmanager;
1520 
1521  // Default field style for content
1522  $this->defaultContentsFieldsStyle = array(
1523  'align' => 'R', // R,C,L
1524  'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1525  );
1526 
1527  // Default field style for content
1528  $this->defaultTitlesFieldsStyle = array(
1529  'align' => 'C', // R,C,L
1530  'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1531  );
1532 
1533  /*
1534  * For exemple
1535  $this->cols['theColKey'] = array(
1536  'rank' => $rank, // int : use for ordering columns
1537  'width' => 20, // the column width in mm
1538  'title' => array(
1539  'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1540  'label' => ' ', // the final label : used fore final generated text
1541  'align' => 'L', // text alignement : R,C,L
1542  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1543  ),
1544  'content' => array(
1545  'align' => 'L', // text alignement : R,C,L
1546  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1547  ),
1548  );
1549  */
1550 
1551  $rank = 0; // do not use negative rank
1552  $this->cols['desc'] = array(
1553  'rank' => $rank,
1554  'width' => false, // only for desc
1555  'status' => true,
1556  'title' => array(
1557  'textkey' => 'Designation', // use lang key is usefull in somme case with module
1558  'align' => 'L',
1559  // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1560  // 'label' => ' ', // the final label
1561  'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1562  ),
1563  'content' => array(
1564  'align' => 'L',
1565  'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1566  ),
1567  );
1568 
1569  $rank = $rank + 10;
1570  $this->cols['photo'] = array(
1571  'rank' => $rank,
1572  'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
1573  'status' => false,
1574  'title' => array(
1575  'textkey' => 'Photo',
1576  'label' => ' '
1577  ),
1578  'content' => array(
1579  'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1580  ),
1581  'border-left' => false, // remove left line separator
1582  );
1583 
1584  if (!empty($conf->global->MAIN_GENERATE_SUPPLIER_ORDER_WITH_PICTURE)) {
1585  $this->cols['photo']['status'] = true;
1586  }
1587 
1588 
1589  $rank = $rank + 10;
1590  $this->cols['vat'] = array(
1591  'rank' => $rank,
1592  'status' => false,
1593  'width' => 16, // in mm
1594  'title' => array(
1595  'textkey' => 'VAT'
1596  ),
1597  'border-left' => true, // add left line separator
1598  );
1599 
1600  if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) {
1601  $this->cols['vat']['status'] = true;
1602  }
1603 
1604  $rank = $rank + 10;
1605  $this->cols['subprice'] = array(
1606  'rank' => $rank,
1607  'width' => 19, // in mm
1608  'status' => false,
1609  'title' => array(
1610  'textkey' => 'PriceUHT'
1611  ),
1612  'border-left' => true, // add left line separator
1613  );
1614 
1615  if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_PURCHASE_ORDER_WITHOUT_UNIT_PRICE)) {
1616  $this->cols['subprice']['status'] = true;
1617  }
1618 
1619  $rank = $rank + 10;
1620  $this->cols['qty'] = array(
1621  'rank' => $rank,
1622  'width' => 16, // in mm
1623  'status' => true,
1624  'title' => array(
1625  'textkey' => 'Qty'
1626  ),
1627  'border-left' => true, // add left line separator
1628  );
1629 
1630  $rank = $rank + 10;
1631  $this->cols['unit'] = array(
1632  'rank' => $rank,
1633  'width' => 11, // in mm
1634  'status' => false,
1635  'title' => array(
1636  'textkey' => 'Unit'
1637  ),
1638  'border-left' => true, // add left line separator
1639  );
1640  if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1641  $this->cols['unit']['status'] = true;
1642  }
1643 
1644  $rank = $rank + 10;
1645  $this->cols['discount'] = array(
1646  'rank' => $rank,
1647  'width' => 13, // in mm
1648  'status' => false,
1649  'title' => array(
1650  'textkey' => 'ReductionShort'
1651  ),
1652  'border-left' => true, // add left line separator
1653  );
1654  if ($this->atleastonediscount) {
1655  $this->cols['discount']['status'] = true;
1656  }
1657 
1658  $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
1659  $this->cols['totalexcltax'] = array(
1660  'rank' => $rank,
1661  'width' => 26, // in mm
1662  'status' => true,
1663  'title' => array(
1664  'textkey' => 'TotalHT'
1665  ),
1666  'border-left' => true, // add left line separator
1667  );
1668 
1669  if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_PURCHASE_ORDER_WITHOUT_TOTAL_COLUMN)) {
1670  $this->cols['totalexcltax']['status'] = true;
1671  }
1672 
1673  // Add extrafields cols
1674  if (!empty($object->lines)) {
1675  $line = reset($object->lines);
1676  $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
1677  }
1678 
1679  $parameters = array(
1680  'object' => $object,
1681  'outputlangs' => $outputlangs,
1682  'hidedetails' => $hidedetails,
1683  'hidedesc' => $hidedesc,
1684  'hideref' => $hideref
1685  );
1686 
1687  $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
1688  if ($reshook < 0) {
1689  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1690  } elseif (empty($reshook)) {
1691  $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
1692  } else {
1693  $this->cols = $hookmanager->resArray;
1694  }
1695  }
1696 }
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
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 supplier 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 the supplier orders with the cornas model.
_tableau_info(&$pdf, $object, $posy, $outputlangs)
Show miscellaneous information (payment mode, payment term, ...)
_pagehead(&$pdf, $object, $showaddress, $outputlangs)
Show top header of page.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
Show table for lines.
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
_tableau_versements(&$pdf, $object, $posy, $outputlangs)
Show payments table.
_tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
Show total to pay.
write_file($object, $outputlangs='', $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
__construct($db)
Constructor.
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.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
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_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_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_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition: pdf.lib.php:1338
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