dolibarr 21.0.0-alpha
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-2024 Frédéric France <frederic.france@free.fr>
9 * Copyright (C) 2024 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(1, 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 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("ManufacturingOrder")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
247 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
248 $pdf->SetCompression(false);
249 }
250
251 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
252 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
253
254 // Does we have at least one line with discount $this->atleastonediscount
255
256 // New page
257 $pdf->AddPage();
258 if (!empty($tplidx)) {
259 $pdf->useTemplate($tplidx);
260 }
261 $pagenb++;
262 $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
263 $pdf->SetFont('', '', $default_font_size - 1);
264 $pdf->MultiCell(0, 3, ''); // Set interline to 3
265 $pdf->SetTextColor(0, 0, 0);
266
267 $tab_top = 90 + $top_shift;
268 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
269
270 $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
271
272
273 // Affiche notes
274 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
275
276 // Extrafields in note
277 $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
278 if (!empty($extranote)) {
279 $notetoshow = dol_concatdesc($notetoshow, $extranote);
280 }
281
282 $pagenb = $pdf->getPage();
283 if ($notetoshow) {
284 $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
285 $pageposbeforenote = $pagenb;
286
287 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
288 complete_substitutions_array($substitutionarray, $outputlangs, $object);
289 $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
290 $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
291
292 $tab_top -= 2;
293
294 $pdf->startTransaction();
295
296 $pdf->SetFont('', '', $default_font_size - 1);
297 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
298 // Description
299 $pageposafternote = $pdf->getPage();
300 $posyafter = $pdf->GetY();
301
302 if ($pageposafternote > $pageposbeforenote) {
303 $pdf->rollbackTransaction(true);
304
305 // prepar pages to receive notes
306 while ($pagenb < $pageposafternote) {
307 $pdf->AddPage();
308 $pagenb++;
309 if (!empty($tplidx)) {
310 $pdf->useTemplate($tplidx);
311 }
312 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
313 $this->_pagehead($pdf, $object, 0, $outputlangs);
314 }
315 // $this->_pagefoot($pdf,$object,$outputlangs,1);
316 $pdf->setTopMargin($tab_top_newpage);
317 // The only function to edit the bottom margin of current page to set it.
318 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
319 }
320
321 // back to start
322 $pdf->setPage($pageposbeforenote);
323 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
324 $pdf->SetFont('', '', $default_font_size - 1);
325 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
326 $pageposafternote = $pdf->getPage();
327
328 $posyafter = $pdf->GetY();
329
330 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text
331 $pdf->AddPage('', '', true);
332 $pagenb++;
333 $pageposafternote++;
334 $pdf->setPage($pageposafternote);
335 $pdf->setTopMargin($tab_top_newpage);
336 // The only function to edit the bottom margin of current page to set it.
337 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
338 //$posyafter = $tab_top_newpage;
339 }
340
341
342 // apply note frame to previous pages
343 $i = $pageposbeforenote;
344 while ($i < $pageposafternote) {
345 $pdf->setPage($i);
346
347 $pdf->SetDrawColor(128, 128, 128);
348 // Draw note frame
349 if ($i > $pageposbeforenote) {
350 $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
351 $pdf->RoundedRect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
352 } else {
353 $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
354 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
355 }
356
357 // Add footer
358 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
359 $this->_pagefoot($pdf, $object, $outputlangs, 1);
360
361 $i++;
362 }
363
364 // apply note frame to last page
365 $pdf->setPage($pageposafternote);
366 if (!empty($tplidx)) {
367 $pdf->useTemplate($tplidx);
368 }
369 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
370 $this->_pagehead($pdf, $object, 0, $outputlangs);
371 }
372 $height_note = $posyafter - $tab_top_newpage;
373 $pdf->RoundedRect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
374 } else {
375 // No pagebreak
376 $pdf->commitTransaction();
377 $posyafter = $pdf->GetY();
378 $height_note = $posyafter - $tab_top;
379 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
380
381
382 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
383 // not enough space, need to add page
384 $pdf->AddPage('', '', true);
385 $pagenb++;
386 $pageposafternote++;
387 $pdf->setPage($pageposafternote);
388 if (!empty($tplidx)) {
389 $pdf->useTemplate($tplidx);
390 }
391 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
392 $this->_pagehead($pdf, $object, 0, $outputlangs);
393 }
394
395 $posyafter = $tab_top_newpage;
396 }
397 }
398
399 $tab_height -= $height_note;
400 $tab_top = $posyafter + 6;
401 } else {
402 $height_note = 0;
403 }
404
405 $nexY = $tab_top + 5;
406
407 // Use new auto column system
408 $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
409
410 // Loop on each lines
411 $pageposbeforeprintlines = $pdf->getPage();
412 $pagenb = $pageposbeforeprintlines;
413
414 $bom = new BOM($this->db);
415 $bom -> fetch($object->fk_bom);
416
417 $nblines = count($bom->lines);
418
419 for ($i = 0; $i < $nblines; $i++) {
420 $curY = $nexY;
421 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
422 $pdf->SetTextColor(0, 0, 0);
423
424 $prod = new Product($this->db);
425 $prod->fetch($bom->lines[$i]->fk_product);
426
427 $pdf->setTopMargin($tab_top_newpage);
428 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
429 $pageposbefore = $pdf->getPage();
430
431 $showpricebeforepagebreak = 1;
432 $posYAfterImage = 0;
433 $posYAfterDescription = 0;
434
435 // Description of product line
436 $curX = $this->posxdesc - 1;
437 $showpricebeforepagebreak = 1;
438
439 if ($this->getColumnStatus('code')) {
440 $pdf->startTransaction(); //description
441 //$this->printColDescContent($pdf, $curY, 'code', $object, $i, $outputlangs, $hideref, $hidedesc, $showsupplierSKU);
442 $this->printStdColumnContent($pdf, $curY, 'code', $prod->ref);
443
444 $pageposafter = $pdf->getPage();
445 $posyafter = $pdf->GetY();
446 if ($pageposafter > $pageposbefore) { // There is a pagebreak
447 $pdf->rollbackTransaction(true);
448
449 //$this->printColDescContent($pdf, $curY, 'code', $object, $i, $outputlangs, $hideref, $hidedesc, $showsupplierSKU);
450 $this->printStdColumnContent($pdf, $curY, 'code', $prod->ref);
451
452 $pageposafter = $pdf->getPage();
453 $posyafter = $pdf->GetY();
454 } elseif ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
455 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
456 $pdf->AddPage('', '', true);
457 if (!empty($tplidx)) {
458 $pdf->useTemplate($tplidx);
459 }
460 //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
461 $pdf->setPage($pageposafter + 1);
462 } else {
463 // We found a page break
464 // Allows data in the first page if description is long enough to break in multiples pages
465 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
466 $showpricebeforepagebreak = 1;
467 } else {
468 $showpricebeforepagebreak = 0;
469 }
470 }
471 } else { // No pagebreak
472 $pdf->commitTransaction();
473 }
474 $posYAfterDescription = $pdf->GetY();
475 }
476
477 $nexY = $pdf->GetY();
478 $pageposafter = $pdf->getPage();
479 $pdf->setPage($pageposbefore);
480 $pdf->setTopMargin($this->marge_haute);
481 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
482
483 // We suppose that a too long description is moved completely on next page
484 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
485 $pdf->setPage($pageposafter);
486 $curY = $tab_top_newpage;
487 }
488
489 if ($this->getColumnStatus('desc')) {
490 $pdf->startTransaction(); //description
491 $des = $prod -> description;
492 $descr = $des;//implode("<br>", $des);
493
494 $this->printStdColumnContent($pdf, $curY, 'desc', $descr);
495
496 $pageposafter = $pdf->getPage();
497 $posyafter = $pdf->GetY();
498 if ($pageposafter > $pageposbefore) { // There is a pagebreak
499 $pdf->rollbackTransaction(true);
500
501 $this->printStdColumnContent($pdf, $curY, 'desc', $descr);
502
503 $pageposafter = $pdf->getPage();
504 $posyafter = $pdf->GetY();
505 } elseif ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
506 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
507 $pdf->AddPage('', '', true);
508 if (!empty($tplidx)) {
509 $pdf->useTemplate($tplidx);
510 }
511 //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
512 $pdf->setPage($pageposafter + 1);
513 } else {
514 // We found a page break
515 // Allows data in the first page if description is long enough to break in multiples pages
516 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
517 $showpricebeforepagebreak = 1;
518 } else {
519 $showpricebeforepagebreak = 0;
520 }
521 }
522 } else { // No pagebreak
523 $pdf->commitTransaction();
524 }
525 $posYAfterDescription = max($posYAfterDescription, $pdf->GetY());
526 }
527
528 $nexY = max($nexY, $pdf->GetY());
529 $pageposafter = $pdf->getPage();
530 $pdf->setPage($pageposbefore);
531 $pdf->setTopMargin($this->marge_haute);
532 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
533
534 // We suppose that a too long description is moved completely on next page
535 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
536 $pdf->setPage($pageposafter);
537 $curY = $tab_top_newpage;
538 }
539
540 $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par default
541
542 // Quantity
543 // Enough for 6 chars
544 if ($this->getColumnStatus('qty')) {
545 $qty = $bom->lines[$i]->qty;
546 $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
547 $nexY = max($pdf->GetY(), $nexY);
548 }
549
550 // Quantity
551 // Enough for 6 chars
552 if ($this->getColumnStatus('qtytot')) {
553 $qtytot = $object->qty * $bom->lines[$i]->qty;
554 $this->printStdColumnContent($pdf, $curY, 'qtytot', $qtytot);
555 $nexY = max($pdf->GetY(), $nexY);
556 }
557
558 // Dimensions
559 if ($this->getColumnStatus('dim')) {
560 $array = array_filter(array($prod->length, $prod->width, $prod->height));
561 $dim = implode("x", $array);
562 $this->printStdColumnContent($pdf, $curY, 'dim', $dim);
563 $nexY = max($pdf->GetY(), $nexY);
564 }
565 }
566
567
568 // Show square
569 if ($pagenb == $pageposbeforeprintlines) {
570 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
571 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
572 } else {
573 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
574 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
575 }
576
577 // Affiche zone infos
578 $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
579
580 // Affiche zone totaux
581 //$posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
582
583 // Affiche zone versements
584 if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) {
585 $posy = $this->_tableau_versements($pdf, $object, $posy, $outputlangs);
586 }
587
588 // Pied de page
589 $this->_pagefoot($pdf, $object, $outputlangs);
590 if (method_exists($pdf, 'AliasNbPages')) {
591 $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod
592 }
593
594 $pdf->Close();
595
596 $pdf->Output($file, 'F');
597
598 // Add pdfgeneration hook
599 $hookmanager->initHooks(array('pdfgeneration'));
600 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
601 global $action;
602 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
603 if ($reshook < 0) {
604 $this->error = $hookmanager->error;
605 $this->errors = $hookmanager->errors;
606 }
607
608 dolChmod($file);
609
610 $this->result = array('fullpath' => $file);
611
612 return 1; // No error
613 } else {
614 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
615 return 0;
616 }
617 } else {
618 $this->error = $langs->trans("ErrorConstantNotDefined", "SUPPLIER_OUTPUTDIR");
619 return 0;
620 }
621 }
622
623 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
624 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
634 protected function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
635 {
636 // phpcs:enable
637 return 1;
638 }
639
640 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
641 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
651 protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
652 {
653 // phpcs:enable
654 global $conf, $mysoc;
655 $default_font_size = pdf_getPDFFontSize($outputlangs);
656
657 // If France, show VAT mention if not applicable
658 if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
659 $pdf->SetFont('', 'B', $default_font_size - 2);
660 $pdf->SetXY($this->marge_gauche, $posy);
661 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
662
663 $posy = $pdf->GetY() + 4;
664 }
665
666 $posxval = 52;
667
668 // Show payments conditions
669 if (!empty($object->cond_reglement_code) || $object->cond_reglement) {
670 $pdf->SetFont('', 'B', $default_font_size - 2);
671 $pdf->SetXY($this->marge_gauche, $posy);
672 $titre = $outputlangs->transnoentities("PaymentConditions").':';
673 $pdf->MultiCell(80, 4, $titre, 0, 'L');
674
675 $pdf->SetFont('', '', $default_font_size - 2);
676 $pdf->SetXY($posxval, $posy);
677 $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);
678 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
679 $pdf->MultiCell(80, 4, $lib_condition_paiement, 0, 'L');
680
681 $posy = $pdf->GetY() + 3;
682 }
683
684 // Show payment mode
685 if (!empty($object->mode_reglement_code)) {
686 $pdf->SetFont('', 'B', $default_font_size - 2);
687 $pdf->SetXY($this->marge_gauche, $posy);
688 $titre = $outputlangs->transnoentities("PaymentMode").':';
689 $pdf->MultiCell(80, 5, $titre, 0, 'L');
690
691 $pdf->SetFont('', '', $default_font_size - 2);
692 $pdf->SetXY($posxval, $posy);
693 $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);
694 $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
695
696 $posy = $pdf->GetY() + 2;
697 }
698
699
700 return $posy;
701 }
702
703 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
704 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
715 protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
716 {
717 // phpcs:enable
718 global $conf, $mysoc;
719
720 $default_font_size = pdf_getPDFFontSize($outputlangs);
721
722 $tab2_top = $posy;
723 $tab2_hl = 4;
724 $pdf->SetFont('', '', $default_font_size - 1);
725
726 // Tableau total
727 $col1x = 120;
728 $col2x = 170;
729 if ($this->page_largeur < 210) { // To work with US executive format
730 $col2x -= 20;
731 }
732 $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
733
734 $useborder = 0;
735 $index = 0;
736
737 // Total HT
738 $pdf->SetFillColor(255, 255, 255);
739 $pdf->SetXY($col1x, $tab2_top);
740 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
741
742 $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
743 $pdf->SetXY($col2x, $tab2_top);
744 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, 'R', 1);
745
746 // Show VAT by rates and total
747 $pdf->SetFillColor(248, 248, 248);
748
749 $this->atleastoneratenotnull = 0;
750 foreach ($this->tva as $tvakey => $tvaval) {
751 if ($tvakey > 0) { // On affiche pas taux 0
752 $this->atleastoneratenotnull++;
753
754 $index++;
755 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
756
757 $tvacompl = '';
758
759 if (preg_match('/\*/', $tvakey)) {
760 $tvakey = str_replace('*', '', $tvakey);
761 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
762 }
763
764 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).' ';
765 $totalvat .= vatrate($tvakey, 1).$tvacompl;
766 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
767
768 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
769 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
770 }
771 }
772 if (!$this->atleastoneratenotnull) { // If no vat at all
773 $index++;
774 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
775 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code), 0, 'L', 1);
776
777 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
778 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_tva), 0, 'R', 1);
779
780 // Total LocalTax1
781 if (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on' && $object->total_localtax1 > 0) {
782 $index++;
783 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
784 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code), 0, 'L', 1);
785 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
786 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax1), $useborder, 'R', 1);
787 }
788
789 // Total LocalTax2
790 if (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on' && $object->total_localtax2 > 0) {
791 $index++;
792 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
793 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code), 0, 'L', 1);
794 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
795 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax2), $useborder, 'R', 1);
796 }
797 } else {
798 //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
799 //{
800 //Local tax 1
801 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
802 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
803 continue;
804 }
805
806 foreach ($localtax_rate as $tvakey => $tvaval) {
807 if ($tvakey != 0) { // On affiche pas taux 0
808 //$this->atleastoneratenotnull++;
809
810 $index++;
811 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
812
813 $tvacompl = '';
814 if (preg_match('/\*/', $tvakey)) {
815 $tvakey = str_replace('*', '', $tvakey);
816 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
817 }
818 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
819 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
820 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
821
822 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
823 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
824 }
825 }
826 }
827
828 //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
829 //{
830 //Local tax 2
831 foreach ($this->localtax2 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("TotalLT2", $mysoc->country_code).' ';
849 $totalvat .= vatrate((string) abs((float) $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, 'R', 1);
854 }
855 }
856 }
857 }
858
859 // Total TTC
860 $index++;
861 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
862 $pdf->SetTextColor(0, 0, 60);
863 $pdf->SetFillColor(224, 224, 224);
864 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
865
866 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
867 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
868 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc), $useborder, 'R', 1);
869 $pdf->SetFont('', '', $default_font_size - 1);
870 $pdf->SetTextColor(0, 0, 0);
871
872 $creditnoteamount = 0;
873 $depositsamount = 0;
874 //$creditnoteamount=$object->getSumCreditNotesUsed();
875 //$depositsamount=$object->getSumDepositsUsed();
876 //print "x".$creditnoteamount."-".$depositsamount;exit;
877 $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
878 if (!empty($object->paye)) {
879 $resteapayer = 0;
880 }
881
882 if ($deja_regle > 0) {
883 // Already paid + Deposits
884 $index++;
885
886 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
887 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
888 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
889 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle), 0, 'R', 0);
890
891 $index++;
892 $pdf->SetTextColor(0, 0, 60);
893 $pdf->SetFillColor(224, 224, 224);
894 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
895 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
896
897 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
898 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer), $useborder, 'R', 1);
899
900 $pdf->SetFont('', '', $default_font_size - 1);
901 $pdf->SetTextColor(0, 0, 0);
902 }
903
904 $index++;
905 return ($tab2_top + ($tab2_hl * $index));
906 }
907
908 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
922 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
923 {
924 global $conf;
925
926 // Force to disable hidetop and hidebottom
927 $hidebottom = 0;
928 if ($hidetop) {
929 $hidetop = -1;
930 }
931
932 $currency = !empty($currency) ? $currency : $conf->currency;
933 $default_font_size = pdf_getPDFFontSize($outputlangs);
934
935 // Amount in (at tab_top - 1)
936 $pdf->SetTextColor(0, 0, 0);
937 $pdf->SetFont('', '', $default_font_size - 2);
938
939 if (empty($hidetop)) {
940 // $title = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
941 $title = '';
942 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($title) + 3), $tab_top - 4);
943 $pdf->MultiCell(($pdf->GetStringWidth($title) + 3), 2, $title);
944
945 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
946 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
947 $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')));
948 }
949 }
950
951 $pdf->SetDrawColor(128, 128, 128);
952 $pdf->SetFont('', '', $default_font_size - 1);
953
954 // Output Rect
955 $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
956
957 foreach ($this->cols as $colKey => $colDef) {
958 if (!$this->getColumnStatus($colKey)) {
959 continue;
960 }
961
962 // get title label
963 $colDef['title']['label'] = !empty($colDef['title']['label']) ? $colDef['title']['label'] : $outputlangs->transnoentities($colDef['title']['textkey']);
964
965 // Add column separator
966 if (!empty($colDef['border-left'])) {
967 $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
968 }
969
970 if (empty($hidetop) && array_key_exists('title', $colDef) && array_key_exists('width', $colDef)) {
971 $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0]);
972
973 $textWidth = $colDef['width'] - $colDef['title']['padding'][3] - $colDef['title']['padding'][1];
974 $pdf->MultiCell($textWidth, 2, $colDef['title']['label'], '', $colDef['title']['align']);
975 }
976 }
977
978 if (empty($hidetop)) {
979 $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
980 }
981 }
982
983 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
993 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
994 {
995 global $langs, $conf, $mysoc;
996
997 $ltrdirection = 'L';
998 if ($outputlangs->trans("DIRECTION") == 'rtl') {
999 $ltrdirection = 'R';
1000 }
1001
1002 // Load translation files required by the page
1003 $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "sendings", "mrp"));
1004
1005 $default_font_size = pdf_getPDFFontSize($outputlangs);
1006
1007 // Do not add the BACKGROUND as this is for suppliers
1008 //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
1009
1010 //Affiche le filigrane brouillon - Print Draft Watermark
1011 /*if($object->statut==0 && getDolGlobalString('COMMANDE_DRAFT_WATERMARK'))
1012 {
1013 pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',getDolGlobalString('COMMANDE_DRAFT_WATERMARK'));
1014 }*/
1015 //Print content
1016
1017 $pdf->SetTextColor(0, 0, 60);
1018 $pdf->SetFont('', 'B', $default_font_size + 3);
1019
1020 $posx = $this->page_largeur - $this->marge_droite - 100;
1021 $posy = $this->marge_haute;
1022 $w = 100;
1023
1024 $pdf->SetXY($this->marge_gauche, $posy);
1025
1026 // Logo
1027 $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
1028 if ($this->emetteur->logo) {
1029 if (is_readable($logo)) {
1030 $height = pdf_getHeightForLogo($logo);
1031 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1032 } else {
1033 $pdf->SetTextColor(200, 0, 0);
1034 $pdf->SetFont('', 'B', $default_font_size - 2);
1035 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1036 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToModuleSetup"), 0, 'L');
1037 }
1038 } else {
1039 $text = $this->emetteur->name;
1040 $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
1041 }
1042
1043 $pdf->SetFont('', 'B', $default_font_size + 3);
1044 $pdf->SetXY($posx, $posy);
1045 $pdf->SetTextColor(0, 0, 60);
1046 $title = $outputlangs->transnoentities("ManufacturingOrder")." ".$outputlangs->convToOutputCharset($object->ref);
1047 $pdf->MultiCell(100, 3, $title, '', 'R');
1048 $posy += 1;
1049
1050 if ($object->ref_supplier) {
1051 $posy += 4;
1052 $pdf->SetFont('', 'B', $default_font_size);
1053 $pdf->SetXY($posx, $posy);
1054 $pdf->SetTextColor(0, 0, 60);
1055 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefSupplier")." : ".$outputlangs->convToOutputCharset($object->ref_supplier), '', 'R');
1056 $posy += 1;
1057 }
1058
1059 $pdf->SetFont('', '', $default_font_size - 1);
1060 if (getDolGlobalString('PDF_SHOW_PROJECT_TITLE')) {
1061 $object->fetchProject();
1062 if (!empty($object->project->ref)) {
1063 $posy += 3;
1064 $pdf->SetXY($posx, $posy);
1065 $pdf->SetTextColor(0, 0, 60);
1066 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1067 }
1068 }
1069
1070 if (getDolGlobalString('PDF_SHOW_PROJECT')) {
1071 $object->fetchProject();
1072 if (!empty($object->project->ref)) {
1073 $outputlangs->load("projects");
1074 $posy += 4;
1075 $pdf->SetXY($posx, $posy);
1076 $langs->load("projects");
1077 $pdf->SetTextColor(0, 0, 60);
1078 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1079 }
1080 }
1081
1082 if (!empty($object->date_start_planned)) {
1083 $posy += 5;
1084 $pdf->SetXY($posx, $posy);
1085 $pdf->SetTextColor(0, 0, 60);
1086 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("MoDate")." : ".dol_print_date($object->date_start_planned, "day", false, $outputlangs, true), '', 'R');
1087 } else {
1088 $posy += 5;
1089 $pdf->SetXY($posx, $posy);
1090 $pdf->SetTextColor(255, 0, 0);
1091 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ToApprove"), '', 'R');
1092 }
1093
1094 // product info
1095 $prodToMake = new Product($this->db);
1096 $resProdToMake = $prodToMake->fetch($object->fk_product);
1097
1098 if ($resProdToMake > 0) {
1099 // ref
1100 $posy += 7;
1101 $pdf->SetFont('', 'B', $default_font_size + 1);
1102 $pdf->SetXY($posx, $posy);
1103 $pdf->SetTextColor(0, 0, 60);
1104 $pdf->MultiCell($w, 3, $prodToMake->ref, '', 'R');
1105
1106 // description
1107 $posy += 5;
1108 $pdf->SetFont('', 'B', $default_font_size + 3);
1109 $pdf->SetXY($posx, $posy);
1110 $pdf->SetTextColor(0, 0, 60);
1111 $pdf->MultiCell($w, 3, html_entity_decode($prodToMake->description), '', 'R', false, 1, '', '', true, 0, false, true, 51, 'T', true);
1112 $posy = $pdf->GetY() - 5;
1113
1114 // dimensions
1115 $array = array_filter(array($prodToMake->length, $prodToMake->width, $prodToMake->height));
1116 $dim = implode("x", $array);
1117 if (!empty($dim)) {
1118 $posy += 5;
1119 $pdf->SetFont('', 'B', $default_font_size + 3);
1120 $pdf->SetXY($posx, $posy);
1121 $pdf->SetTextColor(0, 0, 60);
1122 $pdf->MultiCell($w, 3, $dim, '', 'R');
1123 }
1124 }
1125
1126 $posy += 5;
1127 $pdf->SetFont('', 'B', $default_font_size + 3);
1128 $pdf->SetXY($posx, $posy);
1129 $pdf->SetTextColor(0, 0, 60);
1130 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("QtyToProduce").": " .$object->qty, '', 'R');
1131
1132
1133 $pdf->SetTextColor(0, 0, 60);
1134 $usehourmin = 'day';
1135 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
1136 $usehourmin = 'dayhour';
1137 }
1138 if (!empty($object->delivery_date)) {
1139 $posy += 4;
1140 $pdf->SetXY($posx - 90, $posy);
1141 $pdf->MultiCell(190, 3, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->delivery_date, $usehourmin, false, $outputlangs, true), '', 'R');
1142 }
1143
1144 if ($object->thirdparty->code_fournisseur) {
1145 $posy += 4;
1146 $pdf->SetXY($posx, $posy);
1147 $pdf->SetTextColor(0, 0, 60);
1148 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("SupplierCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_fournisseur), '', 'R');
1149 }
1150
1151 // Get contact
1152 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1153 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1154 if (count($arrayidcontact) > 0) {
1155 $usertmp = new User($this->db);
1156 $usertmp->fetch($arrayidcontact[0]);
1157 $posy += 4;
1158 $pdf->SetXY($posx, $posy);
1159 $pdf->SetTextColor(0, 0, 60);
1160 $pdf->MultiCell(100, 3, $langs->trans("BuyerName")." : ".$usertmp->getFullName($langs), '', 'R');
1161 }
1162 }
1163
1164 $posy += 1;
1165 $pdf->SetTextColor(0, 0, 60);
1166
1167 $top_shift = 0;
1168 // Show list of linked objects
1169 $current_y = $pdf->getY();
1170 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
1171 if ($current_y < $pdf->getY()) {
1172 $top_shift = $pdf->getY() - $current_y;
1173 }
1174
1175 if ($showaddress) {
1176 // Sender properties
1177 $carac_emetteur = '';
1178 // Add internal contact of object if defined
1179 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1180 if (count($arrayidcontact) > 0) {
1181 $object->fetch_user($arrayidcontact[0]);
1182 $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1183 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname.": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1184 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1185 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1186 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1187 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1188 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1189 $carac_emetteur .= "\n";
1190 }
1191
1192 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1193
1194 // Show sender
1195 $posy = 42 + $top_shift;
1196 $posx = $this->marge_gauche;
1197 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1198 $posx = $this->page_largeur - $this->marge_droite - 80;
1199 }
1200 $hautcadre = 40;
1201
1202 // Show sender frame
1203 $pdf->SetTextColor(0, 0, 0);
1204 $pdf->SetFont('', '', $default_font_size - 2);
1205 $pdf->SetXY($posx, $posy - 5);
1206 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1207 $pdf->SetXY($posx, $posy);
1208 $pdf->SetFillColor(230, 230, 230);
1209 $pdf->RoundedRect($posx, $posy, 82, $hautcadre, $this->corner_radius, '1234', 'F');
1210 $pdf->SetTextColor(0, 0, 60);
1211
1212 // Show sender name
1213 $pdf->SetXY($posx + 2, $posy + 3);
1214 $pdf->SetFont('', 'B', $default_font_size);
1215 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1216 $posy = $pdf->getY();
1217
1218 // Show sender information
1219 $pdf->SetXY($posx + 2, $posy);
1220 $pdf->SetFont('', '', $default_font_size - 1);
1221 $pdf->MultiCell(80, 4, $carac_emetteur, 0, $ltrdirection);
1222
1223
1224
1225 // 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'
1226 $usecontact = false;
1227 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1228 if (count($arrayidcontact) > 0) {
1229 $usecontact = true;
1230 $result = $object->fetch_contact($arrayidcontact[0]);
1231 }
1232
1233 // Recipient name
1234 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')))) {
1235 $thirdparty = $object->contact;
1236 } else {
1237 $thirdparty = $object->thirdparty;
1238 }
1239
1240 //$carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1241
1242 //$carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object);
1243
1244 // Show recipient
1245 //$widthrecbox = 100;
1246 //if ($this->page_largeur < 210) {
1247 // $widthrecbox = 84; // To work with US executive format
1248 //}
1249 //$posy = 42 + $top_shift;
1250 //$posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1251 //if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
1252 // $posx = $this->marge_gauche;
1253 //}
1254 //
1256 //$pdf->SetTextColor(0, 0, 0);
1257 //$pdf->SetFont('', '', $default_font_size - 2);
1258 //$pdf->SetXY($posx + 2, $posy - 5);
1259 //$pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1260 //$pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
1261 //
1263 //$pdf->SetXY($posx + 2, $posy + 3);
1264 //$pdf->SetFont('', 'B', $default_font_size);
1265 //$pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, $ltrdirection);
1266 //
1267 //$posy = $pdf->getY();
1268 //
1270 //$pdf->SetFont('', '', $default_font_size - 1);
1271 //$pdf->SetXY($posx + 2, $posy);
1272 //$pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1273 }
1274
1275 return $top_shift;
1276 }
1277
1278 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1288 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1289 {
1290 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1291 return pdf_pagefoot($pdf, $outputlangs, 'SUPPLIER_ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1292 }
1293
1294
1305 public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1306 {
1307 global $conf, $hookmanager;
1308
1309 // Default field style for content
1310 $this->defaultContentsFieldsStyle = array(
1311 'align' => 'R', // R,C,L
1312 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1313 );
1314
1315 // Default field style for content
1316 $this->defaultTitlesFieldsStyle = array(
1317 'align' => 'C', // R,C,L
1318 'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1319 );
1320
1321 /*
1322 * For example
1323 $this->cols['theColKey'] = array(
1324 'rank' => $rank, // int : use for ordering columns
1325 'width' => 20, // the column width in mm
1326 'title' => array(
1327 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1328 'label' => ' ', // the final label : used fore final generated text
1329 'align' => 'L', // text alignment : R,C,L
1330 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1331 ),
1332 'content' => array(
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 );
1337 */
1338 $rank = 0;
1339 $this->cols['code'] = array(
1340 'rank' => $rank,
1341 'status' => true,
1342 'width' => 35, // in mm
1343 'title' => array(
1344 'textkey' => 'Ref',
1345 'align' => 'L',
1346 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1347 ),
1348 'border-left' => true, // add left line separator
1349 'content' => array(
1350 'align' => 'L',
1351 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1352 ),
1353 );
1354
1355 $rank = 1; // do not use negative rank
1356 $this->cols['desc'] = array(
1357 'rank' => $rank,
1358 'width' => false, // only for desc
1359 'status' => true,
1360 'title' => array(
1361 'textkey' => 'Designation', // use lang key is useful in somme case with module
1362 'align' => 'L',
1363 // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1364 // 'label' => ' ', // the final label
1365 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1366 ),
1367 'border-left' => true,
1368 'content' => array(
1369 'align' => 'L',
1370 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1371 ),
1372 );
1373
1374 $rank += 10;
1375 $this->cols['dim'] = array(
1376 'rank' => $rank,
1377 'status' => true,
1378 'width' => 25, // in mm
1379 'title' => array(
1380 'textkey' => 'Dimensions'
1381 ),
1382 'border-left' => true, // add left line separator
1383 );
1384
1385 $rank += 10;
1386 $this->cols['qty'] = array(
1387 'rank' => $rank,
1388 'width' => 16, // in mm
1389 'status' => true,
1390 'title' => array(
1391 'textkey' => 'Qty'
1392 ),
1393 'border-left' => true, // add left line separator
1394 );
1395
1396 $rank += 10;
1397 $this->cols['qtytot'] = array(
1398 'rank' => $rank,
1399 'width' => 25, // in mm
1400 'status' => true,
1401 'title' => array(
1402 'textkey' => 'QtyTot'
1403 ),
1404 'border-left' => true, // add left line separator
1405 );
1406
1407 // Add extrafields cols
1408 if (!empty($object->lines)) {
1409 $line = reset($object->lines);
1410 $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
1411 }
1412
1413 $parameters = array(
1414 'object' => $object,
1415 'outputlangs' => $outputlangs,
1416 'hidedetails' => $hidedetails,
1417 'hidedesc' => $hidedesc,
1418 'hideref' => $hideref
1419 );
1420
1421 $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
1422 if ($reshook < 0) {
1423 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1424 } elseif (empty($reshook)) {
1425 // @phan-suppress-next-line PhanPluginSuspiciousParamOrderInternal
1426 $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
1427 } else {
1428 $this->cols = $hookmanager->resArray;
1429 }
1430 }
1431}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
Class for BOM.
Definition bom.class.php:45
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_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 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)
pdf_getFormat($outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:86
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:288
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:313
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:1027
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1405
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:265
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:434
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:765
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:128
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:137
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140