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