dolibarr  x.y.z
pdf_espadon.modules.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2005-2012 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2014-2015 Marcos García <marcosgdf@gmail.com>
6  * Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  * or see https://www.gnu.org/
21  */
22 
29 require_once DOL_DOCUMENT_ROOT.'/core/modules/expedition/modules_expedition.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
33 
38 {
42  public $db;
43 
47  public $name;
48 
52  public $description;
53 
57  public $update_main_doc_field;
58 
62  public $type;
63 
68  public $phpmin = array(7, 0);
69 
74  public $version = 'dolibarr';
75 
79  public $page_largeur;
80 
84  public $page_hauteur;
85 
89  public $format;
90 
94  public $marge_gauche;
95 
99  public $marge_droite;
100 
104  public $marge_haute;
105 
109  public $marge_basse;
110 
115  public $emetteur;
116 
117 
123  public function __construct(DoliDB $db)
124  {
125  global $conf, $langs, $mysoc;
126 
127  $this->db = $db;
128  $this->name = "espadon";
129  $this->description = $langs->trans("DocumentModelStandardPDF");
130  $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
131 
132  $this->type = 'pdf';
133  $formatarray = pdf_getFormat();
134  $this->page_largeur = $formatarray['width'];
135  $this->page_hauteur = $formatarray['height'];
136  $this->format = array($this->page_largeur, $this->page_hauteur);
137  $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
138  $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
139  $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
140  $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
141 
142  $this->option_logo = 1; // Display logo
143  $this->option_draft_watermark = 1; // Support add of a watermark on drafts
144  $this->watermark = '';
145 
146  // Get source company
147  $this->emetteur = $mysoc;
148  if (!$this->emetteur->country_code) {
149  $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default if not defined
150  }
151 
152  $this->tabTitleHeight = 5; // default height
153  }
154 
155  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
167  public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
168  {
169  // phpcs:enable
170  global $user, $conf, $langs, $hookmanager;
171 
172  $object->fetch_thirdparty();
173 
174  if (!is_object($outputlangs)) {
175  $outputlangs = $langs;
176  }
177  // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
178  if (!empty($conf->global->MAIN_USE_FPDF)) {
179  $outputlangs->charset_output = 'ISO-8859-1';
180  }
181 
182  // Load traductions files required by page
183  $outputlangs->loadLangs(array("main", "bills", "orders", "products", "dict", "companies", "propal", "deliveries", "sendings", "productbatch"));
184 
185  // Show Draft Watermark
186  if ($object->statut == $object::STATUS_DRAFT && (!empty($conf->global->SHIPPING_DRAFT_WATERMARK))) {
187  $this->watermark = $conf->global->SHIPPING_DRAFT_WATERMARK;
188  }
189 
190  global $outputlangsbis;
191  $outputlangsbis = null;
192  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
193  $outputlangsbis = new Translate('', $conf);
194  $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
195  $outputlangsbis->loadLangs(array("main", "bills", "orders", "products", "dict", "companies", "propal", "deliveries", "sendings", "productbatch"));
196  }
197 
198  $nblines = count($object->lines);
199 
200  // Loop on each lines to detect if there is at least one image to show
201  $realpatharray = array();
202  $this->atleastonephoto = false;
203  if (!empty($conf->global->MAIN_GENERATE_SHIPMENT_WITH_PICTURE)) {
204  $objphoto = new Product($this->db);
205 
206  for ($i = 0; $i < $nblines; $i++) {
207  if (empty($object->lines[$i]->fk_product)) {
208  continue;
209  }
210 
211  $objphoto->fetch($object->lines[$i]->fk_product);
212 
213  if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
214  $pdir = get_exdir($object->lines[$i]->fk_product, 2, 0, 0, $objphoto, 'product').$object->lines[$i]->fk_product."/photos/";
215  $dir = $conf->product->dir_output.'/'.$pdir;
216  } else {
217  $pdir = get_exdir(0, 0, 0, 0, $objphoto, 'product');
218  $dir = $conf->product->dir_output.'/'.$pdir;
219  }
220 
221  $realpath = '';
222 
223  foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
224  if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES')) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
225  if ($obj['photo_vignette']) {
226  $filename = $obj['photo_vignette'];
227  } else {
228  $filename = $obj['photo'];
229  }
230  } else {
231  $filename = $obj['photo'];
232  }
233 
234  $realpath = $dir.$filename;
235  $this->atleastonephoto = true;
236  break;
237  }
238 
239  if ($realpath) {
240  $realpatharray[$i] = $realpath;
241  }
242  }
243  }
244 
245  if (count($realpatharray) == 0) {
246  $this->posxpicture = $this->posxweightvol;
247  }
248 
249  if ($conf->expedition->dir_output) {
250  // Definition of $dir and $file
251  if ($object->specimen) {
252  $dir = $conf->expedition->dir_output."/sending";
253  $file = $dir."/SPECIMEN.pdf";
254  } else {
255  $expref = dol_sanitizeFileName($object->ref);
256  $dir = $conf->expedition->dir_output."/sending/".$expref;
257  $file = $dir."/".$expref.".pdf";
258  }
259 
260  if (!file_exists($dir)) {
261  if (dol_mkdir($dir) < 0) {
262  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
263  return 0;
264  }
265  }
266 
267  if (file_exists($dir)) {
268  // Add pdfgeneration hook
269  if (!is_object($hookmanager)) {
270  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
271  $hookmanager = new HookManager($this->db);
272  }
273  $hookmanager->initHooks(array('pdfgeneration'));
274  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
275  global $action;
276  $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
277 
278  // Set nblines with the new facture lines content after hook
279  $nblines = count($object->lines);
280 
281  $pdf = pdf_getInstance($this->format);
282  $default_font_size = pdf_getPDFFontSize($outputlangs);
283  $heightforinfotot = 8; // Height reserved to output the info and total part
284  $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
285  $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
286  if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)) {
287  $heightforfooter += 6;
288  }
289  $pdf->SetAutoPageBreak(1, 0);
290 
291  if (class_exists('TCPDF')) {
292  $pdf->setPrintHeader(false);
293  $pdf->setPrintFooter(false);
294  }
295  $pdf->SetFont(pdf_getPDFFont($outputlangs));
296  // Set path to the background PDF File
297  if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) {
298  $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
299  $tplidx = $pdf->importPage(1);
300  }
301 
302  $pdf->Open();
303  $pagenb = 0;
304  $pdf->SetDrawColor(128, 128, 128);
305 
306  if (method_exists($pdf, 'AliasNbPages')) {
307  $pdf->AliasNbPages();
308  }
309 
310  $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
311  $pdf->SetSubject($outputlangs->transnoentities("Shipment"));
312  $pdf->SetCreator("Dolibarr ".DOL_VERSION);
313  $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
314  $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Shipment"));
315  if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
316  $pdf->SetCompression(false);
317  }
318 
319  $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
320 
321  // New page
322  $pdf->AddPage();
323  if (!empty($tplidx)) {
324  $pdf->useTemplate($tplidx);
325  }
326  $pagenb++;
327  $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
328  $pdf->SetFont('', '', $default_font_size - 1);
329  $pdf->MultiCell(0, 3, ''); // Set interline to 3
330  $pdf->SetTextColor(0, 0, 0);
331 
332  $tab_top = 90;
333  $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift: 10);
334 
335  $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
336 
337  $this->posxdesc = $this->marge_gauche + 1;
338 
339  // Incoterm
340  $height_incoterms = 0;
341  if (isModEnabled('incoterm')) {
342  $desc_incoterms = $object->getIncotermsForPDF();
343  if ($desc_incoterms) {
344  $tab_top -= 2;
345 
346  $pdf->SetFont('', '', $default_font_size - 1);
347  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
348  $nexY = $pdf->GetY();
349  $height_incoterms = $nexY - $tab_top;
350 
351  // Rect takes a length in 3rd parameter
352  $pdf->SetDrawColor(192, 192, 192);
353  $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1);
354 
355  $tab_top = $nexY + 6;
356  $height_incoterms += 4;
357  }
358  }
359 
360  // display note
361  $notetoshow = empty($object->note_public) ? '' : $object->note_public;
362 
363  // Extrafields in note
364  $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
365  if (!empty($extranote)) {
366  $notetoshow = dol_concatdesc($notetoshow, $extranote);
367  }
368 
369  if (!empty($notetoshow) || !empty($object->tracking_number)) {
370  $tab_top -= 2;
371 
372  // Tracking number
373  if (!empty($object->tracking_number)) {
374  $pdf->SetFont('', 'B', $default_font_size - 2);
375  $pdf->writeHTMLCell(60, 4, $this->posxdesc - 1, $tab_top - 1, $outputlangs->transnoentities("TrackingNumber") . " : " . $object->tracking_number, 0, 1, false, true, 'L');
376 
377  $tab_top_alt = $pdf->GetY();
378  $object->getUrlTrackingStatus($object->tracking_number);
379  if (!empty($object->tracking_url)) {
380  if ($object->shipping_method_id > 0) {
381  // Get code using getLabelFromKey
382  $code = $outputlangs->getLabelFromKey($this->db, $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code');
383  $label = '';
384  if ($object->tracking_url != $object->tracking_number) {
385  $label .= $outputlangs->trans("LinkToTrackYourPackage")."<br>";
386  }
387  $label .= $outputlangs->trans("SendingMethod").": ".$outputlangs->trans("SendingMethod".strtoupper($code));
388  //var_dump($object->tracking_url != $object->tracking_number);exit;
389  if ($object->tracking_url != $object->tracking_number) {
390  $label .= " : ";
391  $label .= $object->tracking_url;
392  }
393  $pdf->SetFont('', 'B', $default_font_size - 2);
394  $pdf->writeHTMLCell(60, 4, $this->posxdesc - 1, $tab_top_alt, $label, 0, 1, false, true, 'L');
395 
396  $tab_top = $pdf->GetY();
397  }
398  }
399  }
400 
401 
402  // Notes
403  $pagenb = $pdf->getPage();
404  if (!empty($notetoshow)) {
405  $tab_top -= 2;
406 
407  $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
408  $pageposbeforenote = $pagenb;
409 
410  $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
411  complete_substitutions_array($substitutionarray, $outputlangs, $object);
412  $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
413  $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
414 
415  $pdf->startTransaction();
416 
417  $pdf->SetFont('', '', $default_font_size - 1);
418  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
419  // Description
420  $pageposafternote = $pdf->getPage();
421  $posyafter = $pdf->GetY();
422 
423  if ($pageposafternote > $pageposbeforenote) {
424  $pdf->rollbackTransaction(true);
425 
426  // prepare pages to receive notes
427  while ($pagenb < $pageposafternote) {
428  $pdf->AddPage();
429  $pagenb++;
430  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
431  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
432  // $this->_pagefoot($pdf,$object,$outputlangs,1);
433  $pdf->setTopMargin($tab_top_newpage);
434  // The only function to edit the bottom margin of current page to set it.
435  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
436  }
437 
438  // back to start
439  $pdf->setPage($pageposbeforenote);
440  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
441  $pdf->SetFont('', '', $default_font_size - 1);
442  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
443  $pageposafternote = $pdf->getPage();
444 
445  $posyafter = $pdf->GetY();
446 
447  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text
448  $pdf->AddPage('', '', true);
449  $pagenb++;
450  $pageposafternote++;
451  $pdf->setPage($pageposafternote);
452  $pdf->setTopMargin($tab_top_newpage);
453  // The only function to edit the bottom margin of current page to set it.
454  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
455  //$posyafter = $tab_top_newpage;
456  }
457 
458 
459  // apply note frame to previous pages
460  $i = $pageposbeforenote;
461  while ($i < $pageposafternote) {
462  $pdf->setPage($i);
463 
464 
465  $pdf->SetDrawColor(128, 128, 128);
466  // Draw note frame
467  if ($i > $pageposbeforenote) {
468  $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
469  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
470  } else {
471  $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
472  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
473  }
474 
475  // Add footer
476  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
477  $this->_pagefoot($pdf, $object, $outputlangs, 1);
478 
479  $i++;
480  }
481 
482  // apply note frame to last page
483  $pdf->setPage($pageposafternote);
484  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
485  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
486  $height_note = $posyafter - $tab_top_newpage;
487  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
488  } else // No pagebreak
489  {
490  $pdf->commitTransaction();
491  $posyafter = $pdf->GetY();
492  $height_note = $posyafter - $tab_top;
493  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
494 
495 
496  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
497  // not enough space, need to add page
498  $pdf->AddPage('', '', true);
499  $pagenb++;
500  $pageposafternote++;
501  $pdf->setPage($pageposafternote);
502  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
503  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
504 
505  $posyafter = $tab_top_newpage;
506  }
507  }
508 
509  $tab_height = $tab_height - $height_note;
510  $tab_top = $posyafter + 6;
511  } else {
512  $height_note = 0;
513  }
514  }
515 
516 
517  // Use new auto column system
518  $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
519 
520  // Table simulation to know the height of the title line
521  $pdf->startTransaction();
522  $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs);
523  $pdf->rollbackTransaction(true);
524 
525 
526  $nexY = $tab_top + $this->tabTitleHeight;
527 
528  // Loop on each lines
529  $pageposbeforeprintlines = $pdf->getPage();
530  $pagenb = $pageposbeforeprintlines;
531  for ($i = 0; $i < $nblines; $i++) {
532  $curY = $nexY;
533  $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
534  $pdf->SetTextColor(0, 0, 0);
535 
536  // Define size of image if we need it
537  $imglinesize = array();
538  if (!empty($realpatharray[$i])) {
539  $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
540  }
541 
542  $pdf->setTopMargin($tab_top_newpage);
543  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
544  $pageposbefore = $pdf->getPage();
545 
546  $showpricebeforepagebreak = 1;
547  $posYAfterImage = 0;
548  $posYAfterDescription = 0;
549 
550  if ($this->getColumnStatus('photo')) {
551  // We start with Photo of product line
552  if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot))) { // If photo too high, we moved completely on new page
553  $pdf->AddPage('', '', true);
554  if (!empty($tplidx)) {
555  $pdf->useTemplate($tplidx);
556  }
557  //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
558  $pdf->setPage($pageposbefore + 1);
559 
560  $curY = $tab_top_newpage;
561 
562  // Allows data in the first page if description is long enough to break in multiples pages
563  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
564  $showpricebeforepagebreak = 1;
565  } else {
566  $showpricebeforepagebreak = 0;
567  }
568  }
569 
570 
571  if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) {
572  $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
573  // $pdf->Image does not increase value return by getY, so we save it manually
574  $posYAfterImage = $curY + $imglinesize['height'];
575  }
576  }
577 
578  // Description of product line
579  if ($this->getColumnStatus('desc')) {
580  $pdf->startTransaction();
581 
582  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
583 
584  $pageposafter = $pdf->getPage();
585  if ($pageposafter > $pageposbefore) { // There is a pagebreak
586  $pdf->rollbackTransaction(true);
587 
588  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
589 
590  $pageposafter = $pdf->getPage();
591  $posyafter = $pdf->GetY();
592  //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
593  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot))) { // There is no space left for total+free text
594  if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
595  $pdf->AddPage('', '', true);
596  if (!empty($tplidx)) {
597  $pdf->useTemplate($tplidx);
598  }
599  //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
600  $pdf->setPage($pageposafter + 1);
601  }
602  } else {
603  // We found a page break
604  // Allows data in the first page if description is long enough to break in multiples pages
605  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
606  $showpricebeforepagebreak = 1;
607  } else {
608  $showpricebeforepagebreak = 0;
609  }
610  }
611  } else // No pagebreak
612  {
613  $pdf->commitTransaction();
614  }
615  $posYAfterDescription = $pdf->GetY();
616  }
617 
618  $nexY = max($pdf->GetY(), $posYAfterImage);
619  $pageposafter = $pdf->getPage();
620 
621  $pdf->setPage($pageposbefore);
622  $pdf->setTopMargin($this->marge_haute);
623  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
624 
625  // We suppose that a too long description or photo were moved completely on next page
626  if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
627  $pdf->setPage($pageposafter);
628  $curY = $tab_top_newpage;
629  }
630 
631  // We suppose that a too long description is moved completely on next page
632  if ($pageposafter > $pageposbefore) {
633  $pdf->setPage($pageposafter);
634  $curY = $tab_top_newpage;
635  }
636 
637  $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font
638 
639  // weight
640 
641  $weighttxt = '';
642  if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->weight) {
643  $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units, 1);
644  }
645  $voltxt = '';
646  if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->volume) {
647  $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0, 1);
648  }
649 
650 
651  if ($this->getColumnStatus('weight')) {
652  $this->printStdColumnContent($pdf, $curY, 'weight', $weighttxt.(($weighttxt && $voltxt) ? '<br>' : '').$voltxt);
653  $nexY = max($pdf->GetY(), $nexY);
654  }
655 
656  if ($this->getColumnStatus('qty_asked')) {
657  $this->printStdColumnContent($pdf, $curY, 'qty_asked', $object->lines[$i]->qty_asked);
658  $nexY = max($pdf->GetY(), $nexY);
659  }
660 
661  if ($this->getColumnStatus('unit_order')) {
662  $this->printStdColumnContent($pdf, $curY, 'unit_order', measuringUnitString($object->lines[$i]->fk_unit));
663  $nexY = max($pdf->GetY(), $nexY);
664  }
665 
666  if ($this->getColumnStatus('qty_shipped')) {
667  $this->printStdColumnContent($pdf, $curY, 'qty_shipped', $object->lines[$i]->qty_shipped);
668  $nexY = max($pdf->GetY(), $nexY);
669  }
670 
671  if ($this->getColumnStatus('subprice')) {
672  $this->printStdColumnContent($pdf, $curY, 'subprice', price($object->lines[$i]->subprice, 0, $outputlangs));
673  $nexY = max($pdf->GetY(), $nexY);
674  }
675 
676  // Extrafields
677  if (!empty($object->lines[$i]->array_options)) {
678  foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
679  if ($this->getColumnStatus($extrafieldColKey)) {
680  $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs);
681  $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
682  $nexY = max($pdf->GetY(), $nexY);
683  }
684  }
685  }
686 
687  // Add line
688  if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) {
689  $pdf->setPage($pageposafter);
690  $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
691  //$pdf->SetDrawColor(190,190,200);
692  $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
693  $pdf->SetLineStyle(array('dash'=>0));
694  }
695 
696  // Detect if some page were added automatically and output _tableau for past pages
697  while ($pagenb < $pageposafter) {
698  $pdf->setPage($pagenb);
699  if ($pagenb == $pageposbeforeprintlines) {
700  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
701  } else {
702  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
703  }
704  $this->_pagefoot($pdf, $object, $outputlangs, 1);
705  $pagenb++;
706  $pdf->setPage($pagenb);
707  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
708  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
709  $this->_pagehead($pdf, $object, 0, $outputlangs);
710  }
711  if (!empty($tplidx)) {
712  $pdf->useTemplate($tplidx);
713  }
714  }
715  if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
716  if ($pagenb == 1) {
717  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
718  } else {
719  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
720  }
721  $this->_pagefoot($pdf, $object, $outputlangs, 1);
722  // New page
723  $pdf->AddPage();
724  if (!empty($tplidx)) {
725  $pdf->useTemplate($tplidx);
726  }
727  $pagenb++;
728  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
729  $this->_pagehead($pdf, $object, 0, $outputlangs);
730  }
731  }
732  }
733 
734  // Show square
735  if ($pagenb == 1) {
736  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0);
737  $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
738  } else {
739  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0);
740  $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
741  }
742 
743  // Display total area
744  $posy = $this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs);
745 
746  // Pagefoot
747  $this->_pagefoot($pdf, $object, $outputlangs);
748  if (method_exists($pdf, 'AliasNbPages')) {
749  $pdf->AliasNbPages();
750  }
751 
752  $pdf->Close();
753 
754  $pdf->Output($file, 'F');
755 
756  // Add pdfgeneration hook
757  $hookmanager->initHooks(array('pdfgeneration'));
758  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
759  global $action;
760  $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
761  if ($reshook < 0) {
762  $this->error = $hookmanager->error;
763  $this->errors = $hookmanager->errors;
764  }
765 
766  if (!empty($conf->global->MAIN_UMASK)) {
767  @chmod($file, octdec($conf->global->MAIN_UMASK));
768  }
769 
770  $this->result = array('fullpath'=>$file);
771 
772  return 1; // No error
773  } else {
774  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
775  return 0;
776  }
777  } else {
778  $this->error = $langs->transnoentities("ErrorConstantNotDefined", "EXP_OUTPUTDIR");
779  return 0;
780  }
781  }
782 
783  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
784  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
795  protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
796  {
797  // phpcs:enable
798  global $conf, $mysoc;
799 
800  $sign = 1;
801 
802  $default_font_size = pdf_getPDFFontSize($outputlangs);
803 
804  $tab2_top = $posy;
805  $tab2_hl = 4;
806  $pdf->SetFont('', 'B', $default_font_size - 1);
807 
808  // Total table
809  $col1x = $this->posxweightvol - 50;
810  $col2x = $this->posxweightvol;
811  /*if ($this->page_largeur < 210) // To work with US executive format
812  {
813  $col2x-=20;
814  }*/
815  if (empty($conf->global->SHIPPING_PDF_HIDE_ORDERED)) {
816  $largcol2 = ($this->posxqtyordered - $this->posxweightvol);
817  } else {
818  $largcol2 = ($this->posxqtytoship - $this->posxweightvol);
819  }
820 
821  $useborder = 0;
822  $index = 0;
823 
824  $totalWeighttoshow = '';
825  $totalVolumetoshow = '';
826 
827  // Load dim data
828  $tmparray = $object->getTotalWeightVolume();
829  $totalWeight = $tmparray['weight'];
830  $totalVolume = $tmparray['volume'];
831  $totalOrdered = $tmparray['ordered'];
832  $totalToShip = $tmparray['toship'];
833  // Set trueVolume and volume_units not currently stored into database
834  if ($object->trueWidth && $object->trueHeight && $object->trueDepth) {
835  $object->trueVolume = price(($object->trueWidth * $object->trueHeight * $object->trueDepth), 0, $outputlangs, 0, 0);
836  $object->volume_units = $object->size_units * 3;
837  }
838 
839  if ($totalWeight != '') {
840  $totalWeighttoshow = showDimensionInBestUnit($totalWeight, 0, "weight", $outputlangs);
841  }
842  if ($totalVolume != '') {
843  $totalVolumetoshow = showDimensionInBestUnit($totalVolume, 0, "volume", $outputlangs);
844  }
845  if ($object->trueWeight) {
846  $totalWeighttoshow = showDimensionInBestUnit($object->trueWeight, $object->weight_units, "weight", $outputlangs);
847  }
848  if ($object->trueVolume) {
849  $totalVolumetoshow = showDimensionInBestUnit($object->trueVolume, $object->volume_units, "volume", $outputlangs);
850  }
851 
852 
853 
854 
855  if ($this->getColumnStatus('desc')) {
856  $this->printStdColumnContent($pdf, $tab2_top, 'desc', $outputlangs->transnoentities("Total"));
857  }
858 
859 
860  if ($this->getColumnStatus('weight')) {
861  if ($totalWeighttoshow) {
862  $this->printStdColumnContent($pdf, $tab2_top, 'weight', $totalWeighttoshow);
863  $index++;
864  }
865 
866  if ($totalVolumetoshow) {
867  $y = $tab2_top + ($tab2_hl * $index);
868  $this->printStdColumnContent($pdf, $y, 'weight', $totalVolumetoshow);
869  }
870  }
871 
872  if ($this->getColumnStatus('qty_asked') && $totalOrdered) {
873  $this->printStdColumnContent($pdf, $tab2_top, 'qty_asked', $totalOrdered);
874  }
875 
876  if ($this->getColumnStatus('qty_shipped') && $totalToShip) {
877  $this->printStdColumnContent($pdf, $tab2_top, 'qty_shipped', $totalToShip);
878  }
879 
880  if ($this->getColumnStatus('subprice')) {
881  $this->printStdColumnContent($pdf, $tab2_top, 'subprice', price($object->total_ht, 0, $outputlangs));
882  }
883 
884  $pdf->SetTextColor(0, 0, 0);
885 
886  return ($tab2_top + ($tab2_hl * $index));
887  }
888 
889  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
902  protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0)
903  {
904  global $conf;
905 
906  // Force to disable hidetop and hidebottom
907  $hidebottom = 0;
908  if ($hidetop) {
909  $hidetop = -1;
910  }
911 
912  $currency = !empty($currency) ? $currency : $conf->currency;
913  $default_font_size = pdf_getPDFFontSize($outputlangs);
914 
915  // Amount in (at tab_top - 1)
916  $pdf->SetTextColor(0, 0, 0);
917  $pdf->SetFont('', '', $default_font_size - 2);
918 
919  if (empty($hidetop)) {
920  //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
921  if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) {
922  $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));
923  }
924  }
925 
926  $pdf->SetDrawColor(128, 128, 128);
927  $pdf->SetFont('', '', $default_font_size - 1);
928 
929  // Output Rect
930  $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
931 
932 
933  $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
934 
935  if (empty($hidetop)) {
936  $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
937  }
938  }
939 
940  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
950  protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
951  {
952  global $conf, $langs, $mysoc;
953 
954  $langs->load("orders");
955 
956  $default_font_size = pdf_getPDFFontSize($outputlangs);
957 
958  pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
959 
960  //Prepare next
961  $pdf->SetTextColor(0, 0, 60);
962  $pdf->SetFont('', 'B', $default_font_size + 3);
963 
964  $w = 110;
965 
966  $posy = $this->marge_haute;
967  $posx = $this->page_largeur - $this->marge_droite - $w;
968 
969  $pdf->SetXY($this->marge_gauche, $posy);
970 
971  // Logo
972  if ($this->emetteur->logo) {
973  $logodir = $conf->mycompany->dir_output;
974  if (!empty($conf->mycompany->multidir_output[$object->entity])) {
975  $logodir = $conf->mycompany->multidir_output[$object->entity];
976  }
977  if (!getDolGlobalInt('MAIN_PDF_USE_LARGE_LOGO')) {
978  $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
979  } else {
980  $logo = $logodir.'/logos/'.$this->emetteur->logo;
981  }
982  if (is_readable($logo)) {
983  $height = pdf_getHeightForLogo($logo);
984  $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
985  } else {
986  $pdf->SetTextColor(200, 0, 0);
987  $pdf->SetFont('', 'B', $default_font_size - 2);
988  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
989  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
990  }
991  } else {
992  $text = $this->emetteur->name;
993  $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
994  }
995 
996  // Show barcode
997  if (isModEnabled('barcode')) {
998  $posx = 105;
999  } else {
1000  $posx = $this->marge_gauche + 3;
1001  }
1002  //$pdf->Rect($this->marge_gauche, $this->marge_haute, $this->page_largeur-$this->marge_gauche-$this->marge_droite, 30);
1003  if (isModEnabled('barcode')) {
1004  // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref
1005  //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3);
1006  //$pdf->Image($logo,10, 5, 0, 24);
1007  }
1008 
1009  $pdf->SetDrawColor(128, 128, 128);
1010  if (isModEnabled('barcode')) {
1011  // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref
1012  //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3);
1013  //$pdf->Image($logo,10, 5, 0, 24);
1014  }
1015 
1016 
1017  $posx = $this->page_largeur - $w - $this->marge_droite;
1018  $posy = $this->marge_haute;
1019 
1020  $pdf->SetFont('', 'B', $default_font_size + 2);
1021  $pdf->SetXY($posx, $posy);
1022  $pdf->SetTextColor(0, 0, 60);
1023  $title = $outputlangs->transnoentities("SendingSheet");
1024  $pdf->MultiCell($w, 4, $title, '', 'R');
1025 
1026  $pdf->SetFont('', '', $default_font_size + 1);
1027 
1028  $posy += 5;
1029 
1030  $pdf->SetXY($posx, $posy);
1031  $pdf->SetTextColor(0, 0, 60);
1032  $pdf->MultiCell($w, 4, $outputlangs->transnoentities("RefSending")." : ".$object->ref, '', 'R');
1033 
1034  // Date planned delivery
1035  if (!empty($object->date_delivery)) {
1036  $posy += 4;
1037  $pdf->SetXY($posx, $posy);
1038  $pdf->SetTextColor(0, 0, 60);
1039  $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->date_delivery, "day", false, $outputlangs, true), '', 'R');
1040  }
1041 
1042  if (empty($conf->global->MAIN_PDF_HIDE_CUSTOMER_CODE) && !empty($object->thirdparty->code_client)) {
1043  $posy += 4;
1044  $pdf->SetXY($posx, $posy);
1045  $pdf->SetTextColor(0, 0, 60);
1046  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
1047  }
1048 
1049 
1050  $pdf->SetFont('', '', $default_font_size + 3);
1051  $Yoff = 25;
1052 
1053  // Add list of linked orders
1054  $origin = $object->origin;
1055  $origin_id = $object->origin_id;
1056 
1057  // TODO move to external function
1058  if (!empty($conf->$origin->enabled)) { // commonly $origin='commande'
1059  $outputlangs->load('orders');
1060 
1061  $classname = ucfirst($origin);
1062  $linkedobject = new $classname($this->db);
1063  $result = $linkedobject->fetch($origin_id);
1064  if ($result >= 0) {
1065  //$linkedobject->fetchObjectLinked() Get all linked object to the $linkedobject (commonly order) into $linkedobject->linkedObjects
1066 
1067  $pdf->SetFont('', '', $default_font_size - 2);
1068  $text = $linkedobject->ref;
1069  if ($linkedobject->ref_client) {
1070  $text .= ' ('.$linkedobject->ref_client.')';
1071  }
1072  $Yoff = $Yoff + 8;
1073  $pdf->SetXY($this->page_largeur - $this->marge_droite - $w, $Yoff);
1074  $pdf->MultiCell($w, 2, $outputlangs->transnoentities("RefOrder")." : ".$outputlangs->transnoentities($text), 0, 'R');
1075  $Yoff = $Yoff + 3;
1076  $pdf->SetXY($this->page_largeur - $this->marge_droite - $w, $Yoff);
1077  $pdf->MultiCell($w, 2, $outputlangs->transnoentities("OrderDate")." : ".dol_print_date($linkedobject->date, "day", false, $outputlangs, true), 0, 'R');
1078  }
1079  }
1080 
1081  $top_shift = 0;
1082  // Show list of linked objects
1083  /*$current_y = $pdf->getY();
1084  $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
1085  if ($current_y < $pdf->getY()) {
1086  $top_shift = $pdf->getY() - $current_y;
1087  }*/
1088 
1089  if ($showaddress) {
1090  // Sender properties
1091  $carac_emetteur = '';
1092  // Add internal contact of origin element if defined
1093  $arrayidcontact = array();
1094  if (!empty($origin) && is_object($object->$origin)) {
1095  $arrayidcontact = $object->$origin->getIdContact('internal', 'SALESREPFOLL');
1096  }
1097  if (is_array($arrayidcontact) && count($arrayidcontact) > 0) {
1098  $object->fetch_user(reset($arrayidcontact));
1099  $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";
1100  }
1101 
1102  $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1103 
1104  // Show sender
1105  $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
1106  $posx = $this->marge_gauche;
1107  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
1108  $posx = $this->page_largeur - $this->marge_droite - 80;
1109  }
1110 
1111  $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
1112  $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
1113 
1114  // Show sender frame
1115  if (empty($conf->global->MAIN_PDF_NO_SENDER_FRAME)) {
1116  $pdf->SetTextColor(0, 0, 0);
1117  $pdf->SetFont('', '', $default_font_size - 2);
1118  $pdf->SetXY($posx, $posy - 5);
1119  $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("Sender"), 0, 'L');
1120  $pdf->SetXY($posx, $posy);
1121  $pdf->SetFillColor(230, 230, 230);
1122  $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
1123  $pdf->SetTextColor(0, 0, 60);
1124  $pdf->SetFillColor(255, 255, 255);
1125  }
1126 
1127  // Show sender name
1128  if (empty($conf->global->MAIN_PDF_HIDE_SENDER_NAME)) {
1129  $pdf->SetXY($posx + 2, $posy + 3);
1130  $pdf->SetFont('', 'B', $default_font_size);
1131  $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
1132  $posy = $pdf->getY();
1133  }
1134 
1135  // Show sender information
1136  $pdf->SetXY($posx + 2, $posy);
1137  $pdf->SetFont('', '', $default_font_size - 1);
1138  $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, 'L');
1139 
1140 
1141  // If SHIPPING contact defined, we use it
1142  $usecontact = false;
1143  $arrayidcontact = $object->$origin->getIdContact('external', 'SHIPPING');
1144  if (count($arrayidcontact) > 0) {
1145  $usecontact = true;
1146  $result = $object->fetch_contact($arrayidcontact[0]);
1147  }
1148 
1149  // Recipient name
1150  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)))) {
1151  $thirdparty = $object->contact;
1152  } else {
1153  $thirdparty = $object->thirdparty;
1154  }
1155 
1156  $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1157 
1158  $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (!empty($object->contact) ? $object->contact : null), $usecontact, 'targetwithdetails', $object);
1159 
1160  // Show recipient
1161  $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
1162  if ($this->page_largeur < 210) {
1163  $widthrecbox = 84; // To work with US executive format
1164  }
1165  $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
1166  $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1167  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
1168  $posx = $this->marge_gauche;
1169  }
1170 
1171  // Show recipient frame
1172  if (empty($conf->global->MAIN_PDF_NO_RECIPENT_FRAME)) {
1173  $pdf->SetTextColor(0, 0, 0);
1174  $pdf->SetFont('', '', $default_font_size - 2);
1175  $pdf->SetXY($posx + 2, $posy - 5);
1176  $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("Recipient"), 0, 'L');
1177  $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
1178  }
1179 
1180  // Show recipient name
1181  $pdf->SetXY($posx + 2, $posy + 3);
1182  $pdf->SetFont('', 'B', $default_font_size);
1183  $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L');
1184 
1185  $posy = $pdf->getY();
1186 
1187  // Show recipient information
1188  $pdf->SetFont('', '', $default_font_size - 1);
1189  $pdf->SetXY($posx + 2, $posy);
1190  $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
1191  }
1192 
1193  $pdf->SetTextColor(0, 0, 0);
1194  return $top_shift;
1195  }
1196 
1197  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1207  protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1208  {
1209  $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1210  return pdf_pagefoot($pdf, $outputlangs, 'SHIPPING_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext, $this->page_largeur, $this->watermark);
1211  }
1212 
1223  public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1224  {
1225  global $conf, $hookmanager;
1226 
1227  // Default field style for content
1228  $this->defaultContentsFieldsStyle = array(
1229  'align' => 'R', // R,C,L
1230  'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1231  );
1232 
1233  // Default field style for content
1234  $this->defaultTitlesFieldsStyle = array(
1235  'align' => 'C', // R,C,L
1236  'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1237  );
1238 
1239  /*
1240  * For exemple
1241  $this->cols['theColKey'] = array(
1242  'rank' => $rank, // int : use for ordering columns
1243  'width' => 20, // the column width in mm
1244  'title' => array(
1245  'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1246  'label' => ' ', // the final label : used fore final generated text
1247  'align' => 'L', // text alignement : R,C,L
1248  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1249  ),
1250  'content' => array(
1251  'align' => 'L', // text alignement : R,C,L
1252  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1253  ),
1254  );
1255  */
1256 
1257  $rank = 0; // do not use negative rank
1258  $this->cols['desc'] = array(
1259  'rank' => $rank,
1260  'width' => false, // only for desc
1261  'status' => true,
1262  'title' => array(
1263  'textkey' => 'Designation', // use lang key is usefull in somme case with module
1264  'align' => 'L',
1265  // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1266  // 'label' => ' ', // the final label
1267  'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1268  ),
1269  'content' => array(
1270  'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1271  ),
1272  );
1273 
1274  $rank = $rank + 10;
1275  $this->cols['photo'] = array(
1276  'rank' => $rank,
1277  'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
1278  'status' => false,
1279  'title' => array(
1280  'textkey' => 'Photo',
1281  'label' => ' '
1282  ),
1283  'content' => array(
1284  'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1285  ),
1286  'border-left' => false, // remove left line separator
1287  );
1288 
1289  if (!empty($conf->global->MAIN_GENERATE_SHIPMENT_WITH_PICTURE) && !empty($this->atleastonephoto)) {
1290  $this->cols['photo']['status'] = true;
1291  }
1292 
1293  $rank = $rank + 10;
1294  $this->cols['weight'] = array(
1295  'rank' => $rank,
1296  'width' => 30, // in mm
1297  'status' => true,
1298  'title' => array(
1299  'textkey' => 'WeightVolShort'
1300  ),
1301  'border-left' => true, // add left line separator
1302  );
1303 
1304 
1305  $rank = $rank + 10;
1306  $this->cols['subprice'] = array(
1307  'rank' => $rank,
1308  'width' => 19, // in mm
1309  'status' => !empty($conf->global->MAIN_PDF_SHIPPING_DISPLAY_AMOUNT_HT) ? 1 : 0,
1310  'title' => array(
1311  'textkey' => 'PriceUHT'
1312  ),
1313  'border-left' => true, // add left line separator
1314  );
1315 
1316  $rank = $rank + 10;
1317  $this->cols['totalexcltax'] = array(
1318  'rank' => $rank,
1319  'width' => 26, // in mm
1320  'status' => !empty($conf->global->MAIN_PDF_SHIPPING_DISPLAY_AMOUNT_HT) ? 1 : 0,
1321  'title' => array(
1322  'textkey' => 'TotalHT'
1323  ),
1324  'border-left' => true, // add left line separator
1325  );
1326 
1327  $rank = $rank + 10;
1328  $this->cols['qty_asked'] = array(
1329  'rank' => $rank,
1330  'width' => 30, // in mm
1331  'status' => empty($conf->global->SHIPPING_PDF_HIDE_ORDERED) ? 1 : 0,
1332  'title' => array(
1333  'textkey' => 'QtyOrdered'
1334  ),
1335  'border-left' => true, // add left line separator
1336  'content' => array(
1337  'align' => 'C',
1338  ),
1339  );
1340 
1341  $rank = $rank + 10;
1342  $this->cols['unit_order'] = array(
1343  'rank' => $rank,
1344  'width' => 15, // in mm
1345  'status' => empty($conf->global->PRODUCT_USE_UNITS) ? 0 : 1,
1346  'title' => array(
1347  'textkey' => 'Unit'
1348  ),
1349  'border-left' => true, // add left line separator
1350  'content' => array(
1351  'align' => 'C',
1352  ),
1353  );
1354 
1355  $rank = $rank + 10;
1356  $this->cols['qty_shipped'] = array(
1357  'rank' => $rank,
1358  'width' => 30, // in mm
1359  'status' => true,
1360  'title' => array(
1361  'textkey' => 'QtyToShip'
1362  ),
1363  'border-left' => true, // add left line separator
1364  'content' => array(
1365  'align' => 'C',
1366  ),
1367  );
1368 
1369  // Add extrafields cols
1370  if (!empty($object->lines)) {
1371  $line = reset($object->lines);
1372  $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
1373  }
1374 
1375  $parameters = array(
1376  'object' => $object,
1377  'outputlangs' => $outputlangs,
1378  'hidedetails' => $hidedetails,
1379  'hidedesc' => $hidedesc,
1380  'hideref' => $hideref
1381  );
1382 
1383  $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
1384  if ($reshook < 0) {
1385  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1386  } elseif (empty($reshook)) {
1387  $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
1388  } else {
1389  $this->cols = $hookmanager->resArray;
1390  }
1391  }
1392 }
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 Dolibarr database access.
Class to manage hooks.
Parent class of sending receipts models.
Class to manage products or services.
Class to manage translations.
Class to build sending documents with model espadon.
__construct(DoliDB $db)
Constructor.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
_pagehead(&$pdf, $object, $showaddress, $outputlangs)
Show top header of page.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
Show table for lines.
_tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
Show total to pay.
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!function_exists('dolEscapeXML')) convertBackOfficeMediasLinksToPublicLinks($notetoshow)
Convert links to local wrapper to medias files into a string into a public external URL readable on i...
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.
showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round=-1, $forceunitoutput='no', $use_short_label=0)
Output a dimension with best unit.
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)
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:2505
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:996
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:744
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition: pdf.lib.php:718
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_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
measuringUnitString($unit, $measuring_style='', $scale='', $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
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