dolibarr 21.0.3
pdf_cornas.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) 2023 William Mead <william.mead@manchenumerique.fr>
10 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
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/supplier_order/modules_commandefournisseur.php';
35require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
36require_once DOL_DOCUMENT_ROOT.'/product/class/product.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/pdf.lib.php';
40
41
46{
50 public $db;
51
55 public $name;
56
60 public $description;
61
65 public $update_main_doc_field;
66
70 public $type;
71
76 public $version = 'dolibarr';
77
78
84 public function __construct($db)
85 {
86 global $conf, $langs, $mysoc;
87
88 // Load translation files required by the page
89 $langs->loadLangs(array("main", "bills"));
90
91 $this->db = $db;
92 $this->name = "cornas";
93 $this->description = $langs->trans('SuppliersCommandModel');
94 $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
95
96 // Dimension page
97 $this->type = 'pdf';
98 $formatarray = pdf_getFormat();
99 $this->page_largeur = $formatarray['width'];
100 $this->page_hauteur = $formatarray['height'];
101 $this->format = array($this->page_largeur, $this->page_hauteur);
102 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
103 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
104 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
105 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
106 $this->corner_radius = getDolGlobalInt('MAIN_PDF_FRAME_CORNER_RADIUS', 0);
107 $this->option_logo = 1; // Display logo
108 $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
109 $this->option_modereg = 1; // Display payment mode
110 $this->option_condreg = 1; // Display payment terms
111 $this->option_multilang = 1; //Available in several languages
112 $this->option_escompte = 0; // Displays if there has been a discount
113 $this->option_credit_note = 0; // Support credit notes
114 $this->option_freetext = 1; // Support add of a personalised text
115 $this->option_draft_watermark = 1; // Support add of a watermark on drafts
116
117 // Define position of columns
118 $this->posxdesc = $this->marge_gauche + 1; // For module retrocompatibility support during PDF transition: TODO remove this at the end
119
120 $this->tabTitleHeight = 5; // default height
121
122 $this->tva = array();
123 $this->tva_array = array();
124 $this->localtax1 = array();
125 $this->localtax2 = array();
126 $this->atleastoneratenotnull = 0;
127 $this->atleastonediscount = 0;
128
129 if ($mysoc === null) {
130 dol_syslog(get_class($this).'::__construct() Global $mysoc should not be null.'. getCallerInfoString(), LOG_ERR);
131 return;
132 }
133
134 // Get source company
135 $this->emetteur = $mysoc;
136 if (empty($this->emetteur->country_code)) {
137 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
138 }
139 }
140
141
142 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
154 public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
155 {
156 // phpcs:enable
157 global $user, $langs, $conf, $hookmanager, $mysoc, $nblines;
158
159 if (!is_object($outputlangs)) {
160 $outputlangs = $langs;
161 }
162 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
163 if (getDolGlobalString('MAIN_USE_FPDF')) {
164 $outputlangs->charset_output = 'ISO-8859-1';
165 }
166
167 // Load translation files required by the page
168 $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "dict", "products"));
169
170 global $outputlangsbis;
171 $outputlangsbis = null;
172 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')) {
173 $outputlangsbis = new Translate('', $conf);
174 $outputlangsbis->setDefaultLang(getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE'));
175 $outputlangsbis->loadLangs(array("main", "orders", "companies", "bills", "dict", "products"));
176 }
177
178 $nblines = count($object->lines);
179
180 $hidetop = 0;
181 if (getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE')) {
182 $hidetop = getDolGlobalString('MAIN_PDF_DISABLE_COL_HEAD_TITLE');
183 }
184
185 // Loop on each lines to detect if there is at least one image to show
186 $realpatharray = array();
187 if (getDolGlobalString('MAIN_GENERATE_SUPPLIER_ORDER_WITH_PICTURE')) {
188 for ($i = 0; $i < $nblines; $i++) {
189 if (empty($object->lines[$i]->fk_product)) {
190 continue;
191 }
192
193 $objphoto = new Product($this->db);
194 $objphoto->fetch($object->lines[$i]->fk_product);
195
196 if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
197 $pdir = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$object->lines[$i]->fk_product."/photos/";
198 $dir = $conf->product->dir_output.'/'.$pdir;
199 } else {
200 $pdir = get_exdir($objphoto->id, 0, 0, 0, $objphoto, 'product');
201 $dir = $conf->product->dir_output.'/'.$pdir;
202 }
203
204 $realpath = '';
205
206 $arephoto = false;
207 foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
208 if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES')) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
209 if ($obj['photo_vignette']) {
210 $filename = $obj['photo_vignette'];
211 } else {
212 $filename = $obj['photo'];
213 }
214 } else {
215 $filename = $obj['photo'];
216 }
217 $realpath = $dir.$filename;
218 $arephoto = true;
219 $this->atleastonephoto = true;
220 break;
221 }
222
223 if ($realpath && $arephoto) {
224 $realpatharray[$i] = $realpath;
225 }
226 }
227 }
228 if (count($realpatharray) == 0) {
229 $this->posxpicture = $this->posxtva;
230 }
231
232 if ($conf->fournisseur->commande->dir_output) {
233 $object->fetch_thirdparty();
234
235 $deja_regle = 0;
236 $amount_credit_notes_included = 0;
237 $amount_deposits_included = 0;
238 //$amount_credit_notes_included = $object->getSumCreditNotesUsed();
239 //$amount_deposits_included = $object->getSumDepositsUsed();
240
241 // Definition of $dir and $file
242 if ($object->specimen) {
243 $dir = $conf->fournisseur->commande->dir_output;
244 $file = $dir."/SPECIMEN.pdf";
245 } else {
246 $objectref = dol_sanitizeFileName($object->ref);
247 $objectrefsupplier = dol_sanitizeFileName($object->ref_supplier);
248 $dir = $conf->fournisseur->commande->dir_output.'/'.$objectref;
249 $file = $dir."/".$objectref.".pdf";
250 if (getDolGlobalString('SUPPLIER_REF_IN_NAME')) {
251 $file = $dir."/".$objectref.($objectrefsupplier ? "_".$objectrefsupplier : "").".pdf";
252 }
253 }
254
255 if (!file_exists($dir)) {
256 if (dol_mkdir($dir) < 0) {
257 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
258 return 0;
259 }
260 }
261
262 if (file_exists($dir)) {
263 // Add pdfgeneration hook
264 if (!is_object($hookmanager)) {
265 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
266 $hookmanager = new HookManager($this->db);
267 }
268 $hookmanager->initHooks(array('pdfgeneration'));
269 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
270 global $action;
271 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
272
273 // Set nblines with the new facture lines content after hook
274 $nblines = is_array($object->lines) ? count($object->lines) : 0;
275
276 $pdf = pdf_getInstance($this->format);
277 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
278 $pdf->SetAutoPageBreak(1, 0);
279
280 $heightforinfotot = 40; // Height reserved to output the info and total part
281 $heightforfreetext = getDolGlobalInt('MAIN_PDF_FREETEXT_HEIGHT', 5); // Height reserved to output the free text on last page
282 $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
283 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
284 $heightforfooter += 6;
285 }
286
287 if (class_exists('TCPDF')) {
288 $pdf->setPrintHeader(false);
289 $pdf->setPrintFooter(false);
290 }
291 $pdf->SetFont(pdf_getPDFFont($outputlangs));
292 // Set path to the background PDF File
293 if (!getDolGlobalString('MAIN_DISABLE_FPDI') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
294 $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
295 $tplidx = $pdf->importPage(1);
296 }
297
298 $pdf->Open();
299 $pagenb = 0;
300 $pdf->SetDrawColor(128, 128, 128);
301
302 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
303 $pdf->SetSubject($outputlangs->transnoentities("Order"));
304 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
305 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
306 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Order")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
307 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
308 $pdf->SetCompression(false);
309 }
310
311 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
312 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
313
314 // Does we have at least one line with discount $this->atleastonediscount
315 foreach ($object->lines as $line) {
316 if ($line->remise_percent) {
317 $this->atleastonediscount = true;
318 break;
319 }
320 }
321
322 // New page
323 $pdf->AddPage();
324 if (!empty($tplidx)) {
325 $pdf->useTemplate($tplidx);
326 }
327 $pagenb++;
328 $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
329 $pdf->SetFont('', '', $default_font_size - 1);
330 $pdf->MultiCell(0, 3, ''); // Set interline to 3
331 $pdf->SetTextColor(0, 0, 0);
332
333 $tab_top = 90 + $top_shift;
334 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
335
336 $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
337
338 $nexY = $tab_top - 1;
339
340 // Incoterm
341 $height_incoterms = 0;
342 if (isModEnabled('incoterm')) {
343 $desc_incoterms = $object->getIncotermsForPDF();
344 if ($desc_incoterms) {
345 $tab_top -= 2;
346
347 $pdf->SetFont('', '', $default_font_size - 1);
348 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
349 $nexY = max($pdf->GetY(), $nexY);
350 $height_incoterms = $nexY - $tab_top;
351
352 // Rect takes a length in 3rd parameter
353 $pdf->SetDrawColor(192, 192, 192);
354 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 3, $this->corner_radius, '1234', 'D');
355
356 $tab_top = $nexY + 6;
357 $height_incoterms += 4;
358 }
359 }
360
361 // Displays notes. Here we are still on code executed only for the first page.
362 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
363
364 // Extrafields in note
365 $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
366 if (!empty($extranote)) {
367 $notetoshow = dol_concatdesc($notetoshow, $extranote);
368 }
369
370 $pagenb = $pdf->getPage();
371 if (!empty($notetoshow)) {
372 $tab_top -= 2;
373
374 $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
375 $pageposbeforenote = $pagenb;
376
377 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
378 complete_substitutions_array($substitutionarray, $outputlangs, $object);
379 $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
380 $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
381
382 $pdf->startTransaction();
383
384 $pdf->SetFont('', '', $default_font_size - 1);
385 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
386 // Description
387 $pageposafternote = $pdf->getPage();
388 $posyafter = $pdf->GetY();
389
390 if ($pageposafternote > $pageposbeforenote) {
391 $pdf->rollbackTransaction(true);
392
393 // prepare pages to receive notes
394 while ($pagenb < $pageposafternote) {
395 $pdf->AddPage();
396 $pagenb++;
397 if (!empty($tplidx)) {
398 $pdf->useTemplate($tplidx);
399 }
400 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
401 $this->_pagehead($pdf, $object, 0, $outputlangs);
402 }
403 // $this->_pagefoot($pdf,$object,$outputlangs,1);
404 $pdf->setTopMargin($tab_top_newpage);
405 // The only function to edit the bottom margin of current page to set it.
406 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
407 }
408
409 // back to start
410 $pdf->setPage($pageposbeforenote);
411 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
412 $pdf->SetFont('', '', $default_font_size - 1);
413 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
414 $pageposafternote = $pdf->getPage();
415
416 $posyafter = $pdf->GetY();
417
418 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text
419 $pdf->AddPage('', '', true);
420 $pagenb++;
421 $pageposafternote++;
422 $pdf->setPage($pageposafternote);
423 $pdf->setTopMargin($tab_top_newpage);
424 // The only function to edit the bottom margin of current page to set it.
425 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
426 //$posyafter = $tab_top_newpage;
427 }
428
429
430 // apply note frame to previous pages
431 $i = $pageposbeforenote;
432 while ($i < $pageposafternote) {
433 $pdf->setPage($i);
434
435
436 $pdf->SetDrawColor(128, 128, 128);
437 // Draw note frame
438 if ($i > $pageposbeforenote) {
439 $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
440 $pdf->RoundedRect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
441 } else {
442 $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
443 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
444 }
445
446 // Add footer
447 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
448 $this->_pagefoot($pdf, $object, $outputlangs, 1);
449
450 $i++;
451 }
452
453 // apply note frame to last page
454 $pdf->setPage($pageposafternote);
455 if (!empty($tplidx)) {
456 $pdf->useTemplate($tplidx);
457 }
458 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
459 $this->_pagehead($pdf, $object, 0, $outputlangs);
460 }
461 $height_note = $posyafter - $tab_top_newpage;
462
463 $pdf->RoundedRect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
464 } else { // No pagebreak
465 $pdf->commitTransaction();
466 $posyafter = $pdf->GetY();
467 $height_note = $posyafter - $tab_top;
468 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 2, $this->corner_radius, '1234', 'D');
469
470
471 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
472 // not enough space, need to add page
473 $pdf->AddPage('', '', true);
474 $pagenb++;
475 $pageposafternote++;
476 $pdf->setPage($pageposafternote);
477 if (!empty($tplidx)) {
478 $pdf->useTemplate($tplidx);
479 }
480 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
481 $this->_pagehead($pdf, $object, 0, $outputlangs);
482 }
483
484 $posyafter = $tab_top_newpage;
485 }
486 }
487
488 $tab_height -= $height_note;
489 $tab_top = $posyafter + 6;
490 } else {
491 $height_note = 0;
492 }
493
494 // Use new auto column system
495 $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
496
497 $nexY = $tab_top + $this->tabTitleHeight;
498
499 $pageposbeforeprintlines = $pdf->getPage();
500 $pagenb = $pageposbeforeprintlines;
501
502 // Loop on each lines
503 for ($i = 0; $i < $nblines; $i++) {
504 $curY = $nexY;
505 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
506 $pdf->SetTextColor(0, 0, 0);
507
508 // Define size of image if we need it
509 $imglinesize = array();
510 if (!empty($realpatharray[$i])) {
511 $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
512 }
513
514 $pdf->setTopMargin($tab_top_newpage);
515 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
516 $pageposbefore = $pdf->getPage();
517
518 $showpricebeforepagebreak = 1;
519 $posYAfterImage = 0;
520 $posYAfterDescription = 0;
521
522 // We start with Photo of product line
523 if ($this->getColumnStatus('photo')) {
524 // We start with Photo of product line
525 if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page
526 $pdf->AddPage('', '', true);
527 if (!empty($tplidx)) {
528 $pdf->useTemplate($tplidx);
529 }
530 $pdf->setPage($pageposbefore + 1);
531
532 $curY = $tab_top_newpage;
533
534 // Allows data in the first page if description is long enough to break in multiples pages
535 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
536 $showpricebeforepagebreak = 1;
537 } else {
538 $showpricebeforepagebreak = 0;
539 }
540 }
541
542 if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) {
543 $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
544 // $pdf->Image does not increase value return by getY, so we save it manually
545 $posYAfterImage = $curY + $imglinesize['height'];
546 }
547 }
548
549 // Description of product line
550 $showpricebeforepagebreak = 1;
551
552 if ($this->getColumnStatus('desc')) {
553 $pdf->startTransaction();
554
555 $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1);
556 $pageposafter = $pdf->getPage();
557
558 if ($pageposafter > $pageposbefore) { // There is a pagebreak
559 $pdf->rollbackTransaction(true);
560 $pageposafter = $pageposbefore;
561 $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
562
563 $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1);
564 $pageposafter = $pdf->getPage();
565 $posyafter = $pdf->GetY();
566 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
567 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
568 $pdf->AddPage('', '', true);
569 if (!empty($tplidx)) {
570 $pdf->useTemplate($tplidx);
571 }
572 //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
573 $pdf->setPage($pageposafter + 1);
574 }
575 } else {
576 // We found a page break
577 // Allows data in the first page if description is long enough to break in multiples pages
578 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
579 $showpricebeforepagebreak = 1;
580 } else {
581 $showpricebeforepagebreak = 0;
582 }
583 }
584 } else { // No pagebreak
585 $pdf->commitTransaction();
586 }
587 $posYAfterDescription = $pdf->GetY();
588 }
589
590 $nexY = max($pdf->GetY(), $posYAfterImage);
591
592 $pageposafter = $pdf->getPage();
593
594 $pdf->setPage($pageposbefore);
595 $pdf->setTopMargin($this->marge_haute);
596 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
597
598 // We suppose that a too long description is moved completely on next page
599 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
600 $pdf->setPage($pageposafter);
601 $curY = $tab_top_newpage;
602 }
603
604 $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par default
605
606 // # of line
607 if ($this->getColumnStatus('position')) {
608 $this->printStdColumnContent($pdf, $curY, 'position', (string) ($i + 1));
609 }
610
611 // VAT Rate
612 if ($this->getColumnStatus('vat')) {
613 $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
614 $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
615 $nexY = max($pdf->GetY(), $nexY);
616 }
617
618 // Unit price before discount
619 if ($this->getColumnStatus('subprice')) {
620 $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
621 $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
622 $nexY = max($pdf->GetY(), $nexY);
623 }
624
625 // Quantity
626 // Enough for 6 chars
627 if ($this->getColumnStatus('qty')) {
628 $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
629 $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
630 $nexY = max($pdf->GetY(), $nexY);
631 }
632
633
634 // Unit
635 if ($this->getColumnStatus('unit')) {
636 $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails);
637 $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
638 $nexY = max($pdf->GetY(), $nexY);
639 }
640
641 // Discount on line
642 if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) {
643 $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
644 $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
645 $nexY = max($pdf->GetY(), $nexY);
646 }
647
648 // Total HT line
649 if ($this->getColumnStatus('totalexcltax')) {
650 $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
651 $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
652 $nexY = max($pdf->GetY(), $nexY);
653 }
654
655 // Extrafields
656 if (!empty($object->lines[$i]->array_options)) {
657 foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
658 if ($this->getColumnStatus($extrafieldColKey)) {
659 $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs);
660 $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
661 $nexY = max($pdf->GetY(), $nexY);
662 }
663 }
664 }
665
666 $parameters = array(
667 'object' => $object,
668 'i' => $i,
669 'pdf' => & $pdf,
670 'curY' => & $curY,
671 'nexY' => & $nexY,
672 'outputlangs' => $outputlangs,
673 'hidedetails' => $hidedetails
674 );
675 $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook
676
677
678 // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
679 if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) {
680 $tvaligne = $object->lines[$i]->multicurrency_total_tva;
681 } else {
682 $tvaligne = $object->lines[$i]->total_tva;
683 }
684
685 $localtax1ligne = $object->lines[$i]->total_localtax1;
686 $localtax2ligne = $object->lines[$i]->total_localtax2;
687 $localtax1_rate = $object->lines[$i]->localtax1_tx;
688 $localtax2_rate = $object->lines[$i]->localtax2_tx;
689 $localtax1_type = $object->lines[$i]->localtax1_type;
690 $localtax2_type = $object->lines[$i]->localtax2_type;
691
692 // TODO remise_percent is an obsolete field for object parent
693 /*if (!empty($object->remise_percent)) {
694 $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
695 }
696 if (!empty($object->remise_percent)) {
697 $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
698 }
699 if (!empty($object->remise_percent)) {
700 $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
701 }*/
702
703 $vatrate = (string) $object->lines[$i]->tva_tx;
704
705 // Retrieve type from database for backward compatibility with old records
706 if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
707 && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
708 $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $mysoc, $object->thirdparty);
709 $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
710 $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
711 }
712
713 // retrieve global local tax
714 if ($localtax1_type && $localtax1ligne != 0) {
715 if (empty($this->localtax1[$localtax1_type][$localtax1_rate])) {
716 $this->localtax1[$localtax1_type][$localtax1_rate] = $localtax1ligne;
717 } else {
718 $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
719 }
720 }
721 if ($localtax2_type && $localtax2ligne != 0) {
722 if (empty($this->localtax2[$localtax2_type][$localtax2_rate])) {
723 $this->localtax2[$localtax2_type][$localtax2_rate] = $localtax2ligne;
724 } else {
725 $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
726 }
727 }
728
729 if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
730 $vatrate .= '*';
731 }
732
733 // Fill $this->tva and $this->tva_array
734 if (!isset($this->tva[$vatrate])) {
735 $this->tva[$vatrate] = 0;
736 }
737 $this->tva[$vatrate] += $tvaligne;
738 $vatcode = $object->lines[$i]->vat_src_code;
739 if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
740 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
741 }
742 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
743
744 if ($posYAfterImage > $posYAfterDescription) {
745 $nexY = $posYAfterImage;
746 }
747
748 // Add line
749 if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) {
750 $pdf->setPage($pageposafter);
751 $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(80, 80, 80)));
752 //$pdf->SetDrawColor(190,190,200);
753 $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
754 $pdf->SetLineStyle(array('dash' => 0));
755 }
756
757 // Detect if some page were added automatically and output _tableau for past pages
758 while ($pagenb < $pageposafter) {
759 $pdf->setPage($pagenb);
760 if ($pagenb == $pageposbeforeprintlines) {
761 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
762 } else {
763 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
764 }
765 $this->_pagefoot($pdf, $object, $outputlangs, 1);
766 $pagenb++;
767 $pdf->setPage($pagenb);
768 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
769 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
770 $this->_pagehead($pdf, $object, 0, $outputlangs);
771 }
772 if (!empty($tplidx)) {
773 $pdf->useTemplate($tplidx);
774 }
775 }
776 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { // @phan-suppress-current-line PhanUndeclaredProperty
777 if ($pagenb == $pageposafter) {
778 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
779 } else {
780 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
781 }
782 $this->_pagefoot($pdf, $object, $outputlangs, 1);
783 // New page
784 $pdf->AddPage();
785 if (!empty($tplidx)) {
786 $pdf->useTemplate($tplidx);
787 }
788 $pagenb++;
789 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
790 $this->_pagehead($pdf, $object, 0, $outputlangs);
791 }
792 }
793 }
794
795 // Show square
796 if ($pagenb == $pageposbeforeprintlines) {
797 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
798 } else {
799 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
800 }
801 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
802
803 // Affiche zone infos
804 $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
805
806 // Affiche zone totaux
807 $posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
808
809 // Affiche zone versements
810 if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) {
811 $posy = $this->_tableau_versements($pdf, $object, $posy, $outputlangs);
812 }
813
814 // Pied de page
815 $this->_pagefoot($pdf, $object, $outputlangs);
816 if (method_exists($pdf, 'AliasNbPages')) {
817 $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod
818 }
819
820 $pdf->Close();
821
822 $pdf->Output($file, 'F');
823
824 // Add pdfgeneration hook
825 $hookmanager->initHooks(array('pdfgeneration'));
826 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
827 global $action;
828 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
829 if ($reshook < 0) {
830 $this->error = $hookmanager->error;
831 $this->errors = $hookmanager->errors;
832 }
833
834 dolChmod($file);
835
836 $this->result = array('fullpath' => $file);
837
838 return 1; // No error
839 } else {
840 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
841 return 0;
842 }
843 } else {
844 $this->error = $langs->transnoentities("ErrorConstantNotDefined", "SUPPLIER_OUTPUTDIR");
845 return 0;
846 }
847 }
848
849 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
850 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
860 protected function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
861 {
862 // phpcs:enable
863 return 1;
864 }
865
866 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
867 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
877 protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
878 {
879 // phpcs:enable
880 global $conf, $mysoc;
881 $default_font_size = pdf_getPDFFontSize($outputlangs);
882
883 $diffsizetitle = (!getDolGlobalString('PDF_DIFFSIZE_TITLE') ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
884
885 // If France, show VAT mention if not applicable
886 if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
887 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
888 $pdf->SetXY($this->marge_gauche, $posy);
889 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
890
891 $posy = $pdf->GetY() + 4;
892 }
893
894 $posxval = 52;
895
896 // Show payments conditions
897 if (!empty($object->cond_reglement_code) || $object->cond_reglement) {
898 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
899 $pdf->SetXY($this->marge_gauche, $posy);
900 $titre = $outputlangs->transnoentities("PaymentConditions").':';
901 $pdf->MultiCell(80, 4, $titre, 0, 'L');
902
903 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
904 $pdf->SetXY($posxval, $posy);
905 $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);
906 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
907 $pdf->MultiCell(80, 4, $lib_condition_paiement, 0, 'L');
908
909 $posy = $pdf->GetY() + 3;
910 }
911
912 // Show payment mode
913 if (!empty($object->mode_reglement_code)) {
914 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
915 $pdf->SetXY($this->marge_gauche, $posy);
916 $titre = $outputlangs->transnoentities("PaymentMode").':';
917 $pdf->MultiCell(80, 5, $titre, 0, 'L');
918
919 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
920 $pdf->SetXY($posxval, $posy);
921 $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);
922 $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
923
924 $posy = $pdf->GetY() + 2;
925 }
926
927
928 return $posy;
929 }
930
931 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
932 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
943 protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
944 {
945 // phpcs:enable
946 global $conf, $mysoc, $hookmanager;
947
948 $default_font_size = pdf_getPDFFontSize($outputlangs);
949
950 $tab2_top = $posy;
951 $tab2_hl = 4;
952 $pdf->SetFont('', '', $default_font_size - 1);
953
954 // Tableau total
955 $col1x = 120;
956 $col2x = 170;
957 if ($this->page_largeur < 210) { // To work with US executive format
958 $col2x -= 20;
959 }
960 $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
961
962 $useborder = 0;
963 $index = 0;
964
965 // Total HT
966 $pdf->SetFillColor(255, 255, 255);
967 $pdf->SetXY($col1x, $tab2_top);
968 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
969
970 $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
971 $pdf->SetXY($col2x, $tab2_top);
972 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, 'R', 1);
973
974 // Show VAT by rates and total
975 $pdf->SetFillColor(248, 248, 248);
976
977 $this->atleastoneratenotnull = 0;
978 foreach ($this->tva as $tvakey => $tvaval) {
979 if ($tvakey > 0) { // On affiche pas taux 0
980 $this->atleastoneratenotnull++;
981
982 $index++;
983 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
984
985 $tvacompl = '';
986
987 if (preg_match('/\*/', $tvakey)) {
988 $tvakey = str_replace('*', '', $tvakey);
989 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
990 }
991
992 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).' ';
993 $totalvat .= vatrate($tvakey, 1).$tvacompl;
994 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
995
996 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
997 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
998 }
999 }
1000 if (!$this->atleastoneratenotnull) { // If no vat at all
1001 $index++;
1002 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1003 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code), 0, 'L', 1);
1004
1005 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1006 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_tva), 0, 'R', 1);
1007
1008 // Total LocalTax1
1009 if (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on' && $object->total_localtax1 > 0) {
1010 $index++;
1011 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1012 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code), 0, 'L', 1);
1013 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1014 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax1), $useborder, 'R', 1);
1015 }
1016
1017 // Total LocalTax2
1018 if (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on' && $object->total_localtax2 > 0) {
1019 $index++;
1020 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1021 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code), 0, 'L', 1);
1022 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1023 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax2), $useborder, 'R', 1);
1024 }
1025 } else {
1026 //if (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') && getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on')
1027 //{
1028 //Local tax 1
1029 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1030 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1031 continue;
1032 }
1033
1034 foreach ($localtax_rate as $tvakey => $tvaval) {
1035 if ($tvakey != 0) { // On affiche pas taux 0
1036 //$this->atleastoneratenotnull++;
1037
1038 $index++;
1039 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1040
1041 $tvacompl = '';
1042 if (preg_match('/\*/', (string) $tvakey)) {
1043 $tvakey = str_replace('*', '', (string) $tvakey);
1044 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1045 }
1046 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
1047 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
1048 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1049
1050 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1051 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1052 }
1053 }
1054 }
1055
1056 //if (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') && getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on')
1057 //{
1058 //Local tax 2
1059 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1060 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1061 continue;
1062 }
1063
1064 foreach ($localtax_rate as $tvakey => $tvaval) {
1065 if ($tvakey != 0) { // On affiche pas taux 0
1066 //$this->atleastoneratenotnull++;
1067
1068 $index++;
1069 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1070
1071 $tvacompl = '';
1072 if (preg_match('/\*/', (string) $tvakey)) {
1073 $tvakey = str_replace('*', '', (string) $tvakey);
1074 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1075 }
1076 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
1077 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
1078 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1079
1080 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1081 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
1082 }
1083 }
1084 }
1085 }
1086
1087 // Total TTC
1088 $index++;
1089 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1090 $pdf->SetTextColor(0, 0, 60);
1091 $pdf->SetFillColor(224, 224, 224);
1092 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
1093
1094 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
1095 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1096 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc), $useborder, 'R', 1);
1097 $pdf->SetFont('', '', $default_font_size - 1);
1098 $pdf->SetTextColor(0, 0, 0);
1099
1100 $creditnoteamount = 0;
1101 $depositsamount = 0;
1102 //$creditnoteamount=$object->getSumCreditNotesUsed();
1103 //$depositsamount=$object->getSumDepositsUsed();
1104 //print "x".$creditnoteamount."-".$depositsamount;exit;
1105 $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
1106 if (!empty($object->paye)) {
1107 $resteapayer = 0;
1108 }
1109
1110 if ($deja_regle > 0) {
1111 // Already paid + Deposits
1112 $index++;
1113
1114 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1115 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
1116 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1117 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle), 0, 'R', 0);
1118
1119 $index++;
1120 $pdf->SetTextColor(0, 0, 60);
1121 $pdf->SetFillColor(224, 224, 224);
1122 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1123 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
1124
1125 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1126 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer), $useborder, 'R', 1);
1127
1128 $pdf->SetFont('', '', $default_font_size - 1);
1129 $pdf->SetTextColor(0, 0, 0);
1130 }
1131
1132 $parameters = array('pdf' => &$pdf, 'object' => &$object, 'outputlangs' => $outputlangs, 'index' => &$index, 'posy' => $posy);
1133
1134 $reshook = $hookmanager->executeHooks('afterPDFTotalTable', $parameters, $this); // Note that $action and $object may have been modified by some hooks
1135 if ($reshook < 0) {
1136 $this->error = $hookmanager->error;
1137 $this->errors = $hookmanager->errors;
1138 }
1139
1140 $index++;
1141 return ($tab2_top + ($tab2_hl * $index));
1142 }
1143
1144 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1158 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
1159 {
1160 global $conf;
1161
1162 // Force to disable hidetop and hidebottom
1163 $hidebottom = 0;
1164 if ($hidetop) {
1165 $hidetop = -1;
1166 }
1167
1168 $currency = !empty($currency) ? $currency : $conf->currency;
1169 $default_font_size = pdf_getPDFFontSize($outputlangs);
1170
1171 // Amount in (at tab_top - 1)
1172 $pdf->SetTextColor(0, 0, 0);
1173 $pdf->SetFont('', '', $default_font_size - 2);
1174
1175 if (empty($hidetop)) {
1176 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1177 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1178 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1179
1180 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1181 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
1182 $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')));
1183 }
1184 }
1185
1186 $pdf->SetDrawColor(128, 128, 128);
1187 $pdf->SetFont('', '', $default_font_size - 1);
1188
1189 // Output Rect
1190 $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
1191
1192 $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
1193
1194 if (empty($hidetop)) {
1195 $pdf->line($this->marge_gauche, $tab_top + $this->tabTitleHeight, $this->page_largeur - $this->marge_droite, $tab_top + $this->tabTitleHeight); // line takes a position y in 2nd parameter and 4th parameter
1196 }
1197 }
1198
1199 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1209 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
1210 {
1211 global $langs, $conf, $mysoc;
1212
1213 $ltrdirection = 'L';
1214 if ($outputlangs->trans("DIRECTION") == 'rtl') {
1215 $ltrdirection = 'R';
1216 }
1217
1218 // Load translation files required by the page
1219 $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "sendings"));
1220
1221 $default_font_size = pdf_getPDFFontSize($outputlangs);
1222
1223 // Do not add the BACKGROUND as this is for suppliers
1224 //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
1225
1226 //Affiche le filigrane brouillon - Print Draft Watermark
1227 /*if($object->statut==0 && getDolGlobalString('COMMANDE_DRAFT_WATERMARK'))
1228 {
1229 pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',getDolGlobalString('COMMANDE_DRAFT_WATERMARK'));
1230 }*/
1231 //Print content
1232
1233 $pdf->SetTextColor(0, 0, 60);
1234 $pdf->SetFont('', 'B', $default_font_size + 3);
1235
1236 $w = 110;
1237
1238 $posx = $this->page_largeur - $this->marge_droite - $w;
1239 $posy = $this->marge_haute;
1240
1241 $pdf->SetXY($this->marge_gauche, $posy);
1242
1243 // Logo
1244 if (!getDolGlobalInt('PDF_DISABLE_MYCOMPANY_LOGO')) {
1245 if ($this->emetteur->logo) {
1246 $logodir = $conf->mycompany->dir_output;
1247 if (!empty($conf->mycompany->multidir_output[$object->entity])) {
1248 $logodir = $conf->mycompany->multidir_output[$object->entity];
1249 }
1250 if (!getDolGlobalInt('MAIN_PDF_USE_LARGE_LOGO')) {
1251 $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1252 } else {
1253 $logo = $logodir.'/logos/'.$this->emetteur->logo;
1254 }
1255 if (is_readable($logo)) {
1256 $height = pdf_getHeightForLogo($logo);
1257 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1258 } else {
1259 $pdf->SetTextColor(200, 0, 0);
1260 $pdf->SetFont('', 'B', $default_font_size - 2);
1261 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1262 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1263 }
1264 } else {
1265 $text = $this->emetteur->name;
1266 $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
1267 }
1268 }
1269
1270 $pdf->SetFont('', 'B', $default_font_size + 3);
1271 $pdf->SetXY($posx, $posy);
1272 $pdf->SetTextColor(0, 0, 60);
1273 $title = $outputlangs->transnoentities("SupplierOrder")." ".$outputlangs->convToOutputCharset($object->ref);
1274 if ($object->status == $object::STATUS_DRAFT) {
1275 $pdf->SetTextColor(128, 0, 0);
1276 $title .= ' - '.$outputlangs->transnoentities("NotValidated");
1277 }
1278 $pdf->MultiCell($w, 3, $title, '', 'R');
1279 $posy += 1;
1280
1281 if ($object->ref_supplier) {
1282 $posy += 4;
1283 $pdf->SetFont('', 'B', $default_font_size);
1284 $pdf->SetXY($posx, $posy);
1285 $pdf->SetTextColor(0, 0, 60);
1286 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefSupplier")." : ".$outputlangs->convToOutputCharset($object->ref_supplier), '', 'R');
1287 $posy += 1;
1288 }
1289
1290 $pdf->SetFont('', '', $default_font_size - 1);
1291
1292 if (getDolGlobalString('PDF_SHOW_PROJECT_TITLE')) {
1293 $object->fetchProject();
1294 if (!empty($object->project->ref)) {
1295 $posy += 3;
1296 $pdf->SetXY($posx, $posy);
1297 $pdf->SetTextColor(0, 0, 60);
1298 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1299 }
1300 }
1301
1302 if (getDolGlobalString('PDF_SHOW_PROJECT')) {
1303 $object->fetchProject();
1304 if (!empty($object->project->ref)) {
1305 $outputlangs->load("projects");
1306 $posy += 4;
1307 $pdf->SetXY($posx, $posy);
1308 $langs->load("projects");
1309 $pdf->SetTextColor(0, 0, 60);
1310 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1311 }
1312 }
1313
1314 if (!empty($object->date_commande)) {
1315 $posy += 5;
1316 $pdf->SetXY($posx, $posy);
1317 $pdf->SetTextColor(0, 0, 60);
1318 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("OrderDate")." : ".dol_print_date($object->date_commande, "day", false, $outputlangs, true), '', 'R');
1319 }
1320 // no point in having this here this a document sent to supplier
1321 /*} else {
1322 $posy += 5;
1323 $pdf->SetXY($posx, $posy);
1324 $pdf->SetTextColor(255, 0, 0);
1325 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("OrderToProcess"), '', 'R');
1326 }*/
1327
1328
1329 $pdf->SetTextColor(0, 0, 60);
1330 $usehourmin = 'day';
1331 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
1332 $usehourmin = 'dayhour';
1333 }
1334 if (!empty($object->delivery_date)) {
1335 $posy += 4;
1336 $pdf->SetXY($posx - 90, $posy);
1337 $pdf->MultiCell(190, 3, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->delivery_date, $usehourmin, false, $outputlangs, true), '', 'R');
1338 }
1339
1340 if ($object->thirdparty->code_fournisseur) {
1341 $posy += 4;
1342 $pdf->SetXY($posx, $posy);
1343 $pdf->SetTextColor(0, 0, 60);
1344 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("SupplierCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_fournisseur), '', 'R');
1345 }
1346
1347 // Get contact
1348 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1349 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1350 if (count($arrayidcontact) > 0) {
1351 $usertmp = new User($this->db);
1352 $usertmp->fetch($arrayidcontact[0]);
1353 $posy += 4;
1354 $pdf->SetXY($posx, $posy);
1355 $pdf->SetTextColor(0, 0, 60);
1356 $pdf->MultiCell($w, 3, $langs->trans("BuyerName")." : ".$usertmp->getFullName($langs), '', 'R');
1357 }
1358 }
1359
1360 $posy += 1;
1361 $pdf->SetTextColor(0, 0, 60);
1362
1363 $top_shift = 0;
1364 // Show list of linked objects
1365 $current_y = $pdf->getY();
1366 $posx += 10;
1367 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
1368 if ($current_y < $pdf->getY()) {
1369 $top_shift = $pdf->getY() - $current_y;
1370 }
1371
1372 if ($showaddress) {
1373 // Sender properties
1374 $carac_emetteur = '';
1375 // Add internal contact of object if defined
1376 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1377 if (count($arrayidcontact) > 0) {
1378 $object->fetch_user($arrayidcontact[0]);
1379 $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1380 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname.": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1381 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1382 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1383 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1384 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1385 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1386 $carac_emetteur .= "\n";
1387 }
1388
1389 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1390
1391 // Show sender
1392 $posy = 42 + $top_shift;
1393 $posx = $this->marge_gauche;
1394 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1395 $posx = $this->page_largeur - $this->marge_droite - 80;
1396 }
1397 $hautcadre = 40;
1398
1399 // Show sender frame
1400 $pdf->SetTextColor(0, 0, 0);
1401 $pdf->SetFont('', '', $default_font_size - 2);
1402 $pdf->SetXY($posx, $posy - 5);
1403 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1404 $pdf->SetXY($posx, $posy);
1405 $pdf->SetFillColor(230, 230, 230);
1406 $pdf->RoundedRect($posx, $posy, 82, $hautcadre, $this->corner_radius, '1234', 'F');
1407 $pdf->SetTextColor(0, 0, 60);
1408
1409 // Show sender name
1410 $pdf->SetXY($posx + 2, $posy + 3);
1411 $pdf->SetFont('', 'B', $default_font_size);
1412 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1413 $posy = $pdf->getY();
1414
1415 // Show sender information
1416 $pdf->SetXY($posx + 2, $posy);
1417 $pdf->SetFont('', '', $default_font_size - 1);
1418 $pdf->MultiCell(80, 4, $carac_emetteur, 0, $ltrdirection);
1419
1420
1421
1422 // 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'
1423 $usecontact = false;
1424 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1425 if (count($arrayidcontact) > 0) {
1426 $usecontact = true;
1427 $result = $object->fetch_contact($arrayidcontact[0]);
1428 }
1429
1430 // Recipient name
1431 if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || getDolGlobalString('MAIN_USE_COMPANY_NAME_OF_CONTACT')))) {
1432 $thirdparty = $object->contact;
1433 } else {
1434 $thirdparty = $object->thirdparty;
1435 }
1436
1437 $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1438
1439 $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), ($usecontact ? 1 : 0), 'target', $object);
1440
1441 // Show recipient
1442 $widthrecbox = 100;
1443 if ($this->page_largeur < 210) {
1444 $widthrecbox = 84; // To work with US executive format
1445 }
1446 $posy = 42 + $top_shift;
1447 $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1448 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1449 $posx = $this->marge_gauche;
1450 }
1451
1452 // Show recipient frame
1453 $pdf->SetTextColor(0, 0, 0);
1454 $pdf->SetFont('', '', $default_font_size - 2);
1455 $pdf->SetXY($posx + 2, $posy - 5);
1456 $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1457 $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D');
1458
1459 // Show recipient name
1460 $pdf->SetXY($posx + 2, $posy + 3);
1461 $pdf->SetFont('', 'B', $default_font_size);
1462 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1463 $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, $ltrdirection);
1464
1465 $posy = $pdf->getY();
1466
1467 // Show recipient information
1468 $pdf->SetFont('', '', $default_font_size - 1);
1469 $pdf->SetXY($posx + 2, $posy);
1470 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1471 $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1472 }
1473
1474 return $top_shift;
1475 }
1476
1477 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1487 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1488 {
1489 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1490 return pdf_pagefoot($pdf, $outputlangs, 'SUPPLIER_ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1491 }
1492
1493
1494
1505 public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1506 {
1507 global $conf, $hookmanager;
1508
1509 // Default field style for content
1510 $this->defaultContentsFieldsStyle = array(
1511 'align' => 'R', // R,C,L
1512 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1513 );
1514
1515 // Default field style for content
1516 $this->defaultTitlesFieldsStyle = array(
1517 'align' => 'C', // R,C,L
1518 'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1519 );
1520
1521 /*
1522 * For example
1523 $this->cols['theColKey'] = array(
1524 'rank' => $rank, // int : use for ordering columns
1525 'width' => 20, // the column width in mm
1526 'title' => array(
1527 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1528 'label' => ' ', // the final label : used fore final generated text
1529 'align' => 'L', // text alignment : R,C,L
1530 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1531 ),
1532 'content' => array(
1533 'align' => 'L', // text alignment : R,C,L
1534 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1535 ),
1536 );
1537 */
1538
1539 $rank = 0; // do not use negative rank
1540 $this->cols['position'] = array(
1541 'rank' => $rank,
1542 'width' => 10,
1543 'status' => getDolGlobalInt('PDF_CORNAS_ADD_POSITION') ? true : (getDolGlobalInt('PDF_ADD_POSITION') ? true : false),
1544 'title' => array(
1545 'textkey' => '#', // use lang key is useful in somme case with module
1546 'align' => 'C',
1547 // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1548 // 'label' => ' ', // the final label
1549 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1550 ),
1551 'content' => array(
1552 'align' => 'C',
1553 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1554 ),
1555 );
1556
1557 $rank += 10; // do not use negative rank
1558 $this->cols['desc'] = array(
1559 'rank' => $rank,
1560 'width' => false, // only for desc
1561 'status' => true,
1562 'title' => array(
1563 'textkey' => 'Designation', // use lang key is useful in somme case with module
1564 'align' => 'L',
1565 // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1566 // 'label' => ' ', // the final label
1567 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1568 ),
1569 'content' => array(
1570 'align' => 'L',
1571 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1572 ),
1573 );
1574
1575 $rank += 10;
1576 $this->cols['photo'] = array(
1577 'rank' => $rank,
1578 'width' => getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH', 20), // in mm
1579 'status' => false,
1580 'title' => array(
1581 'textkey' => 'Photo',
1582 'label' => ' '
1583 ),
1584 'content' => array(
1585 'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1586 ),
1587 'border-left' => false, // remove left line separator
1588 );
1589
1590 if (getDolGlobalString('MAIN_GENERATE_SUPPLIER_ORDER_WITH_PICTURE')) {
1591 $this->cols['photo']['status'] = true;
1592 }
1593
1594
1595 $rank += 10;
1596 $this->cols['vat'] = array(
1597 'rank' => $rank,
1598 'status' => false,
1599 'width' => 16, // in mm
1600 'title' => array(
1601 'textkey' => 'VAT'
1602 ),
1603 'border-left' => true, // add left line separator
1604 );
1605
1606 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
1607 $this->cols['vat']['status'] = true;
1608 }
1609
1610 $rank += 10;
1611 $this->cols['subprice'] = array(
1612 'rank' => $rank,
1613 'width' => 19, // in mm
1614 'status' => false,
1615 'title' => array(
1616 'textkey' => 'PriceUHT'
1617 ),
1618 'border-left' => true, // add left line separator
1619 );
1620
1621 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_PURCHASE_ORDER_WITHOUT_UNIT_PRICE')) {
1622 $this->cols['subprice']['status'] = true;
1623 }
1624
1625 $rank += 10;
1626 $this->cols['qty'] = array(
1627 'rank' => $rank,
1628 'width' => 16, // in mm
1629 'status' => true,
1630 'title' => array(
1631 'textkey' => 'Qty'
1632 ),
1633 'border-left' => true, // add left line separator
1634 );
1635
1636 $rank += 10;
1637 $this->cols['unit'] = array(
1638 'rank' => $rank,
1639 'width' => 11, // in mm
1640 'status' => false,
1641 'title' => array(
1642 'textkey' => 'Unit'
1643 ),
1644 'border-left' => true, // add left line separator
1645 );
1646 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1647 $this->cols['unit']['status'] = true;
1648 }
1649
1650 $rank += 10;
1651 $this->cols['discount'] = array(
1652 'rank' => $rank,
1653 'width' => 13, // in mm
1654 'status' => false,
1655 'title' => array(
1656 'textkey' => 'ReductionShort'
1657 ),
1658 'border-left' => true, // add left line separator
1659 );
1660 if ($this->atleastonediscount) {
1661 $this->cols['discount']['status'] = true;
1662 }
1663
1664 $rank += 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
1665 $this->cols['totalexcltax'] = array(
1666 'rank' => $rank,
1667 'width' => 26, // in mm
1668 'status' => false,
1669 'title' => array(
1670 'textkey' => 'TotalHT'
1671 ),
1672 'border-left' => true, // add left line separator
1673 );
1674
1675 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_PURCHASE_ORDER_WITHOUT_TOTAL_COLUMN')) {
1676 $this->cols['totalexcltax']['status'] = true;
1677 }
1678
1679 // Add extrafields cols
1680 if (!empty($object->lines)) {
1681 $line = reset($object->lines);
1682 $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
1683 }
1684
1685 $parameters = array(
1686 'object' => $object,
1687 'outputlangs' => $outputlangs,
1688 'hidedetails' => $hidedetails,
1689 'hidedesc' => $hidedesc,
1690 'hideref' => $hideref
1691 );
1692
1693 $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
1694 if ($reshook < 0) {
1695 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1696 } elseif (empty($reshook)) {
1697 // @phan-suppress-next-line PhanPluginSuspiciousParamOrderInternal
1698 $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
1699 } else {
1700 $this->cols = $hookmanager->resArray;
1701 }
1702 }
1703}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
prepareArrayColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Prepare Array Column Field.
getColumnStatus($colKey)
get column status from column key
printStdColumnContent($pdf, &$curY, $colKey, $columnText='')
print standard column content
pdfTabTitles(&$pdf, $tab_top, $tab_height, $outputlangs, $hidetop=0)
Print standard column content.
printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref=0, $hidedesc=0, $issupplierline=0)
print description column content
getColumnContentXStart($colKey)
get column content X (abscissa) left position from column key
getExtrafieldContent($object, $extrafieldKey, $outputlangs=null)
get extrafield content for pdf writeHtmlCell compatibility usage for PDF line columns and object note...
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 supplier orders models.
Class to manage products or services.
Class to manage translations.
Class to manage Dolibarr users.
Class to generate the supplier orders with the cornas 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(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
Show table for lines.
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
_tableau_versements(&$pdf, $object, $posy, $outputlangs)
Show payments table.
_tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
Show total to pay.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
__construct($db)
Constructor.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!function_exists( 'dolEscapeXML')) convertBackOfficeMediasLinksToPublicLinks($notetoshow)
Convert links to local wrapper to medias files into a string into a public external URL readable on i...
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.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
pdf_getSizeForImage($realpath)
Return dimensions to use for images onto PDF checking that width and height are not higher than maxim...
Definition pdf.lib.php:2705
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2436
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:1031
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:2054
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:1992
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1409
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:438
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0)
Return line unit.
Definition pdf.lib.php:2299
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2342
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2139
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
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition pdf.lib.php:390
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:150
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:153