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