dolibarr  16.0.5
pdf_sponge.modules.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2008 Raphael Bertrand <raphael.bertrand@resultic.fr>
5  * Copyright (C) 2010-2014 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
7  * Copyright (C) 2012 Cédric Salvador <csalvador@gpcsolutions.fr>
8  * Copyright (C) 2012-2014 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
9  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
10  * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
11  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
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 
34 require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
35 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
39 
40 
45 {
49  public $db;
50 
54  public $name;
55 
59  public $description;
60 
64  public $update_main_doc_field;
65 
69  public $type;
70 
75  public $phpmin = array(5, 6);
76 
81  public $version = 'dolibarr';
82 
86  public $page_largeur;
87 
91  public $page_hauteur;
92 
96  public $format;
97 
101  public $marge_gauche;
102 
106  public $marge_droite;
107 
111  public $marge_haute;
112 
116  public $marge_basse;
117 
122  public $emetteur;
123 
127  public $situationinvoice;
128 
129 
133  public $cols;
134 
135 
141  public function __construct($db)
142  {
143  global $conf, $langs, $mysoc;
144 
145  // Translations
146  $langs->loadLangs(array("main", "bills"));
147 
148  $this->db = $db;
149  $this->name = "sponge";
150  $this->description = $langs->trans('PDFSpongeDescription');
151  $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
152 
153  // Dimension page
154  $this->type = 'pdf';
155  $formatarray = pdf_getFormat();
156  $this->page_largeur = $formatarray['width'];
157  $this->page_hauteur = $formatarray['height'];
158  $this->format = array($this->page_largeur, $this->page_hauteur);
159  $this->marge_gauche = isset($conf->global->MAIN_PDF_MARGIN_LEFT) ? $conf->global->MAIN_PDF_MARGIN_LEFT : 10;
160  $this->marge_droite = isset($conf->global->MAIN_PDF_MARGIN_RIGHT) ? $conf->global->MAIN_PDF_MARGIN_RIGHT : 10;
161  $this->marge_haute = isset($conf->global->MAIN_PDF_MARGIN_TOP) ? $conf->global->MAIN_PDF_MARGIN_TOP : 10;
162  $this->marge_basse = isset($conf->global->MAIN_PDF_MARGIN_BOTTOM) ? $conf->global->MAIN_PDF_MARGIN_BOTTOM : 10;
163 
164  $this->option_logo = 1; // Display logo
165  $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
166  $this->option_modereg = 1; // Display payment mode
167  $this->option_condreg = 1; // Display payment terms
168  $this->option_multilang = 1; // Available in several languages
169  $this->option_escompte = 1; // Displays if there has been a discount
170  $this->option_credit_note = 1; // Support credit notes
171  $this->option_freetext = 1; // Support add of a personalised text
172  $this->option_draft_watermark = 1; // Support add of a watermark on drafts
173  $this->watermark = '';
174 
175  // Get source company
176  $this->emetteur = $mysoc;
177  if (empty($this->emetteur->country_code)) {
178  $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
179  }
180 
181  // Define position of columns
182  $this->posxdesc = $this->marge_gauche + 1; // used for notes ans other stuff
183 
184 
185  $this->tabTitleHeight = 5; // default height
186 
187  // Use new system for position of columns, view $this->defineColumnField()
188 
189  $this->tva = array();
190  $this->tva_array = array();
191  $this->localtax1 = array();
192  $this->localtax2 = array();
193  $this->atleastoneratenotnull = 0;
194  $this->atleastonediscount = 0;
195  $this->situationinvoice = false;
196  }
197 
198 
199  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
211  public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
212  {
213  // phpcs:enable
214  global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
215 
216  dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null'));
217 
218  if (!is_object($outputlangs)) {
219  $outputlangs = $langs;
220  }
221  // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
222  if (!empty($conf->global->MAIN_USE_FPDF)) {
223  $outputlangs->charset_output = 'ISO-8859-1';
224  }
225 
226  // Load translation files required by the page
227  $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
228 
229  global $outputlangsbis;
230  $outputlangsbis = null;
231  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
232  $outputlangsbis = new Translate('', $conf);
233  $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
234  $outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies"));
235  }
236 
237  // Show Draft Watermark
238  if ($object->statut == $object::STATUS_DRAFT && (!empty($conf->global->FACTURE_DRAFT_WATERMARK))) {
239  $this->watermark = $conf->global->FACTURE_DRAFT_WATERMARK;
240  }
241 
242  $nblines = count($object->lines);
243 
244  $hidetop = 0;
245  if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) {
246  $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE;
247  }
248 
249  // Loop on each lines to detect if there is at least one image to show
250  $realpatharray = array();
251  $this->atleastonephoto = false;
252  if (!empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE)) {
253  $objphoto = new Product($this->db);
254 
255  for ($i = 0; $i < $nblines; $i++) {
256  if (empty($object->lines[$i]->fk_product)) {
257  continue;
258  }
259 
260  $objphoto->fetch($object->lines[$i]->fk_product);
261  //var_dump($objphoto->ref);exit;
262  if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) {
263  $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
264  $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
265  } else {
266  $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product'); // default
267  $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
268  }
269 
270  $arephoto = false;
271  foreach ($pdir as $midir) {
272  if (!$arephoto) {
273  if ($conf->entity != $objphoto->entity) {
274  $dir = $conf->product->multidir_output[$objphoto->entity].'/'.$midir; //Check repertories of current entities
275  } else {
276  $dir = $conf->product->dir_output.'/'.$midir; //Check repertory of the current product
277  }
278 
279  foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
280  if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
281  if ($obj['photo_vignette']) {
282  $filename = $obj['photo_vignette'];
283  } else {
284  $filename = $obj['photo'];
285  }
286  } else {
287  $filename = $obj['photo'];
288  }
289 
290  $realpath = $dir.$filename;
291  $arephoto = true;
292  $this->atleastonephoto = true;
293  }
294  }
295  }
296 
297  if ($realpath && $arephoto) {
298  $realpatharray[$i] = $realpath;
299  }
300  }
301  }
302 
303  //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
304 
305  if ($conf->facture->multidir_output[$conf->entity]) {
306  $object->fetch_thirdparty();
307 
308  $deja_regle = $object->getSommePaiement((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? 1 : 0);
309  $amount_credit_notes_included = $object->getSumCreditNotesUsed((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? 1 : 0);
310  $amount_deposits_included = $object->getSumDepositsUsed((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? 1 : 0);
311 
312  // Definition of $dir and $file
313  if ($object->specimen) {
314  $dir = $conf->facture->multidir_output[$conf->entity];
315  $file = $dir."/SPECIMEN.pdf";
316  } else {
317  $objectref = dol_sanitizeFileName($object->ref);
318  $dir = $conf->facture->multidir_output[$object->entity]."/".$objectref;
319  $file = $dir."/".$objectref.".pdf";
320  }
321  if (!file_exists($dir)) {
322  if (dol_mkdir($dir) < 0) {
323  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
324  return 0;
325  }
326  }
327 
328  if (file_exists($dir)) {
329  // Add pdfgeneration hook
330  if (!is_object($hookmanager)) {
331  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
332  $hookmanager = new HookManager($this->db);
333  }
334  $hookmanager->initHooks(array('pdfgeneration'));
335  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
336  global $action;
337  $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
338 
339  // Set nblines with the new facture lines content after hook
340  $nblines = count($object->lines);
341  $nbpayments = count($object->getListOfPayments());
342 
343  // Create pdf instance
344  $pdf = pdf_getInstance($this->format);
345  $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
346  $pdf->SetAutoPageBreak(1, 0);
347 
348  $heightforinfotot = 50 + (4 * $nbpayments); // Height reserved to output the info and total part and payment part
349  $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
350  $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin)
351 
352  if (class_exists('TCPDF')) {
353  $pdf->setPrintHeader(false);
354  $pdf->setPrintFooter(false);
355  }
356  $pdf->SetFont(pdf_getPDFFont($outputlangs));
357 
358  // Set path to the background PDF File
359  if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) {
360  $logodir = $conf->mycompany->dir_output;
361  if (!empty($conf->mycompany->multidir_output[$object->entity])) {
362  $logodir = $conf->mycompany->multidir_output[$object->entity];
363  }
364  $pagecount = $pdf->setSourceFile($logodir.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
365  $tplidx = $pdf->importPage(1);
366  }
367 
368  $pdf->Open();
369  $pagenb = 0;
370  $pdf->SetDrawColor(128, 128, 128);
371 
372  $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
373  $pdf->SetSubject($outputlangs->transnoentities("PdfInvoiceTitle"));
374  $pdf->SetCreator("Dolibarr ".DOL_VERSION);
375  $pdf->SetAuthor($mysoc->name.($user->id > 0 ? ' - '.$outputlangs->convToOutputCharset($user->getFullName($outputlangs)) : ''));
376  $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfInvoiceTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
377  if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) {
378  $pdf->SetCompression(false);
379  }
380 
381  // Set certificate
382  $cert = empty($user->conf->CERTIFICATE_CRT) ? '' : $user->conf->CERTIFICATE_CRT;
383  $certprivate = empty($user->conf->CERTIFICATE_CRT_PRIVATE) ? '' : $user->conf->CERTIFICATE_CRT_PRIVATE;
384  // If user has no certificate, we try to take the company one
385  if (!$cert) {
386  $cert = empty($conf->global->CERTIFICATE_CRT) ? '' : $conf->global->CERTIFICATE_CRT;
387  }
388  if (!$certprivate) {
389  $certprivate = empty($conf->global->CERTIFICATE_CRT_PRIVATE) ? '' : $conf->global->CERTIFICATE_CRT_PRIVATE;
390  }
391  // If a certificate is found
392  if ($cert) {
393  $info = array(
394  'Name' => $this->emetteur->name,
395  'Location' => getCountry($this->emetteur->country_code, 0),
396  'Reason' => 'INVOICE',
397  'ContactInfo' => $this->emetteur->email
398  );
399  $pdf->setSignature($cert, $certprivate, $this->emetteur->name, '', 2, $info);
400  }
401 
402  $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
403 
404  // Set $this->atleastonediscount if you have at least one discount
405  for ($i = 0; $i < $nblines; $i++) {
406  if ($object->lines[$i]->remise_percent) {
407  $this->atleastonediscount++;
408  }
409  }
410 
411 
412  // Situation invoice handling
413  if ($object->situation_cycle_ref) {
414  $this->situationinvoice = true;
415  }
416 
417  // New page
418  $pdf->AddPage();
419  if (!empty($tplidx)) {
420  $pdf->useTemplate($tplidx);
421  }
422  $pagenb++;
423 
424  // Output header (logo, ref and address blocks). This is first call for first page.
425  $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis);
426  $pdf->SetFont('', '', $default_font_size - 1);
427  $pdf->MultiCell(0, 3, ''); // Set interline to 3
428  $pdf->SetTextColor(0, 0, 0);
429 
430  // $pdf->GetY() here can't be used. It is bottom of the second addresse box but first one may be higher
431 
432  // $tab_top is y where we must continue content (90 = 42 + 48: 42 is height of logo and ref, 48 is address blocks)
433  $tab_top = 90 + $top_shift; // top_shift is an addition for linked objects or addons (0 in most cases)
434  $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10);
435 
436  // You can add more thing under header here, if you increase $extra_under_address_shift too.
437  $extra_under_address_shift = 0;
438  $qrcodestring = '';
439  if (! empty($conf->global->INVOICE_ADD_ZATCA_QR_CODE)) {
440  $qrcodestring = $object->buildZATCAQRString();
441  } elseif (! empty($conf->global->INVOICE_ADD_SWISS_QR_CODE)) {
442  $qrcodestring = $object->buildSwitzerlandQRString();
443  }
444  if ($qrcodestring) {
445  $qrcodecolor = array('25', '25', '25');
446  // set style for QR-code
447  $styleQr = array(
448  'border' => false,
449  'padding' => 0,
450  'fgcolor' => $qrcodecolor,
451  'bgcolor' => false, //array(255,255,255)
452  'module_width' => 1, // width of a single module in points
453  'module_height' => 1 // height of a single module in points
454  );
455  $pdf->write2DBarcode($qrcodestring, 'QRCODE,M', $this->marge_gauche, $tab_top - 5, 25, 25, $styleQr, 'N');
456  $extra_under_address_shift += 25;
457  }
458 
459  // Call hook printUnderHeaderPDFline
460  $parameters = array(
461  'object' => $object,
462  'i' => $i,
463  'pdf' =>& $pdf,
464  'outputlangs' => $outputlangs,
465  'hidedetails' => $hidedetails
466  );
467  $reshook = $hookmanager->executeHooks('printUnderHeaderPDFline', $parameters, $this); // Note that $object may have been modified by hook
468  if (!empty($hookmanager->resArray['extra_under_address_shift'])) {
469  $extra_under_address_shift += $hookmanager->resArray['extra_under_header_shift'];
470  }
471 
472  $tab_top += $extra_under_address_shift;
473  $tab_top_newpage += 0;
474 
475 
476  // Define heigth of table for lines (for first page)
477  $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
478 
479  $nexY = $tab_top - 1;
480 
481  // Incoterm
482  $height_incoterms = 0;
483  if (!empty($conf->incoterm->enabled)) {
484  $desc_incoterms = $object->getIncotermsForPDF();
485  if ($desc_incoterms) {
486  $tab_top -= 2;
487 
488  $pdf->SetFont('', '', $default_font_size - 1);
489  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
490  $nexY = max($pdf->GetY(), $nexY);
491  $height_incoterms = $nexY - $tab_top;
492 
493  // Rect takes a length in 3rd parameter
494  $pdf->SetDrawColor(192, 192, 192);
495  $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1);
496 
497  $tab_top = $nexY + 6;
498  $height_incoterms += 4;
499  }
500  }
501 
502  // Displays notes. Here we are still on code eecuted only for the first page.
503  $notetoshow = empty($object->note_public) ? '' : $object->note_public;
504  if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) {
505  // Get first sale rep
506  if (is_object($object->thirdparty)) {
507  $salereparray = $object->thirdparty->getSalesRepresentatives($user);
508  $salerepobj = new User($this->db);
509  $salerepobj->fetch($salereparray[0]['id']);
510  if (!empty($salerepobj->signature)) {
511  $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
512  }
513  }
514  }
515 
516  // Extrafields in note
517  $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
518  if (!empty($extranote)) {
519  $notetoshow = dol_concatdesc($notetoshow, $extranote);
520  }
521 
522  $pagenb = $pdf->getPage();
523  if ($notetoshow) {
524  $tab_top -= 2;
525 
526  $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
527  $pageposbeforenote = $pagenb;
528 
529  $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
530  complete_substitutions_array($substitutionarray, $outputlangs, $object);
531  $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
532  $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
533 
534  $pdf->startTransaction();
535 
536  $pdf->SetFont('', '', $default_font_size - 1);
537  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
538  // Description
539  $pageposafternote = $pdf->getPage();
540  $posyafter = $pdf->GetY();
541 
542  if ($pageposafternote > $pageposbeforenote) {
543  $pdf->rollbackTransaction(true);
544 
545  // prepare pages to receive notes
546  while ($pagenb < $pageposafternote) {
547  $pdf->AddPage();
548  $pagenb++;
549  if (!empty($tplidx)) {
550  $pdf->useTemplate($tplidx);
551  }
552  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
553  $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis);
554  }
555  // $this->_pagefoot($pdf,$object,$outputlangs,1);
556  $pdf->setTopMargin($tab_top_newpage);
557  // The only function to edit the bottom margin of current page to set it.
558  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
559  }
560 
561  // back to start
562  $pdf->setPage($pageposbeforenote);
563  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
564  $pdf->SetFont('', '', $default_font_size - 1);
565  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
566  $pageposafternote = $pdf->getPage();
567 
568  $posyafter = $pdf->GetY();
569 
570  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text
571  $pdf->AddPage('', '', true);
572  $pagenb++;
573  $pageposafternote++;
574  $pdf->setPage($pageposafternote);
575  $pdf->setTopMargin($tab_top_newpage);
576  // The only function to edit the bottom margin of current page to set it.
577  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
578  //$posyafter = $tab_top_newpage;
579  }
580 
581 
582  // apply note frame to previous pages
583  $i = $pageposbeforenote;
584  while ($i < $pageposafternote) {
585  $pdf->setPage($i);
586 
587 
588  $pdf->SetDrawColor(128, 128, 128);
589  // Draw note frame
590  if ($i > $pageposbeforenote) {
591  $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
592  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
593  } else {
594  $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
595  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
596  }
597 
598  // Add footer
599  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
600  $this->_pagefoot($pdf, $object, $outputlangs, 1);
601 
602  $i++;
603  }
604 
605  // apply note frame to last page
606  $pdf->setPage($pageposafternote);
607  if (!empty($tplidx)) {
608  $pdf->useTemplate($tplidx);
609  }
610  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
611  $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis);
612  }
613  $height_note = $posyafter - $tab_top_newpage;
614  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
615  } else {
616  // No pagebreak
617  $pdf->commitTransaction();
618  $posyafter = $pdf->GetY();
619  $height_note = $posyafter - $tab_top;
620  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
621 
622 
623  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
624  // not enough space, need to add page
625  $pdf->AddPage('', '', true);
626  $pagenb++;
627  $pageposafternote++;
628  $pdf->setPage($pageposafternote);
629  if (!empty($tplidx)) {
630  $pdf->useTemplate($tplidx);
631  }
632  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
633  $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis);
634  }
635 
636  $posyafter = $tab_top_newpage;
637  }
638  }
639 
640  $tab_height = $tab_height - $height_note;
641  $tab_top = $posyafter + 6;
642  } else {
643  $height_note = 0;
644  }
645 
646  // Use new auto column system
647  $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
648 
649  // Table simulation to know the height of the title line (this set this->tableTitleHeight)
650  $pdf->startTransaction();
651  $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
652  $pdf->rollbackTransaction(true);
653 
654  $nexY = $tab_top + $this->tabTitleHeight;
655 
656  // Loop on each lines
657  $pageposbeforeprintlines = $pdf->getPage();
658  $pagenb = $pageposbeforeprintlines;
659  for ($i = 0; $i < $nblines; $i++) {
660  $curY = $nexY;
661  $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
662  $pdf->SetTextColor(0, 0, 0);
663 
664  // Define size of image if we need it
665  $imglinesize = array();
666  if (!empty($realpatharray[$i])) {
667  $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
668  }
669 
670  $pdf->setTopMargin($tab_top_newpage);
671  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
672  $pageposbefore = $pdf->getPage();
673 
674  $showpricebeforepagebreak = 1;
675  $posYAfterImage = 0;
676  $posYAfterDescription = 0;
677 
678  if ($this->getColumnStatus('photo')) {
679  // We start with Photo of product line
680  if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page
681  $pdf->AddPage('', '', true);
682  if (!empty($tplidx)) {
683  $pdf->useTemplate($tplidx);
684  }
685  $pdf->setPage($pageposbefore + 1);
686 
687  $curY = $tab_top_newpage;
688 
689  // Allows data in the first page if description is long enough to break in multiples pages
690  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
691  $showpricebeforepagebreak = 1;
692  } else {
693  $showpricebeforepagebreak = 0;
694  }
695  }
696 
697  if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) {
698  $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
699  // $pdf->Image does not increase value return by getY, so we save it manually
700  $posYAfterImage = $curY + $imglinesize['height'];
701  }
702  }
703 
704  // Description of product line
705  if ($this->getColumnStatus('desc')) {
706  $pdf->startTransaction();
707 
708  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
709  $pageposafter = $pdf->getPage();
710 
711  if ($pageposafter > $pageposbefore) { // There is a pagebreak
712  $pdf->rollbackTransaction(true);
713  $pageposafter = $pageposbefore;
714  $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
715 
716  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
717 
718  $pageposafter = $pdf->getPage();
719  $posyafter = $pdf->GetY();
720  //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
721  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
722  if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
723  $pdf->AddPage('', '', true);
724  if (!empty($tplidx)) {
725  $pdf->useTemplate($tplidx);
726  }
727  $pdf->setPage($pageposafter + 1);
728  }
729  } else {
730  // We found a page break
731  // Allows data in the first page if description is long enough to break in multiples pages
732  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
733  $showpricebeforepagebreak = 1;
734  } else {
735  $showpricebeforepagebreak = 0;
736  }
737  }
738  } else // No pagebreak
739  {
740  $pdf->commitTransaction();
741  }
742  $posYAfterDescription = $pdf->GetY();
743  }
744 
745  $nexY = max($pdf->GetY(), $posYAfterImage, $posYAfterDescription);
746 
747  $pageposafter = $pdf->getPage();
748  $pdf->setPage($pageposbefore);
749  $pdf->setTopMargin($this->marge_haute);
750  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
751 
752  // We suppose that a too long description or photo were moved completely on next page
753  if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
754  $pdf->setPage($pageposafter);
755  $curY = $tab_top_newpage;
756  }
757 
758  $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font
759 
760  // VAT Rate
761  if ($this->getColumnStatus('vat')) {
762  $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
763  $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
764  $nexY = max($pdf->GetY(), $nexY);
765  }
766 
767  // Unit price before discount
768  if ($this->getColumnStatus('subprice')) {
769  $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
770  $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
771  $nexY = max($pdf->GetY(), $nexY);
772  }
773 
774  // Quantity
775  // Enough for 6 chars
776  if ($this->getColumnStatus('qty')) {
777  $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
778  $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
779  $nexY = max($pdf->GetY(), $nexY);
780  }
781 
782  // Situation progress
783  if ($this->getColumnStatus('progress')) {
784  $progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails);
785  $this->printStdColumnContent($pdf, $curY, 'progress', $progress);
786  $nexY = max($pdf->GetY(), $nexY);
787  }
788 
789  // Unit
790  if ($this->getColumnStatus('unit')) {
791  $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
792  $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
793  $nexY = max($pdf->GetY(), $nexY);
794  }
795 
796  // Discount on line
797  if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) {
798  $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
799  $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
800  $nexY = max($pdf->GetY(), $nexY);
801  }
802 
803  // Total excl tax line (HT)
804  if ($this->getColumnStatus('totalexcltax')) {
805  $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
806  $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
807  $nexY = max($pdf->GetY(), $nexY);
808  }
809 
810  // Total with tax line (TTC)
811  if ($this->getColumnStatus('totalincltax')) {
812  $total_incl_tax = pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails);
813  $this->printStdColumnContent($pdf, $curY, 'totalincltax', $total_incl_tax);
814  $nexY = max($pdf->GetY(), $nexY);
815  }
816 
817  // Extrafields
818  if (!empty($object->lines[$i]->array_options)) {
819  foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
820  if ($this->getColumnStatus($extrafieldColKey)) {
821  $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs);
822  $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
823  $nexY = max($pdf->GetY(), $nexY);
824  }
825  }
826  }
827 
828 
829  $parameters = array(
830  'object' => $object,
831  'i' => $i,
832  'pdf' =>& $pdf,
833  'curY' =>& $curY,
834  'nexY' =>& $nexY,
835  'outputlangs' => $outputlangs,
836  'hidedetails' => $hidedetails
837  );
838  $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook
839 
840 
841  $sign = 1;
842  if (isset($object->type) && $object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) {
843  $sign = -1;
844  }
845  // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
846  $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
847  if ($prev_progress > 0 && !empty($object->lines[$i]->situation_percent)) { // Compute progress from previous situation
848  if (!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) {
849  $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
850  } else {
851  $tvaligne = $sign * $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
852  }
853  } else {
854  if (!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) {
855  $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva;
856  } else {
857  $tvaligne = $sign * $object->lines[$i]->total_tva;
858  }
859  }
860 
861  $localtax1ligne = $object->lines[$i]->total_localtax1;
862  $localtax2ligne = $object->lines[$i]->total_localtax2;
863  $localtax1_rate = $object->lines[$i]->localtax1_tx;
864  $localtax2_rate = $object->lines[$i]->localtax2_tx;
865  $localtax1_type = $object->lines[$i]->localtax1_type;
866  $localtax2_type = $object->lines[$i]->localtax2_type;
867 
868  if ($object->remise_percent) {
869  $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
870  }
871  if ($object->remise_percent) {
872  $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
873  }
874  if ($object->remise_percent) {
875  $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
876  }
877 
878  $vatrate = (string) $object->lines[$i]->tva_tx;
879 
880  // Retrieve type from database for backward compatibility with old records
881  if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
882  && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
883  $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
884  $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
885  $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
886  }
887 
888  // retrieve global local tax
889  if ($localtax1_type && $localtax1ligne != 0) {
890  $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
891  }
892  if ($localtax2_type && $localtax2ligne != 0) {
893  $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
894  }
895 
896  if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
897  $vatrate .= '*';
898  }
899 
900  // Fill $this->tva and $this->tva_array
901  if (!isset($this->tva[$vatrate])) {
902  $this->tva[$vatrate] = 0;
903  }
904  $this->tva[$vatrate] += $tvaligne; // ->tva is abandonned, we use now ->tva_array that is more complete
905  $vatcode = $object->lines[$i]->vat_src_code;
906  if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
907  $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
908  }
909  $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate'=>$vatrate, 'vatcode'=>$vatcode, 'amount'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
910 
911  $nexY = max($nexY, $posYAfterImage);
912 
913  // Add line
914  if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) {
915  $pdf->setPage($pageposafter);
916  $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
917  //$pdf->SetDrawColor(190,190,200);
918  $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
919  $pdf->SetLineStyle(array('dash'=>0));
920  }
921 
922  // Detect if some page were added automatically and output _tableau for past pages
923  while ($pagenb < $pageposafter) {
924  $pdf->setPage($pagenb);
925  if ($pagenb == $pageposbeforeprintlines) {
926  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
927  } else {
928  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
929  }
930  $this->_pagefoot($pdf, $object, $outputlangs, 1);
931  $pagenb++;
932  $pdf->setPage($pagenb);
933  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
934  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
935  $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis);
936  }
937  if (!empty($tplidx)) {
938  $pdf->useTemplate($tplidx);
939  }
940  }
941 
942  if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
943  if ($pagenb == $pageposafter) {
944  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
945  } else {
946  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
947  }
948  $this->_pagefoot($pdf, $object, $outputlangs, 1);
949  // New page
950  $pdf->AddPage();
951  if (!empty($tplidx)) {
952  $pdf->useTemplate($tplidx);
953  }
954  $pagenb++;
955  if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
956  $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis);
957  }
958  }
959  }
960 
961  // Show square
962  if ($pagenb == $pageposbeforeprintlines) {
963  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis);
964  $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
965  } else {
966  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis);
967  $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
968  }
969 
970  // Display infos area
971  $posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs, $outputlangsbis);
972 
973  // Display total zone
974  $posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs, $outputlangsbis);
975 
976  // Display payment area
977  if (($deja_regle || $amount_credit_notes_included || $amount_deposits_included) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS)) {
978  $posy = $this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
979  }
980 
981  // Pagefoot
982  $this->_pagefoot($pdf, $object, $outputlangs);
983  if (method_exists($pdf, 'AliasNbPages')) {
984  $pdf->AliasNbPages();
985  }
986 
987  $pdf->Close();
988 
989  $pdf->Output($file, 'F');
990 
991  // Add pdfgeneration hook
992  $hookmanager->initHooks(array('pdfgeneration'));
993  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
994  global $action;
995  $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
996  if ($reshook < 0) {
997  $this->error = $hookmanager->error;
998  $this->errors = $hookmanager->errors;
999  }
1000 
1001  if (!empty($conf->global->MAIN_UMASK)) {
1002  @chmod($file, octdec($conf->global->MAIN_UMASK));
1003  }
1004 
1005  $this->result = array('fullpath'=>$file);
1006 
1007  return 1; // No error
1008  } else {
1009  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
1010  return 0;
1011  }
1012  } else {
1013  $this->error = $langs->transnoentities("ErrorConstantNotDefined", "FAC_OUTPUTDIR");
1014  return 0;
1015  }
1016  }
1017 
1018 
1028  public function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
1029  {
1030  global $conf;
1031 
1032  $sign = 1;
1033  if ($object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) {
1034  $sign = -1;
1035  }
1036 
1037  $tab3_posx = 120;
1038  $tab3_top = $posy + 8;
1039  $tab3_width = 80;
1040  $tab3_height = 4;
1041  if ($this->page_largeur < 210) { // To work with US executive format
1042  $tab3_posx -= 15;
1043  }
1044 
1045  $default_font_size = pdf_getPDFFontSize($outputlangs);
1046 
1047  $title = $outputlangs->transnoentities("PaymentsAlreadyDone");
1048  if ($object->type == 2) {
1049  $title = $outputlangs->transnoentities("PaymentsBackAlreadyDone");
1050  }
1051 
1052  $pdf->SetFont('', '', $default_font_size - 3);
1053  $pdf->SetXY($tab3_posx, $tab3_top - 4);
1054  $pdf->MultiCell(60, 3, $title, 0, 'L', 0);
1055 
1056  $pdf->line($tab3_posx, $tab3_top, $tab3_posx + $tab3_width, $tab3_top);
1057 
1058  $pdf->SetFont('', '', $default_font_size - 4);
1059  $pdf->SetXY($tab3_posx, $tab3_top);
1060  $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Payment"), 0, 'L', 0);
1061  $pdf->SetXY($tab3_posx + 21, $tab3_top);
1062  $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Amount"), 0, 'L', 0);
1063  $pdf->SetXY($tab3_posx + 40, $tab3_top);
1064  $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Type"), 0, 'L', 0);
1065  $pdf->SetXY($tab3_posx + 58, $tab3_top);
1066  $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Num"), 0, 'L', 0);
1067 
1068  $pdf->line($tab3_posx, $tab3_top - 1 + $tab3_height, $tab3_posx + $tab3_width, $tab3_top - 1 + $tab3_height);
1069 
1070  $y = 0;
1071 
1072  $pdf->SetFont('', '', $default_font_size - 4);
1073 
1074 
1075  // Loop on each discount available (deposits and credit notes and excess of payment included)
1076  $sql = "SELECT re.rowid, re.amount_ht, re.multicurrency_amount_ht, re.amount_tva, re.multicurrency_amount_tva, re.amount_ttc, re.multicurrency_amount_ttc,";
1077  $sql .= " re.description, re.fk_facture_source,";
1078  $sql .= " f.type, f.datef";
1079  $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re, ".MAIN_DB_PREFIX."facture as f";
1080  $sql .= " WHERE re.fk_facture_source = f.rowid AND re.fk_facture = ".((int) $object->id);
1081  $resql = $this->db->query($sql);
1082  if ($resql) {
1083  $num = $this->db->num_rows($resql);
1084  $i = 0;
1085  $invoice = new Facture($this->db);
1086  while ($i < $num) {
1087  $y += 3;
1088  $obj = $this->db->fetch_object($resql);
1089 
1090  if ($obj->type == 2) {
1091  $text = $outputlangs->transnoentities("CreditNote");
1092  } elseif ($obj->type == 3) {
1093  $text = $outputlangs->transnoentities("Deposit");
1094  } elseif ($obj->type == 0) {
1095  $text = $outputlangs->transnoentities("ExcessReceived");
1096  } else {
1097  $text = $outputlangs->transnoentities("UnknownType");
1098  }
1099 
1100  $invoice->fetch($obj->fk_facture_source);
1101 
1102  $pdf->SetXY($tab3_posx, $tab3_top + $y);
1103  $pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($obj->datef), 'day', false, $outputlangs, true), 0, 'L', 0);
1104  $pdf->SetXY($tab3_posx + 21, $tab3_top + $y);
1105  $pdf->MultiCell(20, 3, price((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? $obj->multicurrency_amount_ttc : $obj->amount_ttc, 0, $outputlangs), 0, 'L', 0);
1106  $pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1107  $pdf->MultiCell(20, 3, $text, 0, 'L', 0);
1108  $pdf->SetXY($tab3_posx + 58, $tab3_top + $y);
1109  $pdf->MultiCell(20, 3, $invoice->ref, 0, 'L', 0);
1110 
1111  $pdf->line($tab3_posx, $tab3_top + $y + 3, $tab3_posx + $tab3_width, $tab3_top + $y + 3);
1112 
1113  $i++;
1114  }
1115  } else {
1116  $this->error = $this->db->lasterror();
1117  return -1;
1118  }
1119 
1120  // Loop on each payment
1121  // TODO Call getListOfPaymentsgetListOfPayments instead of hard coded sql
1122  $sql = "SELECT p.datep as date, p.fk_paiement, p.num_paiement as num, pf.amount as amount, pf.multicurrency_amount,";
1123  $sql .= " cp.code";
1124  $sql .= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p";
1125  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id";
1126  $sql .= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = ".((int) $object->id);
1127  //$sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = 1";
1128  $sql .= " ORDER BY p.datep";
1129 
1130  $resql = $this->db->query($sql);
1131  if ($resql) {
1132  $num = $this->db->num_rows($resql);
1133  $i = 0;
1134  while ($i < $num) {
1135  $y += 3;
1136  $row = $this->db->fetch_object($resql);
1137 
1138  $pdf->SetXY($tab3_posx, $tab3_top + $y);
1139  $pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($row->date), 'day', false, $outputlangs, true), 0, 'L', 0);
1140  $pdf->SetXY($tab3_posx + 21, $tab3_top + $y);
1141  $pdf->MultiCell(20, 3, price($sign * ((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? $row->multicurrency_amount : $row->amount), 0, $outputlangs), 0, 'L', 0);
1142  $pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1143  $oper = $outputlangs->transnoentitiesnoconv("PaymentTypeShort".$row->code);
1144 
1145  $pdf->MultiCell(20, 3, $oper, 0, 'L', 0);
1146  $pdf->SetXY($tab3_posx + 58, $tab3_top + $y);
1147  $pdf->MultiCell(30, 3, $row->num, 0, 'L', 0);
1148 
1149  $pdf->line($tab3_posx, $tab3_top + $y + 3, $tab3_posx + $tab3_width, $tab3_top + $y + 3);
1150 
1151  $i++;
1152  }
1153 
1154  return $tab3_top + $y + 3;
1155  } else {
1156  $this->error = $this->db->lasterror();
1157  return -1;
1158  }
1159  }
1160 
1161 
1172  protected function drawInfoTable(&$pdf, $object, $posy, $outputlangs, $outputlangsbis)
1173  {
1174  global $conf, $mysoc;
1175 
1176  $default_font_size = pdf_getPDFFontSize($outputlangs);
1177 
1178  $pdf->SetFont('', '', $default_font_size - 1);
1179 
1180  // If France, show VAT mention if not applicable
1181  if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
1182  $pdf->SetFont('', 'B', $default_font_size - 2);
1183  $pdf->SetXY($this->marge_gauche, $posy);
1184  if ($mysoc->forme_juridique_code == 92) {
1185  $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoiceAsso"), 0, 'L', 0);
1186  } else {
1187  $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
1188  }
1189 
1190  $posy = $pdf->GetY() + 4;
1191  }
1192 
1193  $posxval = 52; // Position of values of properties shown on left side
1194  $posxend = 110; // End of x for text on left side
1195  if ($this->page_largeur < 210) { // To work with US executive format
1196  $posxend -= 10;
1197  }
1198 
1199  // Show payments conditions
1200  if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement)) {
1201  $pdf->SetFont('', 'B', $default_font_size - 2);
1202  $pdf->SetXY($this->marge_gauche, $posy);
1203  $titre = $outputlangs->transnoentities("PaymentConditions").':';
1204  $pdf->MultiCell($posxval - $this->marge_gauche, 4, $titre, 0, 'L');
1205 
1206  $pdf->SetFont('', '', $default_font_size - 2);
1207  $pdf->SetXY($posxval, $posy);
1208  $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);
1209  $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
1210  $pdf->MultiCell($posxend - $posxval, 4, $lib_condition_paiement, 0, 'L');
1211 
1212  $posy = $pdf->GetY() + 3; // We need spaces for 2 lines payment conditions
1213  }
1214 
1215  if ($object->type != 2) {
1216  // Check a payment mode is defined
1217  if (empty($object->mode_reglement_code)
1218  && empty($conf->global->FACTURE_CHQ_NUMBER)
1219  && empty($conf->global->FACTURE_RIB_NUMBER)) {
1220  $this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured");
1221  } elseif (($object->mode_reglement_code == 'CHQ' && empty($conf->global->FACTURE_CHQ_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))
1222  || ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))) {
1223  // Avoid having any valid PDF with setup that is not complete
1224  $outputlangs->load("errors");
1225 
1226  $pdf->SetXY($this->marge_gauche, $posy);
1227  $pdf->SetTextColor(200, 0, 0);
1228  $pdf->SetFont('', 'B', $default_font_size - 2);
1229  $this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup", $object->mode_reglement_code);
1230  $pdf->MultiCell($posxend - $this->marge_gauche, 3, $this->error, 0, 'L', 0);
1231  $pdf->SetTextColor(0, 0, 0);
1232 
1233  $posy = $pdf->GetY() + 1;
1234  }
1235 
1236  // Show payment mode
1237  if (!empty($object->mode_reglement_code)
1238  && $object->mode_reglement_code != 'CHQ'
1239  && $object->mode_reglement_code != 'VIR') {
1240  $pdf->SetFont('', 'B', $default_font_size - 2);
1241  $pdf->SetXY($this->marge_gauche, $posy);
1242  $titre = $outputlangs->transnoentities("PaymentMode").':';
1243  $pdf->MultiCell($posxend - $this->marge_gauche, 5, $titre, 0, 'L');
1244 
1245  $pdf->SetFont('', '', $default_font_size - 2);
1246  $pdf->SetXY($posxval, $posy);
1247  $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);
1248  $pdf->MultiCell($posxend - $posxval, 5, $lib_mode_reg, 0, 'L');
1249 
1250  $posy = $pdf->GetY();
1251  }
1252 
1253  // Show online payment link
1254  if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CB' || $object->mode_reglement_code == 'VAD') {
1255  $useonlinepayment = 0;
1256  if (!empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT)) {
1257  if (!empty($conf->paypal->enabled)) {
1258  $useonlinepayment++;
1259  }
1260  if (!empty($conf->stripe->enabled)) {
1261  $useonlinepayment++;
1262  }
1263  if (!empty($conf->paybox->enabled)) {
1264  $useonlinepayment++;
1265  }
1266  }
1267 
1268  if ($object->statut != Facture::STATUS_DRAFT && $useonlinepayment) {
1269  require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
1270  global $langs;
1271 
1272  $langs->loadLangs(array('payment', 'paybox', 'stripe'));
1273  $servicename = $langs->transnoentities('Online');
1274  $paiement_url = getOnlinePaymentUrl('', 'invoice', $object->ref, '', '', '');
1275  $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' <a href="'.$paiement_url.'">'.$outputlangs->transnoentities("ClickHere").'</a>';
1276 
1277  $pdf->SetXY($this->marge_gauche, $posy);
1278  $pdf->writeHTMLCell($posxend - $this->marge_gauche, 5, '', '', dol_htmlentitiesbr($linktopay), 0, 1);
1279 
1280  $posy = $pdf->GetY() + 1;
1281  }
1282  }
1283 
1284  // Show payment mode CHQ
1285  if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') {
1286  // If payment mode unregulated or payment mode forced to CHQ
1287  if (!empty($conf->global->FACTURE_CHQ_NUMBER)) {
1288  $diffsizetitle = (empty($conf->global->PDF_DIFFSIZE_TITLE) ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
1289 
1290  if ($conf->global->FACTURE_CHQ_NUMBER > 0) {
1291  $account = new Account($this->db);
1292  $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
1293 
1294  $pdf->SetXY($this->marge_gauche, $posy);
1295  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1296  $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0);
1297  $posy = $pdf->GetY() + 1;
1298 
1299  if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) {
1300  $pdf->SetXY($this->marge_gauche, $posy);
1301  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1302  $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
1303  $posy = $pdf->GetY() + 2;
1304  }
1305  }
1306  if ($conf->global->FACTURE_CHQ_NUMBER == -1) {
1307  $pdf->SetXY($this->marge_gauche, $posy);
1308  $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
1309  $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
1310  $posy = $pdf->GetY() + 1;
1311 
1312  if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) {
1313  $pdf->SetXY($this->marge_gauche, $posy);
1314  $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
1315  $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
1316  $posy = $pdf->GetY() + 2;
1317  }
1318  }
1319  }
1320  }
1321 
1322  // If payment mode not forced or forced to VIR, show payment with BAN
1323  if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') {
1324  if ($object->fk_account > 0 || $object->fk_bank > 0 || !empty($conf->global->FACTURE_RIB_NUMBER)) {
1325  $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
1326  if ($object->fk_bank > 0) {
1327  $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
1328  }
1329  $account = new Account($this->db);
1330  $account->fetch($bankid);
1331 
1332  $curx = $this->marge_gauche;
1333  $cury = $posy;
1334 
1335  $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
1336 
1337  $posy += 2;
1338  }
1339  }
1340  }
1341 
1342  return $posy;
1343  }
1344 
1345 
1357  protected function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis)
1358  {
1359  global $conf, $mysoc, $hookmanager;
1360 
1361  $sign = 1;
1362  if ($object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) {
1363  $sign = -1;
1364  }
1365 
1366  $default_font_size = pdf_getPDFFontSize($outputlangs);
1367 
1368  $tab2_top = $posy;
1369  $tab2_hl = 4;
1370  if (is_object($outputlangsbis)) { // When we show 2 languages we need more room for text, so we use a smaller font.
1371  $pdf->SetFont('', '', $default_font_size - 2);
1372  } else {
1373  $pdf->SetFont('', '', $default_font_size - 1);
1374  }
1375 
1376  // Total table
1377  $col1x = 120;
1378  $col2x = 170;
1379  if ($this->page_largeur < 210) { // To work with US executive format
1380  $col1x -= 15;
1381  $col2x -= 10;
1382  }
1383  $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
1384 
1385  $useborder = 0;
1386  $index = 0;
1387 
1388  // Add trigger to allow to edit $object
1389  $parameters = array(
1390  'object' => &$object,
1391  'outputlangs' => $outputlangs,
1392  );
1393  $hookmanager->executeHooks('beforePercentCalculation', $parameters, $this); // Note that $object may have been modified by hook
1394 
1395  // overall percentage of advancement
1396  $percent = 0;
1397  $i = 0;
1398  foreach ($object->lines as $line) {
1399  $percent += $line->situation_percent;
1400  $i++;
1401  }
1402 
1403  if (!empty($i)) {
1404  $avancementGlobal = $percent / $i;
1405  } else {
1406  $avancementGlobal = 0;
1407  }
1408 
1409  $object->fetchPreviousNextSituationInvoice();
1410  $TPreviousIncoice = $object->tab_previous_situation_invoice;
1411 
1412  $total_a_payer = 0;
1413  $total_a_payer_ttc = 0;
1414  foreach ($TPreviousIncoice as &$fac) {
1415  $total_a_payer += $fac->total_ht;
1416  $total_a_payer_ttc += $fac->total_ttc;
1417  }
1418  $total_a_payer += $object->total_ht;
1419  $total_a_payer_ttc += $object->total_ttc;
1420 
1421  if (!empty($avancementGlobal)) {
1422  $total_a_payer = $total_a_payer * 100 / $avancementGlobal;
1423  $total_a_payer_ttc = $total_a_payer_ttc * 100 / $avancementGlobal;
1424  } else {
1425  $total_a_payer = 0;
1426  $total_a_payer_ttc = 0;
1427  }
1428 
1429  $i = 1;
1430  if (!empty($TPreviousIncoice)) {
1431  $pdf->setY($tab2_top);
1432  $posy = $pdf->GetY();
1433 
1434  foreach ($TPreviousIncoice as &$fac) {
1435  if ($posy > $this->page_hauteur - 4) {
1436  $this->_pagefoot($pdf, $object, $outputlangs, 1);
1437  $pdf->addPage();
1438  $pdf->setY($this->marge_haute);
1439  $posy = $pdf->GetY();
1440  }
1441 
1442  // Cumulate preceding VAT
1443  $index++;
1444  $pdf->SetFillColor(255, 255, 255);
1445  $pdf->SetXY($col1x, $posy);
1446  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("PDFSituationTitle", $fac->situation_counter).' '.$outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
1447 
1448  $pdf->SetXY($col2x, $posy);
1449 
1450  $facSign = '';
1451  if ($i > 1) {
1452  $facSign = $fac->total_ht >= 0 ? '+' : '';
1453  }
1454 
1455  $displayAmount = ' '.$facSign.' '.price($fac->total_ht, 0, $outputlangs);
1456 
1457  $pdf->MultiCell($largcol2, $tab2_hl, $displayAmount, 0, 'R', 1);
1458 
1459  $i++;
1460  $posy += $tab2_hl;
1461 
1462  $pdf->setY($posy);
1463  }
1464 
1465  // Display current total
1466  $pdf->SetFillColor(255, 255, 255);
1467  $pdf->SetXY($col1x, $posy);
1468  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("PDFSituationTitle", $object->situation_counter).' '.$outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
1469 
1470  $pdf->SetXY($col2x, $posy);
1471  $facSign = '';
1472  if ($i > 1) {
1473  $facSign = $object->total_ht >= 0 ? '+' : ''; // management of a particular customer case
1474  }
1475 
1476  if ($fac->type === facture::TYPE_CREDIT_NOTE) {
1477  $facSign = '-'; // les avoirs
1478  }
1479 
1480 
1481  $displayAmount = ' '.$facSign.' '.price($object->total_ht, 0, $outputlangs);
1482  $pdf->MultiCell($largcol2, $tab2_hl, $displayAmount, 0, 'R', 1);
1483 
1484  $posy += $tab2_hl;
1485 
1486  // Display all total
1487  $pdf->SetFont('', '', $default_font_size - 1);
1488  $pdf->SetFillColor(255, 255, 255);
1489  $pdf->SetXY($col1x, $posy);
1490  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("SituationTotalProgress", $avancementGlobal), 0, 'L', 1);
1491 
1492  $pdf->SetXY($col2x, $posy);
1493  $pdf->MultiCell($largcol2, $tab2_hl, price($total_a_payer * $avancementGlobal / 100, 0, $outputlangs), 0, 'R', 1);
1494  $pdf->SetFont('', '', $default_font_size - 2);
1495 
1496  $posy += $tab2_hl;
1497 
1498  if ($posy > $this->page_hauteur - 4) {
1499  $pdf->addPage();
1500  $pdf->setY($this->marge_haute);
1501  $posy = $pdf->GetY();
1502  }
1503 
1504  $tab2_top = $posy;
1505  $index = 0;
1506 
1507  $tab2_top += 3;
1508  }
1509 
1510 
1511  // Get Total HT
1512  $total_ht = (!empty($conf->multicurrency->enabled) && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
1513 
1514  // Total remise
1515  $total_line_remise = 0;
1516  foreach ($object->lines as $i => $line) {
1517  $total_line_remise += (float) pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, 2); // TODO: add this method to core/lib/pdf.lib
1518  // Gestion remise sous forme de ligne négative
1519  if ($line->total_ht < 0) {
1520  $total_line_remise += -$line->total_ht;
1521  }
1522  }
1523  if ($total_line_remise > 0) {
1524  if (!empty($conf->global->MAIN_SHOW_AMOUNT_DISCOUNT)) {
1525  $pdf->SetFillColor(255, 255, 255);
1526  $pdf->SetXY($col1x, $tab2_top + $tab2_hl);
1527  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalDiscount").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalDiscount") : ''), 0, 'L', 1);
1528  $pdf->SetXY($col2x, $tab2_top + $tab2_hl);
1529  $pdf->MultiCell($largcol2, $tab2_hl, price($total_line_remise, 0, $outputlangs), 0, 'R', 1);
1530 
1531  $index++;
1532  }
1533  // Show total NET before discount
1534  if (!empty($conf->global->MAIN_SHOW_AMOUNT_BEFORE_DISCOUNT)) {
1535  $pdf->SetFillColor(255, 255, 255);
1536  $pdf->SetXY($col1x, $tab2_top + 0);
1537  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHTBeforeDiscount").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHTBeforeDiscount") : ''), 0, 'L', 1);
1538  $pdf->SetXY($col2x, $tab2_top + 0);
1539  $pdf->MultiCell($largcol2, $tab2_hl, price($total_line_remise + $total_ht, 0, $outputlangs), 0, 'R', 1);
1540 
1541  $index++;
1542  }
1543  }
1544 
1545  // Total HT
1546  $pdf->SetFillColor(255, 255, 255);
1547  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1548  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities(empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) ? "TotalHT" : "Total").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities(empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) ? "TotalHT" : "Total") : ''), 0, 'L', 1);
1549 
1550  $total_ht = ((!empty($conf->multicurrency->enabled) && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
1551  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1552  $pdf->MultiCell($largcol2, $tab2_hl, price($sign * ($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, $outputlangs), 0, 'R', 1);
1553 
1554  // Show VAT by rates and total
1555  $pdf->SetFillColor(248, 248, 248);
1556 
1557  $total_ttc = (!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
1558 
1559  $this->atleastoneratenotnull = 0;
1560  if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) {
1561  $tvaisnull = ((!empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
1562  if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull) {
1563  // Nothing to do
1564  } else {
1565  // FIXME amount of vat not supported with multicurrency
1566 
1567  //Local tax 1 before VAT
1568  //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1569  //{
1570  foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1571  if (in_array((string) $localtax_type, array('1', '3', '5'))) {
1572  continue;
1573  }
1574 
1575  foreach ($localtax_rate as $tvakey => $tvaval) {
1576  if ($tvakey != 0) { // On affiche pas taux 0
1577  //$this->atleastoneratenotnull++;
1578 
1579  $index++;
1580  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1581 
1582  $tvacompl = '';
1583  if (preg_match('/\*/', $tvakey)) {
1584  $tvakey = str_replace('*', '', $tvakey);
1585  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1586  }
1587 
1588  $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1589  $totalvat .= ' ';
1590  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1591  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1592 
1593  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1594  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1595  }
1596  }
1597  }
1598  //}
1599  //Local tax 2 before VAT
1600  //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1601  //{
1602  foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1603  if (in_array((string) $localtax_type, array('1', '3', '5'))) {
1604  continue;
1605  }
1606 
1607  foreach ($localtax_rate as $tvakey => $tvaval) {
1608  if ($tvakey != 0) { // On affiche pas taux 0
1609  //$this->atleastoneratenotnull++;
1610 
1611  $index++;
1612  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1613 
1614  $tvacompl = '';
1615  if (preg_match('/\*/', $tvakey)) {
1616  $tvakey = str_replace('*', '', $tvakey);
1617  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1618  }
1619  $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1620  $totalvat .= ' ';
1621  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1622  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1623 
1624  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1625  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1626  }
1627  }
1628  }
1629  //}
1630 
1631  // Situations totals migth be wrong on huge amounts with old mode 1
1632  if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1 && $object->situation_cycle_ref && $object->situation_counter > 1) {
1633  $sum_pdf_tva = 0;
1634  foreach ($this->tva as $tvakey => $tvaval) {
1635  $sum_pdf_tva += $tvaval; // sum VAT amounts to compare to object
1636  }
1637 
1638  if ($sum_pdf_tva != $object->total_tva) { // apply coef to recover the VAT object amount (the good one)
1639  if (!empty($sum_pdf_tva)) {
1640  $coef_fix_tva = $object->total_tva / $sum_pdf_tva;
1641  } else {
1642  $coef_fix_tva = 1;
1643  }
1644 
1645 
1646  foreach ($this->tva as $tvakey => $tvaval) {
1647  $this->tva[$tvakey] = $tvaval * $coef_fix_tva;
1648  }
1649  foreach ($this->tva_array as $tvakey => $tvaval) {
1650  $this->tva_array[$tvakey]['amount'] = $tvaval['amount'] * $coef_fix_tva;
1651  }
1652  }
1653  }
1654 
1655  // VAT
1656  foreach ($this->tva_array as $tvakey => $tvaval) {
1657  if ($tvakey != 0) { // On affiche pas taux 0
1658  $this->atleastoneratenotnull++;
1659 
1660  $index++;
1661  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1662 
1663  $tvacompl = '';
1664  if (preg_match('/\*/', $tvakey)) {
1665  $tvakey = str_replace('*', '', $tvakey);
1666  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1667  }
1668  $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
1669  $totalvat .= ' ';
1670  if (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'rateonly') {
1671  $totalvat .= vatrate($tvaval['vatrate'], 1).$tvacompl;
1672  } elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'codeonly') {
1673  $totalvat .= ($tvaval['vatcode'] ? $tvaval['vatcode'] : vatrate($tvaval['vatrate'], 1)).$tvacompl;
1674  } else {
1675  $totalvat .= vatrate($tvaval['vatrate'], 1).($tvaval['vatcode'] ? ' ('.$tvaval['vatcode'].')' : '').$tvacompl;
1676  }
1677  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1678 
1679  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1680  $pdf->MultiCell($largcol2, $tab2_hl, price(price2num($tvaval['amount'], 'MT'), 0, $outputlangs), 0, 'R', 1);
1681  }
1682  }
1683 
1684  //Local tax 1 after VAT
1685  //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
1686  //{
1687  foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
1688  if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1689  continue;
1690  }
1691 
1692  foreach ($localtax_rate as $tvakey => $tvaval) {
1693  if ($tvakey != 0) { // On affiche pas taux 0
1694  //$this->atleastoneratenotnull++;
1695 
1696  $index++;
1697  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1698 
1699  $tvacompl = '';
1700  if (preg_match('/\*/', $tvakey)) {
1701  $tvakey = str_replace('*', '', $tvakey);
1702  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1703  }
1704  $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
1705  $totalvat .= ' ';
1706  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1707 
1708  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1709  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1710  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1711  }
1712  }
1713  }
1714  //}
1715  //Local tax 2 after VAT
1716  //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
1717  //{
1718  foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
1719  if (in_array((string) $localtax_type, array('2', '4', '6'))) {
1720  continue;
1721  }
1722 
1723  foreach ($localtax_rate as $tvakey => $tvaval) {
1724  // retrieve global local tax
1725  if ($tvakey != 0) { // On affiche pas taux 0
1726  //$this->atleastoneratenotnull++;
1727 
1728  $index++;
1729  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1730 
1731  $tvacompl = '';
1732  if (preg_match('/\*/', $tvakey)) {
1733  $tvakey = str_replace('*', '', $tvakey);
1734  $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
1735  }
1736  $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
1737  $totalvat .= ' ';
1738 
1739  $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
1740  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
1741 
1742  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1743  $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
1744  }
1745  }
1746  }
1747 
1748 
1749  // Revenue stamp
1750  if (price2num($object->revenuestamp) != 0) {
1751  $index++;
1752  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1753  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RevenueStamp").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RevenueStamp", $mysoc->country_code) : ''), $useborder, 'L', 1);
1754 
1755  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1756  $pdf->MultiCell($largcol2, $tab2_hl, price($sign * $object->revenuestamp), $useborder, 'R', 1);
1757  }
1758 
1759  // Total TTC
1760  $index++;
1761  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1762  $pdf->SetTextColor(0, 0, 60);
1763  $pdf->SetFillColor(224, 224, 224);
1764  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalTTC") : ''), $useborder, 'L', 1);
1765 
1766  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1767  $pdf->MultiCell($largcol2, $tab2_hl, price($sign * $total_ttc, 0, $outputlangs), $useborder, 'R', 1);
1768 
1769 
1770  // Retained warranty
1771  if ($object->displayRetainedWarranty()) {
1772  $pdf->SetTextColor(40, 40, 40);
1773  $pdf->SetFillColor(255, 255, 255);
1774 
1775  $retainedWarranty = $object->getRetainedWarrantyAmount();
1776  $billedWithRetainedWarranty = $object->total_ttc - $retainedWarranty;
1777 
1778  // Billed - retained warranty
1779  $index++;
1780  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1781  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("ToPayOn", dol_print_date($object->date_lim_reglement, 'day')), $useborder, 'L', 1);
1782 
1783  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1784  $pdf->MultiCell($largcol2, $tab2_hl, price($billedWithRetainedWarranty), $useborder, 'R', 1);
1785 
1786  // retained warranty
1787  $index++;
1788  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1789 
1790  $retainedWarrantyToPayOn = $outputlangs->transnoentities("RetainedWarranty").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RetainedWarranty") : '').' ('.$object->retained_warranty.'%)';
1791  $retainedWarrantyToPayOn .= !empty($object->retained_warranty_date_limit) ? ' '.$outputlangs->transnoentities("toPayOn", dol_print_date($object->retained_warranty_date_limit, 'day')) : '';
1792 
1793  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $retainedWarrantyToPayOn, $useborder, 'L', 1);
1794  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1795  $pdf->MultiCell($largcol2, $tab2_hl, price($retainedWarranty), $useborder, 'R', 1);
1796  }
1797  }
1798  }
1799 
1800  $pdf->SetTextColor(0, 0, 0);
1801 
1802  $creditnoteamount = $object->getSumCreditNotesUsed((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? 1 : 0); // Warning, this also include excess received
1803  $depositsamount = $object->getSumDepositsUsed((!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) ? 1 : 0);
1804 
1805  $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
1806  if (!empty($object->paye)) {
1807  $resteapayer = 0;
1808  }
1809 
1810  if (($deja_regle > 0 || $creditnoteamount > 0 || $depositsamount > 0) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS)) {
1811  // Already paid + Deposits
1812  $index++;
1813  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1814  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Paid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("Paid") : ''), 0, 'L', 0);
1815  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1816  $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle + $depositsamount, 0, $outputlangs), 0, 'R', 0);
1817 
1818  // Credit note
1819  if ($creditnoteamount) {
1820  $labeltouse = ($outputlangs->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangs->transnoentities("CreditNotesOrExcessReceived") : $outputlangs->transnoentities("CreditNotes");
1821  $labeltouse .= (is_object($outputlangsbis) ? (' / '.($outputlangsbis->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangsbis->transnoentities("CreditNotesOrExcessReceived") : $outputlangsbis->transnoentities("CreditNotes")) : '');
1822  $index++;
1823  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1824  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $labeltouse, 0, 'L', 0);
1825  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1826  $pdf->MultiCell($largcol2, $tab2_hl, price($creditnoteamount, 0, $outputlangs), 0, 'R', 0);
1827  }
1828 
1829  /*
1830  if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT)
1831  {
1832  $index++;
1833  $pdf->SetFillColor(255, 255, 255);
1834 
1835  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1836  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("EscompteOfferedShort") : ''), $useborder, 'L', 1);
1837  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1838  $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1);
1839 
1840  $resteapayer = 0;
1841  }
1842  */
1843 
1844  $index++;
1845  $pdf->SetTextColor(0, 0, 60);
1846  $pdf->SetFillColor(224, 224, 224);
1847  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1848  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RemainderToPay") : ''), $useborder, 'L', 1);
1849  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1850  $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
1851 
1852  $pdf->SetFont('', '', $default_font_size - 1);
1853  $pdf->SetTextColor(0, 0, 0);
1854  }
1855 
1856  $index++;
1857  return ($tab2_top + ($tab2_hl * $index));
1858  }
1859 
1860  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1868  public static function liste_modeles($db, $maxfilenamelength = 0)
1869  {
1870  // phpcs:enable
1871  return parent::liste_modeles($db, $maxfilenamelength); // TODO: Change the autogenerated stub
1872  }
1873 
1874  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1889  protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
1890  {
1891  global $conf;
1892 
1893  // Force to disable hidetop and hidebottom
1894  $hidebottom = 0;
1895  if ($hidetop) {
1896  $hidetop = -1;
1897  }
1898 
1899  $currency = !empty($currency) ? $currency : $conf->currency;
1900  $default_font_size = pdf_getPDFFontSize($outputlangs);
1901 
1902  // Amount in (at tab_top - 1)
1903  $pdf->SetTextColor(0, 0, 0);
1904  $pdf->SetFont('', '', $default_font_size - 2);
1905 
1906  if (empty($hidetop)) {
1907  $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1908  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
1909  $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency));
1910  }
1911 
1912  $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1913  $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1914 
1915  //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1916  if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) {
1917  $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, 'F', null, explode(',', $conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
1918  }
1919  }
1920 
1921  $pdf->SetDrawColor(128, 128, 128);
1922  $pdf->SetFont('', '', $default_font_size - 1);
1923 
1924  // Output Rect
1925  $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
1926 
1927 
1928  $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
1929 
1930  if (empty($hidetop)) {
1931  $pdf->line($this->marge_gauche, $tab_top + $this->tabTitleHeight, $this->page_largeur - $this->marge_droite, $tab_top + $this->tabTitleHeight); // line takes a position y in 2nd parameter and 4th parameter
1932  }
1933  }
1934 
1935  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1946  protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null)
1947  {
1948  global $conf, $langs;
1949 
1950  $ltrdirection = 'L';
1951  if ($outputlangs->trans("DIRECTION") == 'rtl') $ltrdirection = 'R';
1952 
1953  // Load traductions files required by page
1954  $outputlangs->loadLangs(array("main", "bills", "propal", "companies"));
1955 
1956  $default_font_size = pdf_getPDFFontSize($outputlangs);
1957 
1958  pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
1959 
1960  $pdf->SetTextColor(0, 0, 60);
1961  $pdf->SetFont('', 'B', $default_font_size + 3);
1962 
1963  $w = 110;
1964 
1965  $posy = $this->marge_haute;
1966  $posx = $this->page_largeur - $this->marge_droite - $w;
1967 
1968  $pdf->SetXY($this->marge_gauche, $posy);
1969 
1970  // Logo
1971  if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) {
1972  if ($this->emetteur->logo) {
1973  $logodir = $conf->mycompany->dir_output;
1974  if (!empty($conf->mycompany->multidir_output[$object->entity])) {
1975  $logodir = $conf->mycompany->multidir_output[$object->entity];
1976  }
1977  if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) {
1978  $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1979  } else {
1980  $logo = $logodir.'/logos/'.$this->emetteur->logo;
1981  }
1982  if (is_readable($logo)) {
1983  $height = pdf_getHeightForLogo($logo);
1984  $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1985  } else {
1986  $pdf->SetTextColor(200, 0, 0);
1987  $pdf->SetFont('', 'B', $default_font_size - 2);
1988  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1989  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1990  }
1991  } else {
1992  $text = $this->emetteur->name;
1993  $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
1994  }
1995  }
1996 
1997  $pdf->SetFont('', 'B', $default_font_size + 3);
1998  $pdf->SetXY($posx, $posy);
1999  $pdf->SetTextColor(0, 0, 60);
2000  $title = $outputlangs->transnoentities("PdfInvoiceTitle");
2001  if ($object->type == 1) {
2002  $title = $outputlangs->transnoentities("InvoiceReplacement");
2003  }
2004  if ($object->type == 2) {
2005  $title = $outputlangs->transnoentities("InvoiceAvoir");
2006  }
2007  if ($object->type == 3) {
2008  $title = $outputlangs->transnoentities("InvoiceDeposit");
2009  }
2010  if ($object->type == 4) {
2011  $title = $outputlangs->transnoentities("InvoiceProForma");
2012  }
2013  if ($this->situationinvoice) {
2014  $title = $outputlangs->transnoentities("PDFInvoiceSituation");
2015  }
2016  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
2017  $title .= ' - ';
2018  if ($object->type == 0) {
2019  if ($this->situationinvoice) {
2020  $title .= $outputlangsbis->transnoentities("PDFInvoiceSituation");
2021  }
2022  $title .= $outputlangsbis->transnoentities("PdfInvoiceTitle");
2023  } elseif ($object->type == 1) {
2024  $title .= $outputlangsbis->transnoentities("InvoiceReplacement");
2025  } elseif ($object->type == 2) {
2026  $title .= $outputlangsbis->transnoentities("InvoiceAvoir");
2027  } elseif ($object->type == 3) {
2028  $title .= $outputlangsbis->transnoentities("InvoiceDeposit");
2029  } elseif ($object->type == 4) {
2030  $title .= $outputlangsbis->transnoentities("InvoiceProForma");
2031  }
2032  }
2033  $title .= ' '.$outputlangs->convToOutputCharset($object->ref);
2034  if ($object->statut == $object::STATUS_DRAFT) {
2035  $pdf->SetTextColor(128, 0, 0);
2036  $title .= ' - '.$outputlangs->transnoentities("NotValidated");
2037  }
2038 
2039  $pdf->MultiCell($w, 3, $title, '', 'R');
2040 
2041  $pdf->SetFont('', 'B', $default_font_size);
2042 
2043  /*
2044  $posy += 5;
2045  $pdf->SetXY($posx, $posy);
2046  $pdf->SetTextColor(0, 0, 60);
2047  $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref);
2048  if ($object->statut == $object::STATUS_DRAFT) {
2049  $pdf->SetTextColor(128, 0, 0);
2050  $textref .= ' - '.$outputlangs->transnoentities("NotValidated");
2051  }
2052  $pdf->MultiCell($w, 4, $textref, '', 'R');*/
2053 
2054  $posy += 3;
2055  $pdf->SetFont('', '', $default_font_size - 2);
2056 
2057  if ($object->ref_client) {
2058  $posy += 4;
2059  $pdf->SetXY($posx, $posy);
2060  $pdf->SetTextColor(0, 0, 60);
2061  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".dol_trunc($outputlangs->convToOutputCharset($object->ref_client), 65), '', 'R');
2062  }
2063 
2064  if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) {
2065  $object->fetch_projet();
2066  if (!empty($object->project->ref)) {
2067  $posy += 3;
2068  $pdf->SetXY($posx, $posy);
2069  $pdf->SetTextColor(0, 0, 60);
2070  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
2071  }
2072  }
2073 
2074  if (!empty($conf->global->PDF_SHOW_PROJECT)) {
2075  $object->fetch_projet();
2076  if (!empty($object->project->ref)) {
2077  $outputlangs->load("projects");
2078  $posy += 3;
2079  $pdf->SetXY($posx, $posy);
2080  $pdf->SetTextColor(0, 0, 60);
2081  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
2082  }
2083  }
2084 
2085  $objectidnext = $object->getIdReplacingInvoice('validated');
2086  if ($object->type == 0 && $objectidnext) {
2087  $objectreplacing = new Facture($this->db);
2088  $objectreplacing->fetch($objectidnext);
2089 
2090  $posy += 3;
2091  $pdf->SetXY($posx, $posy);
2092  $pdf->SetTextColor(0, 0, 60);
2093  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementByInvoice").' : '.$outputlangs->convToOutputCharset($objectreplacing->ref), '', 'R');
2094  }
2095  if ($object->type == 1) {
2096  $objectreplaced = new Facture($this->db);
2097  $objectreplaced->fetch($object->fk_facture_source);
2098 
2099  $posy += 4;
2100  $pdf->SetXY($posx, $posy);
2101  $pdf->SetTextColor(0, 0, 60);
2102  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
2103  }
2104  if ($object->type == 2 && !empty($object->fk_facture_source)) {
2105  $objectreplaced = new Facture($this->db);
2106  $objectreplaced->fetch($object->fk_facture_source);
2107 
2108  $posy += 3;
2109  $pdf->SetXY($posx, $posy);
2110  $pdf->SetTextColor(0, 0, 60);
2111  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CorrectionInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
2112  }
2113 
2114  $posy += 4;
2115  $pdf->SetXY($posx, $posy);
2116  $pdf->SetTextColor(0, 0, 60);
2117 
2118  $title = $outputlangs->transnoentities("DateInvoice");
2119  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
2120  $title .= ' - '.$outputlangsbis->transnoentities("DateInvoice");
2121  }
2122  $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date, "day", false, $outputlangs, true), '', 'R');
2123 
2124  if (!empty($conf->global->INVOICE_POINTOFTAX_DATE)) {
2125  $posy += 4;
2126  $pdf->SetXY($posx, $posy);
2127  $pdf->SetTextColor(0, 0, 60);
2128  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DatePointOfTax")." : ".dol_print_date($object->date_pointoftax, "day", false, $outputlangs), '', 'R');
2129  }
2130 
2131  if ($object->type != 2) {
2132  $posy += 3;
2133  $pdf->SetXY($posx, $posy);
2134  $pdf->SetTextColor(0, 0, 60);
2135  $title = $outputlangs->transnoentities("DateDue");
2136  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
2137  $title .= ' - '.$outputlangsbis->transnoentities("DateDue");
2138  }
2139  $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date_lim_reglement, "day", false, $outputlangs, true), '', 'R');
2140  }
2141 
2142  if (empty($conf->global->MAIN_PDF_HIDE_CUSTOMER_CODE) && $object->thirdparty->code_client) {
2143  $posy += 3;
2144  $pdf->SetXY($posx, $posy);
2145  $pdf->SetTextColor(0, 0, 60);
2146  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
2147  }
2148 
2149  // Get contact
2150  if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) {
2151  $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
2152  if (count($arrayidcontact) > 0) {
2153  $usertmp = new User($this->db);
2154  $usertmp->fetch($arrayidcontact[0]);
2155  $posy += 4;
2156  $pdf->SetXY($posx, $posy);
2157  $pdf->SetTextColor(0, 0, 60);
2158  $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
2159  }
2160  }
2161 
2162  $posy += 1;
2163 
2164  $top_shift = 0;
2165  // Show list of linked objects
2166  $current_y = $pdf->getY();
2167  $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
2168  if ($current_y < $pdf->getY()) {
2169  $top_shift = $pdf->getY() - $current_y;
2170  }
2171 
2172  if ($showaddress) {
2173  // Sender properties
2174  $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
2175 
2176  // Show sender
2177  $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
2178  $posy += $top_shift;
2179  $posx = $this->marge_gauche;
2180  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
2181  $posx = $this->page_largeur - $this->marge_droite - 80;
2182  }
2183 
2184  $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
2185  $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
2186 
2187 
2188  // Show sender frame
2189  if (empty($conf->global->MAIN_PDF_NO_SENDER_FRAME)) {
2190  $pdf->SetTextColor(0, 0, 0);
2191  $pdf->SetFont('', '', $default_font_size - 2);
2192  $pdf->SetXY($posx, $posy - 5);
2193  $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
2194  $pdf->SetXY($posx, $posy);
2195  $pdf->SetFillColor(230, 230, 230);
2196  $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
2197  $pdf->SetTextColor(0, 0, 60);
2198  }
2199 
2200  // Show sender name
2201  if (empty($conf->global->MAIN_PDF_HIDE_SENDER_NAME)) {
2202  $pdf->SetXY($posx + 2, $posy + 3);
2203  $pdf->SetFont('', 'B', $default_font_size);
2204  $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
2205  $posy = $pdf->getY();
2206  }
2207 
2208  // Show sender information
2209  $pdf->SetXY($posx + 2, $posy);
2210  $pdf->SetFont('', '', $default_font_size - 1);
2211  $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, $ltrdirection);
2212 
2213  // If BILLING contact defined on invoice, we use it
2214  $usecontact = false;
2215  $arrayidcontact = $object->getIdContact('external', 'BILLING');
2216  if (count($arrayidcontact) > 0) {
2217  $usecontact = true;
2218  $result = $object->fetch_contact($arrayidcontact[0]);
2219  }
2220 
2221  // Recipient name
2222  if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) {
2223  $thirdparty = $object->contact;
2224  } else {
2225  $thirdparty = $object->thirdparty;
2226  }
2227 
2228  $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
2229 
2230  $mode = 'target';
2231  $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, $mode, $object);
2232 
2233  // Show recipient
2234  $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
2235  if ($this->page_largeur < 210) {
2236  $widthrecbox = 84; // To work with US executive format
2237  }
2238  $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
2239  $posy += $top_shift;
2240  $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
2241  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
2242  $posx = $this->marge_gauche;
2243  }
2244 
2245  // Show recipient frame
2246  if (empty($conf->global->MAIN_PDF_NO_RECIPENT_FRAME)) {
2247  $pdf->SetTextColor(0, 0, 0);
2248  $pdf->SetFont('', '', $default_font_size - 2);
2249  $pdf->SetXY($posx + 2, $posy - 5);
2250  $pdf->MultiCell($widthrecbox - 2, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
2251  $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
2252  }
2253 
2254  // Show recipient name
2255  $pdf->SetXY($posx + 2, $posy + 3);
2256  $pdf->SetFont('', 'B', $default_font_size);
2257  $pdf->MultiCell($widthrecbox - 2, 2, $carac_client_name, 0, $ltrdirection);
2258 
2259  $posy = $pdf->getY();
2260 
2261  // Show recipient information
2262  $pdf->SetFont('', '', $default_font_size - 1);
2263  $pdf->SetXY($posx + 2, $posy);
2264  $pdf->MultiCell($widthrecbox - 2, 4, $carac_client, 0, $ltrdirection);
2265  }
2266 
2267  $pdf->SetTextColor(0, 0, 0);
2268  return $top_shift;
2269  }
2270 
2271  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2281  protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
2282  {
2283  global $conf;
2284  $showdetails = empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 0 : $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
2285  return pdf_pagefoot($pdf, $outputlangs, 'INVOICE_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext, $this->page_largeur, $this->watermark);
2286  }
2287 
2298  public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
2299  {
2300  global $conf, $hookmanager;
2301 
2302  // Default field style for content
2303  $this->defaultContentsFieldsStyle = array(
2304  'align' => 'R', // R,C,L
2305  'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2306  );
2307 
2308  // Default field style for content
2309  $this->defaultTitlesFieldsStyle = array(
2310  'align' => 'C', // R,C,L
2311  'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2312  );
2313 
2314  /*
2315  * For exemple
2316  $this->cols['theColKey'] = array(
2317  'rank' => $rank, // int : use for ordering columns
2318  'width' => 20, // the column width in mm
2319  'title' => array(
2320  'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
2321  'label' => ' ', // the final label : used fore final generated text
2322  'align' => 'L', // text alignement : R,C,L
2323  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2324  ),
2325  'content' => array(
2326  'align' => 'L', // text alignement : R,C,L
2327  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2328  ),
2329  );
2330  */
2331 
2332  $rank = 0; // do not use negative rank
2333  $this->cols['desc'] = array(
2334  'rank' => $rank,
2335  'width' => false, // only for desc
2336  'status' => true,
2337  'title' => array(
2338  'textkey' => 'Designation', // use lang key is usefull in somme case with module
2339  'align' => 'L',
2340  // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
2341  // 'label' => ' ', // the final label
2342  'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2343  ),
2344  'content' => array(
2345  'align' => 'L',
2346  'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2347  ),
2348  );
2349 
2350  // Image of product
2351  $rank = $rank + 10;
2352  $this->cols['photo'] = array(
2353  'rank' => $rank,
2354  'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
2355  'status' => false,
2356  'title' => array(
2357  'textkey' => 'Photo',
2358  'label' => ' '
2359  ),
2360  'content' => array(
2361  'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
2362  ),
2363  'border-left' => false, // remove left line separator
2364  );
2365 
2366  if (!empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto)) {
2367  $this->cols['photo']['status'] = true;
2368  }
2369 
2370 
2371  $rank = $rank + 10;
2372  $this->cols['vat'] = array(
2373  'rank' => $rank,
2374  'status' => false,
2375  'width' => 16, // in mm
2376  'title' => array(
2377  'textkey' => 'VAT'
2378  ),
2379  'border-left' => true, // add left line separator
2380  );
2381 
2382  if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) {
2383  $this->cols['vat']['status'] = true;
2384  }
2385 
2386  $rank = $rank + 10;
2387  $this->cols['subprice'] = array(
2388  'rank' => $rank,
2389  'width' => 19, // in mm
2390  'status' => true,
2391  'title' => array(
2392  'textkey' => 'PriceUHT'
2393  ),
2394  'border-left' => true, // add left line separator
2395  );
2396 
2397  // Adapt dynamically the width of subprice, if text is too long.
2398  $tmpwidth = 0;
2399  $nblines = count($object->lines);
2400  for ($i = 0; $i < $nblines; $i++) {
2401  $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails)));
2402  $tmpwidth = max($tmpwidth, $tmpwidth2);
2403  }
2404  if ($tmpwidth > 10) {
2405  $this->cols['subprice']['width'] += (2 * ($tmpwidth - 10));
2406  }
2407 
2408  $rank = $rank + 10;
2409  $this->cols['qty'] = array(
2410  'rank' => $rank,
2411  'width' => 16, // in mm
2412  'status' => true,
2413  'title' => array(
2414  'textkey' => 'Qty'
2415  ),
2416  'border-left' => true, // add left line separator
2417  );
2418 
2419  $rank = $rank + 10;
2420  $this->cols['progress'] = array(
2421  'rank' => $rank,
2422  'width' => 19, // in mm
2423  'status' => false,
2424  'title' => array(
2425  'textkey' => 'Progress'
2426  ),
2427  'border-left' => true, // add left line separator
2428  );
2429 
2430  if ($this->situationinvoice) {
2431  $this->cols['progress']['status'] = true;
2432  }
2433 
2434  $rank = $rank + 10;
2435  $this->cols['unit'] = array(
2436  'rank' => $rank,
2437  'width' => 11, // in mm
2438  'status' => false,
2439  'title' => array(
2440  'textkey' => 'Unit'
2441  ),
2442  'border-left' => true, // add left line separator
2443  );
2444  if (!empty($conf->global->PRODUCT_USE_UNITS)) {
2445  $this->cols['unit']['status'] = true;
2446  }
2447 
2448  $rank = $rank + 10;
2449  $this->cols['discount'] = array(
2450  'rank' => $rank,
2451  'width' => 13, // in mm
2452  'status' => false,
2453  'title' => array(
2454  'textkey' => 'ReductionShort'
2455  ),
2456  'border-left' => true, // add left line separator
2457  );
2458  if ($this->atleastonediscount) {
2459  $this->cols['discount']['status'] = true;
2460  }
2461 
2462  $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
2463  $this->cols['totalexcltax'] = array(
2464  'rank' => $rank,
2465  'width' => 26, // in mm
2466  'status' => empty($conf->global->PDF_PROPAL_HIDE_PRICE_EXCL_TAX) ? true : false,
2467  'title' => array(
2468  'textkey' => 'TotalHT'
2469  ),
2470  'border-left' => true, // add left line separator
2471  );
2472 
2473  $rank = $rank + 1010; // add a big offset to be sure is the last col because default extrafield rank is 100
2474  $this->cols['totalincltax'] = array(
2475  'rank' => $rank,
2476  'width' => 26, // in mm
2477  'status' => empty($conf->global->PDF_PROPAL_SHOW_PRICE_INCL_TAX) ? false : true,
2478  'title' => array(
2479  'textkey' => 'TotalTTC'
2480  ),
2481  'border-left' => true, // add left line separator
2482  );
2483 
2484  // Add extrafields cols
2485  if (!empty($object->lines)) {
2486  $line = reset($object->lines);
2487  $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
2488  }
2489 
2490  $parameters = array(
2491  'object' => $object,
2492  'outputlangs' => $outputlangs,
2493  'hidedetails' => $hidedetails,
2494  'hidedesc' => $hidedesc,
2495  'hideref' => $hideref
2496  );
2497 
2498  $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
2499  if ($reshook < 0) {
2500  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2501  } elseif (empty($reshook)) {
2502  $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
2503  } else {
2504  $this->cols = $hookmanager->resArray;
2505  }
2506  }
2507 }
Facture\STATUS_DRAFT
const STATUS_DRAFT
Draft status.
Definition: facture.class.php:412
make_substitutions
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
Definition: functions.lib.php:7824
pdf_getlinevatrate
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition: pdf.lib.php:1780
getLocalTaxesFromRate
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
Definition: functions.lib.php:6083
db
$conf db
API class for accounts.
Definition: inc.php:41
pdf_getSizeForImage
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:2470
pdf_getlineqty
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition: pdf.lib.php:1927
pdf_getlineupexcltax
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition: pdf.lib.php:1842
dol_trunc
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
Definition: functions.lib.php:3791
dol_sanitizeFileName
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
Definition: functions.lib.php:1212
description
print *****$script_file(".$version.") pid cd cd cd description as description
Definition: email_expire_services_to_customers.php:83
pdf_getlineremisepercent
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition: pdf.lib.php:2131
pdf_getFormat
pdf_getFormat(Translate $outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition: pdf.lib.php:84
pdf_sponge\drawInfoTable
drawInfoTable(&$pdf, $object, $posy, $outputlangs, $outputlangsbis)
Show miscellaneous information (payment mode, payment term, ...)
Definition: pdf_sponge.modules.php:1172
pdf_sponge\_pagehead
_pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis=null)
Show top header of page.
Definition: pdf_sponge.modules.php:1946
CommonDocGenerator\getColumnContentXStart
getColumnContentXStart($colKey)
get column content X (abscissa) left position from column key
Definition: commondocgenerator.class.php:1106
pdf_sponge\write_file
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
Definition: pdf_sponge.modules.php:211
pdf_getInstance
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition: pdf.lib.php:126
CommonDocGenerator\printStdColumnContent
printStdColumnContent($pdf, &$curY, $colKey, $columnText='')
print standard column content
Definition: commondocgenerator.class.php:1180
pdf_getPDFFont
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition: pdf.lib.php:265
Translate
Class to manage translations.
Definition: translate.class.php:30
CommonDocGenerator\pdfTabTitles
pdfTabTitles(&$pdf, $tab_top, $tab_height, $outputlangs, $hidetop=0)
Print standard column content.
Definition: commondocgenerator.class.php:1521
pdf_getlineunit
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0, $hookmanager=false)
Return line unit.
Definition: pdf.lib.php:2088
name
$conf db name
Definition: repair.php:122
CommonDocGenerator\getExtrafieldContent
getExtrafieldContent($object, $extrafieldKey, $outputlangs=null)
get extrafield content for pdf writeHtmlCell compatibility usage for PDF line columns and object note...
Definition: commondocgenerator.class.php:1263
Facture
Class to manage invoices.
Definition: facture.class.php:60
price2num
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
Definition: functions.lib.php:5647
pdf_sponge
Class to manage PDF invoice template sponge.
Definition: pdf_sponge.modules.php:44
CommonDocGenerator\prepareArrayColumnField
prepareArrayColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Prepare Array Column Field.
Definition: commondocgenerator.class.php:1021
pdf_sponge\drawPaymentsTable
drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
Show payments table.
Definition: pdf_sponge.modules.php:1028
dol_print_date
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Definition: functions.lib.php:2500
dol_concatdesc
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
Definition: functions.lib.php:7234
ModelePDFFactures
Parent class of invoice document generators.
Definition: modules_facture.php:38
pdfBuildThirdpartyName
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition: pdf.lib.php:386
pdf_pagehead
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition: pdf.lib.php:711
get_exdir
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
Definition: functions.lib.php:6535
pdf_bank
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank informations for PDF generation.
Definition: pdf.lib.php:812
pdf_getlineprogress
pdf_getlineprogress($object, $i, $outputlangs, $hidedetails=0, $hookmanager=null)
Return line percent.
Definition: pdf.lib.php:2174
pdf_getHeightForLogo
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition: pdf.lib.php:313
pdf_getlinetotalwithtax
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition: pdf.lib.php:2281
CommonDocGenerator\printRect
printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
Rect pdf.
Definition: commondocgenerator.class.php:977
pdf_writeLinkedObjects
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition: pdf.lib.php:1309
dol_string_nohtmltag
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
Definition: functions.lib.php:6680
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1589
pdf_build_address
pdf_build_address($outputlangs, $sourcecompany, $targetcompany='', $targetcontact='', $usecontact=0, $mode='source', $object=null)
Return a string with full address formated for output on documents.
Definition: pdf.lib.php:427
pdf_sponge\defineColumnField
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
Definition: pdf_sponge.modules.php:2298
convertBackOfficeMediasLinksToPublicLinks
if(!function_exists('dolEscapeXML')) convertBackOfficeMediasLinksToPublicLinks($notetoshow)
Convert links to local wrapper to medias files into a string into a public external URL readable on i...
Definition: functions2.lib.php:2711
getDolGlobalString
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
Definition: functions.lib.php:80
dol_strlen
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
Definition: functions.lib.php:3733
pdf_sponge\_tableau
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='', $outputlangsbis=null)
Show table for lines.
Definition: pdf_sponge.modules.php:1889
pdf_sponge\_pagefoot
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
Definition: pdf_sponge.modules.php:2281
pdf_sponge\__construct
__construct($db)
Constructor.
Definition: pdf_sponge.modules.php:141
User
Class to manage Dolibarr users.
Definition: user.class.php:44
Product
Class to manage products or services.
Definition: product.class.php:46
dol_htmlentitiesbr
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...
Definition: functions.lib.php:6977
$resql
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
CommonDocGenerator\printColDescContent
printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref=0, $hidedesc=0, $issupplierline=0)
print description column content
Definition: commondocgenerator.class.php:1226
pdf_getPDFFontSize
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition: pdf.lib.php:288
pdf_getSubstitutionArray
pdf_getSubstitutionArray($outputlangs, $exclude=null, $object=null, $onlykey=0)
Return array of possible substitutions for PDF content (without external module substitutions).
Definition: pdf.lib.php:737
price
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.
Definition: functions.lib.php:5527
getCountry
getCountry($searchkey, $withcode='', $dbtouse=0, $outputlangs='', $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
Definition: company.lib.php:489
setEventMessages
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
Definition: functions.lib.php:8123
dol_mkdir
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
Definition: functions.lib.php:6589
pdf_getlinetotalexcltax
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition: pdf.lib.php:2225
getDolGlobalInt
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
Definition: functions.lib.php:93
pdf_sponge\drawTotalTable
drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis)
Show total to pay.
Definition: pdf_sponge.modules.php:1357
type
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:119
CommonDocGenerator\defineColumnExtrafield
defineColumnExtrafield($object, $outputlangs, $hidedetails=0)
Define Array Column Field for extrafields.
Definition: commondocgenerator.class.php:1598
CommonDocGenerator\getColumnStatus
getColumnStatus($colKey)
get column status from column key
Definition: commondocgenerator.class.php:1502
Account
Class to manage bank accounts.
Definition: account.class.php:38
HookManager
Class to manage hooks.
Definition: hookmanager.class.php:30
complete_substitutions_array
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
Definition: functions.lib.php:7947
vatrate
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages.
Definition: functions.lib.php:5478
pdf_pagefoot
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:989
pdf_sponge\liste_modeles
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
Definition: pdf_sponge.modules.php:1868
pdfGetLineTotalDiscountAmount
pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails=0)
Return line total amount discount.
Definition: pdf.lib.php:2500
float
div float
Buy price without taxes.
Definition: style.css.php:809
if
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
Definition: journals_list.php:25