dolibarr 19.0.4
pdf_vinci.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2005-2011 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
5 * Copyright (C) 2010-2014 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
7 * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
8 * Copyright (C) 2018-2023 Frédéric France <frederic.france@netlogic.fr>
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/mrp/modules_mo.php';
32require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
33require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
38
39
44{
48 public $db;
49
53 public $name;
54
58 public $description;
59
63 public $update_main_doc_field;
64
68 public $type;
69
74 public $version = 'dolibarr';
75
76
82 public function __construct($db)
83 {
84 global $langs, $mysoc;
85
86 // Load translation files required by the page
87 $langs->loadLangs(array("main", "bills", "mrp"));
88
89 $this->db = $db;
90 $this->name = "vinci";
91 $this->description = $langs->trans('DocumentModelStandardPDF');
92 $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
93
94 // Page size for A4 format
95 $this->type = 'pdf';
96 $formatarray = pdf_getFormat();
97 $this->page_largeur = $formatarray['width'];
98 $this->page_hauteur = $formatarray['height'];
99 $this->format = array($this->page_largeur, $this->page_hauteur);
100 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
101 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
102 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
103 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
104
105 $this->option_logo = 1; // Display logo
106 $this->option_multilang = 1; //Available in several languages
107 $this->option_escompte = 0; // Displays if there has been a discount
108 $this->option_credit_note = 0; // Support credit notes
109 $this->option_freetext = 1; // Support add of a personalised text
110 $this->option_draft_watermark = 1; // Support add of a watermark on drafts
111
112 // Get source company
113 $this->emetteur = $mysoc;
114 if (empty($this->emetteur->country_code)) {
115 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
116 }
117
118 // Define position of columns
119 $this->posxdesc = $this->marge_gauche + 1; // For module retrocompatibility support durring PDF transition: TODO remove this at the end
120 }
121
122
123 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
135 public function write_file($object, $outputlangs = '', $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
136 {
137 // phpcs:enable
138 global $user, $langs, $conf, $hookmanager, $mysoc;
139
140 if (!is_object($outputlangs)) {
141 $outputlangs = $langs;
142 }
143 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
144 if (getDolGlobalString('MAIN_USE_FPDF')) {
145 $outputlangs->charset_output = 'ISO-8859-1';
146 }
147
148 // Load translation files required by the page
149 $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "dict", "products"));
150
151 global $outputlangsbis;
152 $outputlangsbis = null;
153 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
154 $outputlangsbis = new Translate('', $conf);
155 $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
156 $outputlangsbis->loadLangs(array("main", "orders", "companies", "bills", "dict", "products"));
157 }
158
159 if (!isset($object->lines) || !is_array($object->lines)) {
160 $object->lines = array();
161 }
162
163 $nblines = count($object->lines);
164
165 $hidetop = 0;
166 if (getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE')) {
167 $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE;
168 }
169
170 // Loop on each lines to detect if there is at least one image to show
171 $realpatharray = array();
172
173 if ($conf->mrp->dir_output) {
174 $object->fetch_thirdparty();
175
176 $deja_regle = 0;
177 $amount_credit_notes_included = 0;
178 $amount_deposits_included = 0;
179 //$amount_credit_notes_included = $object->getSumCreditNotesUsed();
180 //$amount_deposits_included = $object->getSumDepositsUsed();
181
182 // Definition of $dir and $file
183 if ($object->specimen) {
184 $dir = $conf->mrp->dir_output;
185 $file = $dir."/SPECIMEN.pdf";
186 } else {
187 $objectref = dol_sanitizeFileName($object->ref);
188 $dir = $conf->mrp->dir_output.'/'.$objectref;
189 $file = $dir."/".$objectref.".pdf";
190 }
191
192 if (!file_exists($dir)) {
193 if (dol_mkdir($dir) < 0) {
194 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
195 return 0;
196 }
197 }
198
199 if (file_exists($dir)) {
200 // Add pdfgeneration hook
201 if (!is_object($hookmanager)) {
202 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
203 $hookmanager = new HookManager($this->db);
204 }
205 $hookmanager->initHooks(array('pdfgeneration'));
206 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
207 global $action;
208 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
209
210 $nblines = count($object->lines);
211
212 $pdf = pdf_getInstance($this->format);
213 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
214 $heightforinfotot = 50; // Height reserved to output the info and total part
215 $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
216 $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
217 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
218 $heightforfooter += 6;
219 }
220 $pdf->SetAutoPageBreak(1, 0);
221
222 if (class_exists('TCPDF')) {
223 $pdf->setPrintHeader(false);
224 $pdf->setPrintFooter(false);
225 }
226 $pdf->SetFont(pdf_getPDFFont($outputlangs));
227 // Set path to the background PDF File
228 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
229 $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
230 $tplidx = $pdf->importPage(1);
231 }
232
233 $pdf->Open();
234 $pagenb = 0;
235 $pdf->SetDrawColor(128, 128, 128);
236
237 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
238 $pdf->SetSubject($outputlangs->transnoentities("Mo"));
239 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
240 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
241 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Mo")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
242 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
243 $pdf->SetCompression(false);
244 }
245
246 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
247
248 // Does we have at least one line with discount $this->atleastonediscount
249
250 // New page
251 $pdf->AddPage();
252 if (!empty($tplidx)) {
253 $pdf->useTemplate($tplidx);
254 }
255 $pagenb++;
256 $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
257 $pdf->SetFont('', '', $default_font_size - 1);
258 $pdf->MultiCell(0, 3, ''); // Set interline to 3
259 $pdf->SetTextColor(0, 0, 0);
260
261 $tab_top = 90 + $top_shift;
262 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
263
264 $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
265
266
267 // Affiche notes
268 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
269
270 // Extrafields in note
271 $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
272 if (!empty($extranote)) {
273 $notetoshow = dol_concatdesc($notetoshow, $extranote);
274 }
275
276 $pagenb = $pdf->getPage();
277 if ($notetoshow) {
278 $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
279 $pageposbeforenote = $pagenb;
280
281 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
282 complete_substitutions_array($substitutionarray, $outputlangs, $object);
283 $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
284 $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
285
286 $tab_top -= 2;
287
288 $pdf->startTransaction();
289
290 $pdf->SetFont('', '', $default_font_size - 1);
291 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
292 // Description
293 $pageposafternote = $pdf->getPage();
294 $posyafter = $pdf->GetY();
295
296 if ($pageposafternote > $pageposbeforenote) {
297 $pdf->rollbackTransaction(true);
298
299 // prepar pages to receive notes
300 while ($pagenb < $pageposafternote) {
301 $pdf->AddPage();
302 $pagenb++;
303 if (!empty($tplidx)) {
304 $pdf->useTemplate($tplidx);
305 }
306 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
307 $this->_pagehead($pdf, $object, 0, $outputlangs);
308 }
309 // $this->_pagefoot($pdf,$object,$outputlangs,1);
310 $pdf->setTopMargin($tab_top_newpage);
311 // The only function to edit the bottom margin of current page to set it.
312 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
313 }
314
315 // back to start
316 $pdf->setPage($pageposbeforenote);
317 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
318 $pdf->SetFont('', '', $default_font_size - 1);
319 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
320 $pageposafternote = $pdf->getPage();
321
322 $posyafter = $pdf->GetY();
323
324 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text
325 $pdf->AddPage('', '', true);
326 $pagenb++;
327 $pageposafternote++;
328 $pdf->setPage($pageposafternote);
329 $pdf->setTopMargin($tab_top_newpage);
330 // The only function to edit the bottom margin of current page to set it.
331 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
332 //$posyafter = $tab_top_newpage;
333 }
334
335
336 // apply note frame to previus pages
337 $i = $pageposbeforenote;
338 while ($i < $pageposafternote) {
339 $pdf->setPage($i);
340
341
342 $pdf->SetDrawColor(128, 128, 128);
343 // Draw note frame
344 if ($i > $pageposbeforenote) {
345 $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
346 $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
347 } else {
348 $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
349 $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
350 }
351
352 // Add footer
353 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
354 $this->_pagefoot($pdf, $object, $outputlangs, 1);
355
356 $i++;
357 }
358
359 // apply note frame to last page
360 $pdf->setPage($pageposafternote);
361 if (!empty($tplidx)) {
362 $pdf->useTemplate($tplidx);
363 }
364 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
365 $this->_pagehead($pdf, $object, 0, $outputlangs);
366 }
367 $height_note = $posyafter - $tab_top_newpage;
368 $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
369 } else {
370 // No pagebreak
371 $pdf->commitTransaction();
372 $posyafter = $pdf->GetY();
373 $height_note = $posyafter - $tab_top;
374 $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
375
376
377 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
378 // not enough space, need to add page
379 $pdf->AddPage('', '', true);
380 $pagenb++;
381 $pageposafternote++;
382 $pdf->setPage($pageposafternote);
383 if (!empty($tplidx)) {
384 $pdf->useTemplate($tplidx);
385 }
386 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
387 $this->_pagehead($pdf, $object, 0, $outputlangs);
388 }
389
390 $posyafter = $tab_top_newpage;
391 }
392 }
393
394 $tab_height = $tab_height - $height_note;
395 $tab_top = $posyafter + 6;
396 } else {
397 $height_note = 0;
398 }
399
400 $nexY = $tab_top + 5;
401
402 // Use new auto collum system
403 $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
404
405 // Loop on each lines
406 $pageposbeforeprintlines = $pdf->getPage();
407 $pagenb = $pageposbeforeprintlines;
408
409 $bom = new BOM($this->db);
410 $bom -> fetch($object->fk_bom);
411
412 $nblines = count($bom->lines);
413
414 for ($i = 0; $i < $nblines; $i++) {
415 $curY = $nexY;
416 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
417 $pdf->SetTextColor(0, 0, 0);
418
419 $prod = new Product($this->db);
420 $prod->fetch($bom->lines[$i]->fk_product);
421
422 // Define size of image if we need it
423 $imglinesize = array();
424 if (!empty($realpatharray[$i])) {
425 $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
426 }
427
428 $pdf->setTopMargin($tab_top_newpage);
429 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
430 $pageposbefore = $pdf->getPage();
431
432 $showpricebeforepagebreak = 1;
433 $posYAfterImage = 0;
434 $posYAfterDescription = 0;
435
436 // We start with Photo of product line
437 if (!empty($imglinesize['width']) && !empty($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page
438 $pdf->AddPage('', '', true);
439 if (!empty($tplidx)) {
440 $pdf->useTemplate($tplidx);
441 }
442 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
443 $this->_pagehead($pdf, $object, 0, $outputlangs);
444 }
445 $pdf->setPage($pageposbefore + 1);
446
447 $curY = $tab_top_newpage;
448
449 // Allows data in the first page if description is long enough to break in multiples pages
450 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
451 $showpricebeforepagebreak = 1;
452 } else {
453 $showpricebeforepagebreak = 0;
454 }
455 }
456
457 if (!empty($imglinesize['width']) && !empty($imglinesize['height'])) {
458 $curX = $this->posxpicture - 1;
459 $pdf->Image($realpatharray[$i], $curX + (($this->posxtva - $this->posxpicture - $imglinesize['width']) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
460 // $pdf->Image does not increase value return by getY, so we save it manually
461 $posYAfterImage = $curY + $imglinesize['height'];
462 }
463 // Description of product line
464 $curX = $this->posxdesc - 1;
465 $showpricebeforepagebreak = 1;
466
467 if ($this->getColumnStatus('code')) {
468 $pdf->startTransaction(); //description
469 //$this->printColDescContent($pdf, $curY, 'code', $object, $i, $outputlangs, $hideref, $hidedesc, $showsupplierSKU);
470 $this->printStdColumnContent($pdf, $curY, 'code', $prod->ref);
471
472 $pageposafter = $pdf->getPage();
473 $posyafter = $pdf->GetY();
474 if ($pageposafter > $pageposbefore) { // There is a pagebreak
475 $pdf->rollbackTransaction(true);
476
477 //$this->printColDescContent($pdf, $curY, 'code', $object, $i, $outputlangs, $hideref, $hidedesc, $showsupplierSKU);
478 $this->printStdColumnContent($pdf, $curY, 'code', $prod->ref);
479
480 $pageposafter = $pdf->getPage();
481 $posyafter = $pdf->GetY();
482 } elseif ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
483 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
484 $pdf->AddPage('', '', true);
485 if (!empty($tplidx)) {
486 $pdf->useTemplate($tplidx);
487 }
488 //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
489 $pdf->setPage($pageposafter + 1);
490 } else {
491 // We found a page break
492 // Allows data in the first page if description is long enough to break in multiples pages
493 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
494 $showpricebeforepagebreak = 1;
495 } else {
496 $showpricebeforepagebreak = 0;
497 }
498 }
499 } else { // No pagebreak
500 $pdf->commitTransaction();
501 }
502 $posYAfterDescription = $pdf->GetY();
503 }
504
505 $nexY = $pdf->GetY();
506 $pageposafter = $pdf->getPage();
507 $pdf->setPage($pageposbefore);
508 $pdf->setTopMargin($this->marge_haute);
509 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
510
511 // We suppose that a too long description is moved completely on next page
512 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
513 $pdf->setPage($pageposafter);
514 $curY = $tab_top_newpage;
515 }
516
517 if ($this->getColumnStatus('desc')) {
518 $pdf->startTransaction(); //description
519 $des = $prod -> description;
520 $descr = $des;//implode("<br>", $des);
521
522 $this->printStdColumnContent($pdf, $curY, 'desc', $descr);
523
524 $pageposafter = $pdf->getPage();
525 $posyafter = $pdf->GetY();
526 if ($pageposafter > $pageposbefore) { // There is a pagebreak
527 $pdf->rollbackTransaction(true);
528
529 $this->printStdColumnContent($pdf, $curY, 'desc', $descr);
530
531 $pageposafter = $pdf->getPage();
532 $posyafter = $pdf->GetY();
533 } elseif ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
534 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
535 $pdf->AddPage('', '', true);
536 if (!empty($tplidx)) {
537 $pdf->useTemplate($tplidx);
538 }
539 //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
540 $pdf->setPage($pageposafter + 1);
541 } else {
542 // We found a page break
543 // Allows data in the first page if description is long enough to break in multiples pages
544 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
545 $showpricebeforepagebreak = 1;
546 } else {
547 $showpricebeforepagebreak = 0;
548 }
549 }
550 } else { // No pagebreak
551 $pdf->commitTransaction();
552 }
553 $posYAfterDescription = max($posYAfterDescription, $pdf->GetY());
554 }
555
556 $nexY = max($nexY, $pdf->GetY());
557 $pageposafter = $pdf->getPage();
558 $pdf->setPage($pageposbefore);
559 $pdf->setTopMargin($this->marge_haute);
560 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
561
562 // We suppose that a too long description is moved completely on next page
563 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
564 $pdf->setPage($pageposafter);
565 $curY = $tab_top_newpage;
566 }
567
568 $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut
569
570 // Quantity
571 // Enough for 6 chars
572 if ($this->getColumnStatus('qty')) {
573 $qty = $bom->lines[$i]->qty;
574 $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
575 $nexY = max($pdf->GetY(), $nexY);
576 }
577
578 // Quantity
579 // Enough for 6 chars
580 if ($this->getColumnStatus('qtytot')) {
581 $qtytot = $object->qty * $bom->lines[$i]->qty;
582 $this->printStdColumnContent($pdf, $curY, 'qtytot', $qtytot);
583 $nexY = max($pdf->GetY(), $nexY);
584 }
585
586 // Dimensions
587 if ($this->getColumnStatus('dim')) {
588 $array = array_filter(array($prod->length, $prod->width, $prod->height));
589 $dim = implode("x", $array);
590 $this->printStdColumnContent($pdf, $curY, 'dim', $dim);
591 $nexY = max($pdf->GetY(), $nexY);
592 }
593 }
594
595
596
597
598 // Show square
599 if ($pagenb == $pageposbeforeprintlines) {
600 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
601 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
602 } else {
603 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
604 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
605 }
606
607 // Affiche zone infos
608 $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
609
610 // Affiche zone totaux
611 //$posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
612
613 // Affiche zone versements
614 if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) {
615 $posy = $this->_tableau_versements($pdf, $object, $posy, $outputlangs);
616 }
617
618 // Pied de page
619 $this->_pagefoot($pdf, $object, $outputlangs);
620 if (method_exists($pdf, 'AliasNbPages')) {
621 $pdf->AliasNbPages();
622 }
623
624 $pdf->Close();
625
626 $pdf->Output($file, 'F');
627
628 // Add pdfgeneration hook
629 $hookmanager->initHooks(array('pdfgeneration'));
630 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
631 global $action;
632 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
633 if ($reshook < 0) {
634 $this->error = $hookmanager->error;
635 $this->errors = $hookmanager->errors;
636 }
637
638 dolChmod($file);
639
640 $this->result = array('fullpath'=>$file);
641
642 return 1; // No error
643 } else {
644 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
645 return 0;
646 }
647 } else {
648 $this->error = $langs->trans("ErrorConstantNotDefined", "SUPPLIER_OUTPUTDIR");
649 return 0;
650 }
651 }
652
653 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
654 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
664 protected function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
665 {
666 // phpcs:enable
667 return 1;
668 }
669
670 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
671 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
681 protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
682 {
683 // phpcs:enable
684 global $conf, $mysoc;
685 $default_font_size = pdf_getPDFFontSize($outputlangs);
686
687 // If France, show VAT mention if not applicable
688 if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
689 $pdf->SetFont('', 'B', $default_font_size - 2);
690 $pdf->SetXY($this->marge_gauche, $posy);
691 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
692
693 $posy = $pdf->GetY() + 4;
694 }
695
696 $posxval = 52;
697
698 // Show payments conditions
699 if (!empty($object->cond_reglement_code) || $object->cond_reglement) {
700 $pdf->SetFont('', 'B', $default_font_size - 2);
701 $pdf->SetXY($this->marge_gauche, $posy);
702 $titre = $outputlangs->transnoentities("PaymentConditions").':';
703 $pdf->MultiCell(80, 4, $titre, 0, 'L');
704
705 $pdf->SetFont('', '', $default_font_size - 2);
706 $pdf->SetXY($posxval, $posy);
707 $lib_condition_paiement = ($outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != 'PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement_label);
708 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
709 $pdf->MultiCell(80, 4, $lib_condition_paiement, 0, 'L');
710
711 $posy = $pdf->GetY() + 3;
712 }
713
714 // Show payment mode
715 if (!empty($object->mode_reglement_code)) {
716 $pdf->SetFont('', 'B', $default_font_size - 2);
717 $pdf->SetXY($this->marge_gauche, $posy);
718 $titre = $outputlangs->transnoentities("PaymentMode").':';
719 $pdf->MultiCell(80, 5, $titre, 0, 'L');
720
721 $pdf->SetFont('', '', $default_font_size - 2);
722 $pdf->SetXY($posxval, $posy);
723 $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != 'PaymentType'.$object->mode_reglement_code ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement);
724 $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
725
726 $posy = $pdf->GetY() + 2;
727 }
728
729
730 return $posy;
731 }
732
733 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
734 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
745 protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
746 {
747 // phpcs:enable
748 global $conf, $mysoc;
749
750 $default_font_size = pdf_getPDFFontSize($outputlangs);
751
752 $tab2_top = $posy;
753 $tab2_hl = 4;
754 $pdf->SetFont('', '', $default_font_size - 1);
755
756 // Tableau total
757 $col1x = 120;
758 $col2x = 170;
759 if ($this->page_largeur < 210) { // To work with US executive format
760 $col2x -= 20;
761 }
762 $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
763
764 $useborder = 0;
765 $index = 0;
766
767 // Total HT
768 $pdf->SetFillColor(255, 255, 255);
769 $pdf->SetXY($col1x, $tab2_top);
770 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
771
772 $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
773 $pdf->SetXY($col2x, $tab2_top);
774 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, 'R', 1);
775
776 // Show VAT by rates and total
777 $pdf->SetFillColor(248, 248, 248);
778
779 $this->atleastoneratenotnull = 0;
780 foreach ($this->tva as $tvakey => $tvaval) {
781 if ($tvakey > 0) { // On affiche pas taux 0
782 $this->atleastoneratenotnull++;
783
784 $index++;
785 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
786
787 $tvacompl = '';
788
789 if (preg_match('/\*/', $tvakey)) {
790 $tvakey = str_replace('*', '', $tvakey);
791 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
792 }
793
794 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).' ';
795 $totalvat .= vatrate($tvakey, 1).$tvacompl;
796 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
797
798 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
799 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
800 }
801 }
802 if (!$this->atleastoneratenotnull) { // If no vat at all
803 $index++;
804 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
805 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code), 0, 'L', 1);
806
807 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
808 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_tva), 0, 'R', 1);
809
810 // Total LocalTax1
811 if (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on' && $object->total_localtax1 > 0) {
812 $index++;
813 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
814 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code), 0, 'L', 1);
815 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
816 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax1), $useborder, 'R', 1);
817 }
818
819 // Total LocalTax2
820 if (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on' && $object->total_localtax2 > 0) {
821 $index++;
822 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
823 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code), 0, 'L', 1);
824 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
825 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax2), $useborder, 'R', 1);
826 }
827 } else {
828 //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
829 //{
830 //Local tax 1
831 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
832 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
833 continue;
834 }
835
836 foreach ($localtax_rate as $tvakey => $tvaval) {
837 if ($tvakey != 0) { // On affiche pas taux 0
838 //$this->atleastoneratenotnull++;
839
840 $index++;
841 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
842
843 $tvacompl = '';
844 if (preg_match('/\*/', $tvakey)) {
845 $tvakey = str_replace('*', '', $tvakey);
846 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
847 }
848 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
849 $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
850 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
851
852 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
853 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
854 }
855 }
856 }
857
858 //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
859 //{
860 //Local tax 2
861 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
862 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
863 continue;
864 }
865
866 foreach ($localtax_rate as $tvakey => $tvaval) {
867 if ($tvakey != 0) { // On affiche pas taux 0
868 //$this->atleastoneratenotnull++;
869
870 $index++;
871 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
872
873 $tvacompl = '';
874 if (preg_match('/\*/', $tvakey)) {
875 $tvakey = str_replace('*', '', $tvakey);
876 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
877 }
878 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
879 $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
880 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
881
882 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
883 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
884 }
885 }
886 }
887 }
888
889 // Total TTC
890 $index++;
891 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
892 $pdf->SetTextColor(0, 0, 60);
893 $pdf->SetFillColor(224, 224, 224);
894 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
895
896 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
897 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
898 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc), $useborder, 'R', 1);
899 $pdf->SetFont('', '', $default_font_size - 1);
900 $pdf->SetTextColor(0, 0, 0);
901
902 $creditnoteamount = 0;
903 $depositsamount = 0;
904 //$creditnoteamount=$object->getSumCreditNotesUsed();
905 //$depositsamount=$object->getSumDepositsUsed();
906 //print "x".$creditnoteamount."-".$depositsamount;exit;
907 $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
908 if (!empty($object->paye)) {
909 $resteapayer = 0;
910 }
911
912 if ($deja_regle > 0) {
913 // Already paid + Deposits
914 $index++;
915
916 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
917 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
918 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
919 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle), 0, 'R', 0);
920
921 $index++;
922 $pdf->SetTextColor(0, 0, 60);
923 $pdf->SetFillColor(224, 224, 224);
924 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
925 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
926
927 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
928 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer), $useborder, 'R', 1);
929
930 $pdf->SetFont('', '', $default_font_size - 1);
931 $pdf->SetTextColor(0, 0, 0);
932 }
933
934 $index++;
935 return ($tab2_top + ($tab2_hl * $index));
936 }
937
938 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
952 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
953 {
954 global $conf;
955
956 // Force to disable hidetop and hidebottom
957 $hidebottom = 0;
958 if ($hidetop) {
959 $hidetop = -1;
960 }
961
962 $currency = !empty($currency) ? $currency : $conf->currency;
963 $default_font_size = pdf_getPDFFontSize($outputlangs);
964
965 // Amount in (at tab_top - 1)
966 $pdf->SetTextColor(0, 0, 0);
967 $pdf->SetFont('', '', $default_font_size - 2);
968
969 if (empty($hidetop)) {
970 // $title = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
971 $title = '';
972 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($title) + 3), $tab_top - 4);
973 $pdf->MultiCell(($pdf->GetStringWidth($title) + 3), 2, $title);
974
975 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
976 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
977 $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')));
978 }
979 }
980
981 $pdf->SetDrawColor(128, 128, 128);
982 $pdf->SetFont('', '', $default_font_size - 1);
983
984 // Output Rect
985 $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
986
987 foreach ($this->cols as $colKey => $colDef) {
988 if (!$this->getColumnStatus($colKey)) {
989 continue;
990 }
991
992 // get title label
993 $colDef['title']['label'] = !empty($colDef['title']['label']) ? $colDef['title']['label'] : $outputlangs->transnoentities($colDef['title']['textkey']);
994
995 // Add column separator
996 if (!empty($colDef['border-left'])) {
997 $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
998 }
999
1000 if (empty($hidetop)) {
1001 $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0]);
1002
1003 $textWidth = $colDef['width'] - $colDef['title']['padding'][3] - $colDef['title']['padding'][1];
1004 $pdf->MultiCell($textWidth, 2, $colDef['title']['label'], '', $colDef['title']['align']);
1005 }
1006 }
1007
1008 if (empty($hidetop)) {
1009 $pdf->line($this->marge_gauche, $tab_top + 5, $this->page_largeur - $this->marge_droite, $tab_top + 5); // line takes a position y in 2nd parameter and 4th parameter
1010 }
1011 }
1012
1013 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1023 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
1024 {
1025 global $langs, $conf, $mysoc;
1026
1027 $ltrdirection = 'L';
1028 if ($outputlangs->trans("DIRECTION") == 'rtl') {
1029 $ltrdirection = 'R';
1030 }
1031
1032 // Load translation files required by the page
1033 $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "sendings"));
1034
1035 $default_font_size = pdf_getPDFFontSize($outputlangs);
1036
1037 // Do not add the BACKGROUND as this is for suppliers
1038 //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
1039
1040 //Affiche le filigrane brouillon - Print Draft Watermark
1041 /*if($object->statut==0 && getDolGlobalString('COMMANDE_DRAFT_WATERMARK'))
1042 {
1043 pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',getDolGlobalString('COMMANDE_DRAFT_WATERMARK'));
1044 }*/
1045 //Print content
1046
1047 $pdf->SetTextColor(0, 0, 60);
1048 $pdf->SetFont('', 'B', $default_font_size + 3);
1049
1050 $posx = $this->page_largeur - $this->marge_droite - 100;
1051 $posy = $this->marge_haute;
1052 $w = 100;
1053
1054 $pdf->SetXY($this->marge_gauche, $posy);
1055
1056 // Logo
1057 $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
1058 if ($this->emetteur->logo) {
1059 if (is_readable($logo)) {
1060 $height = pdf_getHeightForLogo($logo);
1061 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1062 } else {
1063 $pdf->SetTextColor(200, 0, 0);
1064 $pdf->SetFont('', 'B', $default_font_size - 2);
1065 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1066 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToModuleSetup"), 0, 'L');
1067 }
1068 } else {
1069 $text = $this->emetteur->name;
1070 $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
1071 }
1072
1073 $pdf->SetFont('', 'B', $default_font_size + 3);
1074 $pdf->SetXY($posx, $posy);
1075 $pdf->SetTextColor(0, 0, 60);
1076 $title = $outputlangs->transnoentities("Mo")." ".$outputlangs->convToOutputCharset($object->ref);
1077 $pdf->MultiCell(100, 3, $title, '', 'R');
1078 $posy += 1;
1079
1080 if ($object->ref_supplier) {
1081 $posy += 4;
1082 $pdf->SetFont('', 'B', $default_font_size);
1083 $pdf->SetXY($posx, $posy);
1084 $pdf->SetTextColor(0, 0, 60);
1085 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefSupplier")." : ".$outputlangs->convToOutputCharset($object->ref_supplier), '', 'R');
1086 $posy += 1;
1087 }
1088
1089 $pdf->SetFont('', '', $default_font_size - 1);
1090 if (getDolGlobalString('PDF_SHOW_PROJECT_TITLE')) {
1091 $object->fetch_projet();
1092 if (!empty($object->project->ref)) {
1093 $posy += 3;
1094 $pdf->SetXY($posx, $posy);
1095 $pdf->SetTextColor(0, 0, 60);
1096 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1097 }
1098 }
1099
1100 if (getDolGlobalString('PDF_SHOW_PROJECT')) {
1101 $object->fetch_projet();
1102 if (!empty($object->project->ref)) {
1103 $outputlangs->load("projects");
1104 $posy += 4;
1105 $pdf->SetXY($posx, $posy);
1106 $langs->load("projects");
1107 $pdf->SetTextColor(0, 0, 60);
1108 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1109 }
1110 }
1111
1112 if (!empty($object->date_approve)) {
1113 $posy += 5;
1114 $pdf->SetXY($posx, $posy);
1115 $pdf->SetTextColor(0, 0, 60);
1116 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("MoDate")." : ".dol_print_date($object->date_approve, "day", false, $outputlangs, true), '', 'R');
1117 } else {
1118 $posy += 5;
1119 $pdf->SetXY($posx, $posy);
1120 $pdf->SetTextColor(255, 0, 0);
1121 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ToApprove"), '', 'R');
1122 }
1123
1124 // product info
1125 $prodToMake = new Product($this->db);
1126 $resProdToMake = $prodToMake->fetch($object->fk_product);
1127
1128 if ($resProdToMake > 0) {
1129 // ref
1130 $posy += 7;
1131 $pdf->SetFont('', 'B', $default_font_size + 1);
1132 $pdf->SetXY($posx, $posy);
1133 $pdf->SetTextColor(0, 0, 60);
1134 $pdf->MultiCell($w, 3, $prodToMake->ref, '', 'R');
1135
1136 // description
1137 $posy += 5;
1138 $pdf->SetFont('', 'B', $default_font_size + 3);
1139 $pdf->SetXY($posx, $posy);
1140 $pdf->SetTextColor(0, 0, 60);
1141 $pdf->MultiCell($w, 3, html_entity_decode($prodToMake->description), '', 'R', false, 1, '', '', true, 0, false, true, 51, 'T', true);
1142 $posy = $pdf->GetY() - 5;
1143
1144 // dimensions
1145 $array = array_filter(array($prodToMake->length, $prodToMake->width, $prodToMake->height));
1146 $dim = implode("x", $array);
1147 if (!empty($dim)) {
1148 $posy += 5;
1149 $pdf->SetFont('', 'B', $default_font_size + 3);
1150 $pdf->SetXY($posx, $posy);
1151 $pdf->SetTextColor(0, 0, 60);
1152 $pdf->MultiCell($w, 3, $dim, '', 'R');
1153 }
1154 }
1155
1156 $posy += 5;
1157 $pdf->SetFont('', 'B', $default_font_size + 3);
1158 $pdf->SetXY($posx, $posy);
1159 $pdf->SetTextColor(0, 0, 60);
1160 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("QtyToProduce").": " .$object->qty, '', 'R');
1161
1162
1163 $pdf->SetTextColor(0, 0, 60);
1164 $usehourmin = 'day';
1165 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
1166 $usehourmin = 'dayhour';
1167 }
1168 if (!empty($object->delivery_date)) {
1169 $posy += 4;
1170 $pdf->SetXY($posx - 90, $posy);
1171 $pdf->MultiCell(190, 3, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->delivery_date, $usehourmin, false, $outputlangs, true), '', 'R');
1172 }
1173
1174 if ($object->thirdparty->code_fournisseur) {
1175 $posy += 4;
1176 $pdf->SetXY($posx, $posy);
1177 $pdf->SetTextColor(0, 0, 60);
1178 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("SupplierCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_fournisseur), '', 'R');
1179 }
1180
1181 // Get contact
1182 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1183 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1184 if (count($arrayidcontact) > 0) {
1185 $usertmp = new User($this->db);
1186 $usertmp->fetch($arrayidcontact[0]);
1187 $posy += 4;
1188 $pdf->SetXY($posx, $posy);
1189 $pdf->SetTextColor(0, 0, 60);
1190 $pdf->MultiCell(100, 3, $langs->trans("BuyerName")." : ".$usertmp->getFullName($langs), '', 'R');
1191 }
1192 }
1193
1194 $posy += 1;
1195 $pdf->SetTextColor(0, 0, 60);
1196
1197 $top_shift = 0;
1198 // Show list of linked objects
1199 $current_y = $pdf->getY();
1200 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
1201 if ($current_y < $pdf->getY()) {
1202 $top_shift = $pdf->getY() - $current_y;
1203 }
1204
1205 if ($showaddress) {
1206 // Sender properties
1207 $carac_emetteur = '';
1208 // Add internal contact of object if defined
1209 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1210 if (count($arrayidcontact) > 0) {
1211 $object->fetch_user($arrayidcontact[0]);
1212 $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1213 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname.": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1214 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1215 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1216 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1217 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1218 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1219 $carac_emetteur .= "\n";
1220 }
1221
1222 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1223
1224 // Show sender
1225 $posy = 42 + $top_shift;
1226 $posx = $this->marge_gauche;
1227 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1228 $posx = $this->page_largeur - $this->marge_droite - 80;
1229 }
1230 $hautcadre = 40;
1231
1232 // Show sender frame
1233 $pdf->SetTextColor(0, 0, 0);
1234 $pdf->SetFont('', '', $default_font_size - 2);
1235 $pdf->SetXY($posx, $posy - 5);
1236 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1237 $pdf->SetXY($posx, $posy);
1238 $pdf->SetFillColor(230, 230, 230);
1239 $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
1240 $pdf->SetTextColor(0, 0, 60);
1241
1242 // Show sender name
1243 $pdf->SetXY($posx + 2, $posy + 3);
1244 $pdf->SetFont('', 'B', $default_font_size);
1245 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1246 $posy = $pdf->getY();
1247
1248 // Show sender information
1249 $pdf->SetXY($posx + 2, $posy);
1250 $pdf->SetFont('', '', $default_font_size - 1);
1251 $pdf->MultiCell(80, 4, $carac_emetteur, 0, $ltrdirection);
1252
1253
1254
1255 // If CUSTOMER contact defined on order, we use it. Note: Even if this is a supplier object, the code for external contat that follow order is 'CUSTOMER'
1256 $usecontact = false;
1257 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1258 if (count($arrayidcontact) > 0) {
1259 $usecontact = true;
1260 $result = $object->fetch_contact($arrayidcontact[0]);
1261 }
1262
1263 // Recipient name
1264 if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || getDolGlobalString('MAIN_USE_COMPANY_NAME_OF_CONTACT')))) {
1265 $thirdparty = $object->contact;
1266 } else {
1267 $thirdparty = $object->thirdparty;
1268 }
1269
1270 //$carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1271
1272 //$carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object);
1273
1274 // Show recipient
1275 //$widthrecbox = 100;
1276 //if ($this->page_largeur < 210) {
1277 // $widthrecbox = 84; // To work with US executive format
1278 //}
1279 //$posy = 42 + $top_shift;
1280 //$posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1281 //if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
1282 // $posx = $this->marge_gauche;
1283 //}
1284 //
1286 //$pdf->SetTextColor(0, 0, 0);
1287 //$pdf->SetFont('', '', $default_font_size - 2);
1288 //$pdf->SetXY($posx + 2, $posy - 5);
1289 //$pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1290 //$pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
1291 //
1293 //$pdf->SetXY($posx + 2, $posy + 3);
1294 //$pdf->SetFont('', 'B', $default_font_size);
1295 //$pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, $ltrdirection);
1296 //
1297 //$posy = $pdf->getY();
1298 //
1300 //$pdf->SetFont('', '', $default_font_size - 1);
1301 //$pdf->SetXY($posx + 2, $posy);
1302 //$pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1303 }
1304
1305 return $top_shift;
1306 }
1307
1308 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1318 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1319 {
1320 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1321 return pdf_pagefoot($pdf, $outputlangs, 'SUPPLIER_ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1322 }
1323
1324
1325
1336 public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1337 {
1338 global $conf, $hookmanager;
1339
1340 // Default field style for content
1341 $this->defaultContentsFieldsStyle = array(
1342 'align' => 'R', // R,C,L
1343 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1344 );
1345
1346 // Default field style for content
1347 $this->defaultTitlesFieldsStyle = array(
1348 'align' => 'C', // R,C,L
1349 'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1350 );
1351
1352 /*
1353 * For exemple
1354 $this->cols['theColKey'] = array(
1355 'rank' => $rank, // int : use for ordering columns
1356 'width' => 20, // the column width in mm
1357 'title' => array(
1358 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1359 'label' => ' ', // the final label : used fore final generated text
1360 'align' => 'L', // text alignement : R,C,L
1361 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1362 ),
1363 'content' => array(
1364 'align' => 'L', // text alignement : R,C,L
1365 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1366 ),
1367 );
1368 */
1369 $rank = 0;
1370 $this->cols['code'] = array(
1371 'rank' => $rank,
1372 'status' => true,
1373 'width' => 35, // in mm
1374 'title' => array(
1375 'textkey' => 'Ref'
1376 ),
1377 'border-left' => true, // add left line separator
1378 );
1379
1380 $rank = 1; // do not use negative rank
1381 $this->cols['desc'] = array(
1382 'rank' => $rank,
1383 'width' => false, // only for desc
1384 'status' => true,
1385 'title' => array(
1386 'textkey' => 'Designation', // use lang key is usefull in somme case with module
1387 'align' => 'L',
1388 // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1389 // 'label' => ' ', // the final label
1390 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1391 ),
1392 'border-left' => true,
1393 'content' => array(
1394 'align' => 'L',
1395 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1396 ),
1397 );
1398
1399 $rank = $rank + 10;
1400 $this->cols['photo'] = array(
1401 'rank' => $rank,
1402 'width' => (!getDolGlobalString('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH') ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
1403 'status' => false,
1404 'title' => array(
1405 'textkey' => 'Photo',
1406 'label' => ' '
1407 ),
1408 'content' => array(
1409 'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1410 ),
1411 'border-left' => false, // remove left line separator
1412 );
1413
1414 if (getDolGlobalString('MAIN_GENERATE_ORDERS_WITH_PICTURE')) {
1415 $this->cols['photo']['status'] = true;
1416 }
1417
1418 $rank = $rank + 10;
1419 $this->cols['dim'] = array(
1420 'rank' => $rank,
1421 'status' => true,
1422 'width' => 25, // in mm
1423 'title' => array(
1424 'textkey' => 'Size'
1425 ),
1426 'border-left' => true, // add left line separator
1427 );
1428
1429 $rank = $rank + 10;
1430 $this->cols['qty'] = array(
1431 'rank' => $rank,
1432 'width' => 16, // in mm
1433 'status' => true,
1434 'title' => array(
1435 'textkey' => 'Qty'
1436 ),
1437 'border-left' => true, // add left line separator
1438 );
1439
1440 $rank = $rank + 10;
1441 $this->cols['qtytot'] = array(
1442 'rank' => $rank,
1443 'width' => 25, // in mm
1444 'status' => true,
1445 'title' => array(
1446 'textkey' => 'QtyTot'
1447 ),
1448 'border-left' => true, // add left line separator
1449 );
1450
1451 // Add extrafields cols
1452 if (!empty($object->lines)) {
1453 $line = reset($object->lines);
1454 $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
1455 }
1456
1457 $parameters = array(
1458 'object' => $object,
1459 'outputlangs' => $outputlangs,
1460 'hidedetails' => $hidedetails,
1461 'hidedesc' => $hidedesc,
1462 'hideref' => $hideref
1463 );
1464
1465 $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
1466 if ($reshook < 0) {
1467 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1468 } elseif (empty($reshook)) {
1469 $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
1470 } else {
1471 $this->cols = $hookmanager->resArray;
1472 }
1473 }
1474}
Class for BOM.
Definition bom.class.php:43
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
printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
Rect pdf.
defineColumnExtrafield($object, $outputlangs, $hidedetails=0)
Define Array Column Field for extrafields.
Class to manage hooks.
Parent class for mos models.
Class to manage products or services.
Class to manage translations.
Class to manage Dolibarr users.
Class to generate the manufacturing orders with the vinci model.
_tableau_info(&$pdf, $object, $posy, $outputlangs)
Show miscellaneous information (payment mode, payment term, ...)
_pagehead(&$pdf, $object, $showaddress, $outputlangs)
Show top header of page.
_tableau_versements(&$pdf, $object, $posy, $outputlangs)
Show payments table.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
__construct($db)
Constructor.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
Show table for lines.
_tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
Show total to pay.
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
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.
if(!function_exists( 'dolEscapeXML')) convertBackOfficeMediasLinksToPublicLinks($notetoshow)
Convert links to local wrapper to medias files into a string into a public external URL readable on i...
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
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.
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.
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_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_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
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