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