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