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