dolibarr 25.0.0-alpha
pdf_azur.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-2012 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2008 Raphael Bertrand <raphael.bertrand@resultic.fr>
5 * Copyright (C) 2010-2015 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
7 * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
8 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2017-2018 Ferran Marcet <fmarcet@2byte.es>
10 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
11 * Copyright (C) 2019 Pierre Ardoin <mapiolca@me.com>
12 * Copyright (C) 2021-2024 Anthony Berton <anthony.berton@bb2a.fr>
13 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
14 * Copyright (C) 2024 Nick Fragoulis
15 * Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <https://www.gnu.org/licenses/>.
29 * or see https://www.gnu.org/
30 */
31
38require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
39require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
41require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
42require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
43
44
49{
53 public $db;
54
58 public $entity;
59
63 public $name;
64
68 public $description;
69
73 public $update_main_doc_field;
74
78 public $type;
79
84 public $version = 'dolibarr';
85
86
92 public function __construct($db)
93 {
94 global $langs, $mysoc;
95
96 // Translations
97 $langs->loadLangs(array("main", "bills"));
98
99 $this->db = $db;
100 $this->name = "azur";
101 $this->description = $langs->trans('DocModelAzurDescription');
102 $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
103
104 // Dimension page
105 $this->type = 'pdf';
106 $formatarray = pdf_getFormat();
107 $this->page_largeur = $formatarray['width'];
108 $this->page_hauteur = $formatarray['height'];
109 $this->format = array($this->page_largeur, $this->page_hauteur);
110 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
111 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
112 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
113 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
114 $this->corner_radius = getDolGlobalInt('MAIN_PDF_FRAME_CORNER_RADIUS', 0);
115 $this->option_logo = 1; // Display logo
116 $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
117 $this->option_modereg = 1; // Display payment mode
118 $this->option_condreg = 1; // Display payment terms
119 $this->option_multilang = 1; // Available in several languages
120 $this->option_escompte = 0; // Displays if there has been a discount
121 $this->option_credit_note = 0; // Support credit notes
122 $this->option_freetext = 1; // Support add of a personalised text
123 $this->option_draft_watermark = 1; // Support add of a watermark on drafts
124 $this->watermark = '';
125
126 // Define position of columns
127 $this->posxdesc = $this->marge_gauche + 1;
128 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
129 $this->posxtva = 101;
130 $this->posxup = 118;
131 $this->posxqty = 135;
132 $this->posxunit = 151;
133 } else {
134 $this->posxtva = 106;
135 $this->posxup = 122;
136 $this->posxqty = 145;
137 $this->posxunit = 162;
138 }
139 $this->posxdiscount = 162;
140 $this->postotalht = 174;
141 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') || getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
142 $this->posxtva = $this->posxup;
143 }
144 $this->posxpicture = $this->posxtva - getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH', 20); // width of images
145 if ($this->page_largeur < 210) { // To work with US executive format
146 $this->posxpicture -= 20;
147 $this->posxtva -= 20;
148 $this->posxup -= 20;
149 $this->posxqty -= 20;
150 $this->posxunit -= 20;
151 $this->posxdiscount -= 20;
152 $this->postotalht -= 20;
153 }
154
155 $this->tva = array();
156 $this->tva_array = array();
157 $this->localtax1 = array();
158 $this->localtax2 = array();
159 $this->atleastoneratenotnull = 0;
160 $this->atleastonediscount = 0;
161
162 $this->showAmountBeforeDiscount = getDolGlobalInt('MAIN_HIDE_AMOUNT_BEFORE_DISCOUNT') || getDolGlobalInt('MAIN_HIDE_AMOUNT_BEFORE_DISCOUNT_PROPALE') ? 0 : 1;
163 $this->showDiscountAmount = getDolGlobalInt('MAIN_HIDE_AMOUNT_DISCOUNT') || getDolGlobalInt('MAIN_HIDE_AMOUNT_BEFORE_DISCOUNT_PROPALE') ? 0 : 1;
164
165 if ($mysoc === null) {
166 dol_syslog(get_class($this).'::__construct() Global $mysoc should not be null.'. getCallerInfoString(), LOG_ERR);
167 return;
168 }
169
170 // Get source company
171 $this->emetteur = $mysoc;
172 if (empty($this->emetteur->country_code)) {
173 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
174 }
175 }
176
177 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
189 public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
190 {
191 // phpcs:enable
192 global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
193
194 dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null'));
195
196 if (!is_object($outputlangs)) {
197 $outputlangs = $langs;
198 }
199 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
200 if (getDolGlobalString('MAIN_USE_FPDF')) {
201 $outputlangs->charset_output = 'ISO-8859-1';
202 }
203
204 // Load translation files required by page
205 $langfiles = array("main", "dict", "companies", "bills", "propal", "products", "compta");
206 $outputlangs->loadLangs($langfiles);
207
208 global $outputlangsbis;
209 $outputlangsbis = null;
210 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')) {
211 $outputlangsbis = new Translate('', $conf);
212 $outputlangsbis->setDefaultLang(getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE'));
213 $outputlangsbis->loadLangs($langfiles);
214 }
215
216 // Show Draft Watermark
217 if ($object->statut == $object::STATUS_DRAFT && getDolGlobalString('PROPALE_DRAFT_WATERMARK')) {
218 $this->watermark = getDolGlobalString('PROPALE_DRAFT_WATERMARK');
219 }
220
221 $nblines = count($object->lines);
222
223 // Loop on each lines to detect if there is at least one image to show
224 $realpatharray = array();
225 $this->atleastonephoto = false;
226 if (getDolGlobalString('MAIN_GENERATE_PROPOSALS_WITH_PICTURE')) {
227 $objphoto = new Product($this->db);
228
229 for ($i = 0; $i < $nblines; $i++) {
230 if (empty($object->lines[$i]->fk_product)) {
231 continue;
232 }
233
234 $objphoto->fetch($object->lines[$i]->fk_product);
235 //var_dump($objphoto->ref);exit;
236 $pdir = array();
237 if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
238 $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
239 $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
240 } else {
241 $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product'); // default
242 $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
243 }
244
245 $arephoto = false;
246 $realpath = '';
247 foreach ($pdir as $midir) {
248 if (!$arephoto) {
249 $entity = $objphoto->entity;
250 if ($entity !== null && $conf->entity != $entity) {
251 $dir = $conf->product->multidir_output[$entity].'/'.$midir; //Check repertories of current entities
252 } else {
253 $dir = $conf->product->dir_output.'/'.$midir; //Check repertory of the current product
254 }
255 foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
256 if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES')) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
257 if ($obj['photo_vignette']) {
258 $filename = $obj['photo_vignette'];
259 } else {
260 $filename = $obj['photo'];
261 }
262 } else {
263 $filename = $obj['photo'];
264 }
265
266 $realpath = $dir.$filename;
267 $arephoto = true;
268 $this->atleastonephoto = true;
269 }
270 }
271 }
272
273 if ($realpath && $arephoto) {
274 $realpatharray[$i] = $realpath;
275 }
276 }
277 }
278
279 if (count($realpatharray) == 0) {
280 $this->posxpicture = $this->posxtva;
281 }
282
283 if ($conf->propal->multidir_output[$conf->entity]) {
284 $object->fetch_thirdparty();
285
286 $deja_regle = 0;
287
288 // Definition of $dir and $file
289 if ($object->specimen) {
290 $dir = $conf->propal->multidir_output[$conf->entity];
291 $file = $dir."/SPECIMEN.pdf";
292 } else {
293 $objectref = dol_sanitizeFileName($object->ref);
294 $dir = $conf->propal->multidir_output[$object->entity ?? $conf->entity]."/".$objectref;
295 $file = $dir."/".$objectref.".pdf";
296 }
297
298 if (!file_exists($dir)) {
299 if (dol_mkdir($dir) < 0) {
300 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
301 return 0;
302 }
303 }
304
305 if (file_exists($dir)) {
306 // Add pdfgeneration hook
307 if (!is_object($hookmanager)) {
308 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
309 $hookmanager = new HookManager($this->db);
310 }
311 $hookmanager->initHooks(array('pdfgeneration'));
312 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
313 global $action;
314 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
315
316 // Set nblines with the new content of lines after hook
317 $nblines = count($object->lines);
318 //$nbpayments = count($object->getListOfPayments());
319
320 // Create pdf instance
321 $pdf = pdf_getInstance($this->format);
322 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
323 $pdf->setAutoPageBreak(true, 0);
324
325 if (class_exists('TCPDF')) {
326 $pdf->setPrintHeader(false);
327 $pdf->setPrintFooter(false);
328 }
329 $pdf->SetFont(pdf_getPDFFont($outputlangs));
330 // Set path to the background PDF File
331 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
332 $logodir = $conf->mycompany->dir_output;
333 if (!empty($conf->mycompany->multidir_output[$object->entity ?? $conf->entity])) {
334 $logodir = $conf->mycompany->multidir_output[$object->entity ?? $conf->entity];
335 }
336 $pagecount = $pdf->setSourceFile($logodir.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
337 $tplidx = $pdf->importPage(1);
338 }
339
340 $pdf->Open();
341 $pagenb = 0;
342 $pdf->SetDrawColor(128, 128, 128);
343
344 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
345 $pdf->SetSubject($outputlangs->transnoentities("PdfCommercialProposalTitle"));
346 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
347 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getAnonymisableFullName($outputlangs)));
348 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfCommercialProposalTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
349 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
350 $pdf->SetCompression(false);
351 }
352
353 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
354 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
355
356 // Set $this->atleastonediscount if you have at least one discount
357 for ($i = 0; $i < $nblines; $i++) {
358 if ($object->lines[$i]->remise_percent) {
359 $this->atleastonediscount++;
360 }
361 }
362 if (empty($this->atleastonediscount)) {
363 $delta = ($this->postotalht - $this->posxdiscount);
364 $this->posxpicture += $delta;
365 $this->posxtva += $delta;
366 $this->posxup += $delta;
367 $this->posxqty += $delta;
368 $this->posxunit += $delta;
369 $this->posxdiscount += $delta;
370 // post of fields after are not modified, stay at same position
371 }
372
373 // New page
374 $pdf->AddPage();
375 if (!empty($tplidx)) {
376 $pdf->useTemplate($tplidx);
377 }
378 $pagenb++;
379
380 $heightforinfotot = 40; // Height reserved to output the info and total part
381 $heightforsignature = !getDolGlobalString('PROPAL_DISABLE_SIGNATURE') ? (pdfGetHeightForHtmlContent($pdf, $outputlangs->transnoentities("ProposalCustomerSignature")) + 10) : 0;
382 $heightforfreetext = getDolGlobalInt('MAIN_PDF_FREETEXT_HEIGHT', 5); // Height reserved to output the free text on last page
383 $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
384 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
385 $heightforfooter += 6;
386 }
387 //print $heightforinfotot + $heightforsignature + $heightforfreetext + $heightforfooter;exit;
388
389 $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis);
390 $pdf->SetFont('', '', $default_font_size - 1);
391 $pdf->MultiCell(0, 3, ''); // Set interline to 3
392 $pdf->SetTextColor(0, 0, 0);
393
394
395 $tab_top = 80 + $this->marge_haute + $top_shift;
396 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 32 + $this->marge_haute + $top_shift : $this->marge_haute);
397
398 // Incoterm
399 $height_incoterms = 0;
400 if (isModEnabled('incoterm')) {
401 $desc_incoterms = $object->getIncotermsForPDF();
402 if ($desc_incoterms) {
403 $tab_top -= 2;
404
405 $pdf->SetFont('', '', $default_font_size - 1);
406 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
407 $nexY = $pdf->GetY();
408 $height_incoterms = $nexY - $tab_top;
409
410 // Rect takes a length in 3rd parameter
411 $pdf->SetDrawColor(192, 192, 192);
412 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 3, $this->corner_radius, '1234', 'D');
413
414 $tab_top = $nexY + 6;
415 $height_incoterms += 4;
416 }
417 }
418
419 // Displays notes
420 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
421 if (getDolGlobalString('MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE')) {
422 // Get first sale rep
423 if (is_object($object->thirdparty)) {
424 $salereparray = $object->thirdparty->getSalesRepresentatives($user);
425 $salerepobj = new User($this->db);
426 $salerepobj->fetch($salereparray[0]['id']);
427 if (!empty($salerepobj->signature)) {
428 $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
429 }
430 }
431 }
432 // Extrafields in note
433 $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
434 if (!empty($extranote)) {
435 $notetoshow = dol_concatdesc((string) $notetoshow, $extranote);
436 }
437 if (getDolGlobalString('MAIN_ADD_CREATOR_IN_NOTE') && $object->user_author_id > 0) {
438 $tmpuser = new User($this->db);
439 $tmpuser->fetch($object->user_author_id);
440
441
442 $creator_info = $langs->trans("CaseFollowedBy").' '.$tmpuser->getFullName($langs);
443 if ($tmpuser->email) {
444 $creator_info .= ', '.$langs->trans("EMail").': '.$tmpuser->email;
445 }
446 if ($tmpuser->office_phone) {
447 $creator_info .= ', '.$langs->trans("Phone").': '.$tmpuser->office_phone;
448 }
449
450 $notetoshow = dol_concatdesc((string) $notetoshow, $creator_info);
451 }
452
453 if ($notetoshow) {
454 $tab_top -= 2;
455
456 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
457 complete_substitutions_array($substitutionarray, $outputlangs, $object);
458 $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
459 $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
460
461 $pdf->SetFont('', '', $default_font_size - 1);
462 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($notetoshow), 0, 1);
463 $nexY = $pdf->GetY();
464 $height_note = $nexY - $tab_top;
465
466 // Rect takes a length in 3rd parameter
467 $pdf->SetDrawColor(192, 192, 192);
468 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 2, $this->corner_radius, '1234', 'D');
469
470 $tab_top = $nexY + 6;
471 }
472
473 $iniY = $tab_top + 7;
474 $curY = $tab_top + 7;
475 $nexY = $tab_top + 7;
476
477 // Loop on each lines
478 for ($i = 0; $i < $nblines; $i++) {
479 $curY = $nexY;
480 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
481 $pdf->SetTextColor(0, 0, 0);
482
483 // Define size of image if we need it
484 $imglinesize = array();
485 if (!empty($realpatharray[$i])) {
486 $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
487 }
488
489 $pdf->setTopMargin($tab_top_newpage);
490 $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
491 $pageposbefore = $pdf->getPage();
492
493 $showpricebeforepagebreak = 1;
494 $posYAfterImage = 0;
495 $posYAfterDescription = 0;
496
497 // We start with Photo of product line
498 if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot))) { // If photo too high, we moved completely on new page
499 $pdf->AddPage('', '', true);
500 if (!empty($tplidx)) {
501 $pdf->useTemplate($tplidx);
502 }
503 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
504 $this->_pagehead($pdf, $object, 0, $outputlangs);
505 }
506 $pdf->setPage($pageposbefore + 1);
507
508 $curY = $tab_top_newpage;
509
510 // Allows data in the first page if description is long enough to break in multiples pages
511 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
512 $showpricebeforepagebreak = 1;
513 } else {
514 $showpricebeforepagebreak = 0;
515 }
516 }
517
518 if (isset($imglinesize['width']) && isset($imglinesize['height'])) {
519 $curX = $this->posxpicture - 1;
520 $pdf->Image($realpatharray[$i], $curX + (($this->posxtva - $this->posxpicture - $imglinesize['width']) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
521 // $pdf->Image does not increase value return by getY, so we save it manually
522 $posYAfterImage = $curY + $imglinesize['height'];
523 }
524
525 // Description of product line
526 $curX = $this->posxdesc - 1;
527
528 $pdf->startTransaction();
529 pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxpicture - $curX, 3, $curX, $curY, $hideref, $hidedesc);
530 $pageposafter = $pdf->getPage();
531 if ($pageposafter > $pageposbefore) { // There is a pagebreak
532 $pdf->rollbackTransaction(true);
533 $pageposafter = $pageposbefore;
534 //print $pageposafter.'-'.$pageposbefore;exit;
535 $pdf->setPageOrientation('', true, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
536 pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxpicture - $curX, 3, $curX, $curY, $hideref, $hidedesc);
537
538 $pageposafter = $pdf->getPage();
539 $posyafter = $pdf->GetY();
540 //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
541 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot))) { // There is no space left for total+free text
542 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
543 $pdf->AddPage('', '', true);
544 if (!empty($tplidx)) {
545 $pdf->useTemplate($tplidx);
546 }
547 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
548 $this->_pagehead($pdf, $object, 0, $outputlangs);
549 }
550 $pdf->setPage($pageposafter + 1);
551 }
552 } else {
553 // We found a page break
554
555 // Allows data in the first page if description is long enough to break in multiples pages
556 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
557 $showpricebeforepagebreak = 1;
558 } else {
559 $showpricebeforepagebreak = 0;
560 }
561 }
562 } else { // No pagebreak
563 $pdf->commitTransaction();
564 }
565 $posYAfterDescription = $pdf->GetY();
566
567 $nexY = $pdf->GetY();
568 $pageposafter = $pdf->getPage();
569
570 $pdf->setPage($pageposbefore);
571 $pdf->setTopMargin($this->marge_haute);
572 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
573
574 // We suppose that a too long description or photo were moved completely on next page
575 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
576 $pdf->setPage($pageposafter);
577 $curY = $tab_top_newpage;
578 }
579
580 $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par default
581
582 // VAT Rate
583 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
584 $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
585 $pdf->SetXY($this->posxtva - 5, $curY);
586 $pdf->MultiCell($this->posxup - $this->posxtva + 4, 3, $vat_rate, 0, 'R');
587 }
588
589 // Unit price before discount
590 $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
591 $pdf->SetXY($this->posxup, $curY);
592 $pdf->MultiCell($this->posxqty - $this->posxup - 0.8, 3, $up_excl_tax, 0, 'R', false);
593
594 // Quantity
595 $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
596 $pdf->SetXY($this->posxqty, $curY);
597 $pdf->MultiCell($this->posxunit - $this->posxqty - 0.8, 4, $qty, 0, 'R'); // Enough for 6 chars
598
599 // Unit
600 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
601 $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails);
602 $pdf->SetXY($this->posxunit, $curY);
603 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 0.8, 4, $unit, 0, 'L');
604 }
605
606 // Discount on line
607 $pdf->SetXY($this->posxdiscount, $curY);
608 if ($object->lines[$i]->remise_percent) {
609 $pdf->SetXY($this->posxdiscount - 2, $curY);
610 $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
611 $pdf->MultiCell($this->postotalht - $this->posxdiscount + 2, 3, $remise_percent, 0, 'R');
612 }
613
614 // Total HT line
615 $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
616 $pdf->SetXY($this->postotalht, $curY);
617 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, $total_excl_tax, 0, 'R', false);
618
619 // // Collect total by value of vat rate into $this->tva["taux"]=total_tva
620 if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) {
621 $tvaligne = $object->lines[$i]->multicurrency_total_tva;
622 } else {
623 $tvaligne = $object->lines[$i]->total_tva;
624 }
625
626 $localtax1ligne = $object->lines[$i]->total_localtax1;
627 $localtax2ligne = $object->lines[$i]->total_localtax2;
628 $localtax1_rate = $object->lines[$i]->localtax1_tx;
629 $localtax2_rate = $object->lines[$i]->localtax2_tx;
630 $localtax1_type = $object->lines[$i]->localtax1_type;
631 $localtax2_type = $object->lines[$i]->localtax2_type;
632
633 $vatrate = (string) $object->lines[$i]->tva_tx;
634
635 // Retrieve type from database for backward compatibility with old records
636 if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
637 && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
638 $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
639 $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
640 $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
641 }
642
643 // retrieve global local tax
644 if ($localtax1_type && $localtax1ligne != 0) {
645 if (empty($this->localtax1[$localtax1_type][$localtax1_rate])) {
646 $this->localtax1[$localtax1_type][$localtax1_rate] = $localtax1ligne;
647 } else {
648 $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
649 }
650 }
651 if ($localtax2_type && $localtax2ligne != 0) {
652 if (empty($this->localtax2[$localtax2_type][$localtax2_rate])) {
653 $this->localtax2[$localtax2_type][$localtax2_rate] = $localtax2ligne;
654 } else {
655 $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
656 }
657 }
658
659 if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
660 $vatrate .= '*';
661 }
662
663 // Fill $this->tva and $this->tva_array
664 if (!isset($this->tva[$vatrate])) {
665 $this->tva[$vatrate] = 0;
666 }
667 $this->tva[$vatrate] += $tvaligne;
668 $vatcode = $object->lines[$i]->vat_src_code;
669 if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
670 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
671 }
672 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
673
674 if ($posYAfterImage > $posYAfterDescription) {
675 $nexY = $posYAfterImage;
676 }
677
678 // Add line
679 if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) {
680 $pdf->setPage($pageposafter);
681 $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(80, 80, 80)));
682 //$pdf->SetDrawColor(190,190,200);
683 $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
684 $pdf->SetLineStyle(array('dash' => 0));
685 }
686
687 $nexY += 2; // Add space between lines
688
689 // Detect if some page were added automatically and output _tableau for past pages
690 while ($pagenb < $pageposafter) {
691 $pdf->setPage($pagenb);
692 if ($pagenb == 1) {
693 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
694 } else {
695 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
696 }
697 $this->_pagefoot($pdf, $object, $outputlangs, 1);
698 $pagenb++;
699 $pdf->setPage($pagenb);
700 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
701 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
702 $this->_pagehead($pdf, $object, 0, $outputlangs);
703 }
704 if (!empty($tplidx)) {
705 $pdf->useTemplate($tplidx);
706 }
707 }
708 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { // @phan-suppress-current-line PhanUndeclaredProperty
709 if ($pagenb == 1) {
710 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
711 } else {
712 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
713 }
714 $this->_pagefoot($pdf, $object, $outputlangs, 1);
715 // New page
716 $pdf->AddPage();
717 if (!empty($tplidx)) {
718 $pdf->useTemplate($tplidx);
719 }
720 $pagenb++;
721 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
722 $this->_pagehead($pdf, $object, 0, $outputlangs);
723 }
724 }
725 }
726
727 // Show square
728 if ($pagenb == 1) {
729 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
730 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
731 } else {
732 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
733 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
734 }
735
736 // Affiche zone infos
737 $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
738
739 // Affiche zone totaux
740 $posy = $this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs);
741
742 // Affiche zone versements
743 /*
744 if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included)
745 {
746 $posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs);
747 }
748 */
749
750 // Customer signature area
751 if (!getDolGlobalString('PROPAL_DISABLE_SIGNATURE')) {
752 $posy = $this->_signature_area($pdf, $object, $posy, $outputlangs);
753
754 // Rewrite keywords to add a tag with the numero of page that contains the signature section
755 $keywords = $outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfCommercialProposalTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name);
756 $pdf->SetKeyWords($keywords." PAGESIGN=".$pdf->getPage());
757 }
758
759 // Pied de page
760 $this->_pagefoot($pdf, $object, $outputlangs);
761 if (method_exists($pdf, 'AliasNbPages')) {
762 $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod
763 }
764
765 // Add terms to sale
766 $termsofsalefilename = getDolGlobalString('MAIN_INFO_PROPAL_TERMSOFSALE');
767 if (getDolGlobalInt('MAIN_PDF_ADD_TERMSOFSALE_PROPAL') && $termsofsalefilename) {
768 $termsofsale = $conf->propal->dir_output.'/'.$termsofsalefilename;
769 if (!empty($conf->propal->multidir_output[$object->entity ?? $conf->entity])) {
770 $termsofsale = $conf->propal->multidir_output[$object->entity ?? $conf->entity].'/'.$termsofsalefilename;
771 }
772 if (file_exists($termsofsale) && is_readable($termsofsale)) {
773 $pagecount = $pdf->setSourceFile($termsofsale);
774 for ($i = 1; $i <= $pagecount; $i++) {
775 $tplIdx = $pdf->importPage($i);
776 if ($tplIdx !== false) {
777 $s = $pdf->getTemplatesize($tplIdx);
778 $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
779 $pdf->useTemplate($tplIdx);
780 } else {
781 setEventMessages(null, array($termsofsale.' cannot be added, probably protected PDF'), 'warnings');
782 }
783 }
784 }
785 }
786
787 //If propal merge product PDF is active
788 if (getDolGlobalString('PRODUIT_PDF_MERGE_PROPAL')) {
789 require_once DOL_DOCUMENT_ROOT.'/product/class/propalmergepdfproduct.class.php';
790
791 $already_merged = array();
792 foreach ($object->lines as $line) {
793 if (!empty($line->fk_product) && !(in_array($line->fk_product, $already_merged))) {
794 // Find the desired PDF
795 $filetomerge = new Propalmergepdfproduct($this->db);
796
797 if (getDolGlobalInt('MAIN_MULTILANGS')) {
798 $filetomerge->fetch_by_product($line->fk_product, $outputlangs->defaultlang);
799 } else {
800 $filetomerge->fetch_by_product($line->fk_product);
801 }
802
803 $already_merged[] = $line->fk_product;
804
805 $product = new Product($this->db);
806 $product->fetch($line->fk_product);
807
808 if ($product->entity != $conf->entity) {
809 $entity_product_file = $product->entity;
810 } else {
811 $entity_product_file = $conf->entity;
812 }
813
814 // If PDF is selected and file is not empty
815 if (count($filetomerge->lines) > 0) {
816 foreach ($filetomerge->lines as $linefile) {
817 $filetomerge_dir = null;
818 if (!empty($linefile->id) && !empty($linefile->file_name)) {
819 if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
820 if (isModEnabled("product")) {
821 $filetomerge_dir = $conf->product->multidir_output[$entity_product_file ?? $conf->entity].'/'.get_exdir($product->id, 2, 0, 0, $product, 'product').$product->id."/photos";
822 } elseif (isModEnabled("service")) {
823 $filetomerge_dir = $conf->service->multidir_output[$entity_product_file ?? $conf->entity].'/'.get_exdir($product->id, 2, 0, 0, $product, 'product').$product->id."/photos";
824 }
825 } else {
826 if (isModEnabled("product")) {
827 $filetomerge_dir = $conf->product->multidir_output[$entity_product_file ?? $conf->entity].'/'.get_exdir(0, 0, 0, 0, $product, 'product');
828 } elseif (isModEnabled("service")) {
829 $filetomerge_dir = $conf->service->multidir_output[$entity_product_file ?? $conf->entity].'/'.get_exdir(0, 0, 0, 0, $product, 'product');
830 }
831 }
832
833 dol_syslog(get_class($this).':: upload_dir='.$filetomerge_dir, $filetomerge_dir === null ? LOG_ERR : LOG_DEBUG);
834 if ($filetomerge_dir === null) {
835 // Skip loop
836 continue;
837 }
838
839 $infile = $filetomerge_dir.'/'.$linefile->file_name;
840 if (file_exists($infile) && is_readable($infile)) {
841 $pagecount = $pdf->setSourceFile($infile);
842 for ($i = 1; $i <= $pagecount; $i++) {
843 $tplIdx = $pdf->importPage($i);
844 if ($tplIdx !== false) {
845 $s = $pdf->getTemplatesize($tplIdx);
846 $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
847 $pdf->useTemplate($tplIdx);
848 } else {
849 setEventMessages(null, array($infile.' cannot be added, probably protected PDF'), 'warnings');
850 }
851 }
852 }
853 }
854 }
855 }
856 }
857 }
858 }
859
860 $pdf->Close();
861
862 $pdf->Output($file, 'F');
863
864 //Add pdfgeneration hook
865 $hookmanager->initHooks(array('pdfgeneration'));
866 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
867 global $action;
868 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
869 $this->warnings = $hookmanager->warnings;
870 if ($reshook < 0) {
871 $this->error = $hookmanager->error;
872 $this->errors = $hookmanager->errors;
873 dolChmod($file);
874 return -1;
875 }
876
877 dolChmod($file);
878
879 $this->result = array('fullpath' => $file);
880
881 return 1; // No error
882 } else {
883 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
884 return 0;
885 }
886 } else {
887 $this->error = $langs->trans("ErrorConstantNotDefined", "PROP_OUTPUTDIR");
888 return 0;
889 }
890 }
891
892 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
893 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
903 protected function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
904 {
905 // phpcs:enable
906 return 1;
907 }
908
909 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
910 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
920 protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
921 {
922 // phpcs:enable
923 global $conf, $mysoc;
924 $default_font_size = pdf_getPDFFontSize($outputlangs);
925
926 $pdf->SetFont('', '', $default_font_size - 1);
927
928 $diffsizetitle = getDolGlobalInt('PDF_DIFFSIZE_TITLE', 3);
929
930 // If France, show VAT mention if not applicable
931 if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
932 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
933 $pdf->SetXY($this->marge_gauche, $posy);
934 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', false);
935
936 $posy = $pdf->GetY() + 4;
937 }
938
939 $posxval = 52;
940 if (getDolGlobalString('MAIN_PDF_DELIVERY_DATE_TEXT')) {
941 $displaydate = "daytext";
942 } else {
943 $displaydate = "day";
944 }
945
946 // Show shipping date
947 if (!empty($object->delivery_date)) {
948 $outputlangs->load("sendings");
949 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
950 $pdf->SetXY($this->marge_gauche, $posy);
951 $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
952 $pdf->MultiCell(80, 4, $titre, 0, 'L');
953 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
954 $pdf->SetXY($posxval, $posy);
955 $dlp = dol_print_date($object->delivery_date, $displaydate, false, $outputlangs, true);
956 $pdf->MultiCell(80, 4, $dlp, 0, 'L');
957
958 $posy = $pdf->GetY() + 1;
959 } elseif ($object->availability_code || $object->availability) { // Show availability conditions
960 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
961 $pdf->SetXY($this->marge_gauche, $posy);
962 $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
963 $pdf->MultiCell(80, 4, $titre, 0, 'L');
964 $pdf->SetTextColor(0, 0, 0);
965 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
966 $pdf->SetXY($posxval, $posy);
967 $lib_availability = ($outputlangs->transnoentities("AvailabilityType".$object->availability_code) != 'AvailabilityType'.$object->availability_code) ? $outputlangs->transnoentities("AvailabilityType".$object->availability_code) : $outputlangs->convToOutputCharset($object->availability);
968 $lib_availability = str_replace('\n', "\n", $lib_availability);
969 $pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
970
971 $posy = $pdf->GetY() + 1;
972 }
973
974 // Show delivery mode
975 if (!getDolGlobalString('PROPOSAL_PDF_HIDE_DELIVERYMODE') && $object->shipping_method_id > 0) {
976 $outputlangs->load("sendings");
977
978 $shipping_method_id = $object->shipping_method_id;
979 if (getDolGlobalString('SOCIETE_ASK_FOR_SHIPPING_METHOD') && !empty($this->emetteur->shipping_method_id)) {
980 $shipping_method_id = $this->emetteur->shipping_method_id;
981 }
982 $shipping_method_code = dol_getIdFromCode($this->db, (string) $shipping_method_id, 'c_shipment_mode', 'rowid', 'code');
983 $shipping_method_label = dol_getIdFromCode($this->db, (string) $shipping_method_id, 'c_shipment_mode', 'rowid', 'libelle');
984
985 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
986 $pdf->SetXY($this->marge_gauche, $posy);
987 $titre = $outputlangs->transnoentities("SendingMethod").':';
988 $pdf->MultiCell(43, 4, $titre, 0, 'L');
989
990 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
991 $pdf->SetXY($posxval, $posy);
992 $lib_condition_paiement = ($outputlangs->transnoentities("SendingMethod".strtoupper($shipping_method_code)) != "SendingMethod".strtoupper($shipping_method_code)) ? $outputlangs->trans("SendingMethod".strtoupper($shipping_method_code)) : $shipping_method_label;
993 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
994 $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
995
996 $posy = $pdf->GetY() + 1;
997 }
998
999 // Show payments conditions
1000 if (!getDolGlobalString('PROPOSAL_PDF_HIDE_PAYMENTTERM') && $object->cond_reglement_code) {
1001 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1002 $pdf->SetXY($this->marge_gauche, $posy);
1003 $titre = $outputlangs->transnoentities("PaymentConditions").':';
1004 $pdf->MultiCell(43, 4, $titre, 0, 'L');
1005
1006 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1007 $pdf->SetXY($posxval, $posy);
1008 $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);
1009 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
1010 if ($object->deposit_percent > 0) {
1011 $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', $object->deposit_percent, $lib_condition_paiement);
1012 }
1013 $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
1014
1015 $posy = $pdf->GetY() + 3;
1016 }
1017
1018 if (!getDolGlobalString('PROPOSAL_PDF_HIDE_PAYMENTMODE')) {
1019 // Show payment mode
1020 if ($object->mode_reglement_code
1021 && $object->mode_reglement_code != 'CHQ'
1022 && $object->mode_reglement_code != 'VIR') {
1023 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1024 $pdf->SetXY($this->marge_gauche, $posy);
1025 $titre = $outputlangs->transnoentities("PaymentMode").':';
1026 $pdf->MultiCell(80, 5, $titre, 0, 'L');
1027 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1028 $pdf->SetXY($posxval, $posy);
1029 $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);
1030 $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
1031
1032 $posy = $pdf->GetY() + 2;
1033 }
1034
1035 // Show payment mode CHQ
1036 if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') {
1037 // Si mode reglement non force ou si force a CHQ
1038 if (getDolGlobalInt('FACTURE_CHQ_NUMBER')) {
1039 if (getDolGlobalInt('FACTURE_CHQ_NUMBER') > 0) {
1040 $account = new Account($this->db);
1041 $account->fetch(getDolGlobalInt('FACTURE_CHQ_NUMBER'));
1042
1043 $pdf->SetXY($this->marge_gauche, $posy);
1044 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1045 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->owner_name), 0, 'L', false);
1046 $posy = $pdf->GetY() + 1;
1047
1048 if (!getDolGlobalString('MAIN_PDF_HIDE_CHQ_ADDRESS')) {
1049 $pdf->SetXY($this->marge_gauche, $posy);
1050 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1051 $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', false);
1052 $posy = $pdf->GetY() + 2;
1053 }
1054 }
1055 if (getDolGlobalInt('FACTURE_CHQ_NUMBER') == -1) {
1056 $pdf->SetXY($this->marge_gauche, $posy);
1057 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1058 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', false);
1059 $posy = $pdf->GetY() + 1;
1060
1061 if (!getDolGlobalString('MAIN_PDF_HIDE_CHQ_ADDRESS')) {
1062 $pdf->SetXY($this->marge_gauche, $posy);
1063 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1064 $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', false);
1065 $posy = $pdf->GetY() + 2;
1066 }
1067 }
1068 }
1069 }
1070
1071 // If payment mode not forced or forced to VIR, show payment with BAN
1072 if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') {
1073 if (!empty($object->fk_account) || !empty($object->fk_bank) || getDolGlobalInt('FACTURE_RIB_NUMBER')) {
1074 $bankid = (empty($object->fk_account) ? getDolGlobalInt('FACTURE_RIB_NUMBER') : $object->fk_account);
1075 if (!empty($object->fk_bank) && $object->fk_bank > 0) {
1076 $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
1077 }
1078 $account = new Account($this->db);
1079 $account->fetch((int) $bankid);
1080
1081 $curx = $this->marge_gauche;
1082 $cury = $posy;
1083
1084 $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
1085
1086 $posy += 2;
1087 }
1088 }
1089 }
1090
1091 return $posy;
1092 }
1093
1094 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1095 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1107 protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis = null)
1108 {
1109 // phpcs:enable
1110 global $mysoc;
1111
1112 $default_font_size = pdf_getPDFFontSize($outputlangs);
1113
1114 $tab2_top = $posy;
1115 $tab2_hl = 4;
1116 $pdf->SetFont('', '', $default_font_size - 1);
1117
1118 // Total table
1119 $col1x = 120;
1120 $col2x = 170;
1121 if ($this->page_largeur < 210) { // To work with US executive format
1122 $col2x -= 20;
1123 }
1124 $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
1125
1126 $useborder = 0;
1127 $index = 0;
1128
1129 // Get Total HT
1130 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
1131
1132 // Total discount
1133 $total_discount_on_lines = 0;
1134 $multicurrency_total_discount_on_lines = 0;
1135 foreach ($object->lines as $i => $line) {
1136 $resdiscount = pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, 2);
1137 $multicurrency_resdiscount = pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, 2, 1);
1138
1139 $total_discount_on_lines += (is_numeric($resdiscount) ? $resdiscount : 0);
1140 $multicurrency_total_discount_on_lines += (is_numeric($multicurrency_resdiscount) ? $multicurrency_resdiscount : 0);
1141 // If line was a negative line, we do not count the discount as a discount
1142 if ($line->total_ht < 0) {
1143 $total_discount_on_lines += -$line->total_ht;
1144 $multicurrency_total_discount_on_lines += -$line->multicurrency_total_ht;
1145 }
1146 }
1147
1148 if ($total_discount_on_lines > 0) {
1149 if ($this->showAmountBeforeDiscount) {
1150 // Show total NET before discount
1151 $pdf->SetFillColor(255, 255, 255);
1152 $pdf->SetXY($col1x, $tab2_top);
1153 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHTBeforeDiscount") . (is_object($outputlangsbis) ? ' / ' . $outputlangsbis->transnoentities("TotalHTBeforeDiscount") : ''), 0, 'L', true);
1154 $pdf->SetXY($col2x, $tab2_top);
1155
1156 $total_before_discount_to_show = ((isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? ($object->multicurrency_total_ht + $multicurrency_total_discount_on_lines) : ($object->total_ht + $total_discount_on_lines));
1157 $pdf->MultiCell($largcol2, $tab2_hl, price($total_before_discount_to_show, 0, $outputlangs), 0, 'R', true);
1158
1159 $index++;
1160 }
1161
1162 if ($this->showDiscountAmount) {
1163 $pdf->SetFillColor(255, 255, 255);
1164 $pdf->SetXY($col1x, $tab2_top + $tab2_hl);
1165 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalDiscount") . (is_object($outputlangsbis) ? ' / ' . $outputlangsbis->transnoentities("TotalDiscount") : ''), 0, 'L', true);
1166 $pdf->SetXY($col2x, $tab2_top + $tab2_hl);
1167
1168 $total_discount_to_show = ((isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $multicurrency_total_discount_on_lines : $total_discount_on_lines);
1169 $pdf->MultiCell($largcol2, $tab2_hl, price($total_discount_to_show, 0, $outputlangs), 0, 'R', true);
1170
1171 $index++;
1172 }
1173 }
1174
1175 // Total HT
1176 $pdf->SetFillColor(255, 255, 255);
1177 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1178 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', true);
1179
1180 $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
1181 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1182 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0), 0, $outputlangs), 0, 'R', true);
1183
1184 // Show VAT by rates and total
1185 $pdf->SetFillColor(248, 248, 248);
1186
1187 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
1188
1189 $this->atleastoneratenotnull = 0;
1190 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
1191 $tvaisnull = (!empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000']));
1192 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL') && $tvaisnull) {
1193 // Nothing to do
1194 } else {
1195 //Local tax 1 before VAT
1196 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1197 if (in_array((string) $localtax_type, array('1', '3', '5'))) {
1198 continue;
1199 }
1200
1201 foreach ($localtax_rate as $tvakey => $tvaval) {
1202 if ($tvakey != 0) { // On affiche pas taux 0
1203 //$this->atleastoneratenotnull++;
1204
1205 $index++;
1206 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1207
1208 $tvacompl = '';
1209 if (preg_match('/\*/', $tvakey)) {
1210 $tvakey = str_replace('*', '', $tvakey);
1211 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1212 }
1213 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
1214
1215 if (getDolGlobalString('PDF_LOCALTAX1_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1216 $totalvat .= $tvacompl;
1217 } else {
1218 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
1219 }
1220
1221 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
1222
1223 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1224
1225 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1226 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', true);
1227 }
1228 }
1229 }
1230
1231 //Local tax 2 before VAT
1232 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1233 if (in_array((string) $localtax_type, array('1', '3', '5'))) {
1234 continue;
1235 }
1236
1237 foreach ($localtax_rate as $tvakey => $tvaval) {
1238 if ($tvakey != 0) { // On affiche pas taux 0
1239 //$this->atleastoneratenotnull++;
1240
1241 $index++;
1242 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1243
1244 $tvacompl = '';
1245 if (preg_match('/\*/', $tvakey)) {
1246 $tvakey = str_replace('*', '', $tvakey);
1247 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1248 }
1249 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
1250
1251 if (getDolGlobalString('PDF_LOCALTAX2_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1252 $totalvat .= $tvacompl;
1253 } else {
1254 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
1255 }
1256
1257 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
1258
1259 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1260
1261 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1262 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', true);
1263 }
1264 }
1265 }
1266
1267 // VAT
1268 foreach ($this->tva_array as $tvakey => $tvaval) {
1269 if ($tvakey != 0) { // On affiche pas taux 0
1270 $this->atleastoneratenotnull++;
1271
1272 $index++;
1273 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1274
1275 $tvacompl = '';
1276 if (preg_match('/\*/', $tvakey)) {
1277 $tvakey = str_replace('*', '', $tvakey);
1278 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1279 }
1280 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
1281 $totalvat .= ' ';
1282 if (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'rateonly') {
1283 $totalvat .= vatrate((string) $tvaval['vatrate'], true).$tvacompl;
1284 } elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'codeonly') {
1285 $totalvat .= $tvaval['vatcode'].$tvacompl;
1286 } elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1287 $totalvat .= $tvacompl;
1288 } else {
1289 $totalvat .= vatrate((string) $tvaval['vatrate'], true).($tvaval['vatcode'] ? ' ('.$tvaval['vatcode'].')' : '').$tvacompl;
1290 }
1291 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
1292
1293 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1294 $pdf->MultiCell($largcol2, $tab2_hl, price(price2num($tvaval['amount'], 'MT'), 0, $outputlangs), 0, 'R', true);
1295 }
1296 }
1297
1298 //Local tax 1 after VAT
1299 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1300 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1301 continue;
1302 }
1303
1304 foreach ($localtax_rate as $tvakey => $tvaval) {
1305 if ($tvakey != 0) { // On affiche pas taux 0
1306 //$this->atleastoneratenotnull++;
1307
1308 $index++;
1309 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1310
1311 $tvacompl = '';
1312 if (preg_match('/\*/', $tvakey)) {
1313 $tvakey = str_replace('*', '', $tvakey);
1314 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1315 }
1316 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
1317
1318 if (getDolGlobalString('PDF_LOCALTAX1_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1319 $totalvat .= $tvacompl;
1320 } else {
1321 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
1322 }
1323
1324 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
1325
1326 $total_localtax = ((isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1327
1328 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1329 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', true);
1330 }
1331 }
1332 }
1333
1334 //Local tax 2 after VAT
1335 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1336 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1337 continue;
1338 }
1339
1340 foreach ($localtax_rate as $tvakey => $tvaval) {
1341 // retrieve global local tax
1342 if ($tvakey != 0) { // On affiche pas taux 0
1343 //$this->atleastoneratenotnull++;
1344
1345 $index++;
1346 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1347
1348 $tvacompl = '';
1349 if (preg_match('/\*/', $tvakey)) {
1350 $tvakey = str_replace('*', '', $tvakey);
1351 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1352 }
1353 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
1354
1355 if (getDolGlobalString('PDF_LOCALTAX2_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1356 $totalvat .= $tvacompl;
1357 } else {
1358 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
1359 }
1360
1361 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
1362
1363 $total_localtax = ((isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1364
1365 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1366 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', true);
1367 }
1368 }
1369 }
1370 //}
1371
1372 // Total TTC
1373 $index++;
1374 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1375 $pdf->SetTextColor(0, 0, 60);
1376 $pdf->SetFillColor(224, 224, 224);
1377 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', true);
1378
1379 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1380 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', true);
1381 }
1382 }
1383
1384 $pdf->SetTextColor(0, 0, 0);
1385
1386 $resteapayer = 0;
1387 /*
1388 $resteapayer = $object->total_ttc - $deja_regle;
1389 if (!empty($object->paye)) $resteapayer=0;
1390 */
1391
1392 if ($deja_regle > 0) {
1393 $index++;
1394
1395 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1396 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', false);
1397
1398 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1399 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', false);
1400
1401 /*
1402 if ($object->close_code == 'discount_vat') {
1403 $index++;
1404 $pdf->SetFillColor(255,255,255);
1405
1406 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1407 $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1);
1408
1409 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1410 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle, 0, $outputlangs), $useborder, 'R', 1);
1411
1412 $resteapayer=0;
1413 }
1414 */
1415
1416 $index++;
1417 $pdf->SetTextColor(0, 0, 60);
1418 $pdf->SetFillColor(224, 224, 224);
1419 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1420 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', true);
1421
1422 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1423 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', true);
1424
1425 $pdf->SetFont('', '', $default_font_size - 1);
1426 $pdf->SetTextColor(0, 0, 0);
1427 }
1428
1429 $index++;
1430 return ($tab2_top + ($tab2_hl * $index));
1431 }
1432
1433 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1447 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
1448 {
1449 global $conf;
1450
1451 // Force to disable hidetop and hidebottom
1452 $hidebottom = 0;
1453 if ($hidetop) {
1454 $hidetop = -1;
1455 }
1456
1457 $currency = !empty($currency) ? $currency : $conf->currency;
1458 $default_font_size = pdf_getPDFFontSize($outputlangs);
1459
1460 // Amount in (at tab_top - 1)
1461 $pdf->SetTextColor(0, 0, 0);
1462 $pdf->SetFont('', '', $default_font_size - 2);
1463
1464 if (empty($hidetop)) {
1465 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1466 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1467 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1468
1469 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1470 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
1471 $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')));
1472 }
1473 }
1474
1475 $pdf->SetDrawColor(128, 128, 128);
1476 $pdf->SetFont('', '', $default_font_size - 1);
1477
1478 // Output Rect
1479 $this->printRoundedRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $this->corner_radius, $hidetop, $hidebottom, 'D'); // Rect takes a length in 3rd parameter and 4th parameter
1480
1481 if (empty($hidetop)) {
1482 $pdf->line($this->marge_gauche, $tab_top + 5, $this->page_largeur - $this->marge_droite, $tab_top + 5); // line takes a position y in 2nd parameter and 4th parameter
1483
1484 $pdf->SetXY($this->posxdesc - 1, $tab_top + 1);
1485 $pdf->MultiCell(108, 2, $outputlangs->transnoentities("Designation"), '', 'L');
1486 }
1487
1488 if (getDolGlobalString('MAIN_GENERATE_PROPOSALS_WITH_PICTURE')) {
1489 $pdf->line($this->posxpicture - 1, $tab_top, $this->posxpicture - 1, $tab_top + $tab_height);
1490 //if (empty($hidetop)) {
1491 //$pdf->SetXY($this->posxpicture-1, $tab_top+1);
1492 //$pdf->MultiCell($this->posxtva-$this->posxpicture-1,2, $outputlangs->transnoentities("Photo"),'','C');
1493 //}
1494 }
1495
1496 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
1497 $pdf->line($this->posxtva - 1, $tab_top, $this->posxtva - 1, $tab_top + $tab_height);
1498 if (empty($hidetop)) {
1499 // Not do -3 and +3 instead of -1 -1 to have more space for text 'Sales tax'
1500 $pdf->SetXY($this->posxtva - 3, $tab_top + 1);
1501 $pdf->MultiCell($this->posxup - $this->posxtva + 3, 2, $outputlangs->transnoentities("VAT"), '', 'C');
1502 }
1503 }
1504
1505 $pdf->line($this->posxup - 1, $tab_top, $this->posxup - 1, $tab_top + $tab_height);
1506 if (empty($hidetop)) {
1507 $pdf->SetXY($this->posxup - 1, $tab_top + 1);
1508 $pdf->MultiCell($this->posxqty - $this->posxup - 1, 2, $outputlangs->transnoentities("PriceUHT"), '', 'C');
1509 }
1510
1511 $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height);
1512 if (empty($hidetop)) {
1513 $pdf->SetXY($this->posxqty - 1, $tab_top + 1);
1514 $pdf->MultiCell($this->posxunit - $this->posxqty - 1, 2, $outputlangs->transnoentities("Qty"), '', 'C');
1515 }
1516
1517 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1518 $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height);
1519 if (empty($hidetop)) {
1520 $pdf->SetXY($this->posxunit - 1, $tab_top + 1);
1521 $pdf->MultiCell(
1522 $this->posxdiscount - $this->posxunit - 1,
1523 2,
1524 $outputlangs->transnoentities("Unit"),
1525 '',
1526 'C'
1527 );
1528 }
1529 }
1530
1531 $pdf->line($this->posxdiscount - 1, $tab_top, $this->posxdiscount - 1, $tab_top + $tab_height);
1532 if (empty($hidetop)) {
1533 if ($this->atleastonediscount) {
1534 $pdf->SetXY($this->posxdiscount - 1, $tab_top + 1);
1535 $pdf->MultiCell($this->postotalht - $this->posxdiscount + 1, 2, $outputlangs->transnoentities("ReductionShort"), '', 'C');
1536 }
1537 }
1538 if ($this->atleastonediscount) {
1539 $pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
1540 }
1541 if (empty($hidetop)) {
1542 $pdf->SetXY($this->postotalht - 1, $tab_top + 1);
1543 $pdf->MultiCell(30, 2, $outputlangs->transnoentities("TotalHTShort"), '', 'C');
1544 }
1545 }
1546
1547 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1558 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null)
1559 {
1560 global $conf, $langs;
1561
1562 $ltrdirection = 'L';
1563 if ($outputlangs->trans("DIRECTION") == 'rtl') {
1564 $ltrdirection = 'R';
1565 }
1566
1567 // Load traductions files required by page
1568 $outputlangs->loadLangs(array("main", "propal", "companies", "bills"));
1569
1570 $default_font_size = pdf_getPDFFontSize($outputlangs);
1571
1572 pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
1573
1574 $pdf->SetTextColor(0, 0, 60);
1575 $pdf->SetFont('', 'B', $default_font_size + 3);
1576
1577 $w = 100;
1578
1579 $posy = $this->marge_haute;
1580 $posx = $this->page_largeur - $this->marge_droite - $w;
1581
1582 $pdf->SetXY($this->marge_gauche, $posy);
1583
1584 // Logo
1585 $logodir = $conf->mycompany->dir_output;
1586 if (!empty($conf->mycompany->multidir_output[$object->entity ?? $conf->entity])) {
1587 $logodir = $conf->mycompany->multidir_output[$object->entity ?? $conf->entity];
1588 }
1589 pdf_writeLogoOrCompanyName($pdf, $outputlangs, $this->emetteur, $logodir, $this->marge_gauche, $posy, $w, $default_font_size, $ltrdirection);
1590
1591 $pdf->SetFont('', 'B', $default_font_size + 3);
1592 $pdf->SetXY($posx, $posy);
1593 $pdf->SetTextColor(0, 0, 60);
1594 $title = $outputlangs->transnoentities("PdfCommercialProposalTitle");
1595 $title .= ' '.$outputlangs->convToOutputCharset($object->ref);
1596 if ($object->statut == $object::STATUS_DRAFT) {
1597 $pdf->SetTextColor(128, 0, 0);
1598 $title .= ' - '.$outputlangs->transnoentities("NotValidated");
1599 }
1600 $pdf->MultiCell($w, 4, $title, '', 'R');
1601
1602 $pdf->SetFont('', 'B', $default_font_size);
1603
1604 /*
1605 $posy += 5;
1606 $pdf->SetXY($posx, $posy);
1607 $pdf->SetTextColor(0, 0, 60);
1608 $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref), '', 'R');
1609 */
1610
1611 $posy += 3;
1612 $pdf->SetFont('', '', $default_font_size - 2);
1613
1614 $ref_customer = $object->ref_customer ?: $object->ref_client;
1615 if ($ref_customer) {
1616 $posy += 4;
1617 $pdf->SetXY($posx, $posy);
1618 $pdf->SetTextColor(0, 0, 60);
1619 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($ref_customer), '', 'R');
1620 }
1621
1622 if (getDolGlobalString('PDF_SHOW_PROJECT_TITLE')) {
1623 $object->fetchProject();
1624 if (!empty($object->project->title)) {
1625 $posy += 3;
1626 $pdf->SetXY($posx, $posy);
1627 $pdf->SetTextColor(0, 0, 60);
1628 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ". $object->project->title, '', 'R');
1629 }
1630 }
1631
1632 if (getDolGlobalString('PDF_SHOW_PROJECT')) {
1633 $object->fetchProject();
1634 if (!empty($object->project->ref)) {
1635 $outputlangs->load("projects");
1636 $posy += 3;
1637 $pdf->SetXY($posx, $posy);
1638 $pdf->SetTextColor(0, 0, 60);
1639 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ". $object->project->ref, '', 'R');
1640 }
1641 }
1642
1643 if (getDolGlobalString('MAIN_PDF_DATE_TEXT')) {
1644 $displaydate = "daytext";
1645 } else {
1646 $displaydate = "day";
1647 }
1648
1649 //$posy += 4;
1650 $posy = $pdf->getY();
1651 $pdf->SetXY($posx, $posy);
1652 $pdf->SetTextColor(0, 0, 60);
1653 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DatePropal")." : ".dol_print_date($object->date, $displaydate, false, $outputlangs, true), '', 'R');
1654
1655 $posy += 4;
1656 $pdf->SetXY($posx, $posy);
1657 $pdf->SetTextColor(0, 0, 60);
1658 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateEndPropal")." : ".dol_print_date($object->fin_validite, $displaydate, false, $outputlangs, true), '', 'R');
1659
1660 if (!getDolGlobalString('MAIN_PDF_HIDE_CUSTOMER_CODE') && $object->thirdparty->code_client) {
1661 $posy += 4;
1662 $pdf->SetXY($posx, $posy);
1663 $pdf->SetTextColor(0, 0, 60);
1664 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities((string) $object->thirdparty->code_client), '', 'R');
1665 }
1666
1667 if (!getDolGlobalString('MAIN_PDF_HIDE_CUSTOMER_ACCOUNTING_CODE') && $object->thirdparty->code_compta_client) {
1668 $posy += 4;
1669 $pdf->SetXY($posx, $posy);
1670 $pdf->SetTextColor(0, 0, 60);
1671 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerAccountancyCode")." : ".$outputlangs->transnoentities((string) $object->thirdparty->code_compta_client), '', 'R');
1672 }
1673
1674 // Get contact
1675 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1676 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1677 if (count($arrayidcontact) > 0) {
1678 $usertmp = new User($this->db);
1679 $usertmp->fetch($arrayidcontact[0]);
1680 $posy += 4;
1681 $pdf->SetXY($posx, $posy);
1682 $pdf->SetTextColor(0, 0, 60);
1683 $pdf->MultiCell($w, 3, $outputlangs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
1684 }
1685 }
1686
1687 $posy += 2;
1688
1689 $top_shift = 0;
1690 // Show list of linked objects
1691 $current_y = $pdf->getY();
1692 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
1693 if ($current_y < $pdf->getY()) {
1694 $top_shift = $pdf->getY() - $current_y;
1695 }
1696
1697 if ($showaddress) {
1698 // Sender properties
1699 $carac_emetteur = '';
1700 // Add internal contact of object if defined
1701 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1702 if (count($arrayidcontact) > 0) {
1703 $object->fetch_user($arrayidcontact[0]);
1704 $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1705 $carac_emetteur .= $labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1706 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1707 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1708 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1709 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1710 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1711 $carac_emetteur .= "\n";
1712 }
1713
1714 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1715
1716 // Show sender
1717 $posy = 32 + $this->marge_haute + $top_shift;
1718 $posx = $this->marge_gauche;
1719 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1720 $posx = $this->page_largeur - $this->marge_droite - 80;
1721 }
1722 $hautcadre = 40;
1723
1724 // Show sender frame
1725 if (!getDolGlobalString('MAIN_PDF_NO_SENDER_FRAME')) {
1726 $pdf->SetTextColor(0, 0, 0);
1727 $pdf->SetFont('', '', $default_font_size - 2);
1728 $pdf->SetXY($posx, $posy - 5);
1729 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1730 $pdf->SetXY($posx, $posy);
1731 $pdf->SetFillColor(230, 230, 230);
1732 $pdf->RoundedRect($posx, $posy, 82, $hautcadre, $this->corner_radius, '1234', 'F');
1733 $pdf->SetTextColor(0, 0, 60);
1734 }
1735
1736 // Show company name
1737 if (!getDolGlobalString('MAIN_PDF_HIDE_SENDER_NAME')) {
1738 $pdf->SetXY($posx + 2, $posy + 3);
1739 $pdf->SetFont('', 'B', $default_font_size);
1740 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1741 $posy = $pdf->getY();
1742 }
1743
1744 // Show sender information
1745 $pdf->SetXY($posx + 2, $posy);
1746 $pdf->SetFont('', '', $default_font_size - 1);
1747 $pdf->MultiCell(80, 4, $carac_emetteur, 0, $ltrdirection);
1748
1749
1750 // If CUSTOMER contact defined, we use it
1751 $usecontact = false;
1752 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1753 if (count($arrayidcontact) > 0) {
1754 $usecontact = true;
1755 $result = $object->fetch_contact($arrayidcontact[0]);
1756 }
1757
1758 // Recipient name
1759 if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || getDolGlobalString('MAIN_USE_COMPANY_NAME_OF_CONTACT')))) {
1760 $thirdparty = $object->contact;
1761 } else {
1762 $thirdparty = $object->thirdparty;
1763 }
1764
1765 $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1766
1767 $mode = 'target';
1768 $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), ($usecontact ? 1 : 0), $mode, $object);
1769
1770 // Show recipient
1771 $widthrecbox = 100;
1772 if ($this->page_largeur < 210) {
1773 $widthrecbox = 84; // To work with US executive format
1774 }
1775 $posy = 32 + $this->marge_haute + $top_shift;
1776 $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1777 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1778 $posx = $this->marge_gauche;
1779 }
1780
1781 // Show recipient frame
1782 if (!getDolGlobalString('MAIN_PDF_NO_RECIPENT_FRAME')) {
1783 $pdf->SetTextColor(0, 0, 0);
1784 $pdf->SetFont('', '', $default_font_size - 2);
1785 $pdf->SetXY($posx + 2, $posy - 5);
1786 $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1787 $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D');
1788 }
1789
1790 // Show recipient name
1791 $pdf->SetXY($posx + 2, $posy + 3);
1792 $pdf->SetFont('', 'B', $default_font_size);
1793 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1794 $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, $ltrdirection);
1795
1796 $posy = $pdf->getY();
1797
1798 // Show recipient information
1799 $pdf->SetFont('', '', $default_font_size - 1);
1800 $pdf->SetXY($posx + 2, $posy);
1801 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1802 $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1803 }
1804
1805 $pdf->SetTextColor(0, 0, 0);
1806
1807 return $top_shift;
1808 }
1809
1810 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1820 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1821 {
1822 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1823 return pdf_pagefoot($pdf, $outputlangs, 'PROPOSAL_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext, $this->page_largeur, $this->watermark);
1824 }
1825
1826 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1827 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1837 protected function _signature_area(&$pdf, $object, $posy, $outputlangs)
1838 {
1839 // phpcs:enable
1840 $default_font_size = pdf_getPDFFontSize($outputlangs);
1841 $tab_top = $posy + 4;
1842 $tab_hl = 4;
1843
1844 $posx = 120;
1845 $largcol = ($this->page_largeur - $this->marge_droite - $posx);
1846
1847 // Total HT
1848 $pdf->SetFillColor(255, 255, 255);
1849 $pdf->SetXY($posx, $tab_top);
1850 $pdf->SetFont('', '', $default_font_size - 2);
1851 $pdf->MultiCell($largcol, $tab_hl, $outputlangs->transnoentities("ProposalCustomerSignature"), 0, 'L', true);
1852
1853 $pdf->SetXY($posx, $tab_top + $tab_hl + 3);
1854 //$pdf->MultiCell($largcol, $tab_hl * 3, '', 1, 'R');
1855 $pdf->RoundedRect($posx, $tab_top + $tab_hl + 3, $largcol, $tab_hl * 3, $this->corner_radius, '1234', 'D');
1856 if (getDolGlobalString('MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING')) {
1857 // Can be retrieve with getSignatureAppearanceArray()
1858 // Can be also detected by putting the mouse over the area when using evince pdf reader
1859 $pdf->addEmptySignatureAppearance($posx, $tab_top + $tab_hl, $largcol, $tab_hl * 3);
1860 }
1861
1862 return ($tab_hl * 7);
1863 }
1864}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class to manage bank accounts.
printRoundedRect($pdf, $x, $y, $w, $h, $r, $hidetop=0, $hidebottom=0, $style='D')
Print a rounded rectangle on the PDF.
Class to manage hooks.
Class mere des modeles de propale.
Class to manage products or services.
Put here description of your class.
Class to manage translations.
Class to manage Dolibarr users.
Class to generate PDF proposal Azur.
_tableau_info(&$pdf, $object, $posy, $outputlangs)
Show miscellaneous information (payment mode, payment term, ...)
__construct($db)
Constructor.
_pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis=null)
Show top header of page.
_signature_area(&$pdf, $object, $posy, $outputlangs)
Show area for the customer to sign.
_tableau_versements(&$pdf, $object, $posy, $outputlangs)
Show payments table.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
Show table for lines.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
_tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis=null)
Show total to pay.
global $mysoc
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(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
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...
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='', $useCache=true)
Return an id or code from a code or id.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
getCallerInfoString()
Get caller info as a string that can be appended to a log message.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
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:3217
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2918
pdf_getFormat($outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:87
pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails=0, $multicurrency=0)
Return line total amount discount.
Definition pdf.lib.php:3249
pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1851
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:294
pdf_bank($pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank information for PDF generation.
Definition pdf.lib.php:1282
pdf_writelinedesc($pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref=0, $hidedesc=0, $issupplierline=0, $align='J')
Output line description into PDF.
Definition pdf.lib.php:1889
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:2507
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:2445
pdf_pagehead($pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition pdf.lib.php:790
pdfGetHeightForHtmlContent($pdf, $htmlcontent)
Function to try to calculate height of a HTML Content.
Definition pdf.lib.php:383
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:1464
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:273
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:479
pdf_writeLogoOrCompanyName($pdf, $outputlangs, $emetteur, $logodir, $posx, $posy, $w, $default_font_size, $align)
Output company logo on top-left of a PDF page header, or the company name as fallback text if no logo...
Definition pdf.lib.php:349
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0)
Return line unit.
Definition pdf.lib.php:2752
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2795
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2592
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:1178
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:129
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition pdf.lib.php:434
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:130
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:133