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