dolibarr 22.0.5
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-2025 Frédéric France <frederic.france@free.fr>
9 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
10 * Copyright (C) 2024 Josep Lluís Amador <joseplluis@lliuretic.cat>
11 * Copyright (C) 2024 Nick Fragoulis
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 * or see https://www.gnu.org/
26 */
27
34require_once DOL_DOCUMENT_ROOT.'/core/modules/mrp/modules_mo.php';
35require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
36require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
41
42
47{
51 public $db;
52
56 public $name;
57
61 public $description;
62
66 public $update_main_doc_field;
67
71 public $type;
72
77 public $version = 'dolibarr';
78
79
85 public function __construct($db)
86 {
87 global $langs, $mysoc;
88
89 // Load translation files required by the page
90 $langs->loadLangs(array("main", "bills", "mrp"));
91
92 $this->db = $db;
93 $this->name = "vinci";
94 $this->description = $langs->trans('DocumentModelStandardPDF');
95 $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
96
97 // Page size for A4 format
98 $this->type = 'pdf';
99 $formatarray = pdf_getFormat();
100 $this->page_largeur = $formatarray['width'];
101 $this->page_hauteur = $formatarray['height'];
102 $this->format = array($this->page_largeur, $this->page_hauteur);
103 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
104 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
105 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
106 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
107 $this->corner_radius = getDolGlobalInt('MAIN_PDF_FRAME_CORNER_RADIUS', 0);
108 $this->option_logo = 1; // Display logo
109 $this->option_multilang = 1; //Available in several languages
110 $this->option_escompte = 0; // Displays if there has been a discount
111 $this->option_credit_note = 0; // Support credit notes
112 $this->option_freetext = 1; // Support add of a personalised text
113 $this->option_draft_watermark = 1; // Support add of a watermark on drafts
114
115 // Define position of columns
116 $this->posxdesc = $this->marge_gauche + 1; // For module retrocompatibility support during PDF transition: TODO remove this at the end
117
118 if ($mysoc === null) {
119 dol_syslog(get_class($this).'::__construct() Global $mysoc should not be null.'. getCallerInfoString(), LOG_ERR);
120 return;
121 }
122
123 // Get source company
124 $this->emetteur = $mysoc;
125 if (empty($this->emetteur->country_code)) {
126 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
127 }
128 }
129
130
131 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
143 public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
144 {
145 // phpcs:enable
146 global $user, $langs, $conf, $hookmanager, $mysoc;
147
148 if (!is_object($outputlangs)) {
149 $outputlangs = $langs;
150 }
151 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
152 if (getDolGlobalString('MAIN_USE_FPDF')) {
153 $outputlangs->charset_output = 'ISO-8859-1';
154 }
155
156 // Load translation files required by the page
157 $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "dict", "products"));
158
159 global $outputlangsbis;
160 $outputlangsbis = null;
161 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')) {
162 $outputlangsbis = new Translate('', $conf);
163 $outputlangsbis->setDefaultLang(getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE'));
164 $outputlangsbis->loadLangs(array("main", "orders", "companies", "bills", "dict", "products"));
165 }
166
167 if (!isset($object->lines) || !is_array($object->lines)) {
168 $object->lines = array();
169 }
170
171 $nblines = count($object->lines);
172
173 $hidetop = 0;
174 if (getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE')) {
175 $hidetop = getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE');
176 }
177
178 if ($conf->mrp->dir_output) {
179 $object->fetch_thirdparty();
180
181 $deja_regle = 0;
182 $amount_credit_notes_included = 0;
183 $amount_deposits_included = 0;
184 //$amount_credit_notes_included = $object->getSumCreditNotesUsed();
185 //$amount_deposits_included = $object->getSumDepositsUsed();
186
187 // Definition of $dir and $file
188 if ($object->specimen) {
189 $dir = $conf->mrp->dir_output;
190 $file = $dir."/SPECIMEN.pdf";
191 } else {
192 $objectref = dol_sanitizeFileName($object->ref);
193 $dir = $conf->mrp->dir_output.'/'.$objectref;
194 $file = $dir."/".$objectref.".pdf";
195 }
196
197 if (!file_exists($dir)) {
198 if (dol_mkdir($dir) < 0) {
199 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
200 return 0;
201 }
202 }
203
204 if (file_exists($dir)) {
205 // Add pdfgeneration hook
206 if (!is_object($hookmanager)) {
207 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
208 $hookmanager = new HookManager($this->db);
209 }
210 $hookmanager->initHooks(array('pdfgeneration'));
211 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
212 global $action;
213 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
214
215 $nblines = count($object->lines);
216
217 $pdf = pdf_getInstance($this->format);
218 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
219 $heightforinfotot = 50; // Height reserved to output the info and total part
220 $heightforfreetext = getDolGlobalInt('MAIN_PDF_FREETEXT_HEIGHT', 5); // Height reserved to output the free text on last page
221 $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
222 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
223 $heightforfooter += 6;
224 }
225 $pdf->setAutoPageBreak(true, 0);
226
227 if (class_exists('TCPDF')) {
228 $pdf->setPrintHeader(false);
229 $pdf->setPrintFooter(false);
230 }
231 $pdf->SetFont(pdf_getPDFFont($outputlangs));
232 // Set path to the background PDF File
233 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
234 $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
235 $tplidx = $pdf->importPage(1);
236 }
237
238 $pdf->Open();
239 $pagenb = 0;
240 $pdf->SetDrawColor(128, 128, 128);
241
242 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
243 $pdf->SetSubject($outputlangs->transnoentities("ManufacturingOrder"));
244 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
245 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
246 $key_word=$outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("ManufacturingOrder");
247 if (isset($object->thirdparty->name) && $object->thirdparty->name !== "") {
248 $key_word.=" ".$outputlangs->convToOutputCharset($object->thirdparty->name);
249 }
250 $pdf->SetKeyWords($key_word);
251 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
252 $pdf->SetCompression(false);
253 }
254
255 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
256 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
257
258 // Does we have at least one line with discount $this->atleastonediscount
259
260 // New page
261 $pdf->AddPage();
262 if (!empty($tplidx)) {
263 $pdf->useTemplate($tplidx);
264 }
265 $pagenb++;
266 $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
267 $pdf->SetFont('', '', $default_font_size - 1);
268 $pdf->MultiCell(0, 3, ''); // Set interline to 3
269 $pdf->SetTextColor(0, 0, 0);
270
271 $tab_top = 90 + $top_shift;
272 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
273
274 $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
275
276
277 // Affiche notes
278 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
279
280 // Extrafields in note
281 $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
282 if (!empty($extranote)) {
283 $notetoshow = dol_concatdesc($notetoshow, $extranote);
284 }
285
286 $pagenb = $pdf->getPage();
287 if ($notetoshow) {
288 $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
289 $pageposbeforenote = $pagenb;
290
291 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
292 complete_substitutions_array($substitutionarray, $outputlangs, $object);
293 $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
294 $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
295
296 $tab_top -= 2;
297
298 $pdf->startTransaction();
299
300 $pdf->SetFont('', '', $default_font_size - 1);
301 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
302 // Description
303 $pageposafternote = $pdf->getPage();
304 $posyafter = $pdf->GetY();
305
306 if ($pageposafternote > $pageposbeforenote) {
307 $pdf->rollbackTransaction(true);
308
309 // prepar pages to receive notes
310 while ($pagenb < $pageposafternote) {
311 $pdf->AddPage();
312 $pagenb++;
313 if (!empty($tplidx)) {
314 $pdf->useTemplate($tplidx);
315 }
316 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
317 $this->_pagehead($pdf, $object, 0, $outputlangs);
318 }
319 // $this->_pagefoot($pdf,$object,$outputlangs,1);
320 $pdf->setTopMargin($tab_top_newpage);
321 // The only function to edit the bottom margin of current page to set it.
322 $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext);
323 }
324
325 // back to start
326 $pdf->setPage($pageposbeforenote);
327 $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext);
328 $pdf->SetFont('', '', $default_font_size - 1);
329 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
330 $pageposafternote = $pdf->getPage();
331
332 $posyafter = $pdf->GetY();
333
334 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text
335 $pdf->AddPage('', '', true);
336 $pagenb++;
337 $pageposafternote++;
338 $pdf->setPage($pageposafternote);
339 $pdf->setTopMargin($tab_top_newpage);
340 // The only function to edit the bottom margin of current page to set it.
341 $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext);
342 //$posyafter = $tab_top_newpage;
343 }
344
345
346 // apply note frame to previous pages
347 $i = $pageposbeforenote;
348 while ($i < $pageposafternote) {
349 $pdf->setPage($i);
350
351 $pdf->SetDrawColor(128, 128, 128);
352 // Draw note frame
353 if ($i > $pageposbeforenote) {
354 $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
355 $pdf->RoundedRect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
356 } else {
357 $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
358 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
359 }
360
361 // Add footer
362 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
363 $this->_pagefoot($pdf, $object, $outputlangs, 1);
364
365 $i++;
366 }
367
368 // apply note frame to last page
369 $pdf->setPage($pageposafternote);
370 if (!empty($tplidx)) {
371 $pdf->useTemplate($tplidx);
372 }
373 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
374 $this->_pagehead($pdf, $object, 0, $outputlangs);
375 }
376 $height_note = $posyafter - $tab_top_newpage;
377 $pdf->RoundedRect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
378 } else {
379 // No pagebreak
380 $pdf->commitTransaction();
381 $posyafter = $pdf->GetY();
382 $height_note = $posyafter - $tab_top;
383 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
384
385
386 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
387 // not enough space, need to add page
388 $pdf->AddPage('', '', true);
389 $pagenb++;
390 $pageposafternote++;
391 $pdf->setPage($pageposafternote);
392 if (!empty($tplidx)) {
393 $pdf->useTemplate($tplidx);
394 }
395 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
396 $this->_pagehead($pdf, $object, 0, $outputlangs);
397 }
398
399 $posyafter = $tab_top_newpage;
400 }
401 }
402
403 $tab_height -= $height_note;
404 $tab_top = $posyafter + 6;
405 } else {
406 $height_note = 0;
407 }
408
409 $nexY = $tab_top + 5;
410
411 // Use new auto column system
412 $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
413
414 // Loop on each lines
415 $pageposbeforeprintlines = $pdf->getPage();
416 $pagenb = $pageposbeforeprintlines;
417
418 $bom = new BOM($this->db);
419 $bom -> fetch($object->fk_bom);
420
421 $nblines = count($bom->lines);
422
423 for ($i = 0; $i < $nblines; $i++) {
424 $curY = $nexY;
425 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
426 $pdf->SetTextColor(0, 0, 0);
427
428 $prod = new Product($this->db);
429 $prod->fetch($bom->lines[$i]->fk_product);
430
431 $pdf->setTopMargin($tab_top_newpage);
432 $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
433 $pageposbefore = $pdf->getPage();
434
435 $showpricebeforepagebreak = 1;
436 $posYAfterImage = 0;
437 $posYAfterDescription = 0;
438
439 // Description of product line
440 $curX = $this->posxdesc - 1;
441 $showpricebeforepagebreak = 1;
442
443 if ($this->getColumnStatus('code')) {
444 $pdf->startTransaction(); //description
445 //$this->printColDescContent($pdf, $curY, 'code', $object, $i, $outputlangs, $hideref, $hidedesc, $showsupplierSKU);
446 $this->printStdColumnContent($pdf, $curY, 'code', $prod->ref);
447
448 $pageposafter = $pdf->getPage();
449 $posyafter = $pdf->GetY();
450 if ($pageposafter > $pageposbefore) { // There is a pagebreak
451 $pdf->rollbackTransaction(true);
452
453 //$this->printColDescContent($pdf, $curY, 'code', $object, $i, $outputlangs, $hideref, $hidedesc, $showsupplierSKU);
454 $this->printStdColumnContent($pdf, $curY, 'code', $prod->ref);
455
456 $pageposafter = $pdf->getPage();
457 $posyafter = $pdf->GetY();
458 } elseif ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
459 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
460 $pdf->AddPage('', '', true);
461 if (!empty($tplidx)) {
462 $pdf->useTemplate($tplidx);
463 }
464 //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
465 $pdf->setPage($pageposafter + 1);
466 } else {
467 // We found a page break
468 // Allows data in the first page if description is long enough to break in multiples pages
469 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
470 $showpricebeforepagebreak = 1;
471 } else {
472 $showpricebeforepagebreak = 0;
473 }
474 }
475 } else { // No pagebreak
476 $pdf->commitTransaction();
477 }
478 $posYAfterDescription = $pdf->GetY();
479 }
480
481 $nexY = $pdf->GetY();
482 $pageposafter = $pdf->getPage();
483 $pdf->setPage($pageposbefore);
484 $pdf->setTopMargin($this->marge_haute);
485 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
486
487 // We suppose that a too long description is moved completely on next page
488 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
489 $pdf->setPage($pageposafter);
490 $curY = $tab_top_newpage;
491 }
492
493 if ($this->getColumnStatus('desc')) {
494 $pdf->startTransaction(); //description
495 $des = $prod -> description;
496 $descr = $des;//implode("<br>", $des);
497
498 $this->printStdColumnContent($pdf, $curY, 'desc', $descr);
499
500 $pageposafter = $pdf->getPage();
501 $posyafter = $pdf->GetY();
502 if ($pageposafter > $pageposbefore) { // There is a pagebreak
503 $pdf->rollbackTransaction(true);
504
505 $this->printStdColumnContent($pdf, $curY, 'desc', $descr);
506
507 $pageposafter = $pdf->getPage();
508 $posyafter = $pdf->GetY();
509 } elseif ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
510 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
511 $pdf->AddPage('', '', true);
512 if (!empty($tplidx)) {
513 $pdf->useTemplate($tplidx);
514 }
515 //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
516 $pdf->setPage($pageposafter + 1);
517 } else {
518 // We found a page break
519 // Allows data in the first page if description is long enough to break in multiples pages
520 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
521 $showpricebeforepagebreak = 1;
522 } else {
523 $showpricebeforepagebreak = 0;
524 }
525 }
526 } else { // No pagebreak
527 $pdf->commitTransaction();
528 }
529 $posYAfterDescription = max($posYAfterDescription, $pdf->GetY());
530 }
531
532 $nexY = max($nexY, $pdf->GetY());
533 $pageposafter = $pdf->getPage();
534 $pdf->setPage($pageposbefore);
535 $pdf->setTopMargin($this->marge_haute);
536 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
537
538 // We suppose that a too long description is moved completely on next page
539 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
540 $pdf->setPage($pageposafter);
541 $curY = $tab_top_newpage;
542 }
543
544 $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par default
545
546 // Quantity
547 // Enough for 6 chars
548 if ($this->getColumnStatus('qty')) {
549 $qty = $bom->lines[$i]->qty;
550 $this->printStdColumnContent($pdf, $curY, 'qty', (string) $qty);
551 $nexY = max($pdf->GetY(), $nexY);
552 }
553
554 // Quantity
555 // Enough for 6 chars
556 if ($this->getColumnStatus('qtytot')) {
557 $qtytot = $object->qty * $bom->lines[$i]->qty;
558 $this->printStdColumnContent($pdf, $curY, 'qtytot', (string) $qtytot);
559 $nexY = max($pdf->GetY(), $nexY);
560 }
561
562 // Dimensions
563 if ($this->getColumnStatus('dim')) {
564 $array = array_filter(array($prod->length, $prod->width, $prod->height));
565 $dim = implode("x", $array);
566 $this->printStdColumnContent($pdf, $curY, 'dim', $dim);
567 $nexY = max($pdf->GetY(), $nexY);
568 }
569 }
570
571
572 // Show square
573 if ($pagenb == $pageposbeforeprintlines) {
574 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
575 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
576 } else {
577 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
578 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
579 }
580
581 // Affiche zone infos
582 $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
583
584 // Affiche zone totaux
585 //$posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
586
587 // Affiche zone versements
588 if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) {
589 $posy = $this->_tableau_versements($pdf, $object, $posy, $outputlangs);
590 }
591
592 // Pied de page
593 $this->_pagefoot($pdf, $object, $outputlangs);
594 if (method_exists($pdf, 'AliasNbPages')) {
595 $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod
596 }
597
598 $pdf->Close();
599
600 $pdf->Output($file, 'F');
601
602 // Add pdfgeneration hook
603 $hookmanager->initHooks(array('pdfgeneration'));
604 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
605 global $action;
606 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
607 if ($reshook < 0) {
608 $this->error = $hookmanager->error;
609 $this->errors = $hookmanager->errors;
610 }
611
612 dolChmod($file);
613
614 $this->result = array('fullpath' => $file);
615
616 return 1; // No error
617 } else {
618 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
619 return 0;
620 }
621 } else {
622 $this->error = $langs->trans("ErrorConstantNotDefined", "SUPPLIER_OUTPUTDIR");
623 return 0;
624 }
625 }
626
627 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
628 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
638 protected function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
639 {
640 // phpcs:enable
641 return 1;
642 }
643
644 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
645 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
655 protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
656 {
657 // phpcs:enable
658 global $conf, $mysoc;
659 $default_font_size = pdf_getPDFFontSize($outputlangs);
660
661 // If France, show VAT mention if not applicable
662 if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
663 $pdf->SetFont('', 'B', $default_font_size - 2);
664 $pdf->SetXY($this->marge_gauche, $posy);
665 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', false);
666
667 $posy = $pdf->GetY() + 4;
668 }
669
670 $posxval = 52;
671
672 // Show payments conditions
673 if (!empty($object->cond_reglement_code) || $object->cond_reglement) {
674 $pdf->SetFont('', 'B', $default_font_size - 2);
675 $pdf->SetXY($this->marge_gauche, $posy);
676 $titre = $outputlangs->transnoentities("PaymentConditions").':';
677 $pdf->MultiCell(80, 4, $titre, 0, 'L');
678
679 $pdf->SetFont('', '', $default_font_size - 2);
680 $pdf->SetXY($posxval, $posy);
681 $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);
682 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
683 $pdf->MultiCell(80, 4, $lib_condition_paiement, 0, 'L');
684
685 $posy = $pdf->GetY() + 3;
686 }
687
688 // Show payment mode
689 if (!empty($object->mode_reglement_code)) {
690 $pdf->SetFont('', 'B', $default_font_size - 2);
691 $pdf->SetXY($this->marge_gauche, $posy);
692 $titre = $outputlangs->transnoentities("PaymentMode").':';
693 $pdf->MultiCell(80, 5, $titre, 0, 'L');
694
695 $pdf->SetFont('', '', $default_font_size - 2);
696 $pdf->SetXY($posxval, $posy);
697 $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);
698 $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
699
700 $posy = $pdf->GetY() + 2;
701 }
702
703
704 return $posy;
705 }
706
707 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
708 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
719 protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
720 {
721 // phpcs:enable
722 global $conf, $mysoc;
723
724 $default_font_size = pdf_getPDFFontSize($outputlangs);
725
726 $tab2_top = $posy;
727 $tab2_hl = 4;
728 $pdf->SetFont('', '', $default_font_size - 1);
729
730 // Tableau total
731 $col1x = 120;
732 $col2x = 170;
733 if ($this->page_largeur < 210) { // To work with US executive format
734 $col2x -= 20;
735 }
736 $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
737
738 $useborder = 0;
739 $index = 0;
740
741 // Total HT
742 $pdf->SetFillColor(255, 255, 255);
743 $pdf->SetXY($col1x, $tab2_top);
744 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', true);
745
746 $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
747 $pdf->SetXY($col2x, $tab2_top);
748 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, 'R', true);
749
750 // Show VAT by rates and total
751 $pdf->SetFillColor(248, 248, 248);
752
753 $this->atleastoneratenotnull = 0;
754 foreach ($this->tva as $tvakey => $tvaval) {
755 if ($tvakey > 0) { // On affiche pas taux 0
756 $this->atleastoneratenotnull++;
757
758 $index++;
759 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
760
761 $tvacompl = '';
762
763 if (preg_match('/\*/', $tvakey)) {
764 $tvakey = str_replace('*', '', $tvakey);
765 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
766 }
767
768 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).' ';
769 $totalvat .= vatrate($tvakey, true).$tvacompl;
770 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
771
772 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
773 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', true);
774 }
775 }
776 if (!$this->atleastoneratenotnull) { // If no vat at all
777 $index++;
778 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
779 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code), 0, 'L', true);
780
781 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
782 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_tva), 0, 'R', true);
783
784 // Total LocalTax1
785 if (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on' && $object->total_localtax1 > 0) {
786 $index++;
787 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
788 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code), 0, 'L', true);
789 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
790 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax1), $useborder, 'R', true);
791 }
792
793 // Total LocalTax2
794 if (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on' && $object->total_localtax2 > 0) {
795 $index++;
796 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
797 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code), 0, 'L', true);
798 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
799 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax2), $useborder, 'R', true);
800 }
801 } else {
802 //if (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') && getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on')
803 //{
804 //Local tax 1
805 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
806 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
807 continue;
808 }
809
810 foreach ($localtax_rate as $tvakey => $tvaval) {
811 if ($tvakey != 0) { // On affiche pas taux 0
812 //$this->atleastoneratenotnull++;
813
814 $index++;
815 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
816
817 $tvacompl = '';
818 if (preg_match('/\*/', $tvakey)) {
819 $tvakey = str_replace('*', '', $tvakey);
820 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
821 }
822 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
823 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
824 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
825
826 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
827 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', true);
828 }
829 }
830 }
831
832 //if (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') && getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on')
833 //{
834 //Local tax 2
835 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
836 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
837 continue;
838 }
839
840 foreach ($localtax_rate as $tvakey => $tvaval) {
841 if ($tvakey != 0) { // On affiche pas taux 0
842 //$this->atleastoneratenotnull++;
843
844 $index++;
845 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
846
847 $tvacompl = '';
848 if (preg_match('/\*/', $tvakey)) {
849 $tvakey = str_replace('*', '', $tvakey);
850 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
851 }
852 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
853 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
854 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
855
856 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
857 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', true);
858 }
859 }
860 }
861 }
862
863 // Total TTC
864 $index++;
865 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
866 $pdf->SetTextColor(0, 0, 60);
867 $pdf->SetFillColor(224, 224, 224);
868 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', true);
869
870 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
871 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
872 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc), $useborder, 'R', true);
873 $pdf->SetFont('', '', $default_font_size - 1);
874 $pdf->SetTextColor(0, 0, 0);
875
876 $creditnoteamount = 0;
877 $depositsamount = 0;
878 //$creditnoteamount=$object->getSumCreditNotesUsed();
879 //$depositsamount=$object->getSumDepositsUsed();
880 //print "x".$creditnoteamount."-".$depositsamount;exit;
881 $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
882 if (!empty($object->paye)) {
883 $resteapayer = 0;
884 }
885
886 if ($deja_regle > 0) {
887 // Already paid + Deposits
888 $index++;
889
890 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
891 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', false);
892 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
893 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle), 0, 'R', false);
894
895 $index++;
896 $pdf->SetTextColor(0, 0, 60);
897 $pdf->SetFillColor(224, 224, 224);
898 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
899 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', true);
900
901 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
902 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer), $useborder, 'R', true);
903
904 $pdf->SetFont('', '', $default_font_size - 1);
905 $pdf->SetTextColor(0, 0, 0);
906 }
907
908 $index++;
909 return ($tab2_top + ($tab2_hl * $index));
910 }
911
912 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
926 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
927 {
928 global $conf;
929
930 // Force to disable hidetop and hidebottom
931 $hidebottom = 0;
932 if ($hidetop) {
933 $hidetop = -1;
934 }
935
936 $currency = !empty($currency) ? $currency : $conf->currency;
937 $default_font_size = pdf_getPDFFontSize($outputlangs);
938
939 // Amount in (at tab_top - 1)
940 $pdf->SetTextColor(0, 0, 0);
941 $pdf->SetFont('', '', $default_font_size - 2);
942
943 if (empty($hidetop)) {
944 // $title = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
945 $title = '';
946 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($title) + 3), $tab_top - 4);
947 $pdf->MultiCell(($pdf->GetStringWidth($title) + 3), 2, $title);
948
949 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
950 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
951 $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')));
952 }
953 }
954
955 $pdf->SetDrawColor(128, 128, 128);
956 $pdf->SetFont('', '', $default_font_size - 1);
957
958 // Output Rect
959 $this->printRoundedRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $this->corner_radius, $hidetop, $hidebottom, 'D'); // Rect takes a length in 3rd parameter and 4th parameter
960
961 foreach ($this->cols as $colKey => $colDef) {
962 if (!$this->getColumnStatus($colKey)) {
963 continue;
964 }
965
966 // get title label
967 $colDef['title']['label'] = !empty($colDef['title']['label']) ? $colDef['title']['label'] : $outputlangs->transnoentities($colDef['title']['textkey']);
968
969 // Add column separator
970 if (!empty($colDef['border-left'])) {
971 $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
972 }
973
974 if (empty($hidetop) && array_key_exists('title', $colDef) && array_key_exists('width', $colDef)) {
975 $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0]);
976
977 $textWidth = $colDef['width'] - $colDef['title']['padding'][3] - $colDef['title']['padding'][1];
978 $pdf->MultiCell($textWidth, 2, $colDef['title']['label'], '', $colDef['title']['align']);
979 }
980 }
981
982 if (empty($hidetop)) {
983 $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
984 }
985 }
986
987 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
997 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
998 {
999 global $langs, $conf, $mysoc;
1000
1001 $ltrdirection = 'L';
1002 if ($outputlangs->trans("DIRECTION") == 'rtl') {
1003 $ltrdirection = 'R';
1004 }
1005
1006 // Load translation files required by the page
1007 $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "sendings", "mrp"));
1008
1009 $default_font_size = pdf_getPDFFontSize($outputlangs);
1010
1011 // Do not add the BACKGROUND as this is for suppliers
1012 //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
1013
1014 //Affiche le filigrane brouillon - Print Draft Watermark
1015 /*if($object->statut==0 && getDolGlobalString('COMMANDE_DRAFT_WATERMARK'))
1016 {
1017 pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',getDolGlobalString('COMMANDE_DRAFT_WATERMARK'));
1018 }*/
1019 //Print content
1020
1021 $pdf->SetTextColor(0, 0, 60);
1022 $pdf->SetFont('', 'B', $default_font_size + 3);
1023
1024 $posx = $this->page_largeur - $this->marge_droite - 100;
1025 $posy = $this->marge_haute;
1026 $w = 100;
1027
1028 $pdf->SetXY($this->marge_gauche, $posy);
1029
1030 // Logo
1031 $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
1032 if ($this->emetteur->logo) {
1033 if (is_readable($logo)) {
1034 $height = pdf_getHeightForLogo($logo);
1035 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1036 } else {
1037 $pdf->SetTextColor(200, 0, 0);
1038 $pdf->SetFont('', 'B', $default_font_size - 2);
1039 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1040 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToModuleSetup"), 0, 'L');
1041 }
1042 } else {
1043 $text = $this->emetteur->name;
1044 $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
1045 }
1046
1047 $pdf->SetFont('', 'B', $default_font_size + 3);
1048 $pdf->SetXY($posx, $posy);
1049 $pdf->SetTextColor(0, 0, 60);
1050 $title = $outputlangs->transnoentities("ManufacturingOrder")." ".$outputlangs->convToOutputCharset($object->ref);
1051 $pdf->MultiCell(100, 3, $title, '', 'R');
1052 $posy += 1;
1053
1054 if ($object->ref_supplier) {
1055 $posy += 4;
1056 $pdf->SetFont('', 'B', $default_font_size);
1057 $pdf->SetXY($posx, $posy);
1058 $pdf->SetTextColor(0, 0, 60);
1059 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefSupplier")." : ".$outputlangs->convToOutputCharset($object->ref_supplier), '', 'R');
1060 $posy += 1;
1061 }
1062
1063 $pdf->SetFont('', '', $default_font_size - 1);
1064 if (getDolGlobalString('PDF_SHOW_PROJECT_TITLE')) {
1065 $object->fetchProject();
1066 if (!empty($object->project->ref)) {
1067 $posy += 3;
1068 $pdf->SetXY($posx, $posy);
1069 $pdf->SetTextColor(0, 0, 60);
1070 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1071 }
1072 }
1073
1074 if (getDolGlobalString('PDF_SHOW_PROJECT')) {
1075 $object->fetchProject();
1076 if (!empty($object->project->ref)) {
1077 $outputlangs->load("projects");
1078 $posy += 4;
1079 $pdf->SetXY($posx, $posy);
1080 $langs->load("projects");
1081 $pdf->SetTextColor(0, 0, 60);
1082 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1083 }
1084 }
1085
1086 if (!empty($object->date_start_planned)) {
1087 $posy += 5;
1088 $pdf->SetXY($posx, $posy);
1089 $pdf->SetTextColor(0, 0, 60);
1090 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("MoDate")." : ".dol_print_date($object->date_start_planned, "day", false, $outputlangs, true), '', 'R');
1091 } else {
1092 $posy += 5;
1093 $pdf->SetXY($posx, $posy);
1094 $pdf->SetTextColor(255, 0, 0);
1095 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ToApprove"), '', 'R');
1096 }
1097
1098 // product info
1099 $prodToMake = new Product($this->db);
1100 $resProdToMake = $prodToMake->fetch($object->fk_product);
1101
1102 if ($resProdToMake > 0) {
1103 // ref
1104 $posy += 7;
1105 $pdf->SetFont('', 'B', $default_font_size + 1);
1106 $pdf->SetXY($posx, $posy);
1107 $pdf->SetTextColor(0, 0, 60);
1108 $pdf->MultiCell($w, 3, $prodToMake->ref, '', 'R');
1109
1110 // description
1111 $posy += 5;
1112 $pdf->SetFont('', 'B', $default_font_size + 3);
1113 $pdf->SetXY($posx, $posy);
1114 $pdf->SetTextColor(0, 0, 60);
1115 $pdf->MultiCell($w, 3, html_entity_decode($prodToMake->description), '', 'R', false, 1, null, null, true, 0, false, true, 51, 'T', true);
1116 $posy = $pdf->GetY() - 5;
1117
1118 // dimensions
1119 $array = array_filter(array($prodToMake->length, $prodToMake->width, $prodToMake->height));
1120 $dim = implode("x", $array);
1121 if (!empty($dim)) {
1122 $posy += 5;
1123 $pdf->SetFont('', 'B', $default_font_size + 3);
1124 $pdf->SetXY($posx, $posy);
1125 $pdf->SetTextColor(0, 0, 60);
1126 $pdf->MultiCell($w, 3, $dim, '', 'R');
1127 }
1128 }
1129
1130 $posy += 5;
1131 $pdf->SetFont('', 'B', $default_font_size + 3);
1132 $pdf->SetXY($posx, $posy);
1133 $pdf->SetTextColor(0, 0, 60);
1134 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("QtyToProduce").": " .$object->qty, '', 'R');
1135
1136
1137 $pdf->SetTextColor(0, 0, 60);
1138 $usehourmin = 'day';
1139 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
1140 $usehourmin = 'dayhour';
1141 }
1142 if (!empty($object->delivery_date)) {
1143 $posy += 4;
1144 $pdf->SetXY($posx - 90, $posy);
1145 $pdf->MultiCell(190, 3, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->delivery_date, $usehourmin, false, $outputlangs, true), '', 'R');
1146 }
1147
1148 if (isset($object->thirdparty->code_fournisseur)) {
1149 $posy += 4;
1150 $pdf->SetXY($posx, $posy);
1151 $pdf->SetTextColor(0, 0, 60);
1152 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("SupplierCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_fournisseur), '', 'R');
1153 }
1154
1155 // Get contact
1156 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1157 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1158 if (count($arrayidcontact) > 0) {
1159 $usertmp = new User($this->db);
1160 $usertmp->fetch($arrayidcontact[0]);
1161 $posy += 4;
1162 $pdf->SetXY($posx, $posy);
1163 $pdf->SetTextColor(0, 0, 60);
1164 $pdf->MultiCell(100, 3, $langs->trans("BuyerName")." : ".$usertmp->getFullName($langs), '', 'R');
1165 }
1166 }
1167
1168 $posy += 1;
1169 $pdf->SetTextColor(0, 0, 60);
1170
1171 $top_shift = 0;
1172 // Show list of linked objects
1173 $current_y = $pdf->getY();
1174 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
1175 if ($current_y < $pdf->getY()) {
1176 $top_shift = $pdf->getY() - $current_y;
1177 }
1178
1179 if ($showaddress) {
1180 // Sender properties
1181 $carac_emetteur = '';
1182 // Add internal contact of object if defined
1183 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1184 if (count($arrayidcontact) > 0) {
1185 $object->fetch_user($arrayidcontact[0]);
1186 $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1187 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname.": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1188 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1189 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1190 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1191 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1192 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1193 $carac_emetteur .= "\n";
1194 }
1195
1196 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1197
1198 // Show sender
1199 $posy = 42 + $top_shift;
1200 $posx = $this->marge_gauche;
1201 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1202 $posx = $this->page_largeur - $this->marge_droite - 80;
1203 }
1204 $hautcadre = 40;
1205
1206 // Show sender frame
1207 $pdf->SetTextColor(0, 0, 0);
1208 $pdf->SetFont('', '', $default_font_size - 2);
1209 $pdf->SetXY($posx, $posy - 5);
1210 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1211 $pdf->SetXY($posx, $posy);
1212 $pdf->SetFillColor(230, 230, 230);
1213 $pdf->RoundedRect($posx, $posy, 82, $hautcadre, $this->corner_radius, '1234', 'F');
1214 $pdf->SetTextColor(0, 0, 60);
1215
1216 // Show sender name
1217 $pdf->SetXY($posx + 2, $posy + 3);
1218 $pdf->SetFont('', 'B', $default_font_size);
1219 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1220 $posy = $pdf->getY();
1221
1222 // Show sender information
1223 $pdf->SetXY($posx + 2, $posy);
1224 $pdf->SetFont('', '', $default_font_size - 1);
1225 $pdf->MultiCell(80, 4, $carac_emetteur, 0, $ltrdirection);
1226
1227
1228
1229 // 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'
1230 $usecontact = false;
1231 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1232 if (count($arrayidcontact) > 0) {
1233 $usecontact = true;
1234 $result = $object->fetch_contact($arrayidcontact[0]);
1235 }
1236
1237 // Recipient name
1238 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')))) {
1239 $thirdparty = $object->contact;
1240 } else {
1241 $thirdparty = $object->thirdparty;
1242 }
1243
1244 //$carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1245
1246 //$carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object);
1247
1248 // Show recipient
1249 //$widthrecbox = 100;
1250 //if ($this->page_largeur < 210) {
1251 // $widthrecbox = 84; // To work with US executive format
1252 //}
1253 //$posy = 42 + $top_shift;
1254 //$posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1255 //if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1256 // $posx = $this->marge_gauche;
1257 //}
1258 //
1260 //$pdf->SetTextColor(0, 0, 0);
1261 //$pdf->SetFont('', '', $default_font_size - 2);
1262 //$pdf->SetXY($posx + 2, $posy - 5);
1263 //$pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1264 //$pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
1265 //
1267 //$pdf->SetXY($posx + 2, $posy + 3);
1268 //$pdf->SetFont('', 'B', $default_font_size);
1269 //$pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, $ltrdirection);
1270 //
1271 //$posy = $pdf->getY();
1272 //
1274 //$pdf->SetFont('', '', $default_font_size - 1);
1275 //$pdf->SetXY($posx + 2, $posy);
1276 //$pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1277 }
1278
1279 return $top_shift;
1280 }
1281
1282 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1292 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1293 {
1294 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1295 return pdf_pagefoot($pdf, $outputlangs, 'SUPPLIER_ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1296 }
1297
1298
1309 public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1310 {
1311 global $conf, $hookmanager;
1312
1313 // Default field style for content
1314 $this->defaultContentsFieldsStyle = array(
1315 'align' => 'R', // R,C,L
1316 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1317 );
1318
1319 // Default field style for content
1320 $this->defaultTitlesFieldsStyle = array(
1321 'align' => 'C', // R,C,L
1322 'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1323 );
1324
1325 /*
1326 * For example
1327 $this->cols['theColKey'] = array(
1328 'rank' => $rank, // int : use for ordering columns
1329 'width' => 20, // the column width in mm
1330 'title' => array(
1331 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1332 'label' => ' ', // the final label : used fore final generated text
1333 'align' => 'L', // text alignment : R,C,L
1334 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1335 ),
1336 'content' => array(
1337 'align' => 'L', // text alignment : R,C,L
1338 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1339 ),
1340 );
1341 */
1342 $rank = 0;
1343 $this->cols['code'] = array(
1344 'rank' => $rank,
1345 'status' => true,
1346 'width' => 35, // in mm
1347 'title' => array(
1348 'textkey' => 'Ref',
1349 'align' => 'L',
1350 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1351 ),
1352 'border-left' => true, // add left line separator
1353 'content' => array(
1354 'align' => 'L',
1355 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1356 ),
1357 );
1358
1359 $rank = 1; // do not use negative rank
1360 $this->cols['desc'] = array(
1361 'rank' => $rank,
1362 'width' => false, // only for desc
1363 'status' => true,
1364 'title' => array(
1365 'textkey' => 'Designation', // use lang key is useful in somme case with module
1366 'align' => 'L',
1367 // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1368 // 'label' => ' ', // the final label
1369 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1370 ),
1371 'border-left' => true,
1372 'content' => array(
1373 'align' => 'L',
1374 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1375 ),
1376 );
1377
1378 $rank += 10;
1379 $this->cols['dim'] = array(
1380 'rank' => $rank,
1381 'status' => true,
1382 'width' => 25, // in mm
1383 'title' => array(
1384 'textkey' => 'Dimensions'
1385 ),
1386 'border-left' => true, // add left line separator
1387 );
1388
1389 $rank += 10;
1390 $this->cols['qty'] = array(
1391 'rank' => $rank,
1392 'width' => 16, // in mm
1393 'status' => true,
1394 'title' => array(
1395 'textkey' => 'Qty'
1396 ),
1397 'border-left' => true, // add left line separator
1398 );
1399
1400 $rank += 10;
1401 $this->cols['qtytot'] = array(
1402 'rank' => $rank,
1403 'width' => 25, // in mm
1404 'status' => true,
1405 'title' => array(
1406 'textkey' => 'QtyTot'
1407 ),
1408 'border-left' => true, // add left line separator
1409 );
1410
1411 // Add extrafields cols
1412 if (!empty($object->lines)) {
1413 $line = reset($object->lines);
1414 $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
1415 }
1416
1417 $parameters = array(
1418 'object' => $object,
1419 'outputlangs' => $outputlangs,
1420 'hidedetails' => $hidedetails,
1421 'hidedesc' => $hidedesc,
1422 'hideref' => $hideref
1423 );
1424
1425 $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
1426 if ($reshook < 0) {
1427 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1428 } elseif (empty($reshook)) {
1429 // @phan-suppress-next-line PhanPluginSuspiciousParamOrderInternal
1430 $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
1431 } else {
1432 $this->cols = $hookmanager->resArray;
1433 }
1434 }
1435}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
Class for BOM.
Definition bom.class.php:42
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
printRoundedRect($pdf, $x, $y, $w, $h, $r, $hidetop=0, $hidebottom=0, $style='D')
Print a rounded rectangle on the 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.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!function_exists( 'dolEscapeXML')) convertBackOfficeMediasLinksToPublicLinks($notetoshow)
Convert links to local wrapper to medias files into a string into a public external URL readable on i...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted 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 '.
getCallerInfoString()
Get caller info as a string that can be appended to a log message.
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.
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
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...
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...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
pdf_getFormat($outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:87
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:289
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:1047
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1425
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 formatted for output on PDF documents.
Definition pdf.lib.php:439
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:778
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:129
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:158
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:161