dolibarr 25.0.0-alpha
pdf_muscadet.modules.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2011 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
6 * Copyright (C) 2010-2014 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
8 * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
9 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
10 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
11 * Copyright (C) 2024 Nick Fragoulis
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 * or see https://www.gnu.org/
26 */
27
34require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php';
35require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
36require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
40
41
46{
50 public $db;
51
55 public $name;
56
60 public $description;
61
65 public $update_main_doc_field;
66
70 public $type;
71
76 public $version = 'dolibarr';
77
78
84 public function __construct($db)
85 {
86 global $conf, $langs, $mysoc;
87
88 // Load translation files required by the page
89 $langs->loadLangs(array("main", "bills"));
90
91 $this->db = $db;
92 $this->name = "muscadet";
93 $this->description = $langs->trans('SuppliersCommandModelMuscadet');
94 $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
95
96 // Page size for A4 format
97 $this->type = 'pdf';
98 $formatarray = pdf_getFormat();
99 $this->page_largeur = $formatarray['width'];
100 $this->page_hauteur = $formatarray['height'];
101 $this->format = array($this->page_largeur, $this->page_hauteur);
102 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
103 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
104 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
105 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
106 $this->corner_radius = getDolGlobalInt('MAIN_PDF_FRAME_CORNER_RADIUS', 0);
107 $this->option_logo = 1; // Display logo
108 $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
109 $this->option_modereg = 1; // Display payment mode
110 $this->option_condreg = 1; // Display payment terms
111 $this->option_multilang = 1; // Available in several languages
112 $this->option_escompte = 0; // Displays if there has been a discount
113 $this->option_credit_note = 0; // Support credit notes
114 $this->option_freetext = 1; // Support add of a personalised text
115 $this->option_draft_watermark = 1; // Support add of a watermark on drafts
116
117 // Define position of columns
118 $this->posxdesc = $this->marge_gauche + 1;
119 $this->posxdiscount = 162;
120 $this->postotalht = 174;
121
122 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
123 $this->posxtva = 95;
124 $this->posxup = 114;
125 $this->posxqty = 132;
126 $this->posxunit = 147;
127 } else {
128 $this->posxtva = 106;
129 $this->posxup = 122;
130 $this->posxqty = 145;
131 $this->posxunit = 162;
132 }
133
134 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
135 $this->posxup = $this->posxtva; // posxtva is picture position reference
136 }
137 $this->posxpicture = $this->posxtva - getDolGlobalInt('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH', 20); // width of images
138 if ($this->page_largeur < 210) { // To work with US executive format
139 $this->posxpicture -= 20;
140 $this->posxtva -= 20;
141 $this->posxup -= 20;
142 $this->posxqty -= 20;
143 $this->posxunit -= 20;
144 $this->posxdiscount -= 20;
145 $this->postotalht -= 20;
146 }
147
148 $this->tva = array();
149 $this->tva_array = array();
150 $this->localtax1 = array();
151 $this->localtax2 = array();
152 $this->atleastoneratenotnull = 0;
153 $this->atleastonediscount = 0;
154
155 if ($mysoc === null) {
156 dol_syslog(get_class($this).'::__construct() Global $mysoc should not be null.'. getCallerInfoString(), LOG_ERR);
157 return;
158 }
159
160 // Get source company
161 $this->emetteur = $mysoc;
162 if (empty($this->emetteur->country_code)) {
163 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
164 }
165 }
166
167
168 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
180 public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
181 {
182 // phpcs:enable
183 global $user, $langs, $conf, $hookmanager, $mysoc, $nblines;
184
185 if (!is_object($outputlangs)) {
186 $outputlangs = $langs;
187 }
188 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
189 if (getDolGlobalString('MAIN_USE_FPDF')) {
190 $outputlangs->charset_output = 'ISO-8859-1';
191 }
192
193 // Load translation files required by the page
194 $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "dict", "products"));
195
196 $nblines = count($object->lines);
197
198 // Loop on each lines to detect if there is at least one image to show
199 $realpatharray = array();
200 if (getDolGlobalString('MAIN_GENERATE_SUPPLIER_ORDER_WITH_PICTURE')) {
201 for ($i = 0; $i < $nblines; $i++) {
202 if (empty($object->lines[$i]->fk_product)) {
203 continue;
204 }
205
206 $objphoto = new Product($this->db);
207 $objphoto->fetch($object->lines[$i]->fk_product);
208
209 if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
210 $pdir = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$object->lines[$i]->fk_product."/photos/";
211 $dir = $conf->product->dir_output.'/'.$pdir;
212 } else {
213 $pdir = get_exdir($objphoto->id, 0, 0, 0, $objphoto, 'product');
214 $dir = $conf->product->dir_output.'/'.$pdir;
215 }
216 $realpath = '';
217 foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
218 if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES')) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
219 if ($obj['photo_vignette']) {
220 $filename = $obj['photo_vignette'];
221 } else {
222 $filename = $obj['photo'];
223 }
224 } else {
225 $filename = $obj['photo'];
226 }
227 $realpath = $dir.$filename;
228 break;
229 }
230
231 if ($realpath) {
232 $realpatharray[$i] = $realpath;
233 }
234 }
235 }
236 if (count($realpatharray) == 0) {
237 $this->posxpicture = $this->posxtva;
238 }
239
240 if ($conf->fournisseur->commande->dir_output) {
241 $object->fetch_thirdparty();
242
243 $deja_regle = 0;
244 $amount_credit_notes_included = 0;
245 $amount_deposits_included = 0;
246 //$amount_credit_notes_included = $object->getSumCreditNotesUsed();
247 //$amount_deposits_included = $object->getSumDepositsUsed();
248
249 // Definition of $dir and $file
250 if ($object->specimen) {
251 $dir = $conf->fournisseur->commande->dir_output;
252 $file = $dir."/SPECIMEN.pdf";
253 } else {
254 $objectref = dol_sanitizeFileName($object->ref);
255 $objectrefsupplier = dol_sanitizeFileName($object->ref_supplier);
256 $dir = $conf->fournisseur->commande->dir_output.'/'.$objectref;
257 $file = $dir."/".$objectref.".pdf";
258 if (getDolGlobalString('SUPPLIER_REF_IN_NAME')) {
259 $file = $dir."/".$objectref.($objectrefsupplier ? "_".$objectrefsupplier : "").".pdf";
260 }
261 }
262
263 if (!file_exists($dir)) {
264 if (dol_mkdir($dir) < 0) {
265 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
266 return 0;
267 }
268 }
269
270 if (file_exists($dir)) {
271 // Add pdfgeneration hook
272 if (!is_object($hookmanager)) {
273 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
274 $hookmanager = new HookManager($this->db);
275 }
276 $hookmanager->initHooks(array('pdfgeneration'));
277 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
278 global $action;
279 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
280
281 $nblines = count($object->lines);
282
283 $pdf = pdf_getInstance($this->format);
284 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
285 $heightforinfotot = 50; // Height reserved to output the info and total part
286 $heightforfreetext = getDolGlobalInt('MAIN_PDF_FREETEXT_HEIGHT', 5); // Height reserved to output the free text on last page
287 $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
288 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
289 $heightforfooter += 6;
290 }
291 $pdf->setAutoPageBreak(true, 0);
292
293 if (class_exists('TCPDF')) {
294 $pdf->setPrintHeader(false);
295 $pdf->setPrintFooter(false);
296 }
297 $pdf->SetFont(pdf_getPDFFont($outputlangs));
298 // Set path to the background PDF File
299 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
300 $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
301 $tplidx = $pdf->importPage(1);
302 }
303
304 $pdf->Open();
305 $pagenb = 0;
306 $pdf->SetDrawColor(128, 128, 128);
307
308 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
309 $pdf->SetSubject($outputlangs->transnoentities("SupplierOrder"));
310 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
311 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getAnonymisableFullName($outputlangs)));
312
313 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("SupplierOrder")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
314 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
315 $pdf->SetCompression(false);
316 }
317
318 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
319 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
320
321 // Set $this->atleastonediscount if there is at least one discount
322 for ($i = 0; $i < $nblines; $i++) {
323 if ($object->lines[$i]->remise_percent) {
324 $this->atleastonediscount++;
325 }
326 }
327 if (empty($this->atleastonediscount)) {
328 $delta = ($this->postotalht - $this->posxdiscount);
329 $this->posxpicture += $delta;
330 $this->posxtva += $delta;
331 $this->posxup += $delta;
332 $this->posxqty += $delta;
333 $this->posxunit += $delta;
334 $this->posxdiscount += $delta;
335 // post of fields after are not modified, stay at same position
336 }
337
338 // New page
339 $pdf->AddPage();
340 if (!empty($tplidx)) {
341 $pdf->useTemplate($tplidx);
342 }
343 $pagenb++;
344 $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
345 $pdf->SetFont('', '', $default_font_size - 1);
346 $pdf->MultiCell(0, 3, ''); // Set interline to 3
347 $pdf->SetTextColor(0, 0, 0);
348
349 $tab_top = 80 + $top_shift + $this->marge_haute;
350 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 32 + $top_shift + $this->marge_haute : $this->marge_haute);
351
352 // Incoterm
353 if (isModEnabled('incoterm')) {
354 $desc_incoterms = $object->getIncotermsForPDF();
355 if ($desc_incoterms) {
356 $tab_top -= 2;
357
358 $pdf->SetFont('', '', $default_font_size - 1);
359 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
360 $nexY = $pdf->GetY();
361 $height_incoterms = $nexY - $tab_top;
362
363 // Rect takes a length in 3rd parameter
364 $pdf->SetDrawColor(192, 192, 192);
365 $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');
366
367 $tab_top = $nexY + 6;
368 }
369 }
370
371 // Affiche notes
372 if (!empty($object->note_public)) {
373 $tab_top -= 2;
374
375 $pdf->SetFont('', '', $default_font_size - 1);
376 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr((string) $object->note_public), 0, 1);
377 $nexY = $pdf->GetY();
378 $height_note = $nexY - $tab_top;
379
380 // Rect takes a length in 3rd parameter
381 $pdf->SetDrawColor(192, 192, 192);
382 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 2, $this->corner_radius, '1234', 'D');
383
384 $tab_top = $nexY + 6;
385 }
386
387 $iniY = $tab_top + 7;
388 $curY = $tab_top + 7;
389 $nexY = $tab_top + 7;
390
391 // Loop on each lines
392 for ($i = 0; $i < $nblines; $i++) {
393 $curY = $nexY;
394 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
395 $pdf->SetTextColor(0, 0, 0);
396
397 // Define size of image if we need it
398 $imglinesize = array();
399 if (!empty($realpatharray[$i])) {
400 $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
401 }
402
403 $pdf->setTopMargin($tab_top_newpage);
404 $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
405 $pageposbefore = $pdf->getPage();
406
407 $showpricebeforepagebreak = 1;
408 $posYAfterImage = 0;
409 $posYAfterDescription = 0;
410
411 // We start with Photo of product line
412 if (!empty($imglinesize['width']) && !empty($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page
413 $pdf->AddPage('', '', true);
414 if (!empty($tplidx)) {
415 $pdf->useTemplate($tplidx);
416 }
417 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
418 $this->_pagehead($pdf, $object, 0, $outputlangs);
419 }
420 $pdf->setPage($pageposbefore + 1);
421
422 $curY = $tab_top_newpage;
423
424 // Allows data in the first page if description is long enough to break in multiples pages
425 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
426 $showpricebeforepagebreak = 1;
427 } else {
428 $showpricebeforepagebreak = 0;
429 }
430 }
431
432 if (!empty($imglinesize['width']) && !empty($imglinesize['height'])) {
433 $curX = $this->posxpicture - 1;
434 $pdf->Image($realpatharray[$i], $curX + (($this->posxtva - $this->posxpicture - $imglinesize['width']) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
435 // $pdf->Image does not increase value return by getY, so we save it manually
436 $posYAfterImage = $curY + $imglinesize['height'];
437 }
438 // Description of product line
439 $curX = $this->posxdesc - 1;
440 $showpricebeforepagebreak = 1;
441
442 $pdf->startTransaction();
443 if ($posYAfterImage > 0) {
444 $descWidth = $this->posxpicture - $curX;
445 } else {
446 $descWidth = $this->posxtva - $curX;
447 }
448 pdf_writelinedesc($pdf, $object, $i, $outputlangs, $descWidth, 3, $curX, $curY, $hideref, $hidedesc, 1);
449
450 $pageposafter = $pdf->getPage();
451 if ($pageposafter > $pageposbefore) { // There is a pagebreak
452 $pdf->rollbackTransaction(true);
453 $pageposafter = $pageposbefore;
454 //print $pageposafter.'-'.$pageposbefore;exit;
455 $pdf->setPageOrientation('', true, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
456 pdf_writelinedesc($pdf, $object, $i, $outputlangs, $descWidth, 3, $curX, $curY, $hideref, $hidedesc, 1);
457 $posyafter = $pdf->GetY();
458 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
459 if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
460 $pdf->AddPage('', '', true);
461 if (!empty($tplidx)) {
462 $pdf->useTemplate($tplidx);
463 }
464 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
465 $this->_pagehead($pdf, $object, 0, $outputlangs);
466 }
467 $pdf->setPage($pageposafter + 1);
468 }
469 } else {
470 // We found a page break
471 // Allows data in the first page if description is long enough to break in multiples pages
472 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
473 $showpricebeforepagebreak = 1;
474 } else {
475 $showpricebeforepagebreak = 0;
476 }
477 }
478 } else { // No pagebreak
479 $pdf->commitTransaction();
480 }
481
482 $nexY = $pdf->GetY();
483 $pageposafter = $pdf->getPage();
484 $pdf->setPage($pageposbefore);
485 $pdf->setTopMargin($this->marge_haute);
486 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
487
488 // We suppose that a too long description is moved completely on next page
489 if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
490 $pdf->setPage($pageposafter);
491 $curY = $tab_top_newpage;
492 }
493
494 $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par default
495
496 // VAT Rate
497 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) {
498 $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
499 $pdf->SetXY($this->posxtva, $curY);
500 $pdf->MultiCell($this->posxup - $this->posxtva - 1, 3, $vat_rate, 0, 'R');
501 }
502
503 // Unit price before discount
504 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_PURCHASE_ORDER_WITHOUT_UNIT_PRICE')) {
505 $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
506 $pdf->SetXY($this->posxup, $curY);
507 $pdf->MultiCell($this->posxqty - $this->posxup - 0.8, 3, $up_excl_tax, 0, 'R', false);
508 }
509
510 // Quantity
511 $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
512 $pdf->SetXY($this->posxqty, $curY);
513 $pdf->MultiCell($this->posxunit - $this->posxqty - 0.8, 4, $qty, 0, 'R'); // Enough for 6 chars
514
515 // Unit
516 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
517 $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails);
518 $pdf->SetXY($this->posxunit, $curY);
519 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 0.8, 4, $unit, 0, 'L');
520 }
521
522 // Discount on line
523 $pdf->SetXY($this->posxdiscount, $curY);
524 if ($object->lines[$i]->remise_percent) {
525 $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
526 $pdf->MultiCell($this->postotalht - $this->posxdiscount - 1, 3, $remise_percent, 0, 'R');
527 }
528
529 // Total HT line
530 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_PURCHASE_ORDER_WITHOUT_TOTAL_COLUMN')) {
531 $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
532 $pdf->SetXY($this->postotalht, $curY);
533 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, $total_excl_tax, 0, 'R', false);
534 }
535
536 // // Collect total by value of vat rate into $this->tva["taux"]=total_tva
537 if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) {
538 $tvaligne = $object->lines[$i]->multicurrency_total_tva;
539 } else {
540 $tvaligne = $object->lines[$i]->total_tva;
541 }
542
543 $localtax1ligne = $object->lines[$i]->total_localtax1;
544 $localtax2ligne = $object->lines[$i]->total_localtax2;
545 $localtax1_rate = $object->lines[$i]->localtax1_tx;
546 $localtax2_rate = $object->lines[$i]->localtax2_tx;
547 $localtax1_type = $object->lines[$i]->localtax1_type;
548 $localtax2_type = $object->lines[$i]->localtax2_type;
549
550 $vatrate = (string) $object->lines[$i]->tva_tx;
551
552 // Retrieve type from database for backward compatibility with old records
553 if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
554 && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
555 $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $mysoc, $object->thirdparty);
556 $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
557 $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
558 }
559
560 // retrieve global local tax
561 if ($localtax1_type && $localtax1ligne != 0) {
562 if (empty($this->localtax1[$localtax1_type][$localtax1_rate])) {
563 $this->localtax1[$localtax1_type][$localtax1_rate] = $localtax1ligne;
564 } else {
565 $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
566 }
567 }
568 if ($localtax2_type && $localtax2ligne != 0) {
569 if (empty($this->localtax2[$localtax2_type][$localtax2_rate])) {
570 $this->localtax2[$localtax2_type][$localtax2_rate] = $localtax2ligne;
571 } else {
572 $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
573 }
574 }
575
576 if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
577 $vatrate .= '*';
578 }
579
580 // Fill $this->tva and $this->tva_array
581 if (!isset($this->tva[$vatrate])) {
582 $this->tva[$vatrate] = 0;
583 }
584 $this->tva[$vatrate] += $tvaligne;
585 $vatcode = $object->lines[$i]->vat_src_code;
586 if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
587 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
588 }
589 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
590
591 if ($posYAfterImage > $posYAfterDescription) {
592 $nexY = $posYAfterImage;
593 }
594
595 // Add line
596 if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) {
597 $pdf->setPage($pageposafter);
598 $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(80, 80, 80)));
599 //$pdf->SetDrawColor(190,190,200);
600 $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
601 $pdf->SetLineStyle(array('dash' => 0));
602 }
603
604 $nexY += 2; // Add space between lines
605
606 // Detect if some page were added automatically and output _tableau for past pages
607 while ($pagenb < $pageposafter) {
608 $pdf->setPage($pagenb);
609 if ($pagenb == 1) {
610 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
611 } else {
612 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
613 }
614 $this->_pagefoot($pdf, $object, $outputlangs, 1);
615 $pagenb++;
616 $pdf->setPage($pagenb);
617 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
618 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
619 $this->_pagehead($pdf, $object, 0, $outputlangs);
620 }
621 if (!empty($tplidx)) {
622 $pdf->useTemplate($tplidx);
623 }
624 }
625 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { // @phan-suppress-current-line PhanUndeclaredProperty
626 if ($pagenb == 1) {
627 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
628 } else {
629 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
630 }
631 $this->_pagefoot($pdf, $object, $outputlangs, 1);
632 // New page
633 $pdf->AddPage();
634 if (!empty($tplidx)) {
635 $pdf->useTemplate($tplidx);
636 }
637 $pagenb++;
638 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
639 $this->_pagehead($pdf, $object, 0, $outputlangs);
640 }
641 }
642 }
643
644 // Show square
645 if ($pagenb == 1) {
646 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
647 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
648 } else {
649 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
650 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
651 }
652
653 // Affiche zone infos
654 $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
655
656 // Affiche zone totaux
657 $posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
658
659 // Affiche zone versements
660 if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) {
661 $posy = $this->_tableau_versements($pdf, $object, $posy, $outputlangs);
662 }
663
664 // Pied de page
665 $this->_pagefoot($pdf, $object, $outputlangs);
666 if (method_exists($pdf, 'AliasNbPages')) {
667 $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod
668 }
669
670 $pdf->Close();
671
672 $pdf->Output($file, 'F');
673
674 // Add pdfgeneration hook
675 $hookmanager->initHooks(array('pdfgeneration'));
676 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
677 global $action;
678 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
679 $this->warnings = $hookmanager->warnings;
680 if ($reshook < 0) {
681 $this->error = $hookmanager->error;
682 $this->errors = $hookmanager->errors;
683 dolChmod($file);
684 return -1;
685 }
686
687 dolChmod($file);
688
689 $this->result = array('fullpath' => $file);
690
691 return 1; // No error
692 } else {
693 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
694 return 0;
695 }
696 } else {
697 $this->error = $langs->trans("ErrorConstantNotDefined", "SUPPLIER_OUTPUTDIR");
698 return 0;
699 }
700 }
701
702 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
703 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
713 protected function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
714 {
715 // phpcs:enable
716 return 1;
717 }
718
719 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
720 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
730 protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
731 {
732 // phpcs:enable
733 global $conf, $mysoc;
734 $default_font_size = pdf_getPDFFontSize($outputlangs);
735
736 $diffsizetitle = getDolGlobalInt('PDF_DIFFSIZE_TITLE', 3);
737
738 // If France, show VAT mention if not applicable
739 if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
740 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
741 $pdf->SetXY($this->marge_gauche, $posy);
742 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', false);
743
744 $posy = $pdf->GetY() + 4;
745 }
746
747 $posxval = 52;
748
749 // Show payments conditions
750 if (!empty($object->cond_reglement_code) || $object->cond_reglement_id) {
751 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
752 $pdf->SetXY($this->marge_gauche, $posy);
753 $titre = $outputlangs->transnoentities("PaymentConditions").':';
754 $pdf->MultiCell(80, 4, $titre, 0, 'L');
755
756 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
757 $pdf->SetXY($posxval, $posy);
758 $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);
759 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
760 if ($object->deposit_percent > 0) {
761 $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', $object->deposit_percent, $lib_condition_paiement);
762 }
763 $pdf->MultiCell(80, 4, $lib_condition_paiement, 0, 'L');
764
765 $posy = $pdf->GetY() + 3;
766 }
767
768 // Show payment mode
769 if (!empty($object->mode_reglement_code)) {
770 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
771 $pdf->SetXY($this->marge_gauche, $posy);
772 $titre = $outputlangs->transnoentities("PaymentMode").':';
773 $pdf->MultiCell(80, 5, $titre, 0, 'L');
774
775 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
776 $pdf->SetXY($posxval, $posy);
777 $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);
778 $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
779
780 $posy = $pdf->GetY() + 2;
781 }
782
783 return $posy;
784 }
785
786 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
787 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
798 protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
799 {
800 // phpcs:enable
801 global $conf, $mysoc;
802
803 $default_font_size = pdf_getPDFFontSize($outputlangs);
804
805 $tab2_top = $posy;
806 $tab2_hl = 4;
807 $pdf->SetFont('', '', $default_font_size - 1);
808
809 // Tableau total
810 $col1x = 120;
811 $col2x = 170;
812 if ($this->page_largeur < 210) { // To work with US executive format
813 $col2x -= 20;
814 }
815 $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
816
817 $useborder = 0;
818 $index = 0;
819
820 // Total HT
821 $pdf->SetFillColor(255, 255, 255);
822 $pdf->SetXY($col1x, $tab2_top);
823 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', true);
824
825 $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
826 $pdf->SetXY($col2x, $tab2_top);
827 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, 'R', true);
828
829 // Show VAT by rates and total
830 $pdf->SetFillColor(248, 248, 248);
831
832 $this->atleastoneratenotnull = 0;
833 foreach ($this->tva as $tvakey => $tvaval) {
834 if ($tvakey > 0) { // On affiche pas taux 0
835 $this->atleastoneratenotnull++;
836
837 $index++;
838 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
839
840 $tvacompl = '';
841
842 if (preg_match('/\*/', $tvakey)) {
843 $tvakey = str_replace('*', '', $tvakey);
844 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
845 }
846
847 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).' ';
848 $totalvat .= vatrate($tvakey, true).$tvacompl;
849 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
850
851 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
852 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', true);
853 }
854 }
855 if (!$this->atleastoneratenotnull) { // If no vat at all
856 $index++;
857 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
858 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code), 0, 'L', true);
859
860 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
861 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_tva), 0, 'R', true);
862
863 // Total LocalTax1
864 if (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on' && $object->total_localtax1 > 0) {
865 $index++;
866 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
867 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code), 0, 'L', true);
868 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
869 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax1), $useborder, 'R', true);
870 }
871
872 // Total LocalTax2
873 if (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on' && $object->total_localtax2 > 0) {
874 $index++;
875 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
876 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code), 0, 'L', true);
877 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
878 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax2), $useborder, 'R', true);
879 }
880 } else {
881 //if (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') && getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on')
882 //{
883 //Local tax 1
884 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
885 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
886 continue;
887 }
888
889 foreach ($localtax_rate as $tvakey => $tvaval) {
890 if ($tvakey != 0) { // On affiche pas taux 0
891 //$this->atleastoneratenotnull++;
892
893 $index++;
894 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
895
896 $tvacompl = '';
897 if (preg_match('/\*/', (string) $tvakey)) {
898 $tvakey = str_replace('*', '', (string) $tvakey);
899 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
900 }
901 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
902 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
903 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
904
905 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
906 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', true);
907 }
908 }
909 }
910
911 //if (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') && getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on')
912 //{
913 //Local tax 2
914 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
915 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
916 continue;
917 }
918
919 foreach ($localtax_rate as $tvakey => $tvaval) {
920 if ($tvakey != 0) { // On affiche pas taux 0
921 //$this->atleastoneratenotnull++;
922
923 $index++;
924 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
925
926 $tvacompl = '';
927 if (preg_match('/\*/', (string) $tvakey)) {
928 $tvakey = str_replace('*', '', (string) $tvakey);
929 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
930 }
931 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
932 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
933 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
934
935 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
936 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', true);
937 }
938 }
939 }
940 }
941
942 // Total TTC
943 $index++;
944 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
945 $pdf->SetTextColor(0, 0, 60);
946 $pdf->SetFillColor(224, 224, 224);
947 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', true);
948
949 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
950 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
951 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc), $useborder, 'R', true);
952 $pdf->SetFont('', '', $default_font_size - 1);
953 $pdf->SetTextColor(0, 0, 0);
954
955 $creditnoteamount = 0;
956 $depositsamount = 0;
957 //$creditnoteamount=$object->getSumCreditNotesUsed();
958 //$depositsamount=$object->getSumDepositsUsed();
959 //print "x".$creditnoteamount."-".$depositsamount;exit;
960 $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
961 if (!empty($object->paye)) {
962 $resteapayer = 0;
963 }
964
965 if ($deja_regle > 0) {
966 // Already paid + Deposits
967 $index++;
968
969 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
970 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', false);
971 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
972 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle), 0, 'R', false);
973
974 $index++;
975 $pdf->SetTextColor(0, 0, 60);
976 $pdf->SetFillColor(224, 224, 224);
977 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
978 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', true);
979
980 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
981 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer), $useborder, 'R', true);
982
983 $pdf->SetFont('', '', $default_font_size - 1);
984 $pdf->SetTextColor(0, 0, 0);
985 }
986
987 $index++;
988 return ($tab2_top + ($tab2_hl * $index));
989 }
990
991 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1005 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
1006 {
1007 global $conf;
1008
1009 // Force to disable hidetop and hidebottom
1010 $hidebottom = 0;
1011 if ($hidetop) {
1012 $hidetop = -1;
1013 }
1014
1015 $currency = !empty($currency) ? $currency : $conf->currency;
1016 $default_font_size = pdf_getPDFFontSize($outputlangs);
1017
1018 // Amount in (at tab_top - 1)
1019 $pdf->SetTextColor(0, 0, 0);
1020 $pdf->SetFont('', '', $default_font_size - 2);
1021
1022 if (empty($hidetop)) {
1023 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1024 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1025 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1026
1027 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1028 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
1029 $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')));
1030 }
1031 }
1032
1033 $pdf->SetDrawColor(128, 128, 128);
1034 $pdf->SetFont('', '', $default_font_size - 1);
1035
1036 // Output Rect
1037 $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
1038
1039 if (empty($hidetop)) {
1040 $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
1041
1042 $pdf->SetXY($this->posxdesc - 1, $tab_top + 1);
1043 $pdf->MultiCell(108, 2, $outputlangs->transnoentities("Designation"), '', 'L');
1044 }
1045
1046 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
1047 $pdf->line($this->posxtva, $tab_top, $this->posxtva, $tab_top + $tab_height);
1048 if (empty($hidetop)) {
1049 $pdf->SetXY($this->posxtva - 3, $tab_top + 1);
1050 $pdf->MultiCell($this->posxup - $this->posxtva + 3, 2, $outputlangs->transnoentities("VAT"), '', 'C');
1051 }
1052 }
1053
1054 $pdf->line($this->posxup, $tab_top, $this->posxup, $tab_top + $tab_height);
1055 if (empty($hidetop)) {
1056 $pdf->SetXY($this->posxup - 1, $tab_top + 1);
1057 $pdf->MultiCell($this->posxqty - $this->posxup - 1, 2, $outputlangs->transnoentities("PriceUHT"), '', 'C');
1058 }
1059
1060 $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height);
1061 if (empty($hidetop)) {
1062 $pdf->SetXY($this->posxqty - 1, $tab_top + 1);
1063 $pdf->MultiCell($this->posxunit - $this->posxqty - 1, 2, $outputlangs->transnoentities("Qty"), '', 'C');
1064 }
1065
1066 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1067 $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height);
1068 if (empty($hidetop)) {
1069 $pdf->SetXY($this->posxunit - 1, $tab_top + 1);
1070 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("Unit"), '', 'C');
1071 }
1072 }
1073
1074 $pdf->line($this->posxdiscount - 1, $tab_top, $this->posxdiscount - 1, $tab_top + $tab_height);
1075 if (empty($hidetop)) {
1076 if ($this->atleastonediscount) {
1077 $pdf->SetXY($this->posxdiscount - 1, $tab_top + 1);
1078 $pdf->MultiCell($this->postotalht - $this->posxdiscount + 1, 2, $outputlangs->transnoentities("ReductionShort"), '', 'C');
1079 }
1080 }
1081
1082 if ($this->atleastonediscount) {
1083 $pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
1084 }
1085 if (empty($hidetop)) {
1086 $pdf->SetXY($this->postotalht - 1, $tab_top + 1);
1087 $pdf->MultiCell(30, 2, $outputlangs->transnoentities("TotalHTShort"), '', 'C');
1088 }
1089 }
1090
1091 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1101 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
1102 {
1103 global $langs, $conf, $mysoc;
1104
1105 $ltrdirection = 'L';
1106 if ($outputlangs->trans("DIRECTION") == 'rtl') {
1107 $ltrdirection = 'R';
1108 }
1109
1110 // Load translation files required by the page
1111 $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "sendings"));
1112
1113 $default_font_size = pdf_getPDFFontSize($outputlangs);
1114
1115 // Do not add the BACKGROUND as this is for suppliers
1116 //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
1117
1118 // Print Draft Watermark
1119 /*if($object->statut==0 && getDolGlobalString('COMMANDE_DRAFT_WATERMARK'))
1120 {
1121 pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',getDolGlobalString('COMMANDE_DRAFT_WATERMARK'));
1122 }*/
1123 //Print content
1124
1125 $pdf->SetTextColor(0, 0, 60);
1126 $pdf->SetFont('', 'B', $default_font_size + 3);
1127
1128 $w = 100;
1129
1130 $posx = $this->page_largeur - $this->marge_droite - 100;
1131 $posy = $this->marge_haute;
1132
1133 $pdf->SetXY($this->marge_gauche, $posy);
1134
1135 // Logo
1136 $logodir = $conf->mycompany->dir_output;
1137 if (!empty($conf->mycompany->multidir_output[$object->entity ?? $conf->entity])) {
1138 $logodir = $conf->mycompany->multidir_output[$object->entity ?? $conf->entity];
1139 }
1140 pdf_writeLogoOrCompanyName($pdf, $outputlangs, $this->emetteur, $logodir, $this->marge_gauche, $posy, $w, $default_font_size, $ltrdirection);
1141
1142 $pdf->SetFont('', 'B', $default_font_size + 3);
1143 $pdf->SetXY($posx, $posy);
1144 $pdf->SetTextColor(0, 0, 60);
1145 $title = $outputlangs->transnoentities("SupplierOrder")." ".$outputlangs->convToOutputCharset($object->ref);
1146 if ($object->status == $object::STATUS_DRAFT) {
1147 $pdf->SetTextColor(128, 0, 0);
1148 $title .= ' - '.$outputlangs->transnoentities("NotValidated");
1149 }
1150 $pdf->MultiCell($w, 3, $title, '', 'R');
1151 $posy += 1;
1152
1153 if ($object->ref_supplier) {
1154 $posy += 4;
1155 $pdf->SetFont('', 'B', $default_font_size);
1156 $pdf->SetXY($posx, $posy);
1157 $pdf->SetTextColor(0, 0, 60);
1158 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefSupplier")." : ".$outputlangs->convToOutputCharset($object->ref_supplier), '', 'R');
1159 $posy += 1;
1160 }
1161
1162 $pdf->SetFont('', '', $default_font_size - 1);
1163
1164 if (getDolGlobalString('PDF_SHOW_PROJECT_TITLE')) {
1165 $object->fetchProject();
1166 if (!empty($object->project->ref)) {
1167 $posy += 3;
1168 $pdf->SetXY($posx, $posy);
1169 $pdf->SetTextColor(0, 0, 60);
1170 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1171 }
1172 }
1173
1174 if (getDolGlobalString('PDF_SHOW_PROJECT')) {
1175 $object->fetchProject();
1176 if (!empty($object->project->ref)) {
1177 $outputlangs->load("projects");
1178 $posy += 4;
1179 $pdf->SetXY($posx, $posy);
1180 $langs->load("projects");
1181 $pdf->SetTextColor(0, 0, 60);
1182 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1183 }
1184 }
1185
1186 if (!empty($object->date_commande)) {
1187 $posy += 5;
1188 $pdf->SetXY($posx, $posy);
1189 $pdf->SetTextColor(0, 0, 60);
1190 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("OrderDate")." : ".dol_print_date($object->date_commande, "day", false, $outputlangs, true), '', 'R');
1191 }
1192 // no point in having this here this a document sent to supplier
1193 /*} else {
1194 $posy += 5;
1195 $pdf->SetXY($posx, $posy);
1196 $pdf->SetTextColor(255, 0, 0);
1197 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("OrderToProcess"), '', 'R');
1198 }*/
1199
1200 $pdf->SetTextColor(0, 0, 60);
1201 $usehourmin = 'day';
1202 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
1203 $usehourmin = 'dayhour';
1204 }
1205 if (!empty($object->delivery_date)) {
1206 $posy += 4;
1207 $pdf->SetXY($posx - 90, $posy);
1208 $pdf->MultiCell(190, 3, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->delivery_date, $usehourmin, false, $outputlangs, true), '', 'R');
1209 }
1210
1211 if ($object->thirdparty->code_fournisseur) {
1212 $posy += 4;
1213 $pdf->SetXY($posx, $posy);
1214 $pdf->SetTextColor(0, 0, 60);
1215 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("SupplierCode")." : ".$outputlangs->transnoentities((string) $object->thirdparty->code_fournisseur), '', 'R');
1216 }
1217
1218 // Get contact
1219 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1220 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1221 if (count($arrayidcontact) > 0) {
1222 $usertmp = new User($this->db);
1223 $usertmp->fetch($arrayidcontact[0]);
1224 $posy += 4;
1225 $pdf->SetXY($posx, $posy);
1226 $pdf->SetTextColor(0, 0, 60);
1227 $pdf->MultiCell($w, 3, $langs->trans("BuyerName")." : ".$usertmp->getFullName($langs), '', 'R');
1228 }
1229 }
1230
1231 $posy += 1;
1232 $pdf->SetTextColor(0, 0, 60);
1233
1234 $top_shift = 0;
1235 // Show list of linked objects
1236 $current_y = $pdf->getY();
1237 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
1238 if ($current_y < $pdf->getY()) {
1239 $top_shift = $pdf->getY() - $current_y;
1240 }
1241
1242 if ($showaddress) {
1243 // Sender properties
1244 $carac_emetteur = '';
1245 // Add internal contact of object if defined
1246 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1247 if (count($arrayidcontact) > 0) {
1248 $object->fetch_user($arrayidcontact[0]);
1249 $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1250 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname.": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1251 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1252 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1253 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1254 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1255 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1256 $carac_emetteur .= "\n";
1257 }
1258
1259 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1260
1261 // Show sender
1262 $posy = 32 + $top_shift + $this->marge_haute;
1263 $posx = $this->marge_gauche;
1264 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1265 $posx = $this->page_largeur - $this->marge_droite - 80;
1266 }
1267 $hautcadre = 40;
1268
1269 // Show sender frame
1270 $pdf->SetTextColor(0, 0, 0);
1271 $pdf->SetFont('', '', $default_font_size - 2);
1272 $pdf->SetXY($posx, $posy - 5);
1273 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1274 $pdf->SetXY($posx, $posy);
1275 $pdf->SetFillColor(230, 230, 230);
1276 $pdf->RoundedRect($posx, $posy, 82, $hautcadre, $this->corner_radius, '1234', 'F');
1277 $pdf->SetTextColor(0, 0, 60);
1278
1279 // Show sender name
1280 $pdf->SetXY($posx + 2, $posy + 3);
1281 $pdf->SetFont('', 'B', $default_font_size);
1282 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1283 $posy = $pdf->getY();
1284
1285 // Show sender information
1286 $pdf->SetXY($posx + 2, $posy);
1287 $pdf->SetFont('', '', $default_font_size - 1);
1288 $pdf->MultiCell(80, 4, $carac_emetteur, 0, $ltrdirection);
1289
1290
1291 // If CUSTOMER contact defined on order, we use it. Note: Even if this is a supplier object, the code for external contat that follow order is 'CUSTOMER'
1292 $usecontact = false;
1293 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1294 if (count($arrayidcontact) > 0) {
1295 $usecontact = true;
1296 $result = $object->fetch_contact($arrayidcontact[0]);
1297 }
1298
1299 // Recipient name
1300 if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || getDolGlobalString('MAIN_USE_COMPANY_NAME_OF_CONTACT')))) {
1301 $thirdparty = $object->contact;
1302 } else {
1303 $thirdparty = $object->thirdparty;
1304 }
1305
1306 $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1307
1308 $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), ($usecontact ? 1 : 0), 'target', $object);
1309
1310 // Show recipient
1311 $widthrecbox = 100;
1312 if ($this->page_largeur < 210) {
1313 $widthrecbox = 84; // To work with US executive format
1314 }
1315 $posy = 32 + $top_shift + $this->marge_haute;
1316 $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1317 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1318 $posx = $this->marge_gauche;
1319 }
1320
1321 // Show recipient frame
1322 $pdf->SetTextColor(0, 0, 0);
1323 $pdf->SetFont('', '', $default_font_size - 2);
1324 $pdf->SetXY($posx + 2, $posy - 5);
1325 $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1326 $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D');
1327
1328 // Show recipient name
1329 $pdf->SetXY($posx + 2, $posy + 3);
1330 $pdf->SetFont('', 'B', $default_font_size);
1331 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1332 $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, $ltrdirection);
1333
1334 $posy = $pdf->getY();
1335
1336 // Show recipient information
1337 $pdf->SetFont('', '', $default_font_size - 1);
1338 $pdf->SetXY($posx + 2, $posy);
1339 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1340 $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1341 }
1342
1343 return $top_shift;
1344 }
1345
1346 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1356 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1357 {
1358 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1359 return pdf_pagefoot($pdf, $outputlangs, 'SUPPLIER_ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1360 }
1361}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
printRoundedRect($pdf, $x, $y, $w, $h, $r, $hidetop=0, $hidebottom=0, $style='D')
Print a rounded rectangle on the PDF.
Class to manage hooks.
Parent class for supplier orders models.
Class to manage products or services.
Class to manage Dolibarr users.
Class to generate the supplier orders with the muscadet model.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
Show table for lines.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
_tableau_versements(&$pdf, $object, $posy, $outputlangs)
Show payments table.
_tableau_info(&$pdf, $object, $posy, $outputlangs)
Show miscellaneous information (payment mode, payment term, ...)
_pagehead(&$pdf, $object, $showaddress, $outputlangs)
Show top header of page.
_tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
Show total to pay.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
__construct($db)
Constructor.
global $mysoc
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
getCallerInfoString()
Get caller info as a string that can be appended to a log message.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
pdf_getSizeForImage($realpath)
Return dimensions to use for images onto PDF checking that width and height are not higher than maxim...
Definition pdf.lib.php:3217
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2918
pdf_getFormat($outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:87
pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1851
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:294
pdf_writelinedesc($pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref=0, $hidedesc=0, $issupplierline=0, $align='J')
Output line description into PDF.
Definition pdf.lib.php:1889
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:2507
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:2445
pdf_pagefoot($pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails=0, $hidefreetext=0, $page_largeur=0, $watermark='')
Show footer of page for PDF generation.
Definition pdf.lib.php:1464
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:273
pdf_build_address($outputlangs, $sourcecompany, $targetcompany='', $targetcontact='', $usecontact=0, $mode='source', $object=null)
Return a string with full address formatted for output on PDF documents.
Definition pdf.lib.php:479
pdf_writeLogoOrCompanyName($pdf, $outputlangs, $emetteur, $logodir, $posx, $posy, $w, $default_font_size, $align)
Output company logo on top-left of a PDF page header, or the company name as fallback text if no logo...
Definition pdf.lib.php:349
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0)
Return line unit.
Definition pdf.lib.php:2752
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2795
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2592
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:129
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition pdf.lib.php:434
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:130
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:133