dolibarr 22.0.5
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-2025 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("PurchaseOrder"));
310 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
311 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
312
313 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PurchaseOrder")." ".$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 // Positionne $this->atleastonediscount si on a au moins une remise
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 = 90 + $top_shift;
350 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
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($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 // Collecte des totaux par valeur de tva dans $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 // TODO remise_percent is an obsolete field for object parent
551 /*if (!empty($object->remise_percent)) {
552 $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
553 }
554 if (!empty($object->remise_percent)) {
555 $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
556 }
557 if (!empty($object->remise_percent)) {
558 $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
559 }*/
560
561 $vatrate = (string) $object->lines[$i]->tva_tx;
562
563 // Retrieve type from database for backward compatibility with old records
564 if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
565 && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
566 $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $mysoc, $object->thirdparty);
567 $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
568 $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
569 }
570
571 // retrieve global local tax
572 if ($localtax1_type && $localtax1ligne != 0) {
573 if (empty($this->localtax1[$localtax1_type][$localtax1_rate])) {
574 $this->localtax1[$localtax1_type][$localtax1_rate] = $localtax1ligne;
575 } else {
576 $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
577 }
578 }
579 if ($localtax2_type && $localtax2ligne != 0) {
580 if (empty($this->localtax2[$localtax2_type][$localtax2_rate])) {
581 $this->localtax2[$localtax2_type][$localtax2_rate] = $localtax2ligne;
582 } else {
583 $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
584 }
585 }
586
587 if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
588 $vatrate .= '*';
589 }
590
591 // Fill $this->tva and $this->tva_array
592 if (!isset($this->tva[$vatrate])) {
593 $this->tva[$vatrate] = 0;
594 }
595 $this->tva[$vatrate] += $tvaligne;
596 $vatcode = $object->lines[$i]->vat_src_code;
597 if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
598 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
599 }
600 $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
601
602 if ($posYAfterImage > $posYAfterDescription) {
603 $nexY = $posYAfterImage;
604 }
605
606 // Add line
607 if (getDolGlobalString('MAIN_PDF_DASH_BETWEEN_LINES') && $i < ($nblines - 1)) {
608 $pdf->setPage($pageposafter);
609 $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(80, 80, 80)));
610 //$pdf->SetDrawColor(190,190,200);
611 $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
612 $pdf->SetLineStyle(array('dash' => 0));
613 }
614
615 $nexY += 2; // Add space between lines
616
617 // Detect if some page were added automatically and output _tableau for past pages
618 while ($pagenb < $pageposafter) {
619 $pdf->setPage($pagenb);
620 if ($pagenb == 1) {
621 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
622 } else {
623 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
624 }
625 $this->_pagefoot($pdf, $object, $outputlangs, 1);
626 $pagenb++;
627 $pdf->setPage($pagenb);
628 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
629 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
630 $this->_pagehead($pdf, $object, 0, $outputlangs);
631 }
632 if (!empty($tplidx)) {
633 $pdf->useTemplate($tplidx);
634 }
635 }
636 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { // @phan-suppress-current-line PhanUndeclaredProperty
637 if ($pagenb == 1) {
638 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
639 } else {
640 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
641 }
642 $this->_pagefoot($pdf, $object, $outputlangs, 1);
643 // New page
644 $pdf->AddPage();
645 if (!empty($tplidx)) {
646 $pdf->useTemplate($tplidx);
647 }
648 $pagenb++;
649 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
650 $this->_pagehead($pdf, $object, 0, $outputlangs);
651 }
652 }
653 }
654
655 // Show square
656 if ($pagenb == 1) {
657 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
658 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
659 } else {
660 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
661 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
662 }
663
664 // Affiche zone infos
665 $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
666
667 // Affiche zone totaux
668 $posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
669
670 // Affiche zone versements
671 if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) {
672 $posy = $this->_tableau_versements($pdf, $object, $posy, $outputlangs);
673 }
674
675 // Pied de page
676 $this->_pagefoot($pdf, $object, $outputlangs);
677 if (method_exists($pdf, 'AliasNbPages')) {
678 $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod
679 }
680
681 $pdf->Close();
682
683 $pdf->Output($file, 'F');
684
685 // Add pdfgeneration hook
686 $hookmanager->initHooks(array('pdfgeneration'));
687 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
688 global $action;
689 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
690 if ($reshook < 0) {
691 $this->error = $hookmanager->error;
692 $this->errors = $hookmanager->errors;
693 }
694
695 dolChmod($file);
696
697 $this->result = array('fullpath' => $file);
698
699 return 1; // No error
700 } else {
701 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
702 return 0;
703 }
704 } else {
705 $this->error = $langs->trans("ErrorConstantNotDefined", "SUPPLIER_OUTPUTDIR");
706 return 0;
707 }
708 }
709
710 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
711 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
721 protected function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
722 {
723 // phpcs:enable
724 return 1;
725 }
726
727 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
728 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
738 protected function _tableau_info(&$pdf, $object, $posy, $outputlangs)
739 {
740 // phpcs:enable
741 global $conf, $mysoc;
742 $default_font_size = pdf_getPDFFontSize($outputlangs);
743
744 $diffsizetitle = getDolGlobalInt('PDF_DIFFSIZE_TITLE', 3);
745
746 // If France, show VAT mention if not applicable
747 if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
748 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
749 $pdf->SetXY($this->marge_gauche, $posy);
750 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', false);
751
752 $posy = $pdf->GetY() + 4;
753 }
754
755 $posxval = 52;
756
757 // Show payments conditions
758 if (!empty($object->cond_reglement_code) || $object->cond_reglement_id) {
759 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
760 $pdf->SetXY($this->marge_gauche, $posy);
761 $titre = $outputlangs->transnoentities("PaymentConditions").':';
762 $pdf->MultiCell(80, 4, $titre, 0, 'L');
763
764 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
765 $pdf->SetXY($posxval, $posy);
766 $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);
767 $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
768 $pdf->MultiCell(80, 4, $lib_condition_paiement, 0, 'L');
769
770 $posy = $pdf->GetY() + 3;
771 }
772
773 // Show payment mode
774 if (!empty($object->mode_reglement_code)) {
775 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
776 $pdf->SetXY($this->marge_gauche, $posy);
777 $titre = $outputlangs->transnoentities("PaymentMode").':';
778 $pdf->MultiCell(80, 5, $titre, 0, 'L');
779
780 $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
781 $pdf->SetXY($posxval, $posy);
782 $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);
783 $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
784
785 $posy = $pdf->GetY() + 2;
786 }
787
788 return $posy;
789 }
790
791 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
792 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
803 protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
804 {
805 // phpcs:enable
806 global $conf, $mysoc;
807
808 $default_font_size = pdf_getPDFFontSize($outputlangs);
809
810 $tab2_top = $posy;
811 $tab2_hl = 4;
812 $pdf->SetFont('', '', $default_font_size - 1);
813
814 // Tableau total
815 $col1x = 120;
816 $col2x = 170;
817 if ($this->page_largeur < 210) { // To work with US executive format
818 $col2x -= 20;
819 }
820 $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
821
822 $useborder = 0;
823 $index = 0;
824
825 // Total HT
826 $pdf->SetFillColor(255, 255, 255);
827 $pdf->SetXY($col1x, $tab2_top);
828 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', true);
829
830 $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
831 $pdf->SetXY($col2x, $tab2_top);
832 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, 'R', true);
833
834 // Show VAT by rates and total
835 $pdf->SetFillColor(248, 248, 248);
836
837 $this->atleastoneratenotnull = 0;
838 foreach ($this->tva as $tvakey => $tvaval) {
839 if ($tvakey > 0) { // On affiche pas taux 0
840 $this->atleastoneratenotnull++;
841
842 $index++;
843 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
844
845 $tvacompl = '';
846
847 if (preg_match('/\*/', $tvakey)) {
848 $tvakey = str_replace('*', '', $tvakey);
849 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
850 }
851
852 $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).' ';
853 $totalvat .= vatrate($tvakey, true).$tvacompl;
854 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
855
856 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
857 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', true);
858 }
859 }
860 if (!$this->atleastoneratenotnull) { // If no vat at all
861 $index++;
862 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
863 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code), 0, 'L', true);
864
865 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
866 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_tva), 0, 'R', true);
867
868 // Total LocalTax1
869 if (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on' && $object->total_localtax1 > 0) {
870 $index++;
871 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
872 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code), 0, 'L', true);
873 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
874 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax1), $useborder, 'R', true);
875 }
876
877 // Total LocalTax2
878 if (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on' && $object->total_localtax2 > 0) {
879 $index++;
880 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
881 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code), 0, 'L', true);
882 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
883 $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax2), $useborder, 'R', true);
884 }
885 } else {
886 //if (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') && getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on')
887 //{
888 //Local tax 1
889 foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
890 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
891 continue;
892 }
893
894 foreach ($localtax_rate as $tvakey => $tvaval) {
895 if ($tvakey != 0) { // On affiche pas taux 0
896 //$this->atleastoneratenotnull++;
897
898 $index++;
899 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
900
901 $tvacompl = '';
902 if (preg_match('/\*/', (string) $tvakey)) {
903 $tvakey = str_replace('*', '', (string) $tvakey);
904 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
905 }
906 $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
907 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
908 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
909
910 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
911 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', true);
912 }
913 }
914 }
915
916 //if (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') && getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on')
917 //{
918 //Local tax 2
919 foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
920 if (in_array((string) $localtax_type, array('2', '4', '6'))) {
921 continue;
922 }
923
924 foreach ($localtax_rate as $tvakey => $tvaval) {
925 if ($tvakey != 0) { // On affiche pas taux 0
926 //$this->atleastoneratenotnull++;
927
928 $index++;
929 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
930
931 $tvacompl = '';
932 if (preg_match('/\*/', (string) $tvakey)) {
933 $tvakey = str_replace('*', '', (string) $tvakey);
934 $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
935 }
936 $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
937 $totalvat .= vatrate((string) abs((float) $tvakey), true).$tvacompl;
938 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', true);
939
940 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
941 $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', true);
942 }
943 }
944 }
945 }
946
947 // Total TTC
948 $index++;
949 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
950 $pdf->SetTextColor(0, 0, 60);
951 $pdf->SetFillColor(224, 224, 224);
952 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', true);
953
954 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
955 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
956 $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc), $useborder, 'R', true);
957 $pdf->SetFont('', '', $default_font_size - 1);
958 $pdf->SetTextColor(0, 0, 0);
959
960 $creditnoteamount = 0;
961 $depositsamount = 0;
962 //$creditnoteamount=$object->getSumCreditNotesUsed();
963 //$depositsamount=$object->getSumDepositsUsed();
964 //print "x".$creditnoteamount."-".$depositsamount;exit;
965 $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
966 if (!empty($object->paye)) {
967 $resteapayer = 0;
968 }
969
970 if ($deja_regle > 0) {
971 // Already paid + Deposits
972 $index++;
973
974 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
975 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', false);
976 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
977 $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle), 0, 'R', false);
978
979 $index++;
980 $pdf->SetTextColor(0, 0, 60);
981 $pdf->SetFillColor(224, 224, 224);
982 $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
983 $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', true);
984
985 $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
986 $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer), $useborder, 'R', true);
987
988 $pdf->SetFont('', '', $default_font_size - 1);
989 $pdf->SetTextColor(0, 0, 0);
990 }
991
992 $index++;
993 return ($tab2_top + ($tab2_hl * $index));
994 }
995
996 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1010 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
1011 {
1012 global $conf;
1013
1014 // Force to disable hidetop and hidebottom
1015 $hidebottom = 0;
1016 if ($hidetop) {
1017 $hidetop = -1;
1018 }
1019
1020 $currency = !empty($currency) ? $currency : $conf->currency;
1021 $default_font_size = pdf_getPDFFontSize($outputlangs);
1022
1023 // Amount in (at tab_top - 1)
1024 $pdf->SetTextColor(0, 0, 0);
1025 $pdf->SetFont('', '', $default_font_size - 2);
1026
1027 if (empty($hidetop)) {
1028 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1029 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1030 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1031
1032 //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1033 if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) {
1034 $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')));
1035 }
1036 }
1037
1038 $pdf->SetDrawColor(128, 128, 128);
1039 $pdf->SetFont('', '', $default_font_size - 1);
1040
1041 // Output Rect
1042 $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
1043
1044 if (empty($hidetop)) {
1045 $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
1046
1047 $pdf->SetXY($this->posxdesc - 1, $tab_top + 1);
1048 $pdf->MultiCell(108, 2, $outputlangs->transnoentities("Designation"), '', 'L');
1049 }
1050
1051 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
1052 $pdf->line($this->posxtva, $tab_top, $this->posxtva, $tab_top + $tab_height);
1053 if (empty($hidetop)) {
1054 $pdf->SetXY($this->posxtva - 3, $tab_top + 1);
1055 $pdf->MultiCell($this->posxup - $this->posxtva + 3, 2, $outputlangs->transnoentities("VAT"), '', 'C');
1056 }
1057 }
1058
1059 $pdf->line($this->posxup, $tab_top, $this->posxup, $tab_top + $tab_height);
1060 if (empty($hidetop)) {
1061 $pdf->SetXY($this->posxup - 1, $tab_top + 1);
1062 $pdf->MultiCell($this->posxqty - $this->posxup - 1, 2, $outputlangs->transnoentities("PriceUHT"), '', 'C');
1063 }
1064
1065 $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height);
1066 if (empty($hidetop)) {
1067 $pdf->SetXY($this->posxqty - 1, $tab_top + 1);
1068 $pdf->MultiCell($this->posxunit - $this->posxqty - 1, 2, $outputlangs->transnoentities("Qty"), '', 'C');
1069 }
1070
1071 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1072 $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height);
1073 if (empty($hidetop)) {
1074 $pdf->SetXY($this->posxunit - 1, $tab_top + 1);
1075 $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("Unit"), '', 'C');
1076 }
1077 }
1078
1079 $pdf->line($this->posxdiscount - 1, $tab_top, $this->posxdiscount - 1, $tab_top + $tab_height);
1080 if (empty($hidetop)) {
1081 if ($this->atleastonediscount) {
1082 $pdf->SetXY($this->posxdiscount - 1, $tab_top + 1);
1083 $pdf->MultiCell($this->postotalht - $this->posxdiscount + 1, 2, $outputlangs->transnoentities("ReductionShort"), '', 'C');
1084 }
1085 }
1086
1087 if ($this->atleastonediscount) {
1088 $pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
1089 }
1090 if (empty($hidetop)) {
1091 $pdf->SetXY($this->postotalht - 1, $tab_top + 1);
1092 $pdf->MultiCell(30, 2, $outputlangs->transnoentities("TotalHTShort"), '', 'C');
1093 }
1094 }
1095
1096 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1106 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
1107 {
1108 global $langs, $conf, $mysoc;
1109
1110 $ltrdirection = 'L';
1111 if ($outputlangs->trans("DIRECTION") == 'rtl') {
1112 $ltrdirection = 'R';
1113 }
1114
1115 // Load translation files required by the page
1116 $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "sendings"));
1117
1118 $default_font_size = pdf_getPDFFontSize($outputlangs);
1119
1120 // Do not add the BACKGROUND as this is for suppliers
1121 //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
1122
1123 //Affiche le filigrane brouillon - Print Draft Watermark
1124 /*if($object->statut==0 && getDolGlobalString('COMMANDE_DRAFT_WATERMARK'))
1125 {
1126 pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',getDolGlobalString('COMMANDE_DRAFT_WATERMARK'));
1127 }*/
1128 //Print content
1129
1130 $pdf->SetTextColor(0, 0, 60);
1131 $pdf->SetFont('', 'B', $default_font_size + 3);
1132
1133 $w = 100;
1134
1135 $posx = $this->page_largeur - $this->marge_droite - 100;
1136 $posy = $this->marge_haute;
1137
1138 $pdf->SetXY($this->marge_gauche, $posy);
1139
1140 // Logo
1141 if (!getDolGlobalInt('PDF_DISABLE_MYCOMPANY_LOGO')) {
1142 if ($this->emetteur->logo) {
1143 $logodir = $conf->mycompany->dir_output;
1144 if (!empty($conf->mycompany->multidir_output[$object->entity])) {
1145 $logodir = $conf->mycompany->multidir_output[$object->entity];
1146 }
1147 if (!getDolGlobalInt('MAIN_PDF_USE_LARGE_LOGO')) {
1148 $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1149 } else {
1150 $logo = $logodir.'/logos/'.$this->emetteur->logo;
1151 }
1152 if (is_readable($logo)) {
1153 $height = pdf_getHeightForLogo($logo);
1154 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1155 } else {
1156 $pdf->SetTextColor(200, 0, 0);
1157 $pdf->SetFont('', 'B', $default_font_size - 2);
1158 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1159 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1160 }
1161 } else {
1162 $text = $this->emetteur->name;
1163 $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
1164 }
1165 }
1166
1167 $pdf->SetFont('', 'B', $default_font_size + 3);
1168 $pdf->SetXY($posx, $posy);
1169 $pdf->SetTextColor(0, 0, 60);
1170 $title = $outputlangs->transnoentities("SupplierOrder")." ".$outputlangs->convToOutputCharset($object->ref);
1171 if ($object->status == $object::STATUS_DRAFT) {
1172 $pdf->SetTextColor(128, 0, 0);
1173 $title .= ' - '.$outputlangs->transnoentities("NotValidated");
1174 }
1175 $pdf->MultiCell($w, 3, $title, '', 'R');
1176 $posy += 1;
1177
1178 if ($object->ref_supplier) {
1179 $posy += 4;
1180 $pdf->SetFont('', 'B', $default_font_size);
1181 $pdf->SetXY($posx, $posy);
1182 $pdf->SetTextColor(0, 0, 60);
1183 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefSupplier")." : ".$outputlangs->convToOutputCharset($object->ref_supplier), '', 'R');
1184 $posy += 1;
1185 }
1186
1187 $pdf->SetFont('', '', $default_font_size - 1);
1188
1189 if (getDolGlobalString('PDF_SHOW_PROJECT_TITLE')) {
1190 $object->fetchProject();
1191 if (!empty($object->project->ref)) {
1192 $posy += 3;
1193 $pdf->SetXY($posx, $posy);
1194 $pdf->SetTextColor(0, 0, 60);
1195 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
1196 }
1197 }
1198
1199 if (getDolGlobalString('PDF_SHOW_PROJECT')) {
1200 $object->fetchProject();
1201 if (!empty($object->project->ref)) {
1202 $outputlangs->load("projects");
1203 $posy += 4;
1204 $pdf->SetXY($posx, $posy);
1205 $langs->load("projects");
1206 $pdf->SetTextColor(0, 0, 60);
1207 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
1208 }
1209 }
1210
1211 if (!empty($object->date_commande)) {
1212 $posy += 5;
1213 $pdf->SetXY($posx, $posy);
1214 $pdf->SetTextColor(0, 0, 60);
1215 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("OrderDate")." : ".dol_print_date($object->date_commande, "day", false, $outputlangs, true), '', 'R');
1216 }
1217 // no point in having this here this a document sent to supplier
1218 /*} else {
1219 $posy += 5;
1220 $pdf->SetXY($posx, $posy);
1221 $pdf->SetTextColor(255, 0, 0);
1222 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("OrderToProcess"), '', 'R');
1223 }*/
1224
1225 $pdf->SetTextColor(0, 0, 60);
1226 $usehourmin = 'day';
1227 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
1228 $usehourmin = 'dayhour';
1229 }
1230 if (!empty($object->delivery_date)) {
1231 $posy += 4;
1232 $pdf->SetXY($posx - 90, $posy);
1233 $pdf->MultiCell(190, 3, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->delivery_date, $usehourmin, false, $outputlangs, true), '', 'R');
1234 }
1235
1236 if ($object->thirdparty->code_fournisseur) {
1237 $posy += 4;
1238 $pdf->SetXY($posx, $posy);
1239 $pdf->SetTextColor(0, 0, 60);
1240 $pdf->MultiCell($w, 3, $outputlangs->transnoentities("SupplierCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_fournisseur), '', 'R');
1241 }
1242
1243 // Get contact
1244 if (getDolGlobalString('DOC_SHOW_FIRST_SALES_REP')) {
1245 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1246 if (count($arrayidcontact) > 0) {
1247 $usertmp = new User($this->db);
1248 $usertmp->fetch($arrayidcontact[0]);
1249 $posy += 4;
1250 $pdf->SetXY($posx, $posy);
1251 $pdf->SetTextColor(0, 0, 60);
1252 $pdf->MultiCell($w, 3, $langs->trans("BuyerName")." : ".$usertmp->getFullName($langs), '', 'R');
1253 }
1254 }
1255
1256 $posy += 1;
1257 $pdf->SetTextColor(0, 0, 60);
1258
1259 $top_shift = 0;
1260 // Show list of linked objects
1261 $current_y = $pdf->getY();
1262 $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
1263 if ($current_y < $pdf->getY()) {
1264 $top_shift = $pdf->getY() - $current_y;
1265 }
1266
1267 if ($showaddress) {
1268 // Sender properties
1269 $carac_emetteur = '';
1270 // Add internal contact of object if defined
1271 $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1272 if (count($arrayidcontact) > 0) {
1273 $object->fetch_user($arrayidcontact[0]);
1274 $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
1275 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname.": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs));
1276 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ' (' : '';
1277 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && !empty($object->user->office_phone)) ? $object->user->office_phone : '';
1278 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') && getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ', ' : '';
1279 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT') && !empty($object->user->email)) ? $object->user->email : '';
1280 $carac_emetteur .= (getDolGlobalInt('PDF_SHOW_PHONE_AFTER_USER_CONTACT') || getDolGlobalInt('PDF_SHOW_EMAIL_AFTER_USER_CONTACT')) ? ')' : '';
1281 $carac_emetteur .= "\n";
1282 }
1283
1284 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1285
1286 // Show sender
1287 $posy = 42 + $top_shift;
1288 $posx = $this->marge_gauche;
1289 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1290 $posx = $this->page_largeur - $this->marge_droite - 80;
1291 }
1292 $hautcadre = 40;
1293
1294 // Show sender frame
1295 $pdf->SetTextColor(0, 0, 0);
1296 $pdf->SetFont('', '', $default_font_size - 2);
1297 $pdf->SetXY($posx, $posy - 5);
1298 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
1299 $pdf->SetXY($posx, $posy);
1300 $pdf->SetFillColor(230, 230, 230);
1301 $pdf->RoundedRect($posx, $posy, 82, $hautcadre, $this->corner_radius, '1234', 'F');
1302 $pdf->SetTextColor(0, 0, 60);
1303
1304 // Show sender name
1305 $pdf->SetXY($posx + 2, $posy + 3);
1306 $pdf->SetFont('', 'B', $default_font_size);
1307 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
1308 $posy = $pdf->getY();
1309
1310 // Show sender information
1311 $pdf->SetXY($posx + 2, $posy);
1312 $pdf->SetFont('', '', $default_font_size - 1);
1313 $pdf->MultiCell(80, 4, $carac_emetteur, 0, $ltrdirection);
1314
1315
1316 // 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'
1317 $usecontact = false;
1318 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
1319 if (count($arrayidcontact) > 0) {
1320 $usecontact = true;
1321 $result = $object->fetch_contact($arrayidcontact[0]);
1322 }
1323
1324 // Recipient name
1325 if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || getDolGlobalString('MAIN_USE_COMPANY_NAME_OF_CONTACT')))) {
1326 $thirdparty = $object->contact;
1327 } else {
1328 $thirdparty = $object->thirdparty;
1329 }
1330
1331 $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1332
1333 $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), ($usecontact ? 1 : 0), 'target', $object);
1334
1335 // Show recipient
1336 $widthrecbox = 100;
1337 if ($this->page_largeur < 210) {
1338 $widthrecbox = 84; // To work with US executive format
1339 }
1340 $posy = 42 + $top_shift;
1341 $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1342 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
1343 $posx = $this->marge_gauche;
1344 }
1345
1346 // Show recipient frame
1347 $pdf->SetTextColor(0, 0, 0);
1348 $pdf->SetFont('', '', $default_font_size - 2);
1349 $pdf->SetXY($posx + 2, $posy - 5);
1350 $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
1351 $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D');
1352
1353 // Show recipient name
1354 $pdf->SetXY($posx + 2, $posy + 3);
1355 $pdf->SetFont('', 'B', $default_font_size);
1356 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1357 $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, $ltrdirection);
1358
1359 $posy = $pdf->getY();
1360
1361 // Show recipient information
1362 $pdf->SetFont('', '', $default_font_size - 1);
1363 $pdf->SetXY($posx + 2, $posy);
1364 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1365 $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
1366 }
1367
1368 return $top_shift;
1369 }
1370
1371 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1381 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1382 {
1383 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1384 return pdf_pagefoot($pdf, $outputlangs, 'SUPPLIER_ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1385 }
1386}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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_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...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
pdf_getSizeForImage($realpath)
Return dimensions to use for images onto PDF checking that width and height are not higher than maxim...
Definition pdf.lib.php:2731
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:1463
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2462
pdf_getFormat($outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:87
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:289
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:314
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:1047
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:2080
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:2018
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1425
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:266
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:439
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0)
Return line unit.
Definition pdf.lib.php:2325
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2368
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2165
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:391
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:158
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:161