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