dolibarr 19.0.3
pdf_storm.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2005-2014 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
5 * Copyright (C) 2008 Chiptronik
6 * Copyright (C) 2011-2021 Philippe Grand <philippe.grand@atoo-net.com>
7 * Copyright (C) 2015 Marcos GarcĂ­a <marcosgdf@gmail.com>
8 * Copyright (C) 2020 John BOTELLA
9
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 * or see https://www.gnu.org/
23 */
24
31require_once DOL_DOCUMENT_ROOT.'/core/modules/delivery/modules_delivery.php';
32require_once DOL_DOCUMENT_ROOT.'/delivery/class/delivery.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
35
36
41{
45 public $db;
46
50 public $name;
51
55 public $description;
56
60 public $update_main_doc_field;
61
65 public $type;
66
71 public $version = 'dolibarr';
72
73
79 public function __construct($db)
80 {
81 global $langs, $mysoc;
82
83 // Translations
84 $langs->loadLangs(array("main", "bills", "sendings", "companies"));
85
86 $this->db = $db;
87 $this->name = "Storm";
88 $this->description = $langs->trans("DocumentModelStorm");
89 $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
90
91 // Page size for A4 format
92 $this->type = 'pdf';
93 $formatarray = pdf_getFormat();
94 $this->page_largeur = $formatarray['width'];
95 $this->page_hauteur = $formatarray['height'];
96 $this->format = array($this->page_largeur, $this->page_hauteur);
97 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
98 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
99 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
100 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
101
102 $this->option_logo = 1; // Display logo FAC_PDF_LOGO
103 $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
104
105 // Get source company
106 $this->emetteur = $mysoc;
107 if (empty($this->emetteur->country_code)) {
108 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
109 }
110 }
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, $langs, $conf, $mysoc, $hookmanager;
129
130 if (!is_object($outputlangs)) {
131 $outputlangs = $langs;
132 }
133 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
134 if (getDolGlobalString('MAIN_USE_FPDF')) {
135 $outputlangs->charset_output = 'ISO-8859-1';
136 }
137
138 // Load translation files required by the page
139 $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "sendings", "deliveries"));
140
141 if ($conf->expedition->dir_output) {
142 $object->fetch_thirdparty();
143
144 // Definition of $dir and $file
145 if ($object->specimen) {
146 $dir = $conf->expedition->dir_output."/receipt";
147 $file = $dir."/SPECIMEN.pdf";
148 } else {
149 $objectref = dol_sanitizeFileName($object->ref);
150 $dir = $conf->expedition->dir_output."/receipt/".$objectref;
151 $file = $dir."/".$objectref.".pdf";
152 }
153
154 if (!file_exists($dir)) {
155 if (dol_mkdir($dir) < 0) {
156 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
157 return 0;
158 }
159 }
160
161 if (file_exists($dir)) {
162 // Add pdfgeneration hook
163 if (!is_object($hookmanager)) {
164 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
165 $hookmanager = new HookManager($this->db);
166 }
167 $hookmanager->initHooks(array('pdfgeneration'));
168 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
169 global $action;
170 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
171
172 $nblines = count($object->lines);
173
174
175 // Loop on each lines to detect if there is at least one image to show
176 $realpatharray = array();
177 $this->atleastonephoto = false;
178 if (getDolGlobalString('MAIN_GENERATE_DELIVERY_WITH_PICTURE')) {
179 $objphoto = new Product($this->db);
180
181 for ($i = 0; $i < $nblines; $i++) {
182 if (empty($object->lines[$i]->fk_product)) {
183 continue;
184 }
185
186 $objphoto->fetch($object->lines[$i]->fk_product);
187
188 if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
189 $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
190 $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
191 } else {
192 $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product'); // default
193 $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
194 }
195
196 $arephoto = false;
197 foreach ($pdir as $midir) {
198 if (!$arephoto) {
199 $dir = $conf->product->dir_output.'/'.$midir;
200
201 foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
202 if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES')) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
203 if ($obj['photo_vignette']) {
204 $filename = $obj['photo_vignette'];
205 } else {
206 $filename = $obj['photo'];
207 }
208 } else {
209 $filename = $obj['photo'];
210 }
211
212 $realpath = $dir.$filename;
213 $arephoto = true;
214 $this->atleastonephoto = true;
215 }
216 }
217 }
218
219 if ($realpath && $arephoto) {
220 $realpatharray[$i] = $realpath;
221 }
222 }
223 }
224
225
226 // Create pdf instance
227 $pdf = pdf_getInstance($this->format);
228 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
229 $heightforinfotot = 30; // Height reserved to output the info and total part
230 $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
231 $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
232 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
233 $heightforfooter += 6;
234 }
235 $pdf->SetAutoPageBreak(1, 0);
236
237 if (class_exists('TCPDF')) {
238 $pdf->setPrintHeader(false);
239 $pdf->setPrintFooter(false);
240 }
241 $pdf->SetFont(pdf_getPDFFont($outputlangs));
242 // Set path to the background PDF File
243 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
244 $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
245 $tplidx = $pdf->importPage(1);
246 }
247
248 // We get the shipment that is the origin of delivery receipt
249 $expedition = new Expedition($this->db);
250 $result = $expedition->fetch($object->origin_id);
251 // Now we get the order that is origin of shipment
252 $commande = new Commande($this->db);
253 if ($expedition->origin == 'commande') {
254 $commande->fetch($expedition->origin_id);
255 }
256 $object->commande = $commande; // We set order of shipment onto delivery.
257 $object->commande->loadExpeditions();
258
259
260 $pdf->Open();
261 $pagenb = 0;
262 $pdf->SetDrawColor(128, 128, 128);
263
264 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
265 $pdf->SetSubject($outputlangs->transnoentities("DeliveryOrder"));
266 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
267 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
268 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("DeliveryOrder"));
269 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
270 $pdf->SetCompression(false);
271 }
272
273 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
274
275
276 // New page
277 $pdf->AddPage();
278 if (!empty($tplidx)) {
279 $pdf->useTemplate($tplidx);
280 }
281 $pagenb++;
282 $this->_pagehead($pdf, $object, 1, $outputlangs);
283 $pdf->SetFont('', '', $default_font_size - 1);
284 $pdf->MultiCell(0, 3, ''); // Set interline to 3
285 $pdf->SetTextColor(0, 0, 0);
286
287 $tab_top = 90;
288 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 : 10);
289
290 $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
291
292 $this->posxdesc = $this->marge_gauche + 1;
293
294 // Incoterm
295 $height_incoterms = 0;
296 if (isModEnabled('incoterm')) {
297 $desc_incoterms = $object->getIncotermsForPDF();
298 if ($desc_incoterms) {
299 $tab_top -= 2;
300
301 $pdf->SetFont('', '', $default_font_size - 1);
302 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
303 $nexY = $pdf->GetY();
304 $height_incoterms = $nexY - $tab_top;
305
306 // Rect takes a length in 3rd parameter
307 $pdf->SetDrawColor(192, 192, 192);
308 $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1);
309
310 $tab_top = $nexY + 6;
311 $height_incoterms += 4;
312 }
313 }
314
315 // display note
316 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
317
318 // Extrafields in note
319 $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
320 if (!empty($extranote)) {
321 $notetoshow = dol_concatdesc($notetoshow, $extranote);
322 }
323
324 if (!empty($notetoshow)) {
325 $tab_top = 88 + $height_incoterms;
326
327 $pdf->SetFont('', '', $default_font_size - 1);
328 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
329 $nexY = $pdf->GetY();
330 $height_note = $nexY - $tab_top;
331
332 // Rect takes a length in 3rd parameter
333 $pdf->SetDrawColor(192, 192, 192);
334 $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 1);
335
336 $tab_height = $tab_height - $height_note;
337 $tab_top = $nexY + 6;
338 } else {
339 $height_note = 0;
340 }
341
342 // Use new auto column system
343 $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
344
345 // Table simulation to know the height of the title line
346 $pdf->startTransaction();
347 $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, 0);
348 $pdf->rollbackTransaction(true);
349
350 $iniY = $tab_top + $this->tabTitleHeight + 2;
351 $curY = $tab_top + $this->tabTitleHeight + 2;
352 $nexY = $tab_top + $this->tabTitleHeight + 2;
353
354 // Loop on each lines
355 for ($i = 0; $i < $nblines; $i++) {
356 // Fetch optionals
357 if (empty($object->lines[$i]->array_options)) {
358 $object->lines[$i]->fetch_optionals();
359 }
360
361 $curY = $nexY;
362 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
363 $pdf->SetTextColor(0, 0, 0);
364
365 // Define size of image if we need it
366 $imglinesize = array();
367 if (!empty($realpatharray[$i])) {
368 $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
369 }
370
371
372 $pdf->setTopMargin($tab_top_newpage);
373 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
374 $pageposbefore = $pdf->getPage();
375
376 // Description of product line
377 $curX = $this->posxdesc - 1;
378
379 $showpricebeforepagebreak = 1;
380
381 $posYAfterImage = 0;
382 $posYAfterDescription = 0;
383 if ($this->getColumnStatus('photo')) {
384 // We start with Photo of product line
385 if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page
386 $pdf->AddPage('', '', true);
387 if (!empty($tplidx)) {
388 $pdf->useTemplate($tplidx);
389 }
390 //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
391 $pdf->setPage($pageposbefore + 1);
392
393 $curY = $tab_top_newpage;
394
395 // Allows data in the first page if description is long enough to break in multiples pages
396 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
397 $showpricebeforepagebreak = 1;
398 } else {
399 $showpricebeforepagebreak = 0;
400 }
401 }
402
403
404 if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) {
405 $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
406 // $pdf->Image does not increase value return by getY, so we save it manually
407 $posYAfterImage = $curY + $imglinesize['height'];
408 }
409 }
410
411
412 // Description of product line
413 if ($this->getColumnStatus('desc')) {
414 $pdf->startTransaction();
415 pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
416 $pageposafter = $pdf->getPage();
417 if ($pageposafter > $pageposbefore) { // There is a pagebreak
418 $pdf->rollbackTransaction(true);
419 $pageposafter = $pageposbefore;
420 //print $pageposafter.'-'.$pageposbefore;exit;
421 $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
422 pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 4, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
423 $posyafter = $pdf->GetY();
424 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
425 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
426 $pdf->AddPage('', '', true);
427 if (!empty($tplidx)) {
428 $pdf->useTemplate($tplidx);
429 }
430 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
431 $this->_pagehead($pdf, $object, 0, $outputlangs);
432 }
433 $pdf->setPage($pageposafter + 1);
434 }
435 } else {
436 // We found a page break
437 // Allows data in the first page if description is long enough to break in multiples pages
438 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
439 $showpricebeforepagebreak = 1;
440 } else {
441 $showpricebeforepagebreak = 0;
442 }
443 }
444 } else { // No pagebreak
445 $pdf->commitTransaction();
446 }
447
448 $posYAfterDescription = $pdf->GetY();
449 }
450
451 $nexY = $pdf->GetY();
452 $pageposafter = $pdf->getPage();
453 $pdf->setPage($pageposbefore);
454 $pdf->setTopMargin($this->marge_haute);
455 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
456
457 // We suppose that a too long description is moved completely on next page
458 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
459 $pdf->setPage($pageposafter);
460 $curY = $tab_top_newpage;
461 }
462
463 $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut
464
465
466 // Quantity
467 if ($this->getColumnStatus('qty_shipped')) {
468 $this->printStdColumnContent($pdf, $curY, 'qty_shipped', $object->lines[$i]->qty_shipped);
469 $nexY = max($pdf->GetY(), $nexY);
470 }
471
472 // Remaining to ship
473 if ($this->getColumnStatus('qty_remaining')) {
474 $qtyRemaining = $object->lines[$i]->qty_asked - $object->commande->expeditions[$object->lines[$i]->fk_origin_line];
475 $this->printStdColumnContent($pdf, $curY, 'qty_remaining', $qtyRemaining);
476 $nexY = max($pdf->GetY(), $nexY);
477 }
478
479 $nexY = max($nexY, $posYAfterImage);
480
481 // Extrafields
482 if (!empty($object->lines[$i]->array_options)) {
483 foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
484 if ($this->getColumnStatus($extrafieldColKey)) {
485 $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs);
486 $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
487 $nexY = max($pdf->GetY(), $nexY);
488 }
489 }
490 }
491
492 // Add line
493 if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) {
494 $pdf->setPage($pageposafter);
495 $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
496 //$pdf->SetDrawColor(190,190,200);
497 $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
498 $pdf->SetLineStyle(array('dash'=>0));
499 }
500
501 $nexY += 2; // Add space between lines
502
503 // Detect if some page were added automatically and output _tableau for past pages
504 while ($pagenb < $pageposafter) {
505 $pdf->setPage($pagenb);
506 if ($pagenb == 1) {
507 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
508 } else {
509 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
510 }
511 $this->_pagefoot($pdf, $object, $outputlangs, 1);
512 $pagenb++;
513 $pdf->setPage($pagenb);
514 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
515 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
516 $this->_pagehead($pdf, $object, 0, $outputlangs);
517 }
518 if (!empty($tplidx)) {
519 $pdf->useTemplate($tplidx);
520 }
521 }
522 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
523 if ($pagenb == 1) {
524 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
525 } else {
526 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
527 }
528 $this->_pagefoot($pdf, $object, $outputlangs, 1);
529 // New page
530 $pdf->AddPage();
531 if (!empty($tplidx)) {
532 $pdf->useTemplate($tplidx);
533 }
534 $pagenb++;
535 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
536 $this->_pagehead($pdf, $object, 0, $outputlangs);
537 }
538 }
539 }
540
541 // Show square
542 if ($pagenb == 1) {
543 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0);
544 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
545 } else {
546 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0);
547 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
548 }
549
550 // Affiche zone infos
551 $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
552
553 // Pied de page
554 $this->_pagefoot($pdf, $object, $outputlangs);
555
556 if (method_exists($pdf, 'AliasNbPages')) {
557 $pdf->AliasNbPages();
558 }
559
560 $pdf->Close();
561
562 $pdf->Output($file, 'F');
563
564 // Add pdfgeneration hook
565 if (!is_object($hookmanager)) {
566 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
567 $hookmanager = new HookManager($this->db);
568 }
569 $hookmanager->initHooks(array('pdfgeneration'));
570 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
571 global $action;
572 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
573 if ($reshook < 0) {
574 $this->error = $hookmanager->error;
575 $this->errors = $hookmanager->errors;
576 }
577
578 dolChmod($file);
579
580 $this->result = array('fullpath'=>$file);
581
582 return 1; // No error
583 } else {
584 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
585 return 0;
586 }
587 }
588
589 $this->error = $langs->transnoentities("ErrorConstantNotDefined", "LIVRAISON_OUTPUTDIR");
590 return 0;
591 }
592
593 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
594 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
604 protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
605 {
606 // phpcs:enable
607 global $conf, $mysoc;
608 $default_font_size = pdf_getPDFFontSize($outputlangs);
609
610 $pdf->SetFont('', '', $default_font_size);
611 $pdf->SetXY($this->marge_gauche, $posy);
612
613 $larg_sign = ($this->page_largeur - $this->marge_gauche - $this->marge_droite) / 3;
614 $pdf->Rect($this->marge_gauche, $posy + 1, $larg_sign, 25);
615 $pdf->SetXY($this->marge_gauche + 2, $posy + 2);
616 $pdf->MultiCell($larg_sign, 2, $outputlangs->trans("For").' '.$outputlangs->convToOutputCharset($mysoc->name).":", '', 'L');
617
618 $pdf->Rect(2 * $larg_sign + $this->marge_gauche, $posy + 1, $larg_sign, 25);
619 $pdf->SetXY(2 * $larg_sign + $this->marge_gauche + 2, $posy + 2);
620 $pdf->MultiCell($larg_sign, 2, $outputlangs->trans("ForCustomer").':', '', 'L');
621 }
622
623
624 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
637 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0)
638 {
639 global $conf;
640
641 // Force to disable hidetop and hidebottom
642 $hidebottom = 0;
643 if ($hidetop) {
644 $hidetop = -1;
645 }
646
647 $default_font_size = pdf_getPDFFontSize($outputlangs);
648
649 // Amount in (at tab_top - 1)
650 $pdf->SetTextColor(0, 0, 0);
651 $pdf->SetFont('', '', $default_font_size - 2);
652
653 if (empty($hidetop)) {
654 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
655 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
656 $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')));
657 }
658 }
659
660 $pdf->SetDrawColor(128, 128, 128);
661 $pdf->SetFont('', '', $default_font_size - 1);
662
663 // Output Rect
664 $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
665
666
667 $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
668
669 if (empty($hidetop)) {
670 $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
671 }
672 }
673
674 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
684 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
685 {
686 global $conf, $langs, $hookmanager;
687
688 $default_font_size = pdf_getPDFFontSize($outputlangs);
689
690 pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
691
692 // Show Draft Watermark
693 if ($object->statut == 0 && getDolGlobalString('COMMANDE_DRAFT_WATERMARK')) {
694 pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', getDolGlobalString('COMMANDE_DRAFT_WATERMARK'));
695 }
696
697 $pdf->SetTextColor(0, 0, 60);
698 $pdf->SetFont('', 'B', $default_font_size + 3);
699
700 $posy = $this->marge_haute;
701 $posx = $this->page_largeur - $this->marge_droite - 100;
702
703 $pdf->SetXY($this->marge_gauche, $posy);
704
705 // Logo
706 $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
707 if ($this->emetteur->logo) {
708 if (is_readable($logo)) {
709 $height = pdf_getHeightForLogo($logo);
710 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
711 } else {
712 $pdf->SetTextColor(200, 0, 0);
713 $pdf->SetFont('', 'B', $default_font_size - 2);
714 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
715 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
716 }
717 } else {
718 $pdf->MultiCell(100, 4, $this->emetteur->name, 0, 'L');
719 }
720
721 $pdf->SetFont('', 'B', $default_font_size + 2);
722 $pdf->SetXY($posx, $posy);
723 $pdf->SetTextColor(0, 0, 60);
724 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DeliveryOrder")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R');
725
726 $pdf->SetFont('', '', $default_font_size + 2);
727
728 $posy += 5;
729 $pdf->SetXY($posx, $posy);
730 $pdf->SetTextColor(0, 0, 60);
731 if ($object->date_valid) {
732 $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Date")." : ".dol_print_date($object->date_delivery, "%d %b %Y", false, $outputlangs, true), '', 'R');
733 } else {
734 $pdf->SetTextColor(255, 0, 0);
735 $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DeliveryNotValidated"), '', 'R');
736 $pdf->SetTextColor(0, 0, 60);
737 }
738
739 if ($object->thirdparty->code_client) {
740 $posy += 5;
741 $pdf->SetXY($posx, $posy);
742 $pdf->SetTextColor(0, 0, 60);
743 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
744 }
745
746 $pdf->SetTextColor(0, 0, 60);
747
748 $posy += 2;
749
750 // Show list of linked objects
751 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
752
753 if ($showaddress) {
754 // Sender properties
755 $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
756
757 // Show sender
758 $posy = 42;
759 $posx = $this->marge_gauche;
760 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
761 $posx = $this->page_largeur - $this->marge_droite - 80;
762 }
763 $hautcadre = 40;
764
765 // Show sender frame
766 $pdf->SetTextColor(0, 0, 0);
767 $pdf->SetFont('', '', $default_font_size - 2);
768 $pdf->SetXY($posx, $posy - 5);
769 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, 'L');
770 $pdf->SetXY($posx, $posy);
771 $pdf->SetFillColor(230, 230, 230);
772 $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
773 $pdf->SetTextColor(0, 0, 60);
774
775 // Show sender name
776 $pdf->SetXY($posx + 2, $posy + 3);
777 $pdf->SetFont('', 'B', $default_font_size);
778 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
779 $posy = $pdf->getY();
780
781 // Show sender information
782 $pdf->SetXY($posx + 2, $posy);
783 $pdf->SetFont('', '', $default_font_size - 1);
784 $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
785
786 // Client destinataire
787 $posy = 42;
788 $posx = 102;
789 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
790 $posx = $this->marge_gauche;
791 }
792 $pdf->SetTextColor(0, 0, 0);
793 $pdf->SetFont('', '', $default_font_size - 2);
794 $pdf->SetXY($posx, $posy - 5);
795 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("DeliveryAddress"), 0, 'L');
796
797 // If SHIPPING contact defined on order, we use it
798 $usecontact = false;
799 $arrayidcontact = $object->commande->getIdContact('external', 'SHIPPING');
800 if (count($arrayidcontact) > 0) {
801 $usecontact = true;
802 $result = $object->fetch_contact($arrayidcontact[0]);
803 }
804
805 // Recipient name
806 if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || getDolGlobalString('MAIN_USE_COMPANY_NAME_OF_CONTACT')))) {
807 $thirdparty = $object->contact;
808 } else {
809 $thirdparty = $object->thirdparty;
810 }
811
812 $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
813
814 $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object);
815
816 // Show recipient
817 $widthrecbox = 100;
818 if ($this->page_largeur < 210) {
819 $widthrecbox = 84; // To work with US executive format
820 }
821 $posy = 42;
822 $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
823 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
824 $posx = $this->marge_gauche;
825 }
826
827 // Show recipient frame
828 $pdf->SetTextColor(0, 0, 0);
829 $pdf->SetFont('', '', $default_font_size - 2);
830 $pdf->SetXY($posx + 2, $posy - 5);
831 //$pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":",0,'L');
832 $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
833
834 // Show recipient name
835 $pdf->SetXY($posx + 2, $posy + 3);
836 $pdf->SetFont('', 'B', $default_font_size);
837 $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L');
838
839 $posy = $pdf->getY();
840
841 // Show recipient information
842 $pdf->SetFont('', '', $default_font_size - 1);
843 $pdf->SetXY($posx + 2, $posy);
844 $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
845 }
846
847 $pdf->SetTextColor(0, 0, 60);
848 }
849
850 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
860 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
861 {
862 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
863 return pdf_pagefoot($pdf, $outputlangs, 'DELIVERY_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
864 }
865
866
867
878 public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
879 {
880 global $conf, $hookmanager;
881
882 // Default field style for content
883 $this->defaultContentsFieldsStyle = array(
884 'align' => 'R', // R,C,L
885 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
886 );
887
888 // Default field style for content
889 $this->defaultTitlesFieldsStyle = array(
890 'align' => 'C', // R,C,L
891 'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
892 );
893
894 /*
895 * For exemple
896 $this->cols['theColKey'] = array(
897 'rank' => $rank, // int : use for ordering columns
898 'width' => 20, // the column width in mm
899 'title' => array(
900 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
901 'label' => ' ', // the final label : used fore final generated text
902 'align' => 'L', // text alignement : R,C,L
903 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
904 ),
905 'content' => array(
906 'align' => 'L', // text alignement : R,C,L
907 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
908 ),
909 );
910 */
911
912 $rank = 0; // do not use negative rank
913 $this->cols['desc'] = array(
914 'rank' => $rank,
915 'width' => false, // only for desc
916 'status' => true,
917 'title' => array(
918 'textkey' => 'Designation', // use lang key is usefull in somme case with module
919 'align' => 'L',
920 // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
921 // 'label' => ' ', // the final label
922 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
923 ),
924 'content' => array(
925 'align' => 'L',
926 ),
927 );
928
929 $rank = $rank + 10;
930 $this->cols['photo'] = array(
931 'rank' => $rank,
932 'width' => (!getDolGlobalString('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH') ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
933 'status' => false,
934 'title' => array(
935 'textkey' => 'Photo',
936 'label' => ' '
937 ),
938 'content' => array(
939 'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
940 ),
941 'border-left' => false, // remove left line separator
942 );
943
944 if (getDolGlobalString('MAIN_GENERATE_DELIVERY_WITH_PICTURE') && !empty($this->atleastonephoto)) {
945 $this->cols['photo']['status'] = true;
946 }
947
948
949 $rank = $rank + 10;
950 $this->cols['Comments'] = array(
951 'rank' => $rank,
952 'width' => 50, // in mm
953 'status' => true,
954 'title' => array(
955 'textkey' => 'Comments'
956 ),
957 'border-left' => true, // add left line separator
958 );
959
960 // $rank = $rank + 10;
961 // $this->cols['weight'] = array(
962 // 'rank' => $rank,
963 // 'width' => 30, // in mm
964 // 'status' => false,
965 // 'title' => array(
966 // 'textkey' => 'WeightVolShort'
967 // ),
968 // 'border-left' => true, // add left line separator
969 // );
970
971 $rank = $rank + 10;
972 $this->cols['qty_shipped'] = array(
973 'rank' => $rank,
974 'width' => 20, // in mm
975 'status' => true,
976 'title' => array(
977 'textkey' => 'QtyShippedShort'
978 ),
979 'border-left' => true, // add left line separator
980 );
981
982 $rank = $rank + 10;
983 $this->cols['qty_remaining'] = array(
984 'rank' => $rank,
985 'width' => 20, // in mm
986 'status' => 1,
987 'title' => array(
988 'textkey' => 'KeepToShipShort'
989 ),
990 'border-left' => true, // add left line separator
991 );
992
993
994 // Add extrafields cols
995 if (!empty($object->lines)) {
996 $line = reset($object->lines);
997 $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
998 }
999
1000 $parameters = array(
1001 'object' => $object,
1002 'outputlangs' => $outputlangs,
1003 'hidedetails' => $hidedetails,
1004 'hidedesc' => $hidedesc,
1005 'hideref' => $hideref
1006 );
1007
1008 $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
1009 if ($reshook < 0) {
1010 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1011 } elseif (empty($reshook)) {
1012 $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
1013 } else {
1014 $this->cols = $hookmanager->resArray;
1015 }
1016 }
1017}
Class to manage customers orders.
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.
getColumnContentXStart($colKey)
get column content X (abscissa) left position from column key
printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
Rect pdf.
getColumnContentWidth($colKey)
get column content width from column key
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 shipments.
Class to manage hooks.
Classe mere des modeles de bon de livraison.
Class to manage products or services.
Class to build Delivery Order documents with storm model.
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
_tableau_info(&$pdf, $object, $posy, $outputlangs)
Show miscellaneous information (payment mode, payment term, ...)
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
Show table for lines.
__construct($db)
Constructor.
_pagehead(&$pdf, $object, $showaddress, $outputlangs)
Show top header of page.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
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.
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.
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...
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_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref=0, $hidedesc=0, $issupplierline=0)
Output line description into PDF.
Definition pdf.lib.php:1422
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_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1386
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_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
pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition pdf.lib.php:782
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