dolibarr 21.0.0-alpha
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 $pdf->Close();
644
645 $pdf->Output($file, 'F');
646
647 // Add pdfgeneration hook
648 $hookmanager->initHooks(array('pdfgeneration'));
649 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
650 global $action;
651 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
652 if ($reshook < 0) {
653 $this->error = $hookmanager->error;
654 $this->errors = $hookmanager->errors;
655 }
656
657 dolChmod($file);
658
659 $this->result = array('fullpath' => $file);
660
661 return 1; // No error
662 } else {
663 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
664 return 0;
665 }
666 } else {
667 $this->error = $langs->transnoentities("ErrorConstantNotDefined", "COMMANDE_OUTPUTDIR");
668 return 0;
669 }
670 }
671
672 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
673 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
683 protected function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
684 {
685 // phpcs:enable
686 return 1;
687 }
688
689 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
690 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
700 protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
701 {
702 // phpcs:enable
703 global $conf, $mysoc;
704 $default_font_size = pdf_getPDFFontSize($outputlangs);
705
706 $pdf->SetFont('', '', $default_font_size - 1);
707
708 $diffsizetitle = (!getDolGlobalString('PDF_DIFFSIZE_TITLE') ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
709
710 // If France, show VAT mention if not applicable
711 if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
712 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
713 $pdf->SetXY($this->marge_gauche, $posy);
714 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
715
716 $posy = $pdf->GetY() + 4;
717 }
718
719 $posxval = 52;
720
721 $diffsizetitle = (!getDolGlobalString('PDF_DIFFSIZE_TITLE') ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
722
723 // Show payments conditions
724 if ($object->cond_reglement_code || $object->cond_reglement) {
725 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
726 $pdf->SetXY($this->marge_gauche, $posy);
727 $titre = $outputlangs->transnoentities("PaymentConditions").':';
728 $pdf->MultiCell(43, 4, $titre, 0, 'L');
729
730 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
731 $pdf->SetXY($posxval, $posy);
732 $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);
733 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
734 if ($object->deposit_percent > 0) {
735 $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', (string) $object->deposit_percent, $lib_condition_paiement);
736 }
737 $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
738
739 $posy = $pdf->GetY() + 3;
740 }
741
742 // Check a payment mode is defined
743 /* Not used with orders
744 if (empty($object->mode_reglement_code)
745 && ! $conf->global->FACTURE_CHQ_NUMBER
746 && ! $conf->global->FACTURE_RIB_NUMBER)
747 {
748 $pdf->SetXY($this->marge_gauche, $posy);
749 $pdf->SetTextColor(200,0,0);
750 $pdf->SetFont('','B', $default_font_size - 2);
751 $pdf->MultiCell(80, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0);
752 $pdf->SetTextColor(0,0,0);
753
754 $posy=$pdf->GetY()+1;
755 }
756 */
757 /* TODO
758 else if (!empty($object->availability_code))
759 {
760 $pdf->SetXY($this->marge_gauche, $posy);
761 $pdf->SetTextColor(200,0,0);
762 $pdf->SetFont('','B', $default_font_size - 2);
763 $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0);
764 $pdf->SetTextColor(0,0,0);
765
766 $posy=$pdf->GetY()+1;
767 }*/
768
769 // Show planned date of delivery
770 if (!empty($object->delivery_date)) {
771 $outputlangs->load("sendings");
772 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
773 $pdf->SetXY($this->marge_gauche, $posy);
774 $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
775 $pdf->MultiCell(80, 4, $titre, 0, 'L');
776 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
777 $pdf->SetXY($posxval, $posy);
778 $dlp = dol_print_date($object->delivery_date, "daytext", false, $outputlangs, true);
779 $pdf->MultiCell(80, 4, $dlp, 0, 'L');
780
781 $posy = $pdf->GetY() + 1;
782 } elseif ($object->availability_code || $object->availability) {
783 // Show availability conditions
784 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
785 $pdf->SetXY($this->marge_gauche, $posy);
786 $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
787 $pdf->MultiCell(80, 4, $titre, 0, 'L');
788 $pdf->SetTextColor(0, 0, 0);
789 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
790 $pdf->SetXY($posxval, $posy);
791 $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 : '');
792 $lib_availability = str_replace('\n', "\n", $lib_availability);
793 $pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
794
795 $posy = $pdf->GetY() + 1;
796 }
797
798 // Show payment mode
799 if ($object->mode_reglement_code
800 && $object->mode_reglement_code != 'CHQ'
801 && $object->mode_reglement_code != 'VIR') {
802 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
803 $pdf->SetXY($this->marge_gauche, $posy);
804 $titre = $outputlangs->transnoentities("PaymentMode").':';
805 $pdf->MultiCell(80, 5, $titre, 0, 'L');
806
807 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
808 $pdf->SetXY($posxval, $posy);
809 $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);
810 $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
811
812 $posy = $pdf->GetY() + 2;
813 }
814
815 // Show payment mode CHQ
816 if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') {
817 // Si mode reglement non force ou si force a CHQ
818 if (getDolGlobalString('FACTURE_CHQ_NUMBER')) {
819 if (getDolGlobalInt('FACTURE_CHQ_NUMBER') > 0) {
820 $account = new Account($this->db);
821 $account->fetch(getDolGlobalString('FACTURE_CHQ_NUMBER'));
822
823 $pdf->SetXY($this->marge_gauche, $posy);
824 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
825 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->owner_name), 0, 'L', 0);
826 $posy = $pdf->GetY() + 1;
827
828 if (!getDolGlobalString('MAIN_PDF_HIDE_CHQ_ADDRESS')) {
829 $pdf->SetXY($this->marge_gauche, $posy);
830 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
831 $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
832 $posy = $pdf->GetY() + 2;
833 }
834 }
835 if ($conf->global->FACTURE_CHQ_NUMBER == -1) {
836 $pdf->SetXY($this->marge_gauche, $posy);
837 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
838 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
839 $posy = $pdf->GetY() + 1;
840
841 if (!getDolGlobalString('MAIN_PDF_HIDE_CHQ_ADDRESS')) {
842 $pdf->SetXY($this->marge_gauche, $posy);
843 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
844 $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
845 $posy = $pdf->GetY() + 2;
846 }
847 }
848 }
849 }
850
851 // If payment mode not forced or forced to VIR, show payment with BAN
852 if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') {
853 if ($object->fk_account > 0 || $object->fk_bank > 0 || getDolGlobalInt('FACTURE_RIB_NUMBER')) {
854 $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
855 if ($object->fk_bank > 0) {
856 $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
857 }
858 $account = new Account($this->db);
859 $account->fetch($bankid);
860
861 $curx = $this->marge_gauche;
862 $cury = $posy;
863
864 $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
865
866 $posy += 2;
867 }
868 }
869
870 return $posy;
871 }
872
873 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
874 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
886 protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis = null)
887 {
888 // phpcs:enable
889 global $conf, $mysoc, $hookmanager;
890
891 $default_font_size = pdf_getPDFFontSize($outputlangs);
892
893 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')) {
894 $outputlangsbis = new Translate('', $conf);
895 $outputlangsbis->setDefaultLang(getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE'));
896 $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
897 $default_font_size--;
898 }
899
900 $tab2_top = $posy;
901 $tab2_hl = 4;
902 $pdf->SetFont('', '', $default_font_size - 1);
903
904 // Total table
905 $col1x = 120;
906 $col2x = 170;
907 if ($this->page_largeur < 210) { // To work with US executive format
908 $col2x -= 20;
909 }
910 $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
911
912 $useborder = 0;
913 $index = 0;
914
915 // Get Total HT
916 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
917
918 // Total remise
919 $total_line_remise = 0;
920 foreach ($object->lines as $i => $line) {
921 $resdiscount = pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, 2);
922 $total_line_remise += (is_numeric($resdiscount) ? $resdiscount : 0);
923 // Gestion remise sous forme de ligne négative
924 if ($line->total_ht < 0) {
925 $total_line_remise += -$line->total_ht;
926 }
927 }
928 if ($total_line_remise > 0) {
929 $pdf->SetFillColor(255, 255, 255);
930 $pdf->SetXY($col1x, $tab2_top + $tab2_hl);
931 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalDiscount").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalDiscount") : ''), 0, 'L', 1);
932 $pdf->SetXY($col2x, $tab2_top + $tab2_hl);
933 $pdf->MultiCell($largcol2, $tab2_hl, price($total_line_remise, 0, $outputlangs), 0, 'R', 1);
934
935 $index++;
936
937 // Show total NET before discount
938 $pdf->SetFillColor(255, 255, 255);
939 $pdf->SetXY($col1x, $tab2_top);
940 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHTBeforeDiscount").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHTBeforeDiscount") : ''), 0, 'L', 1);
941 $pdf->SetXY($col2x, $tab2_top);
942 $pdf->MultiCell($largcol2, $tab2_hl, price($total_line_remise + $total_ht, 0, $outputlangs), 0, 'R', 1);
943
944 $index++;
945 }
946
947 // Total HT
948 $pdf->SetFillColor(255, 255, 255);
949 $pdf->SetXY($col1x, $tab2_top+ $tab2_hl * $index);
950 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1);
951
952 $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
953 $pdf->SetXY($col2x, $tab2_top+ $tab2_hl * $index);
954 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0), 0, $outputlangs), 0, 'R', 1);
955
956 // Show VAT by rates and total
957 $pdf->SetFillColor(248, 248, 248);
958
959 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
960
961 $this->atleastoneratenotnull = 0;
962 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
963 $tvaisnull = (!empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000']));
964 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL') && $tvaisnull) {
965 // Nothing to do
966 } else {
967 //Local tax 1 before VAT
968 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
969 if (in_array((string) $localtax_type, array('1', '3', '5'))) {
970 continue;
971 }
972 foreach ($localtax_rate as $tvakey => $tvaval) {
973 if ($tvakey != 0) { // On affiche pas taux 0
974 //$this->atleastoneratenotnull++;
975
976 $index++;
977 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
978
979 $tvacompl = '';
980 if (preg_match('/\*/', (string) $tvakey)) {
981 $tvakey = str_replace('*', '', (string) $tvakey);
982 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
983 }
984 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
985 $totalvat .= ' ';
986
987 if (getDolGlobalString('PDF_LOCALTAX1_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
988 $totalvat .= $tvacompl;
989 } else {
990 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
991 }
992
993 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
994
995 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
996
997 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
998 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
999 }
1000 }
1001 }
1002
1003 //Local tax 2 before VAT
1004 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1005 if (in_array((string) $localtax_type, array('1', '3', '5'))) {
1006 continue;
1007 }
1008 foreach ($localtax_rate as $tvakey => $tvaval) {
1009 if ($tvakey != 0) { // On affiche pas taux 0
1010 //$this->atleastoneratenotnull++;
1011
1012 $index++;
1013 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1014
1015 $tvacompl = '';
1016 if (preg_match('/\*/', (string) $tvakey)) {
1017 $tvakey = str_replace('*', '', (string) $tvakey);
1018 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1019 }
1020 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1021 $totalvat .= ' ';
1022
1023 if (getDolGlobalString('PDF_LOCALTAX2_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1024 $totalvat .= $tvacompl;
1025 } else {
1026 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
1027 }
1028
1029 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1030
1031 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1032
1033 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1034 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1035 }
1036 }
1037 }
1038
1039 // VAT
1040 foreach ($this->tva_array as $tvakey => $tvaval) {
1041 if ($tvakey != 0) { // On affiche pas taux 0
1042 $this->atleastoneratenotnull++;
1043
1044 $index++;
1045 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1046
1047 $tvacompl = '';
1048 if (preg_match('/\*/', $tvakey)) {
1049 $tvakey = str_replace('*', '', $tvakey);
1050 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1051 }
1052 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
1053 $totalvat .= ' ';
1054 if (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'rateonly') {
1055 $totalvat .= vatrate($tvaval['vatrate'], 1).$tvacompl;
1056 } elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'codeonly') {
1057 $totalvat .= $tvaval['vatcode'].$tvacompl;
1058 } elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1059 $totalvat .= $tvacompl;
1060 } else {
1061 $totalvat .= vatrate($tvaval['vatrate'], 1).($tvaval['vatcode'] ? ' ('.$tvaval['vatcode'].')' : '').$tvacompl;
1062 }
1063 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1064
1065 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1066 $pdf->MultiCell($largcol2, $tab2_hl, price(price2num($tvaval['amount'], 'MT'), 0, $outputlangs), 0, 'R', 1);
1067 }
1068 }
1069
1070 //Local tax 1 after VAT
1071 //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1072 //{
1073 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1074 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1075 continue;
1076 }
1077
1078 foreach ($localtax_rate as $tvakey => $tvaval) {
1079 if ($tvakey != 0) { // On affiche pas taux 0
1080 //$this->atleastoneratenotnull++;
1081
1082 $index++;
1083 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1084
1085 $tvacompl = '';
1086 if (preg_match('/\*/', (string) $tvakey)) {
1087 $tvakey = str_replace('*', '', (string) $tvakey);
1088 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1089 }
1090 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1091 $totalvat .= ' ';
1092
1093 if (getDolGlobalString('PDF_LOCALTAX1_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1094 $totalvat .= $tvacompl;
1095 } else {
1096 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
1097 }
1098
1099 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1100
1101 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1102
1103 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1104 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1105 }
1106 }
1107 }
1108 //}
1109 //Local tax 2 after VAT
1110 //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1111 //{
1112 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1113 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1114 continue;
1115 }
1116
1117 foreach ($localtax_rate as $tvakey => $tvaval) {
1118 // retrieve global local tax
1119 if ($tvakey != 0) { // On affiche pas taux 0
1120 //$this->atleastoneratenotnull++;
1121
1122 $index++;
1123 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1124
1125 $tvacompl = '';
1126 if (preg_match('/\*/', (string) $tvakey)) {
1127 $tvakey = str_replace('*', '', (string) $tvakey);
1128 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1129 }
1130 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1131 $totalvat .= ' ';
1132
1133 if (getDolGlobalString('PDF_LOCALTAX2_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
1134 $totalvat .= $tvacompl;
1135 } else {
1136 $totalvat .= vatrate((string) abs((float) $tvakey), 1).$tvacompl;
1137 }
1138
1139 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1140
1141 $total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
1142
1143 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1144 $pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
1145 }
1146 }
1147 }
1148 //}
1149
1150 // Total TTC
1151 $index++;
1152 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1153 $pdf->SetTextColor(0, 0, 60);
1154 $pdf->SetFillColor(224, 224, 224);
1155 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalTTC", $mysoc->country_code) : ''), $useborder, 'L', 1);
1156
1157 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1158 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
1159 }
1160 }
1161
1162 $pdf->SetTextColor(0, 0, 0);
1163
1164 $creditnoteamount = 0;
1165 $depositsamount = 0;
1166 //$creditnoteamount=$object->getSumCreditNotesUsed();
1167 //$depositsamount=$object->getSumDepositsUsed();
1168 //print "x".$creditnoteamount."-".$depositsamount;exit;
1169 $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
1170 if (!empty($object->paye)) {
1171 $resteapayer = 0;
1172 }
1173
1174 if ($deja_regle > 0) {
1175 // Already paid + Deposits
1176 $index++;
1177
1178 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1179 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), 0, 'L', 0);
1180 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1181 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
1182
1183 $index++;
1184 $pdf->SetTextColor(0, 0, 60);
1185 $pdf->SetFillColor(224, 224, 224);
1186 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1187 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), $useborder, 'L', 1);
1188
1189 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1190 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
1191
1192 $pdf->SetFont('', '', $default_font_size - 1);
1193 $pdf->SetTextColor(0, 0, 0);
1194 }
1195
1196 $index++;
1197 return ($tab2_top + ($tab2_hl * $index));
1198 }
1199
1200 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1215 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
1216 {
1217 global $conf;
1218
1219 // Force to disable hidetop and hidebottom
1220 $hidebottom = 0;
1221 if ($hidetop) {
1222 $hidetop = -1;
1223 }
1224
1225 $currency = !empty($currency) ? $currency : $conf->currency;
1226 $default_font_size = pdf_getPDFFontSize($outputlangs);
1227
1228 // Amount in (at tab_top - 1)
1229 $pdf->SetTextColor(0, 0, 0);
1230 $pdf->SetFont('', '', $default_font_size - 2);
1231
1232 if (empty($hidetop)) {
1233 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1234 if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && is_object($outputlangsbis)) {
1235 $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency));
1236 }
1237
1238 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1239 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1240
1241 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1242 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
1243 $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')));
1244 }
1245 }
1246
1247 $pdf->SetDrawColor(128, 128, 128);
1248 $pdf->SetFont('', '', $default_font_size - 1);
1249
1250 // Output Rect
1251 $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
1252
1253 if (empty($hidetop)) {
1254 $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
1255
1256 $pdf->SetXY($this->posxdesc - 1, $tab_top + 1);
1257 $pdf->MultiCell(108, 2, $outputlangs->transnoentities("Designation"), '', 'L');
1258 }
1259
1260 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
1261 $pdf->line($this->posxtva - 1, $tab_top, $this->posxtva - 1, $tab_top + $tab_height);
1262 if (empty($hidetop)) {
1263 $pdf->SetXY($this->posxtva - 3, $tab_top + 1);
1264 $pdf->MultiCell($this->posxup - $this->posxtva + 3, 2, $outputlangs->transnoentities("VAT"), '', 'C');
1265 }
1266 }
1267
1268 $pdf->line($this->posxup - 1, $tab_top, $this->posxup - 1, $tab_top + $tab_height);
1269 if (empty($hidetop)) {
1270 $pdf->SetXY($this->posxup - 1, $tab_top + 1);
1271 $pdf->MultiCell($this->posxqty - $this->posxup - 1, 2, $outputlangs->transnoentities("PriceUHT"), '', 'C');
1272 }
1273
1274 $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height);
1275 if (empty($hidetop)) {
1276 $pdf->SetXY($this->posxqty - 1, $tab_top + 1);
1277 $pdf->MultiCell($this->posxunit - $this->posxqty - 1, 2, $outputlangs->transnoentities("Qty"), '', 'C');
1278 }
1279
1280 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1281 $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height);
1282 if (empty($hidetop)) {
1283 $pdf->SetXY($this->posxunit - 1, $tab_top + 1);
1284 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("Unit"), '', 'C');
1285 }
1286 }
1287
1288 $pdf->line($this->posxdiscount - 1, $tab_top, $this->posxdiscount - 1, $tab_top + $tab_height);
1289 if (empty($hidetop)) {
1290 if ($this->atleastonediscount) {
1291 $pdf->SetXY($this->posxdiscount - 1, $tab_top + 1);
1292 $pdf->MultiCell($this->postotalht - $this->posxdiscount + 1, 2, $outputlangs->transnoentities("ReductionShort"), '', 'C');
1293 }
1294 }
1295
1296 if ($this->atleastonediscount) {
1297 $pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
1298 }
1299 if (empty($hidetop)) {
1300 $pdf->SetXY($this->postotalht - 1, $tab_top + 1);
1301 $pdf->MultiCell(30, 2, $outputlangs->transnoentities("TotalHTShort"), '', 'C');
1302 }
1303 }
1304
1305 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1306 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1318 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null, $titlekey = "PdfOrderTitle")
1319 {
1320 // phpcs:enable
1321 global $conf, $langs, $hookmanager;
1322
1323 $ltrdirection = 'L';
1324 if ($outputlangs->trans("DIRECTION") == 'rtl') {
1325 $ltrdirection = 'R';
1326 }
1327
1328 // Load traductions files required by page
1329 $outputlangs->loadLangs(array("main", "bills", "propal", "orders", "companies"));
1330
1331 $default_font_size = pdf_getPDFFontSize($outputlangs);
1332
1333 pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
1334
1335 $pdf->SetTextColor(0, 0, 60);
1336 $pdf->SetFont('', 'B', $default_font_size + 3);
1337
1338 $w = 100;
1339
1340 $posy = $this->marge_haute;
1341 $posx = $this->page_largeur - $this->marge_droite - $w;
1342
1343 $pdf->SetXY($this->marge_gauche, $posy);
1344
1345 // Logo
1346 if (!getDolGlobalInt('PDF_DISABLE_MYCOMPANY_LOGO')) {
1347 if ($this->emetteur->logo) {
1348 $logodir = $conf->mycompany->dir_output;
1349 if (!empty($conf->mycompany->multidir_output[$object->entity])) {
1350 $logodir = $conf->mycompany->multidir_output[$object->entity];
1351 }
1352 if (!getDolGlobalInt('MAIN_PDF_USE_LARGE_LOGO')) {
1353 $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1354 } else {
1355 $logo = $logodir.'/logos/'.$this->emetteur->logo;
1356 }
1357 if (is_readable($logo)) {
1358 $height = pdf_getHeightForLogo($logo);
1359 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1360 } else {
1361 $pdf->SetTextColor(200, 0, 0);
1362 $pdf->SetFont('', 'B', $default_font_size - 2);
1363 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1364 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1365 }
1366 } else {
1367 $text = $this->emetteur->name;
1368 $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
1369 }
1370 }
1371
1372 $pdf->SetFont('', 'B', $default_font_size + 3);
1373 $pdf->SetXY($posx, $posy);
1374 $pdf->SetTextColor(0, 0, 60);
1375 $title = $outputlangs->transnoentities($titlekey);
1376 $title .= ' '.$outputlangs->convToOutputCharset($object->ref);
1377 if ($object->statut == $object::STATUS_DRAFT) {
1378 $pdf->SetTextColor(128, 0, 0);
1379 $title .= ' - '.$outputlangs->transnoentities("NotValidated");
1380 }
1381 $pdf->MultiCell($w, 3, $title, '', 'R');
1382
1383 $pdf->SetFont('', 'B', $default_font_size);
1384
1385 /*
1386 $posy += 5;
1387 $pdf->SetXY($posx, $posy);
1388 $pdf->SetTextColor(0, 0, 60);
1389 $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref), '', 'R');
1390 */
1391
1392 $posy += 3;
1393 $pdf->SetFont('', '', $default_font_size - 1);
1394
1395 if ($object->ref_client) {
1396 $posy += 5;
1397 $pdf->SetXY($posx, $posy);
1398 $pdf->SetTextColor(0, 0, 60);
1399 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R');
1400 }
1401
1402 if (getDolGlobalString('PDF_SHOW_PROJECT_TITLE')) {
1403 $object->fetchProject();
1404 if (!empty($object->project->ref)) {
1405 $posy += 3;
1406 $pdf->SetXY($posx, $posy);
1407 $pdf->SetTextColor(0, 0, 60);
1408 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1409 }
1410 }
1411
1412 if (getDolGlobalString('PDF_SHOW_PROJECT')) {
1413 $object->fetchProject();
1414 if (!empty($object->project->ref)) {
1415 $outputlangs->load("projects");
1416 $posy += 3;
1417 $pdf->SetXY($posx, $posy);
1418 $pdf->SetTextColor(0, 0, 60);
1419 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1420 }
1421 }
1422
1423 $posy += 4;
1424 $pdf->SetXY($posx, $posy);
1425 $pdf->SetTextColor(0, 0, 60);
1426 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("OrderDate")." : ".dol_print_date($object->date, "day", false, $outputlangs, true), '', 'R');
1427
1428 if (!getDolGlobalString('MAIN_PDF_HIDE_CUSTOMER_CODE') && !empty($object->thirdparty->code_client)) {
1429 $posy += 4;
1430 $pdf->SetXY($posx, $posy);
1431 $pdf->SetTextColor(0, 0, 60);
1432 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
1433 }
1434
1435 if (!getDolGlobalString('MAIN_PDF_HIDE_CUSTOMER_ACCOUNTING_CODE') && !empty($object->thirdparty->code_compta_client)) {
1436 $posy += 4;
1437 $pdf->SetXY($posx, $posy);
1438 $pdf->SetTextColor(0, 0, 60);
1439 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerAccountancyCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_compta_client), '', 'R');
1440 }
1441
1442 // Get contact
1443 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1444 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1445 if (count($arrayidcontact) > 0) {
1446 $usertmp = new User($this->db);
1447 $usertmp->fetch($arrayidcontact[0]);
1448 $posy += 4;
1449 $pdf->SetXY($posx, $posy);
1450 $pdf->SetTextColor(0, 0, 60);
1451 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
1452 }
1453 }
1454
1455 $posy += 2;
1456
1457 $top_shift = 0;
1458 $shipp_shift = 0;
1459 // Show list of linked objects
1460 $current_y = $pdf->getY();
1461 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
1462 if ($current_y < $pdf->getY()) {
1463 $top_shift = $pdf->getY() - $current_y;
1464 }
1465
1466 if ($showaddress) {
1467 // Sender properties
1468 $carac_emetteur = '';
1469 // Add internal contact of object if defined
1470 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1471 if (count($arrayidcontact) > 0) {
1472 $object->fetch_user($arrayidcontact[0]);
1473 $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1474 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1475 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1476 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1477 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1478 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1479 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1480 $carac_emetteur .= "\n";
1481 }
1482
1483 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1484
1485 // Show sender
1486 $posy = 42 + $top_shift;
1487 $posx = $this->marge_gauche;
1488 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1489 $posx = $this->page_largeur - $this->marge_droite - 80;
1490 }
1491 $hautcadre = 40;
1492
1493 // Show sender frame
1494 if (!getDolGlobalString('MAIN_PDF_NO_SENDER_FRAME')) {
1495 $pdf->SetTextColor(0, 0, 0);
1496 $pdf->SetFont('', '', $default_font_size - 2);
1497 $pdf->SetXY($posx, $posy - 5);
1498 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1499 $pdf->SetXY($posx, $posy);
1500 $pdf->SetFillColor(230, 230, 230);
1501 $pdf->RoundedRect($posx, $posy, 82, $hautcadre, $this->corner_radius, '1234', 'F');
1502 $pdf->SetTextColor(0, 0, 60);
1503 }
1504
1505 // Show sender name
1506 if (!getDolGlobalString('MAIN_PDF_HIDE_SENDER_NAME')) {
1507 $pdf->SetXY($posx + 2, $posy + 3);
1508 $pdf->SetFont('', 'B', $default_font_size);
1509 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1510 $posy = $pdf->getY();
1511 }
1512
1513 // Show sender information
1514 $pdf->SetXY($posx + 2, $posy);
1515 $pdf->SetFont('', '', $default_font_size - 1);
1516 $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
1517
1518
1519 // If CUSTOMER contact defined, we use it
1520 $usecontact = false;
1521 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1522 if (count($arrayidcontact) > 0) {
1523 $usecontact = true;
1524 $result = $object->fetch_contact($arrayidcontact[0]);
1525 }
1526
1527 // Recipient name
1528 if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || getDolGlobalString('MAIN_USE_COMPANY_NAME_OF_CONTACT')))) {
1529 $thirdparty = $object->contact;
1530 } else {
1531 $thirdparty = $object->thirdparty;
1532 }
1533
1534 $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1535
1536 $mode = 'target';
1537 $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), ($usecontact ? 1 : 0), $mode, $object);
1538
1539 // Show recipient
1540 $widthrecbox = getDolGlobalString('MAIN_PDF_USE_ISO_LOCATION') ? 92 : 100;
1541 if ($this->page_largeur < 210) {
1542 $widthrecbox = 84; // To work with US executive format
1543 }
1544 $posy = getDolGlobalString('MAIN_PDF_USE_ISO_LOCATION') ? 40 : 42;
1545 $posy += $top_shift;
1546 $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1547 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1548 $posx = $this->marge_gauche;
1549 }
1550
1551 // Show recipient frame
1552 if (!getDolGlobalString('MAIN_PDF_NO_RECIPENT_FRAME')) {
1553 $pdf->SetTextColor(0, 0, 0);
1554 $pdf->SetFont('', '', $default_font_size - 2);
1555 $pdf->SetXY($posx + 2, $posy - 5);
1556 $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1557 $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D');
1558 }
1559
1560 // Show recipient name
1561 $pdf->SetXY($posx + 2, $posy + 3);
1562 $pdf->SetFont('', 'B', $default_font_size);
1563 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1564 $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, $ltrdirection);
1565
1566 $posy = $pdf->getY();
1567
1568 // Show recipient information
1569 $pdf->SetFont('', '', $default_font_size - 1);
1570 $pdf->SetXY($posx + 2, $posy);
1571 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1572 $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1573
1574 // Show shipping address
1575 if (getDolGlobalInt('SALES_ORDER_SHOW_SHIPPING_ADDRESS')) {
1576 $idaddressshipping = $object->getIdContact('external', 'SHIPPING');
1577
1578 if (!empty($idaddressshipping)) {
1579 $contactshipping = $object->fetch_Contact($idaddressshipping[0]);
1580 $companystatic = new Societe($this->db);
1581 $companystatic->fetch($object->contact->fk_soc);
1582 $carac_client_name_shipping = pdfBuildThirdpartyName($object->contact, $outputlangs);
1583 $carac_client_shipping = pdf_build_address($outputlangs, $this->emetteur, $companystatic, $object->contact, ($usecontact ? 1 : 0), 'target', $object);
1584 } else {
1585 $carac_client_name_shipping = pdfBuildThirdpartyName($object->thirdparty, $outputlangs);
1586 $carac_client_shipping = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'target', $object);
1587 }
1588 if (!empty($carac_client_shipping)) {
1589 $posy += $hautcadre;
1590
1591 $hautcadre -= 10; // Height for the shipping address does not need to be as high as main box
1592
1593 // Show shipping frame
1594 $pdf->SetXY($posx + 2, $posy - 5);
1595 $pdf->SetFont('', '', $default_font_size - 2);
1596 $pdf->MultiCell($widthrecbox, '', $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0);
1597 $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D');
1598
1599 // Show shipping name
1600 $pdf->SetXY($posx + 2, $posy + 1);
1601 $pdf->SetFont('', 'B', $default_font_size);
1602 $pdf->MultiCell($widthrecbox - 2, 2, $carac_client_name_shipping, '', 'L');
1603
1604 $posy = $pdf->getY();
1605
1606 // Show shipping information
1607 $pdf->SetXY($posx + 2, $posy);
1608 $pdf->SetFont('', '', $default_font_size - 1);
1609 $pdf->MultiCell($widthrecbox - 2, 2, $carac_client_shipping, '', 'L');
1610
1611 $shipp_shift += $hautcadre + 10;
1612 }
1613 }
1614 }
1615
1616 $pdf->SetTextColor(0, 0, 0);
1617
1618 $pagehead = array('top_shift' => $top_shift, 'shipp_shift' => $shipp_shift);
1619
1620 return $pagehead;
1621 }
1622
1623 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1624 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1634 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1635 {
1636 // phpcs:enable
1637 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1638 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);
1639 }
1640}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
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...
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)
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:2679
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:137
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140