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