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