dolibarr 21.0.0-beta
pdf_einstein.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-2013 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) 2024 MDW <mdeweerd@users.noreply.github.com>
12 * Copyright (C) 2024 Nick Fragoulis
13 * Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <https://www.gnu.org/licenses/>.
27 * or see https://www.gnu.org/
28 */
29
36require_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
37require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
41
42
47{
51 public $db;
52
56 public $entity;
57
61 public $name;
62
66 public $description;
67
71 public $update_main_doc_field;
72
76 public $type;
77
82 public $version = 'dolibarr';
83
84
90 public function __construct(DoliDB $db)
91 {
92 global $conf, $langs, $mysoc;
93
94 // Translations
95 $langs->loadLangs(array("main", "bills", "products"));
96
97 $this->db = $db;
98 $this->name = "einstein";
99 $this->description = $langs->trans('PDFEinsteinDescription');
100 $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
101
102 // Dimension page
103 $this->type = 'pdf';
104 $formatarray = pdf_getFormat();
105 $this->page_largeur = $formatarray['width'];
106 $this->page_hauteur = $formatarray['height'];
107 $this->format = array($this->page_largeur, $this->page_hauteur);
108 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
109 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
110 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
111 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
112 $this->corner_radius = getDolGlobalInt('MAIN_PDF_FRAME_CORNER_RADIUS', 0);
113 $this->option_logo = 1; // Display logo
114 $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
115 $this->option_modereg = 1; // Display payment mode
116 $this->option_condreg = 1; // Display payment terms
117 $this->option_multilang = 1; // Available in several languages
118 $this->option_escompte = 0; // Displays if there has been a discount
119 $this->option_credit_note = 0; // Support credit notes
120 $this->option_freetext = 1; // Support add of a personalised text
121 $this->option_draft_watermark = 1; // Support add of a watermark on drafts
122 $this->watermark = '';
123
124 // Define position of columns
125 $this->posxdesc = $this->marge_gauche + 1;
126 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
127 $this->posxtva = 101;
128 $this->posxup = 118;
129 $this->posxqty = 135;
130 $this->posxunit = 151;
131 } else {
132 $this->posxtva = 106;
133 $this->posxup = 122;
134 $this->posxqty = 145;
135 $this->posxunit = 162;
136 }
137 $this->posxdiscount = 162;
138 $this->postotalht = 174;
139 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') || getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
140 $this->posxtva = $this->posxup;
141 }
142 $this->posxpicture = $this->posxtva - getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH', 20); // width of images
143 if ($this->page_largeur < 210) { // To work with US executive format
144 $this->posxpicture -= 20;
145 $this->posxtva -= 20;
146 $this->posxup -= 20;
147 $this->posxqty -= 20;
148 $this->posxunit -= 20;
149 $this->posxdiscount -= 20;
150 $this->postotalht -= 20;
151 }
152
153 $this->tva = array();
154 $this->tva_array = array();
155 $this->localtax1 = array();
156 $this->localtax2 = array();
157 $this->atleastoneratenotnull = 0;
158 $this->atleastonediscount = 0;
159
160 if ($mysoc === null) {
161 dol_syslog(get_class($this).'::__construct() Global $mysoc should not be null.'. getCallerInfoString(), LOG_ERR);
162 return;
163 }
164
165 // Get source company
166 $this->emetteur = $mysoc;
167 if (empty($this->emetteur->country_code)) {
168 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
169 }
170 }
171
172 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
184 public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
185 {
186 // phpcs:enable
187 global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
188
189 if (!is_object($outputlangs)) {
190 $outputlangs = $langs;
191 }
192 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
193 if (getDolGlobalString('MAIN_USE_FPDF')) {
194 $outputlangs->charset_output = 'ISO-8859-1';
195 }
196
197 // Load translation files required by the page
198 $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries", "compta"));
199
200 // Show Draft Watermark
201 if ($object->statut == $object::STATUS_DRAFT && getDolGlobalString('COMMANDE_DRAFT_WATERMARK')) {
202 $this->watermark = getDolGlobalString('COMMANDE_DRAFT_WATERMARK');
203 }
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(array("main", "dict", "companies", "bills", "products", "orders", "deliveries", "compta"));
211 }
212
213 $nblines = count($object->lines);
214
215 if ($conf->commande->multidir_output[$conf->entity]) {
216 $object->fetch_thirdparty();
217
218 $deja_regle = 0;
219
220 // Definition of $dir and $file
221 if ($object->specimen) {
222 $dir = $conf->commande->multidir_output[$conf->entity];
223 $file = $dir."/SPECIMEN.pdf";
224 } else {
225 // Possibility to use suffix for proforma
226 $suffix = '';
227 if (getDolGlobalString('PROFORMA_PDF_WITH_SUFFIX')) {
228 $suffix = (GETPOST('model') == 'proforma') ? getDolGlobalString('PROFORMA_PDF_WITH_SUFFIX') : '';
229 $suffix = dol_sanitizeFileName($suffix);
230 }
231
232 $objectref = dol_sanitizeFileName($object->ref);
233 $dir = $conf->commande->multidir_output[$object->entity]."/".$objectref;
234 $file = $dir."/".$objectref.$suffix.".pdf";
235 }
236
237 if (!file_exists($dir)) {
238 if (dol_mkdir($dir) < 0) {
239 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
240 return 0;
241 }
242 }
243
244 if (file_exists($dir)) {
245 // Add pdfgeneration hook
246 if (!is_object($hookmanager)) {
247 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
248 $hookmanager = new HookManager($this->db);
249 }
250 $hookmanager->initHooks(array('pdfgeneration'));
251 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
252 global $action;
253 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
254
255 // Set nblines with the new command lines content after hook
256 $nblines = count($object->lines);
257
258 // Create pdf instance
259 $pdf = pdf_getInstance($this->format);
260 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
261 $pdf->SetAutoPageBreak(1, 0);
262
263 $heightforinfotot = 40; // Height reserved to output the info and total part
264 $heightforfreetext = getDolGlobalInt('MAIN_PDF_FREETEXT_HEIGHT', 5); // Height reserved to output the free text on last page
265 $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
266 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
267 $heightforfooter += 6;
268 }
269
270 if (class_exists('TCPDF')) {
271 $pdf->setPrintHeader(false);
272 $pdf->setPrintFooter(false);
273 }
274 $pdf->SetFont(pdf_getPDFFont($outputlangs));
275 // Set path to the background PDF File
276 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
277 $logodir = $conf->mycompany->dir_output;
278 if (!empty($conf->mycompany->multidir_output[$object->entity])) {
279 $logodir = $conf->mycompany->multidir_output[$object->entity];
280 }
281 $pagecount = $pdf->setSourceFile($logodir.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
282 $tplidx = $pdf->importPage(1);
283 }
284
285 $pdf->Open();
286 $pagenb = 0;
287 $pdf->SetDrawColor(128, 128, 128);
288
289 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
290 $pdf->SetSubject($outputlangs->transnoentities("PdfOrderTitle"));
291 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
292 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
293 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfOrderTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
294 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
295 $pdf->SetCompression(false);
296 }
297
298 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
299 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
300
301 // Set $this->atleastonediscount if you have at least one discount
302 for ($i = 0; $i < $nblines; $i++) {
303 if ($object->lines[$i]->remise_percent) {
304 $this->atleastonediscount++;
305 }
306 }
307 if (empty($this->atleastonediscount)) {
308 $delta = ($this->postotalht - $this->posxdiscount);
309 $this->posxpicture += $delta;
310 $this->posxtva += $delta;
311 $this->posxup += $delta;
312 $this->posxqty += $delta;
313 $this->posxunit += $delta;
314 $this->posxdiscount += $delta;
315 // post of fields after are not modified, stay at same position
316 }
317
318 // New page
319 $pdf->AddPage();
320 if (!empty($tplidx)) {
321 $pdf->useTemplate($tplidx);
322 }
323 $pagenb++;
324 $pagehead = $this->_pagehead($pdf, $object, 1, $outputlangs, (is_object($outputlangsbis) ? $outputlangsbis : null));
325 $top_shift = $pagehead['top_shift'];
326 $shipp_shift = $pagehead['shipp_shift'];
327 $pdf->SetFont('', '', $default_font_size - 1);
328 $pdf->MultiCell(0, 3, ''); // Set interline to 3
329 $pdf->SetTextColor(0, 0, 0);
330
331 $tab_top = 90 + $top_shift + $shipp_shift;
332 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
333
334 // Incoterm
335 $height_incoterms = 0;
336 if (isModEnabled('incoterm')) {
337 $desc_incoterms = $object->getIncotermsForPDF();
338 if ($desc_incoterms) {
339 $tab_top -= 2;
340
341 $pdf->SetFont('', '', $default_font_size - 1);
342 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
343 $nexY = $pdf->GetY();
344 $height_incoterms = $nexY - $tab_top;
345
346 // Rect takes a length in 3rd parameter
347 $pdf->SetDrawColor(192, 192, 192);
348 $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');
349
350 $tab_top = $nexY + 6;
351 }
352 }
353
354 // Displays notes
355 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
356 if (getDolGlobalString('MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE')) {
357 // Get first sale rep
358 if (is_object($object->thirdparty)) {
359 $salereparray = $object->thirdparty->getSalesRepresentatives($user);
360 $salerepobj = new User($this->db);
361 $salerepobj->fetch($salereparray[0]['id']);
362 if (!empty($salerepobj->signature)) {
363 $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
364 }
365 }
366 }
367 // Extrafields in note
368 $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
369 if (!empty($extranote)) {
370 $notetoshow = dol_concatdesc($notetoshow, $extranote);
371 }
372
373 if ($notetoshow) {
374 $tab_top -= 2;
375
376 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
377 complete_substitutions_array($substitutionarray, $outputlangs, $object);
378 $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
379 $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
380
381 $pdf->SetFont('', '', $default_font_size - 1);
382 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($notetoshow), 0, 1);
383 $nexY = $pdf->GetY();
384 $height_note = $nexY - $tab_top;
385
386 // Rect takes a length in 3rd parameter
387 $pdf->SetDrawColor(192, 192, 192);
388 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 1, $this->corner_radius, '1234', 'D');
389
390 $tab_top = $nexY + 6;
391 }
392
393 $iniY = $tab_top + 7;
394 $curY = $tab_top + 7;
395 $nexY = $tab_top + 7;
396
397 // Loop on each lines
398 for ($i = 0; $i < $nblines; $i++) {
399 $curY = $nexY;
400 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
401 $pdf->SetTextColor(0, 0, 0);
402
403 $pdf->setTopMargin($tab_top_newpage);
404 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
405 $pageposbefore = $pdf->getPage();
406
407 // Description of product line
408 $curX = $this->posxdesc - 1;
409
410 $showpricebeforepagebreak = 1;
411
412 $pdf->startTransaction();
413 pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxtva - $curX, 3, $curX, $curY, $hideref, $hidedesc);
414 $pageposafter = $pdf->getPage();
415 if ($pageposafter > $pageposbefore) { // There is a pagebreak
416 $pdf->rollbackTransaction(true);
417 $pageposafter = $pageposbefore;
418 //print $pageposafter.'-'.$pageposbefore;exit;
419 $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
420 pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxtva - $curX, 4, $curX, $curY, $hideref, $hidedesc);
421 $pageposafter = $pdf->getPage();
422 $posyafter = $pdf->GetY();
423 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
424 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
425 $pdf->AddPage('', '', true);
426 if (!empty($tplidx)) {
427 $pdf->useTemplate($tplidx);
428 }
429 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
430 $this->_pagehead($pdf, $object, 0, $outputlangs);
431 }
432 $pdf->setPage($pageposafter + 1);
433 }
434 } else {
435 // We found a page break
436 // Allows data in the first page if description is long enough to break in multiples pages
437 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
438 $showpricebeforepagebreak = 1;
439 } else {
440 $showpricebeforepagebreak = 0;
441 }
442 }
443 } else { // No pagebreak
444 $pdf->commitTransaction();
445 }
446 $posYAfterDescription = $pdf->GetY();
447
448 $nexY = $pdf->GetY();
449 $pageposafter = $pdf->getPage();
450
451 $pdf->setPage($pageposbefore);
452 $pdf->setTopMargin($this->marge_haute);
453 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
454
455 // We suppose that a too long description is moved completely on next page
456 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
457 $pdf->setPage($pageposafter);
458 $curY = $tab_top_newpage;
459 }
460
461 $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font
462
463 // VAT Rate
464 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
465 $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
466 $pdf->SetXY($this->posxtva - 5, $curY);
467 $pdf->MultiCell($this->posxup - $this->posxtva + 4, 3, $vat_rate, 0, 'R');
468 }
469
470 // Unit price before discount
471 $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
472 $pdf->SetXY($this->posxup, $curY);
473 $pdf->MultiCell($this->posxqty - $this->posxup - 0.8, 3, $up_excl_tax, 0, 'R', 0);
474
475 // Quantity
476 $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
477 $pdf->SetXY($this->posxqty, $curY);
478 $pdf->MultiCell($this->posxunit - $this->posxqty - 0.8, 4, $qty, 0, 'R'); // Enough for 6 chars
479
480 // Unit
481 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
482 $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails);
483 $pdf->SetXY($this->posxunit, $curY);
484 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 0.8, 4, $unit, 0, 'L');
485 }
486
487 // Discount on line
488 $pdf->SetXY($this->posxdiscount, $curY);
489 if ($object->lines[$i]->remise_percent) {
490 $pdf->SetXY($this->posxdiscount - 2, $curY);
491 $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
492 $pdf->MultiCell($this->postotalht - $this->posxdiscount + 2, 3, $remise_percent, 0, 'R');
493 }
494
495 // Total HT line
496 $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
497 $pdf->SetXY($this->postotalht, $curY);
498 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, $total_excl_tax, 0, 'R', 0);
499
500 // Collection of totals by value of vat in $this->vat["rate"] = total_tva
501 if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) {
502 $tvaligne = $object->lines[$i]->multicurrency_total_tva;
503 } else {
504 $tvaligne = $object->lines[$i]->total_tva;
505 }
506
507 $localtax1ligne = $object->lines[$i]->total_localtax1;
508 $localtax2ligne = $object->lines[$i]->total_localtax2;
509 $localtax1_rate = $object->lines[$i]->localtax1_tx;
510 $localtax2_rate = $object->lines[$i]->localtax2_tx;
511 $localtax1_type = $object->lines[$i]->localtax1_type;
512 $localtax2_type = $object->lines[$i]->localtax2_type;
513
514 // TODO remise_percent is an obsolete field for object parent
515 /*if ($object->remise_percent) {
516 $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
517 }
518 if ($object->remise_percent) {
519 $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
520 }
521 if ($object->remise_percent) {
522 $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
523 }*/
524
525 $vatrate = (string) $object->lines[$i]->tva_tx;
526
527 // Retrieve type from database for backward compatibility with old records
528 if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
529 && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
530 $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
531 $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
532 $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
533 }
534
535 // retrieve global local tax
536 if ($localtax1_type && $localtax1ligne != 0) {
537 if (empty($this->localtax1[$localtax1_type][$localtax1_rate])) {
538 $this->localtax1[$localtax1_type][$localtax1_rate] = $localtax1ligne;
539 } else {
540 $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
541 }
542 }
543 if ($localtax2_type && $localtax2ligne != 0) {
544 if (empty($this->localtax2[$localtax2_type][$localtax2_rate])) {
545 $this->localtax2[$localtax2_type][$localtax2_rate] = $localtax2ligne;
546 } else {
547 $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
548 }
549 }
550
551 if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
552 $vatrate .= '*';
553 }
554
555 // Fill $this->tva and $this->tva_array
556 if (!isset($this->tva[$vatrate])) {
557 $this->tva[$vatrate] = 0;
558 }
559 $this->tva[$vatrate] += $tvaligne;
560 $vatcode = $object->lines[$i]->vat_src_code;
561 if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
562 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
563 }
564 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
565
566 // Add line
567 if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) {
568 $pdf->setPage($pageposafter);
569 $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(80, 80, 80)));
570 //$pdf->SetDrawColor(190,190,200);
571 $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
572 $pdf->SetLineStyle(array('dash' => 0));
573 }
574
575 $nexY += 2; // Add space between lines
576
577 // Detect if some page were added automatically and output _tableau for past pages
578 while ($pagenb < $pageposafter) {
579 $pdf->setPage($pagenb);
580 if ($pagenb == 1) {
581 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
582 } else {
583 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
584 }
585 $this->_pagefoot($pdf, $object, $outputlangs, 1);
586 $pagenb++;
587 $pdf->setPage($pagenb);
588 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
589 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
590 $this->_pagehead($pdf, $object, 0, $outputlangs);
591 }
592 if (!empty($tplidx)) {
593 $pdf->useTemplate($tplidx);
594 }
595 }
596 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { // @phan-suppress-current-line PhanUndeclaredProperty
597 if ($pagenb == 1) {
598 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
599 } else {
600 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
601 }
602 $this->_pagefoot($pdf, $object, $outputlangs, 1);
603 // New page
604 $pdf->AddPage();
605 if (!empty($tplidx)) {
606 $pdf->useTemplate($tplidx);
607 }
608 $pagenb++;
609 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
610 $this->_pagehead($pdf, $object, 0, $outputlangs);
611 }
612 }
613 }
614
615 // Show square
616 if ($pagenb == 1) {
617 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
618 } else {
619 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
620 }
621 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
622
623 // Display infos area
624 $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
625
626 // Display total zone
627 $posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
628
629 // Affiche zone versements
630 /*
631 if ($deja_regle)
632 {
633 $posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs);
634 }
635 */
636
637 // Pied de page
638 $this->_pagefoot($pdf, $object, $outputlangs);
639 if (method_exists($pdf, 'AliasNbPages')) {
640 $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod
641 }
642
643 // Add terms to sale
644 if (!empty($mysoc->termsofsale) && getDolGlobalInt('MAIN_PDF_ADD_TERMSOFSALE_ORDER')) {
645 $termsofsale = $conf->mycompany->dir_output.'/'.$mysoc->termsofsale;
646 if (!empty($conf->mycompany->multidir_output[$object->entity])) {
647 $termsofsale = $conf->mycompany->multidir_output[$object->entity].'/'.$mysoc->termsofsale;
648 }
649 if (file_exists($termsofsale) && is_readable($termsofsale)) {
650 $pagecount = $pdf->setSourceFile($termsofsale);
651 for ($i = 1; $i <= $pagecount; $i++) {
652 $tplIdx = $pdf->importPage($i);
653 if ($tplIdx!==false) {
654 $s = $pdf->getTemplatesize($tplIdx);
655 $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
656 $pdf->useTemplate($tplIdx);
657 } else {
658 setEventMessages(null, array($termsofsale.' cannot be added, probably protected PDF'), 'warnings');
659 }
660 }
661 }
662 }
663
664 $pdf->Close();
665
666 $pdf->Output($file, 'F');
667
668 // Add pdfgeneration hook
669 $hookmanager->initHooks(array('pdfgeneration'));
670 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
671 global $action;
672 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
673 if ($reshook < 0) {
674 $this->error = $hookmanager->error;
675 $this->errors = $hookmanager->errors;
676 }
677
678 dolChmod($file);
679
680 $this->result = array('fullpath' => $file);
681
682 return 1; // No error
683 } else {
684 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
685 return 0;
686 }
687 } else {
688 $this->error = $langs->transnoentities("ErrorConstantNotDefined", "COMMANDE_OUTPUTDIR");
689 return 0;
690 }
691 }
692
693 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
694 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
704 protected function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
705 {
706 // phpcs:enable
707 return 1;
708 }
709
710 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
711 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
721 protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
722 {
723 // phpcs:enable
724 global $conf, $mysoc;
725 $default_font_size = pdf_getPDFFontSize($outputlangs);
726
727 $pdf->SetFont('', '', $default_font_size - 1);
728
729 $diffsizetitle = (!getDolGlobalString('PDF_DIFFSIZE_TITLE') ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
730
731 // If France, show VAT mention if not applicable
732 if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
733 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
734 $pdf->SetXY($this->marge_gauche, $posy);
735 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
736
737 $posy = $pdf->GetY() + 4;
738 }
739
740 $posxval = 52;
741
742 $diffsizetitle = (!getDolGlobalString('PDF_DIFFSIZE_TITLE') ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
743
744 // Show payments conditions
745 if ($object->cond_reglement_code || $object->cond_reglement) {
746 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
747 $pdf->SetXY($this->marge_gauche, $posy);
748 $titre = $outputlangs->transnoentities("PaymentConditions").':';
749 $pdf->MultiCell(43, 4, $titre, 0, 'L');
750
751 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
752 $pdf->SetXY($posxval, $posy);
753 $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);
754 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
755 if ($object->deposit_percent > 0) {
756 $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', (string) $object->deposit_percent, $lib_condition_paiement);
757 }
758 $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
759
760 $posy = $pdf->GetY() + 3;
761 }
762
763 // Check a payment mode is defined
764 /* Not used with orders
765 if (empty($object->mode_reglement_code)
766 && ! $conf->global->FACTURE_CHQ_NUMBER
767 && ! $conf->global->FACTURE_RIB_NUMBER)
768 {
769 $pdf->SetXY($this->marge_gauche, $posy);
770 $pdf->SetTextColor(200,0,0);
771 $pdf->SetFont('','B', $default_font_size - 2);
772 $pdf->MultiCell(80, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0);
773 $pdf->SetTextColor(0,0,0);
774
775 $posy=$pdf->GetY()+1;
776 }
777 */
778 /* TODO
779 else if (!empty($object->availability_code))
780 {
781 $pdf->SetXY($this->marge_gauche, $posy);
782 $pdf->SetTextColor(200,0,0);
783 $pdf->SetFont('','B', $default_font_size - 2);
784 $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0);
785 $pdf->SetTextColor(0,0,0);
786
787 $posy=$pdf->GetY()+1;
788 }*/
789
790 // Show planned date of delivery
791 if (!empty($object->delivery_date)) {
792 $outputlangs->load("sendings");
793 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
794 $pdf->SetXY($this->marge_gauche, $posy);
795 $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
796 $pdf->MultiCell(80, 4, $titre, 0, 'L');
797 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
798 $pdf->SetXY($posxval, $posy);
799 $dlp = dol_print_date($object->delivery_date, "daytext", false, $outputlangs, true);
800 $pdf->MultiCell(80, 4, $dlp, 0, 'L');
801
802 $posy = $pdf->GetY() + 1;
803 } elseif ($object->availability_code || $object->availability) {
804 // Show availability conditions
805 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
806 $pdf->SetXY($this->marge_gauche, $posy);
807 $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
808 $pdf->MultiCell(80, 4, $titre, 0, 'L');
809 $pdf->SetTextColor(0, 0, 0);
810 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
811 $pdf->SetXY($posxval, $posy);
812 $lib_availability = $outputlangs->transnoentities("AvailabilityType".$object->availability_code) != 'AvailabilityType'.$object->availability_code ? $outputlangs->transnoentities("AvailabilityType".$object->availability_code) : $outputlangs->convToOutputCharset(isset($object->availability) ? $object->availability : '');
813 $lib_availability = str_replace('\n', "\n", $lib_availability);
814 $pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
815
816 $posy = $pdf->GetY() + 1;
817 }
818
819 // Show payment mode
820 if ($object->mode_reglement_code
821 && $object->mode_reglement_code != 'CHQ'
822 && $object->mode_reglement_code != 'VIR') {
823 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
824 $pdf->SetXY($this->marge_gauche, $posy);
825 $titre = $outputlangs->transnoentities("PaymentMode").':';
826 $pdf->MultiCell(80, 5, $titre, 0, 'L');
827
828 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
829 $pdf->SetXY($posxval, $posy);
830 $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);
831 $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
832
833 $posy = $pdf->GetY() + 2;
834 }
835
836 // Show payment mode CHQ
837 if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') {
838 // Si mode reglement non force ou si force a CHQ
839 if (getDolGlobalString('FACTURE_CHQ_NUMBER')) {
840 if (getDolGlobalInt('FACTURE_CHQ_NUMBER') > 0) {
841 $account = new Account($this->db);
842 $account->fetch(getDolGlobalString('FACTURE_CHQ_NUMBER'));
843
844 $pdf->SetXY($this->marge_gauche, $posy);
845 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
846 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->owner_name), 0, 'L', 0);
847 $posy = $pdf->GetY() + 1;
848
849 if (!getDolGlobalString('MAIN_PDF_HIDE_CHQ_ADDRESS')) {
850 $pdf->SetXY($this->marge_gauche, $posy);
851 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
852 $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
853 $posy = $pdf->GetY() + 2;
854 }
855 }
856 if ($conf->global->FACTURE_CHQ_NUMBER == -1) {
857 $pdf->SetXY($this->marge_gauche, $posy);
858 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
859 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
860 $posy = $pdf->GetY() + 1;
861
862 if (!getDolGlobalString('MAIN_PDF_HIDE_CHQ_ADDRESS')) {
863 $pdf->SetXY($this->marge_gauche, $posy);
864 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
865 $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
866 $posy = $pdf->GetY() + 2;
867 }
868 }
869 }
870 }
871
872 // If payment mode not forced or forced to VIR, show payment with BAN
873 if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') {
874 if ($object->fk_account > 0 || $object->fk_bank > 0 || getDolGlobalInt('FACTURE_RIB_NUMBER')) {
875 $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
876 if ($object->fk_bank > 0) {
877 $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
878 }
879 $account = new Account($this->db);
880 $account->fetch($bankid);
881
882 $curx = $this->marge_gauche;
883 $cury = $posy;
884
885 $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
886
887 $posy += 2;
888 }
889 }
890
891 return $posy;
892 }
893
894 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
895 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
907 protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis = null)
908 {
909 // phpcs:enable
910 global $conf, $mysoc, $hookmanager;
911
912 $default_font_size = pdf_getPDFFontSize($outputlangs);
913
914 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')) {
915 $outputlangsbis = new Translate('', $conf);
916 $outputlangsbis->setDefaultLang(getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE'));
917 $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
918 $default_font_size--;
919 }
920
921 $tab2_top = $posy;
922 $tab2_hl = 4;
923 $pdf->SetFont('', '', $default_font_size - 1);
924
925 // Total table
926 $col1x = 120;
927 $col2x = 170;
928 if ($this->page_largeur < 210) { // To work with US executive format
929 $col2x -= 20;
930 }
931 $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
932
933 $useborder = 0;
934 $index = 0;
935
936 // Get Total HT
937 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
938
939 // Total remise
940 $total_line_remise = 0;
941 foreach ($object->lines as $i => $line) {
942 $resdiscount = pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, 2);
943 $total_line_remise += (is_numeric($resdiscount) ? $resdiscount : 0);
944 // Gestion remise sous forme de ligne négative
945 if ($line->total_ht < 0) {
946 $total_line_remise += -$line->total_ht;
947 }
948 }
949 if ($total_line_remise > 0) {
950 $pdf->SetFillColor(255, 255, 255);
951 $pdf->SetXY($col1x, $tab2_top + $tab2_hl);
952 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalDiscount").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalDiscount") : ''), 0, 'L', 1);
953 $pdf->SetXY($col2x, $tab2_top + $tab2_hl);
954 $pdf->MultiCell($largcol2, $tab2_hl, price($total_line_remise, 0, $outputlangs), 0, 'R', 1);
955
956 $index++;
957
958 // Show total NET before discount
959 $pdf->SetFillColor(255, 255, 255);
960 $pdf->SetXY($col1x, $tab2_top);
961 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHTBeforeDiscount").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHTBeforeDiscount") : ''), 0, 'L', 1);
962 $pdf->SetXY($col2x, $tab2_top);
963 $pdf->MultiCell($largcol2, $tab2_hl, price($total_line_remise + $total_ht, 0, $outputlangs), 0, 'R', 1);
964
965 $index++;
966 }
967
968 // Total HT
969 $pdf->SetFillColor(255, 255, 255);
970 $pdf->SetXY($col1x, $tab2_top+ $tab2_hl * $index);
971 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1);
972
973 $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
974 $pdf->SetXY($col2x, $tab2_top+ $tab2_hl * $index);
975 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0), 0, $outputlangs), 0, 'R', 1);
976
977 // Show VAT by rates and total
978 $pdf->SetFillColor(248, 248, 248);
979
980 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
981
982 $this->atleastoneratenotnull = 0;
983 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
984 $tvaisnull = (!empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000']));
985 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL') && $tvaisnull) {
986 // Nothing to do
987 } else {
988 //Local tax 1 before VAT
989 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
990 if (in_array((string) $localtax_type, array('1', '3', '5'))) {
991 continue;
992 }
993 foreach ($localtax_rate as $tvakey => $tvaval) {
994 if ($tvakey != 0) { // On affiche pas taux 0
995 //$this->atleastoneratenotnull++;
996
997 $index++;
998 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
999
1000 $tvacompl = '';
1001 if (preg_match('/\*/', (string) $tvakey)) {
1002 $tvakey = str_replace('*', '', (string) $tvakey);
1003 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1004 }
1005 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1006 $totalvat .= ' ';
1007
1008 if (getDolGlobalString('PDF_LOCALTAX1_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1009 $totalvat .= $tvacompl;
1010 } else {
1011 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
1012 }
1013
1014 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1015
1016 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1017
1018 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1019 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1020 }
1021 }
1022 }
1023
1024 //Local tax 2 before VAT
1025 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1026 if (in_array((string) $localtax_type, array('1', '3', '5'))) {
1027 continue;
1028 }
1029 foreach ($localtax_rate as $tvakey => $tvaval) {
1030 if ($tvakey != 0) { // On affiche pas taux 0
1031 //$this->atleastoneratenotnull++;
1032
1033 $index++;
1034 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1035
1036 $tvacompl = '';
1037 if (preg_match('/\*/', (string) $tvakey)) {
1038 $tvakey = str_replace('*', '', (string) $tvakey);
1039 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1040 }
1041 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1042 $totalvat .= ' ';
1043
1044 if (getDolGlobalString('PDF_LOCALTAX2_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1045 $totalvat .= $tvacompl;
1046 } else {
1047 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
1048 }
1049
1050 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1051
1052 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1053
1054 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1055 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1056 }
1057 }
1058 }
1059
1060 // VAT
1061 foreach ($this->tva_array as $tvakey => $tvaval) {
1062 if ($tvakey != 0) { // On affiche pas taux 0
1063 $this->atleastoneratenotnull++;
1064
1065 $index++;
1066 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1067
1068 $tvacompl = '';
1069 if (preg_match('/\*/', $tvakey)) {
1070 $tvakey = str_replace('*', '', $tvakey);
1071 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1072 }
1073 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
1074 $totalvat .= ' ';
1075 if (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'rateonly') {
1076 $totalvat .= vatrate($tvaval['vatrate'], 1).$tvacompl;
1077 } elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'codeonly') {
1078 $totalvat .= $tvaval['vatcode'].$tvacompl;
1079 } elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1080 $totalvat .= $tvacompl;
1081 } else {
1082 $totalvat .= vatrate($tvaval['vatrate'], 1).($tvaval['vatcode'] ? ' ('.$tvaval['vatcode'].')' : '').$tvacompl;
1083 }
1084 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1085
1086 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1087 $pdf->MultiCell($largcol2, $tab2_hl, price(price2num($tvaval['amount'], 'MT'), 0, $outputlangs), 0, 'R', 1);
1088 }
1089 }
1090
1091 //Local tax 1 after VAT
1092 //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1093 //{
1094 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1095 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1096 continue;
1097 }
1098
1099 foreach ($localtax_rate as $tvakey => $tvaval) {
1100 if ($tvakey != 0) { // On affiche pas taux 0
1101 //$this->atleastoneratenotnull++;
1102
1103 $index++;
1104 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1105
1106 $tvacompl = '';
1107 if (preg_match('/\*/', (string) $tvakey)) {
1108 $tvakey = str_replace('*', '', (string) $tvakey);
1109 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1110 }
1111 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1112 $totalvat .= ' ';
1113
1114 if (getDolGlobalString('PDF_LOCALTAX1_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1115 $totalvat .= $tvacompl;
1116 } else {
1117 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
1118 }
1119
1120 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1121
1122 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1123
1124 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1125 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1126 }
1127 }
1128 }
1129 //}
1130 //Local tax 2 after VAT
1131 //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1132 //{
1133 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1134 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1135 continue;
1136 }
1137
1138 foreach ($localtax_rate as $tvakey => $tvaval) {
1139 // retrieve global local tax
1140 if ($tvakey != 0) { // On affiche pas taux 0
1141 //$this->atleastoneratenotnull++;
1142
1143 $index++;
1144 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1145
1146 $tvacompl = '';
1147 if (preg_match('/\*/', (string) $tvakey)) {
1148 $tvakey = str_replace('*', '', (string) $tvakey);
1149 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1150 }
1151 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1152 $totalvat .= ' ';
1153
1154 if (getDolGlobalString('PDF_LOCALTAX2_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1155 $totalvat .= $tvacompl;
1156 } else {
1157 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
1158 }
1159
1160 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1161
1162 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1163
1164 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1165 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1166 }
1167 }
1168 }
1169 //}
1170
1171 // Total TTC
1172 $index++;
1173 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1174 $pdf->SetTextColor(0, 0, 60);
1175 $pdf->SetFillColor(224, 224, 224);
1176 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalTTC", $mysoc->country_code) : ''), $useborder, 'L', 1);
1177
1178 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1179 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
1180 }
1181 }
1182
1183 $pdf->SetTextColor(0, 0, 0);
1184
1185 $creditnoteamount = 0;
1186 $depositsamount = 0;
1187 //$creditnoteamount=$object->getSumCreditNotesUsed();
1188 //$depositsamount=$object->getSumDepositsUsed();
1189 //print "x".$creditnoteamount."-".$depositsamount;exit;
1190 $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
1191 if (!empty($object->paye)) {
1192 $resteapayer = 0;
1193 }
1194
1195 if ($deja_regle > 0) {
1196 // Already paid + Deposits
1197 $index++;
1198
1199 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1200 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), 0, 'L', 0);
1201 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1202 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
1203
1204 $index++;
1205 $pdf->SetTextColor(0, 0, 60);
1206 $pdf->SetFillColor(224, 224, 224);
1207 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1208 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), $useborder, 'L', 1);
1209
1210 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1211 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
1212
1213 $pdf->SetFont('', '', $default_font_size - 1);
1214 $pdf->SetTextColor(0, 0, 0);
1215 }
1216
1217 $index++;
1218 return ($tab2_top + ($tab2_hl * $index));
1219 }
1220
1221 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1236 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
1237 {
1238 global $conf;
1239
1240 // Force to disable hidetop and hidebottom
1241 $hidebottom = 0;
1242 if ($hidetop) {
1243 $hidetop = -1;
1244 }
1245
1246 $currency = !empty($currency) ? $currency : $conf->currency;
1247 $default_font_size = pdf_getPDFFontSize($outputlangs);
1248
1249 // Amount in (at tab_top - 1)
1250 $pdf->SetTextColor(0, 0, 0);
1251 $pdf->SetFont('', '', $default_font_size - 2);
1252
1253 if (empty($hidetop)) {
1254 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1255 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && is_object($outputlangsbis)) {
1256 $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency));
1257 }
1258
1259 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1260 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1261
1262 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1263 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
1264 $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')));
1265 }
1266 }
1267
1268 $pdf->SetDrawColor(128, 128, 128);
1269 $pdf->SetFont('', '', $default_font_size - 1);
1270
1271 // Output Rect
1272 $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
1273
1274 if (empty($hidetop)) {
1275 $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
1276
1277 $pdf->SetXY($this->posxdesc - 1, $tab_top + 1);
1278 $pdf->MultiCell(108, 2, $outputlangs->transnoentities("Designation"), '', 'L');
1279 }
1280
1281 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
1282 $pdf->line($this->posxtva - 1, $tab_top, $this->posxtva - 1, $tab_top + $tab_height);
1283 if (empty($hidetop)) {
1284 $pdf->SetXY($this->posxtva - 3, $tab_top + 1);
1285 $pdf->MultiCell($this->posxup - $this->posxtva + 3, 2, $outputlangs->transnoentities("VAT"), '', 'C');
1286 }
1287 }
1288
1289 $pdf->line($this->posxup - 1, $tab_top, $this->posxup - 1, $tab_top + $tab_height);
1290 if (empty($hidetop)) {
1291 $pdf->SetXY($this->posxup - 1, $tab_top + 1);
1292 $pdf->MultiCell($this->posxqty - $this->posxup - 1, 2, $outputlangs->transnoentities("PriceUHT"), '', 'C');
1293 }
1294
1295 $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height);
1296 if (empty($hidetop)) {
1297 $pdf->SetXY($this->posxqty - 1, $tab_top + 1);
1298 $pdf->MultiCell($this->posxunit - $this->posxqty - 1, 2, $outputlangs->transnoentities("Qty"), '', 'C');
1299 }
1300
1301 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1302 $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height);
1303 if (empty($hidetop)) {
1304 $pdf->SetXY($this->posxunit - 1, $tab_top + 1);
1305 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("Unit"), '', 'C');
1306 }
1307 }
1308
1309 $pdf->line($this->posxdiscount - 1, $tab_top, $this->posxdiscount - 1, $tab_top + $tab_height);
1310 if (empty($hidetop)) {
1311 if ($this->atleastonediscount) {
1312 $pdf->SetXY($this->posxdiscount - 1, $tab_top + 1);
1313 $pdf->MultiCell($this->postotalht - $this->posxdiscount + 1, 2, $outputlangs->transnoentities("ReductionShort"), '', 'C');
1314 }
1315 }
1316
1317 if ($this->atleastonediscount) {
1318 $pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
1319 }
1320 if (empty($hidetop)) {
1321 $pdf->SetXY($this->postotalht - 1, $tab_top + 1);
1322 $pdf->MultiCell(30, 2, $outputlangs->transnoentities("TotalHTShort"), '', 'C');
1323 }
1324 }
1325
1326 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1327 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1339 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null, $titlekey = "PdfOrderTitle")
1340 {
1341 // phpcs:enable
1342 global $conf, $langs, $hookmanager;
1343
1344 $ltrdirection = 'L';
1345 if ($outputlangs->trans("DIRECTION") == 'rtl') {
1346 $ltrdirection = 'R';
1347 }
1348
1349 // Load traductions files required by page
1350 $outputlangs->loadLangs(array("main", "bills", "propal", "orders", "companies"));
1351
1352 $default_font_size = pdf_getPDFFontSize($outputlangs);
1353
1354 pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
1355
1356 $pdf->SetTextColor(0, 0, 60);
1357 $pdf->SetFont('', 'B', $default_font_size + 3);
1358
1359 $w = 100;
1360
1361 $posy = $this->marge_haute;
1362 $posx = $this->page_largeur - $this->marge_droite - $w;
1363
1364 $pdf->SetXY($this->marge_gauche, $posy);
1365
1366 // Logo
1367 if (!getDolGlobalInt('PDF_DISABLE_MYCOMPANY_LOGO')) {
1368 if ($this->emetteur->logo) {
1369 $logodir = $conf->mycompany->dir_output;
1370 if (!empty($conf->mycompany->multidir_output[$object->entity])) {
1371 $logodir = $conf->mycompany->multidir_output[$object->entity];
1372 }
1373 if (!getDolGlobalInt('MAIN_PDF_USE_LARGE_LOGO')) {
1374 $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1375 } else {
1376 $logo = $logodir.'/logos/'.$this->emetteur->logo;
1377 }
1378 if (is_readable($logo)) {
1379 $height = pdf_getHeightForLogo($logo);
1380 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1381 } else {
1382 $pdf->SetTextColor(200, 0, 0);
1383 $pdf->SetFont('', 'B', $default_font_size - 2);
1384 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1385 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1386 }
1387 } else {
1388 $text = $this->emetteur->name;
1389 $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
1390 }
1391 }
1392
1393 $pdf->SetFont('', 'B', $default_font_size + 3);
1394 $pdf->SetXY($posx, $posy);
1395 $pdf->SetTextColor(0, 0, 60);
1396 $title = $outputlangs->transnoentities($titlekey);
1397 $title .= ' '.$outputlangs->convToOutputCharset($object->ref);
1398 if ($object->statut == $object::STATUS_DRAFT) {
1399 $pdf->SetTextColor(128, 0, 0);
1400 $title .= ' - '.$outputlangs->transnoentities("NotValidated");
1401 }
1402 $pdf->MultiCell($w, 3, $title, '', 'R');
1403
1404 $pdf->SetFont('', 'B', $default_font_size);
1405
1406 /*
1407 $posy += 5;
1408 $pdf->SetXY($posx, $posy);
1409 $pdf->SetTextColor(0, 0, 60);
1410 $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref), '', 'R');
1411 */
1412
1413 $posy += 3;
1414 $pdf->SetFont('', '', $default_font_size - 1);
1415
1416 if ($object->ref_client) {
1417 $posy += 5;
1418 $pdf->SetXY($posx, $posy);
1419 $pdf->SetTextColor(0, 0, 60);
1420 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R');
1421 }
1422
1423 if (getDolGlobalString('PDF_SHOW_PROJECT_TITLE')) {
1424 $object->fetchProject();
1425 if (!empty($object->project->ref)) {
1426 $posy += 3;
1427 $pdf->SetXY($posx, $posy);
1428 $pdf->SetTextColor(0, 0, 60);
1429 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1430 }
1431 }
1432
1433 if (getDolGlobalString('PDF_SHOW_PROJECT')) {
1434 $object->fetchProject();
1435 if (!empty($object->project->ref)) {
1436 $outputlangs->load("projects");
1437 $posy += 3;
1438 $pdf->SetXY($posx, $posy);
1439 $pdf->SetTextColor(0, 0, 60);
1440 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1441 }
1442 }
1443
1444 $posy += 4;
1445 $pdf->SetXY($posx, $posy);
1446 $pdf->SetTextColor(0, 0, 60);
1447 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("OrderDate")." : ".dol_print_date($object->date, "day", false, $outputlangs, true), '', 'R');
1448
1449 if (!getDolGlobalString('MAIN_PDF_HIDE_CUSTOMER_CODE') && !empty($object->thirdparty->code_client)) {
1450 $posy += 4;
1451 $pdf->SetXY($posx, $posy);
1452 $pdf->SetTextColor(0, 0, 60);
1453 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
1454 }
1455
1456 if (!getDolGlobalString('MAIN_PDF_HIDE_CUSTOMER_ACCOUNTING_CODE') && !empty($object->thirdparty->code_compta_client)) {
1457 $posy += 4;
1458 $pdf->SetXY($posx, $posy);
1459 $pdf->SetTextColor(0, 0, 60);
1460 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerAccountancyCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_compta_client), '', 'R');
1461 }
1462
1463 // Get contact
1464 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1465 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1466 if (count($arrayidcontact) > 0) {
1467 $usertmp = new User($this->db);
1468 $usertmp->fetch($arrayidcontact[0]);
1469 $posy += 4;
1470 $pdf->SetXY($posx, $posy);
1471 $pdf->SetTextColor(0, 0, 60);
1472 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
1473 }
1474 }
1475
1476 $posy += 2;
1477
1478 $top_shift = 0;
1479 $shipp_shift = 0;
1480 // Show list of linked objects
1481 $current_y = $pdf->getY();
1482 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
1483 if ($current_y < $pdf->getY()) {
1484 $top_shift = $pdf->getY() - $current_y;
1485 }
1486
1487 if ($showaddress) {
1488 // Sender properties
1489 $carac_emetteur = '';
1490 // Add internal contact of object if defined
1491 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1492 if (count($arrayidcontact) > 0) {
1493 $object->fetch_user($arrayidcontact[0]);
1494 $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1495 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1496 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1497 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1498 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1499 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1500 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1501 $carac_emetteur .= "\n";
1502 }
1503
1504 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1505
1506 // Show sender
1507 $posy = 42 + $top_shift;
1508 $posx = $this->marge_gauche;
1509 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1510 $posx = $this->page_largeur - $this->marge_droite - 80;
1511 }
1512 $hautcadre = 40;
1513
1514 // Show sender frame
1515 if (!getDolGlobalString('MAIN_PDF_NO_SENDER_FRAME')) {
1516 $pdf->SetTextColor(0, 0, 0);
1517 $pdf->SetFont('', '', $default_font_size - 2);
1518 $pdf->SetXY($posx, $posy - 5);
1519 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1520 $pdf->SetXY($posx, $posy);
1521 $pdf->SetFillColor(230, 230, 230);
1522 $pdf->RoundedRect($posx, $posy, 82, $hautcadre, $this->corner_radius, '1234', 'F');
1523 $pdf->SetTextColor(0, 0, 60);
1524 }
1525
1526 // Show sender name
1527 if (!getDolGlobalString('MAIN_PDF_HIDE_SENDER_NAME')) {
1528 $pdf->SetXY($posx + 2, $posy + 3);
1529 $pdf->SetFont('', 'B', $default_font_size);
1530 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1531 $posy = $pdf->getY();
1532 }
1533
1534 // Show sender information
1535 $pdf->SetXY($posx + 2, $posy);
1536 $pdf->SetFont('', '', $default_font_size - 1);
1537 $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
1538
1539
1540 // If CUSTOMER contact defined, we use it
1541 $usecontact = false;
1542 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1543 if (count($arrayidcontact) > 0) {
1544 $usecontact = true;
1545 $result = $object->fetch_contact($arrayidcontact[0]);
1546 }
1547
1548 // Recipient name
1549 if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || getDolGlobalString('MAIN_USE_COMPANY_NAME_OF_CONTACT')))) {
1550 $thirdparty = $object->contact;
1551 } else {
1552 $thirdparty = $object->thirdparty;
1553 }
1554
1555 $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1556
1557 $mode = 'target';
1558 $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), ($usecontact ? 1 : 0), $mode, $object);
1559
1560 // Show recipient
1561 $widthrecbox = getDolGlobalString('MAIN_PDF_USE_ISO_LOCATION') ? 92 : 100;
1562 if ($this->page_largeur < 210) {
1563 $widthrecbox = 84; // To work with US executive format
1564 }
1565 $posy = getDolGlobalString('MAIN_PDF_USE_ISO_LOCATION') ? 40 : 42;
1566 $posy += $top_shift;
1567 $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1568 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1569 $posx = $this->marge_gauche;
1570 }
1571
1572 // Show recipient frame
1573 if (!getDolGlobalString('MAIN_PDF_NO_RECIPENT_FRAME')) {
1574 $pdf->SetTextColor(0, 0, 0);
1575 $pdf->SetFont('', '', $default_font_size - 2);
1576 $pdf->SetXY($posx + 2, $posy - 5);
1577 $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1578 $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D');
1579 }
1580
1581 // Show recipient name
1582 $pdf->SetXY($posx + 2, $posy + 3);
1583 $pdf->SetFont('', 'B', $default_font_size);
1584 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1585 $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, $ltrdirection);
1586
1587 $posy = $pdf->getY();
1588
1589 // Show recipient information
1590 $pdf->SetFont('', '', $default_font_size - 1);
1591 $pdf->SetXY($posx + 2, $posy);
1592 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1593 $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1594
1595 // Show shipping address
1596 if (getDolGlobalInt('SALES_ORDER_SHOW_SHIPPING_ADDRESS')) {
1597 $idaddressshipping = $object->getIdContact('external', 'SHIPPING');
1598
1599 if (!empty($idaddressshipping)) {
1600 $contactshipping = $object->fetch_Contact($idaddressshipping[0]);
1601 $companystatic = new Societe($this->db);
1602 $companystatic->fetch($object->contact->fk_soc);
1603 $carac_client_name_shipping = pdfBuildThirdpartyName($object->contact, $outputlangs);
1604 $carac_client_shipping = pdf_build_address($outputlangs, $this->emetteur, $companystatic, $object->contact, ($usecontact ? 1 : 0), 'target', $object);
1605 } else {
1606 $carac_client_name_shipping = pdfBuildThirdpartyName($object->thirdparty, $outputlangs);
1607 $carac_client_shipping = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'target', $object);
1608 }
1609 if (!empty($carac_client_shipping)) {
1610 $posy += $hautcadre;
1611
1612 $hautcadre -= 10; // Height for the shipping address does not need to be as high as main box
1613
1614 // Show shipping frame
1615 $pdf->SetXY($posx + 2, $posy - 5);
1616 $pdf->SetFont('', '', $default_font_size - 2);
1617 $pdf->MultiCell($widthrecbox, '', $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0);
1618 $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D');
1619
1620 // Show shipping name
1621 $pdf->SetXY($posx + 2, $posy + 1);
1622 $pdf->SetFont('', 'B', $default_font_size);
1623 $pdf->MultiCell($widthrecbox - 2, 2, $carac_client_name_shipping, '', 'L');
1624
1625 $posy = $pdf->getY();
1626
1627 // Show shipping information
1628 $pdf->SetXY($posx + 2, $posy);
1629 $pdf->SetFont('', '', $default_font_size - 1);
1630 $pdf->MultiCell($widthrecbox - 2, 2, $carac_client_shipping, '', 'L');
1631
1632 $shipp_shift += $hautcadre + 10;
1633 }
1634 }
1635 }
1636
1637 $pdf->SetTextColor(0, 0, 0);
1638
1639 $pagehead = array('top_shift' => $top_shift, 'shipp_shift' => $shipp_shift);
1640
1641 return $pagehead;
1642 }
1643
1644 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1645 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1655 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1656 {
1657 // phpcs:enable
1658 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1659 return pdf_pagefoot($pdf, $outputlangs, 'ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext, $this->page_largeur, $this->watermark);
1660 }
1661}
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 Dolibarr database access.
Class to manage hooks.
Parent class for orders models.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
Class to generate PDF orders with template Einstein.
_pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis=null, $titlekey="PdfOrderTitle")
Show top header of page.
_tableau_info(&$pdf, $object, $posy, $outputlangs)
Show miscellaneous information (payment mode, payment term, ...)
_tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis=null)
Show total to pay.
__construct(DoliDB $db)
Constructor.
_tableau_versements(&$pdf, $object, $posy, $outputlangs)
Show payments table.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='', $outputlangsbis=null)
Show table for lines.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!function_exists( 'dolEscapeXML')) convertBackOfficeMediasLinksToPublicLinks($notetoshow)
Convert links to local wrapper to medias files into a string into a public external URL readable on i...
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.
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...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
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.
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_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
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