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