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