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