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