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