dolibarr  17.0.4
pdf_eagle_proforma.modules.php
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-2013 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
7  * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
8  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
9  * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
10  * Copyright (C) 2018-2019 Frédéric France <frederic.france@netlogic.fr>
11  * Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.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/commande/modules_commande.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(7, 0);
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 
124 
130  public function __construct($db)
131  {
132  global $conf, $langs, $mysoc;
133 
134  // Translations
135  $langs->loadLangs(array("main", "bills", "products"));
136 
137  $this->db = $db;
138  $this->name = $langs->trans("StockTransferSheetProforma");
139  $this->description = $langs->trans('StockTransferSheetProforma');
140  $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
141 
142  // Dimension page
143  $this->type = 'pdf';
144  $formatarray = pdf_getFormat();
145  $this->page_largeur = $formatarray['width'];
146  $this->page_hauteur = $formatarray['height'];
147  $this->format = array($this->page_largeur, $this->page_hauteur);
148  $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
149  $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
150  $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
151  $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
152 
153  $this->option_logo = 1; // Display logo
154  $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
155  $this->option_modereg = 1; // Display payment mode
156  $this->option_condreg = 1; // Display payment terms
157  $this->option_codeproduitservice = 1; // Display product-service code
158  $this->option_multilang = 1; // Available in several languages
159  $this->option_escompte = 0; // Displays if there has been a discount
160  $this->option_credit_note = 0; // Support credit notes
161  $this->option_freetext = 1; // Support add of a personalised text
162  $this->option_draft_watermark = 1; // Support add of a watermark on drafts
163 
164  // Get source company
165  $this->emetteur = $mysoc;
166  if (empty($this->emetteur->country_code)) $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
167 
168  // Define position of columns
169  $this->posxdesc = $this->marge_gauche + 1;
170 
171 
172  $this->tabTitleHeight = 5; // default height
173 
174  $this->tva = array();
175  $this->localtax1 = array();
176  $this->localtax2 = array();
177  $this->atleastoneratenotnull = 0;
178  $this->atleastonediscount = 0;
179  }
180 
181  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
193  public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
194  {
195  // phpcs:enable
196  global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
197 
198  if (!is_object($outputlangs)) $outputlangs = $langs;
199  // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
200  if (!empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output = 'ISO-8859-1';
201 
202  // Load translation files required by the page
203  $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries"));
204 
205  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
206  global $outputlangsbis;
207  $outputlangsbis = new Translate('', $conf);
208  $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
209  $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries"));
210  }
211 
212  $nblines = count($object->lines);
213 
214  $hidetop = 0;
215  if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) {
216  $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE;
217  }
218 
219  // Loop on each lines to detect if there is at least one image to show
220  $realpatharray = array();
221  $this->atleastonephoto = false;
222  if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) {
223  $objphoto = new Product($this->db);
224 
225  for ($i = 0; $i < $nblines; $i++) {
226  if (empty($object->lines[$i]->fk_product)) continue;
227 
228  $objphoto->fetch($object->lines[$i]->fk_product);
229  //var_dump($objphoto->ref);exit;
230  if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
231  $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
232  $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
233  } else {
234  $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; // default
235  $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
236  }
237 
238  $arephoto = false;
239  foreach ($pdir as $midir) {
240  if (!$arephoto) {
241  $dir = $conf->product->dir_output.'/'.$midir;
242 
243  foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
244  if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES')) { // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
245  if ($obj['photo_vignette']) {
246  $filename = $obj['photo_vignette'];
247  } else {
248  $filename = $obj['photo'];
249  }
250  } else {
251  $filename = $obj['photo'];
252  }
253 
254  $realpath = $dir.$filename;
255  $arephoto = true;
256  $this->atleastonephoto = true;
257  }
258  }
259  }
260 
261  if ($realpath && $arephoto) $realpatharray[$i] = $realpath;
262  }
263  }
264 
265 
266 
267  if ($conf->stocktransfer->dir_output) {
268  $object->fetch_thirdparty();
269 
270  $deja_regle = 0;
271 
272  // Definition of $dir and $file
273  if ($object->specimen) {
274  $dir = $conf->stocktransfer->multidir_output[$conf->entity];
275  $file = $dir."/SPECIMEN.pdf";
276  } else {
277  $objectref = dol_sanitizeFileName($object->ref);
278  $dir = $conf->stocktransfer->multidir_output[$conf->entity]."/".$object->element."/".$objectref;
279  $file = $dir."/".$objectref."-proforma.pdf";
280  }
281 
282  if (!file_exists($dir)) {
283  if (dol_mkdir($dir) < 0) {
284  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
285  return 0;
286  }
287  }
288 
289  if (file_exists($dir)) {
290  // Add pdfgeneration hook
291  if (!is_object($hookmanager)) {
292  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
293  $hookmanager = new HookManager($this->db);
294  }
295  $hookmanager->initHooks(array('pdfgeneration'));
296  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
297  global $action;
298  $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
299 
300  // Create pdf instance
301  $pdf = pdf_getInstance($this->format);
302  $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
303  $pdf->SetAutoPageBreak(1, 0);
304 
305  $heightforinfotot = 40; // Height reserved to output the info and total part
306  $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
307  $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)
308 
309  if (class_exists('TCPDF')) {
310  $pdf->setPrintHeader(false);
311  $pdf->setPrintFooter(false);
312  }
313  $pdf->SetFont(pdf_getPDFFont($outputlangs));
314  // Set path to the background PDF File
315  if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) {
316  $pagecount = $pdf->setSourceFile($conf->mycompany->multidir_output[$object->entity].'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
317  $tplidx = $pdf->importPage(1);
318  }
319 
320  $pdf->Open();
321  $pagenb = 0;
322  $pdf->SetDrawColor(128, 128, 128);
323 
324  $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
325  $pdf->SetSubject($outputlangs->transnoentities("PdfOrderTitle"));
326  $pdf->SetCreator("Dolibarr ".DOL_VERSION);
327  $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
328  $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfOrderTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
329  if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
330  $pdf->SetCompression(false);
331  }
332 
333  $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
334 
336  foreach ($object->lines as $line) {
337  if ($line->remise_percent) {
338  $this->atleastonediscount = true;
339  break;
340  }
341  }
342 
343 
344  // New page
345  $pdf->AddPage();
346  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
347  $pagenb++;
348  $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
349  $pdf->SetFont('', '', $default_font_size - 1);
350  $pdf->MultiCell(0, 3, ''); // Set interline to 3
351  $pdf->SetTextColor(0, 0, 0);
352 
353 
354  $tab_top = 90 + $top_shift;
355  $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
356 
357  // Incoterm
358  if ($conf->incoterm->enabled) {
359  $desc_incoterms = $object->getIncotermsForPDF();
360  if ($desc_incoterms) {
361  $tab_top -= 2;
362 
363  $pdf->SetFont('', '', $default_font_size - 1);
364  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
365  $nexY = $pdf->GetY();
366  $height_incoterms = $nexY - $tab_top;
367 
368  // Rect takes a length in 3rd parameter
369  $pdf->SetDrawColor(192, 192, 192);
370  $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1);
371 
372  $tab_top = $nexY + 6;
373  }
374  }
375 
376  // Displays notes
377  $notetoshow = empty($object->note_public) ? '' : $object->note_public;
378  if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) {
379  // Get first sale rep
380  if (is_object($object->thirdparty)) {
381  $salereparray = $object->thirdparty->getSalesRepresentatives($user);
382  $salerepobj = new User($this->db);
383  $salerepobj->fetch($salereparray[0]['id']);
384  if (!empty($salerepobj->signature)) $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
385  }
386  }
387 
388  // Extrafields in note
389  $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
390  if (!empty($extranote)) {
391  $notetoshow = dol_concatdesc($notetoshow, $extranote);
392  }
393 
394  $pagenb = $pdf->getPage();
395  if ($notetoshow) {
396  $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
397  $pageposbeforenote = $pagenb;
398 
399  $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
400  complete_substitutions_array($substitutionarray, $outputlangs, $object);
401  $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
402  $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
403 
404  $tab_top -= 2;
405 
406  $pdf->startTransaction();
407 
408  $pdf->SetFont('', '', $default_font_size - 1);
409  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
410  // Description
411  $pageposafternote = $pdf->getPage();
412  $posyafter = $pdf->GetY();
413 
414  if ($pageposafternote > $pageposbeforenote) {
415  $pdf->rollbackTransaction(true);
416 
417  // prepare pages to receive notes
418  while ($pagenb < $pageposafternote) {
419  $pdf->AddPage();
420  $pagenb++;
421  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
422  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
423  // $this->_pagefoot($pdf,$object,$outputlangs,1);
424  $pdf->setTopMargin($tab_top_newpage);
425  // The only function to edit the bottom margin of current page to set it.
426  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
427  }
428 
429  // back to start
430  $pdf->setPage($pageposbeforenote);
431  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
432  $pdf->SetFont('', '', $default_font_size - 1);
433  $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
434  $pageposafternote = $pdf->getPage();
435 
436  $posyafter = $pdf->GetY();
437 
438  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text
439  $pdf->AddPage('', '', true);
440  $pagenb++;
441  $pageposafternote++;
442  $pdf->setPage($pageposafternote);
443  $pdf->setTopMargin($tab_top_newpage);
444  // The only function to edit the bottom margin of current page to set it.
445  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
446  //$posyafter = $tab_top_newpage;
447  }
448 
449 
450  // apply note frame to previous pages
451  $i = $pageposbeforenote;
452  while ($i < $pageposafternote) {
453  $pdf->setPage($i);
454 
455 
456  $pdf->SetDrawColor(128, 128, 128);
457  // Draw note frame
458  if ($i > $pageposbeforenote) {
459  $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
460  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
461  } else {
462  $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
463  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
464  }
465 
466  // Add footer
467  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
468  $this->_pagefoot($pdf, $object, $outputlangs, 1);
469 
470  $i++;
471  }
472 
473  // apply note frame to last page
474  $pdf->setPage($pageposafternote);
475  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
476  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
477  $height_note = $posyafter - $tab_top_newpage;
478  $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
479  } else // No pagebreak
480  {
481  $pdf->commitTransaction();
482  $posyafter = $pdf->GetY();
483  $height_note = $posyafter - $tab_top;
484  $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
485 
486 
487  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
488  // not enough space, need to add page
489  $pdf->AddPage('', '', true);
490  $pagenb++;
491  $pageposafternote++;
492  $pdf->setPage($pageposafternote);
493  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
494  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
495 
496  $posyafter = $tab_top_newpage;
497  }
498  }
499 
500  $tab_height = $tab_height - $height_note;
501  $tab_top = $posyafter + 6;
502  } else {
503  $height_note = 0;
504  }
505 
506 
507  // Use new auto column system
508  $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
509 
510  // tab simulation to know line height
511  $pdf->startTransaction();
512  $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
513  $pdf->rollbackTransaction(true);
514 
515  $nexY = $tab_top + $this->tabTitleHeight;
516 
517  // Loop on each lines
518  $pageposbeforeprintlines = $pdf->getPage();
519  $pagenb = $pageposbeforeprintlines;
520  for ($i = 0; $i < $nblines; $i++) {
521  $curY = $nexY;
522  $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
523  $pdf->SetTextColor(0, 0, 0);
524 
525  // Define size of image if we need it
526  $imglinesize = array();
527  if (!empty($realpatharray[$i])) $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
528 
529  $pdf->setTopMargin($tab_top_newpage);
530  $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
531  $pageposbefore = $pdf->getPage();
532 
533 
534  $showpricebeforepagebreak = 1;
535  $posYAfterImage = 0;
536 
537  if ($this->getColumnStatus('photo')) {
538  // We start with Photo of product line
539  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
540  $pdf->AddPage('', '', true);
541  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
542  $pdf->setPage($pageposbefore + 1);
543 
544  $curY = $tab_top_newpage;
545 
546  // Allows data in the first page if description is long enough to break in multiples pages
547  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
548  $showpricebeforepagebreak = 1;
549  else $showpricebeforepagebreak = 0;
550  }
551 
552  if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) {
553  $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
554  // $pdf->Image does not increase value return by getY, so we save it manually
555  $posYAfterImage = $curY + $imglinesize['height'];
556  }
557  }
558 
559  if ($this->getColumnStatus('desc')) {
560  $pdf->startTransaction();
561 
562  if (method_exists($object->lines[$i], 'fetch_product')) {
563  $object->lines[$i]->fetch_product();
564  $object->lines[$i]->label = $object->lines[$i]->product->label;
565  $object->lines[$i]->description = $object->lines[$i]->product->description;
566  $object->lines[$i]->fk_unit = $object->lines[$i]->product->fk_unit;
567  }
568 
569  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
570 
571  $pageposafter = $pdf->getPage();
572  if ($pageposafter > $pageposbefore) { // There is a pagebreak
573  $pdf->rollbackTransaction(true);
574  $pageposafter = $pageposbefore;
575  //print $pageposafter.'-'.$pageposbefore;exit;
576  $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
577 
578  $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
579  $pageposafter = $pdf->getPage();
580  $posyafter = $pdf->GetY();
581  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
582  if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
583  $pdf->AddPage('', '', true);
584  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
585  //if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
586  $pdf->setPage($pageposafter + 1);
587  }
588  } else {
589  // We found a page break
590  // Allows data in the first page if description is long enough to break in multiples pages
591  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
592  $showpricebeforepagebreak = 1;
593  else $showpricebeforepagebreak = 0;
594  }
595  } else // No pagebreak
596  {
597  $pdf->commitTransaction();
598  }
599  }
600 
601 
602 
603  $nexY = max($pdf->GetY(), $posYAfterImage);
604 
605 
606  $pageposafter = $pdf->getPage();
607 
608  $pdf->setPage($pageposbefore);
609  $pdf->setTopMargin($this->marge_haute);
610  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
611 
612  // We suppose that a too long description is moved completely on next page
613  if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
614  $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
615  }
616 
617  $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font
618 
619  // VAT Rate
620  if ($this->getColumnStatus('vat')) {
621  $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
622  $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
623  $nexY = max($pdf->GetY(), $nexY);
624  }
625 
626  // Unit price before discount
627  if ($this->getColumnStatus('subprice')) {
628  $pmp = $object->lines[$i]->pmp;
629  $this->printStdColumnContent($pdf, $curY, 'subprice', price($pmp));
630  $nexY = max($pdf->GetY(), $nexY);
631  }
632 
633  // Quantity
634  // Enough for 6 chars
635  if ($this->getColumnStatus('qty')) {
636  $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
637  $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
638  $nexY = max($pdf->GetY(), $nexY);
639  }
640 
641 
642  // Unit
643  if ($this->getColumnStatus('unit')) {
644  $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
645  $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
646  $nexY = max($pdf->GetY(), $nexY);
647  }
648 
649  // Discount on line
650  if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) {
651  $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
652  $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
653  $nexY = max($pdf->GetY(), $nexY);
654  }
655 
656  // Total HT line
657  if ($this->getColumnStatus('totalexcltax')) {
658  $pmp_qty = $pmp * $object->lines[$i]->qty;
659  $this->printStdColumnContent($pdf, $curY, 'totalexcltax', price($pmp_qty));
660  $nexY = max($pdf->GetY(), $nexY);
661  }
662 
663  // Extrafields
664  if (!empty($object->lines[$i]->array_options)) {
665  foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
666  if ($this->getColumnStatus($extrafieldColKey)) {
667  $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey);
668  $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
669  $nexY = max($pdf->GetY(), $nexY);
670  }
671  }
672  }
673 
674  $parameters = array(
675  'object' => $object,
676  'i' => $i,
677  'pdf' =>& $pdf,
678  'curY' =>& $curY,
679  'nexY' =>& $nexY,
680  'outputlangs' => $outputlangs,
681  'hidedetails' => $hidedetails
682  );
683  $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook
684 
685 
686  // Collection of totals by value of vat in $this->tva["rate"] = total_tva
687  if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) $tvaligne = $object->lines[$i]->multicurrency_total_tva;
688  else $tvaligne = $object->lines[$i]->total_tva;
689 
690  $localtax1ligne = $object->lines[$i]->total_localtax1;
691  $localtax2ligne = $object->lines[$i]->total_localtax2;
692  $localtax1_rate = $object->lines[$i]->localtax1_tx;
693  $localtax2_rate = $object->lines[$i]->localtax2_tx;
694  $localtax1_type = $object->lines[$i]->localtax1_type;
695  $localtax2_type = $object->lines[$i]->localtax2_type;
696 
697  if ($object->remise_percent) $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
698  if ($object->remise_percent) $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
699  if ($object->remise_percent) $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
700 
701  $vatrate = (string) $object->lines[$i]->tva_tx;
702 
703  // Retrieve type from database for backward compatibility with old records
704  if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
705  && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
706  $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
707  $localtax1_type = $localtaxtmp_array[0];
708  $localtax2_type = $localtaxtmp_array[2];
709  }
710 
711  // retrieve global local tax
712  if ($localtax1_type && $localtax1ligne != 0)
713  $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
714  if ($localtax2_type && $localtax2ligne != 0)
715  $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
716 
717  if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate .= '*';
718  if (!isset($this->tva[$vatrate])) $this->tva[$vatrate] = 0;
719  $this->tva[$vatrate] += $tvaligne;
720 
721  // Add line
722  if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) {
723  $pdf->setPage($pageposafter);
724  $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
725  //$pdf->SetDrawColor(190,190,200);
726  $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
727  $pdf->SetLineStyle(array('dash'=>0));
728  }
729 
730 
731  // Detect if some page were added automatically and output _tableau for past pages
732  while ($pagenb < $pageposafter) {
733  $pdf->setPage($pagenb);
734  if ($pagenb == $pageposbeforeprintlines) {
735  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
736  } else {
737  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
738  }
739  $this->_pagefoot($pdf, $object, $outputlangs, 1);
740  $pagenb++;
741  $pdf->setPage($pagenb);
742  $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
743  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
744  }
745  if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
746  if ($pagenb == $pageposafter) {
747  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
748  } else {
749  $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
750  }
751  $this->_pagefoot($pdf, $object, $outputlangs, 1);
752  // New page
753  $pdf->AddPage();
754  if (!empty($tplidx)) $pdf->useTemplate($tplidx);
755  $pagenb++;
756  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) $this->_pagehead($pdf, $object, 0, $outputlangs);
757  }
758  }
759 
760  // Show square
761  if ($pagenb == $pageposbeforeprintlines)
762  $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
763  else $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
764  $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
765 
766  // Affiche zone infos
767  // ! No paiement information for this model !
768  //$posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
769 
770  // Affiche zone totaux
771  $posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
772 
773  // Affiche zone versements
774  /*
775  if ($deja_regle)
776  {
777  $posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
778  }
779  */
780 
781  // Pied de page
782  $this->_pagefoot($pdf, $object, $outputlangs);
783  if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages();
784 
785  $pdf->Close();
786 
787  $pdf->Output($file, 'F');
788 
789  // Add pdfgeneration hook
790  $hookmanager->initHooks(array('pdfgeneration'));
791  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
792  global $action;
793  $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
794  if ($reshook < 0) {
795  $this->error = $hookmanager->error;
796  $this->errors = $hookmanager->errors;
797  }
798 
799  if (!empty($conf->global->MAIN_UMASK))
800  @chmod($file, octdec($conf->global->MAIN_UMASK));
801 
802  $this->result = array('fullpath'=>$file);
803 
804  return 1; // No error
805  } else {
806  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
807  return 0;
808  }
809  } else {
810  $this->error = $langs->transnoentities("ErrorConstantNotDefined", "STOCKTRANSFER_OUTPUTDIR");
811  return 0;
812  }
813  }
814 
824  protected function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
825  {
826  }
827 
837  protected function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
838  {
839  global $conf, $mysoc;
840  $default_font_size = pdf_getPDFFontSize($outputlangs);
841 
842  $pdf->SetFont('', '', $default_font_size - 1);
843 
844  // If France, show VAT mention if not applicable
845  if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
846  $pdf->SetFont('', 'B', $default_font_size - 2);
847  $pdf->SetXY($this->marge_gauche, $posy);
848  $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
849 
850  $posy = $pdf->GetY() + 4;
851  }
852 
853  $posxval = 52;
854 
855  // Show payments conditions
856  if ($object->cond_reglement_code || $object->cond_reglement) {
857  $pdf->SetFont('', 'B', $default_font_size - 2);
858  $pdf->SetXY($this->marge_gauche, $posy);
859  $titre = $outputlangs->transnoentities("PaymentConditions").':';
860  $pdf->MultiCell(43, 4, $titre, 0, 'L');
861 
862  $pdf->SetFont('', '', $default_font_size - 2);
863  $pdf->SetXY($posxval, $posy);
864  $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);
865  $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
866  $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
867 
868  $posy = $pdf->GetY() + 3;
869  }
870 
871  // Check a payment mode is defined
872  /* Not used with orders
873  if (empty($object->mode_reglement_code)
874  && ! $conf->global->FACTURE_CHQ_NUMBER
875  && ! $conf->global->FACTURE_RIB_NUMBER)
876  {
877  $pdf->SetXY($this->marge_gauche, $posy);
878  $pdf->SetTextColor(200,0,0);
879  $pdf->SetFont('','B', $default_font_size - 2);
880  $pdf->MultiCell(80, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0);
881  $pdf->SetTextColor(0,0,0);
882 
883  $posy=$pdf->GetY()+1;
884  }
885  */
886  /* TODO
887  else if (!empty($object->availability_code))
888  {
889  $pdf->SetXY($this->marge_gauche, $posy);
890  $pdf->SetTextColor(200,0,0);
891  $pdf->SetFont('','B', $default_font_size - 2);
892  $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0);
893  $pdf->SetTextColor(0,0,0);
894 
895  $posy=$pdf->GetY()+1;
896  }*/
897 
898  // Show planed date of delivery
899  if (!empty($object->date_livraison)) {
900  $outputlangs->load("sendings");
901  $pdf->SetFont('', 'B', $default_font_size - 2);
902  $pdf->SetXY($this->marge_gauche, $posy);
903  $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
904  $pdf->MultiCell(80, 4, $titre, 0, 'L');
905  $pdf->SetFont('', '', $default_font_size - 2);
906  $pdf->SetXY($posxval, $posy);
907  $dlp = dol_print_date($object->date_livraison, "daytext", false, $outputlangs, true);
908  $pdf->MultiCell(80, 4, $dlp, 0, 'L');
909 
910  $posy = $pdf->GetY() + 1;
911  } elseif ($object->availability_code || $object->availability) { // Show availability conditions
912  $pdf->SetFont('', 'B', $default_font_size - 2);
913  $pdf->SetXY($this->marge_gauche, $posy);
914  $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
915  $pdf->MultiCell(80, 4, $titre, 0, 'L');
916  $pdf->SetTextColor(0, 0, 0);
917  $pdf->SetFont('', '', $default_font_size - 2);
918  $pdf->SetXY($posxval, $posy);
919  $lib_availability = $outputlangs->transnoentities("AvailabilityType".$object->availability_code) != ('AvailabilityType'.$object->availability_code) ? $outputlangs->transnoentities("AvailabilityType".$object->availability_code) : $outputlangs->convToOutputCharset(isset($object->availability) ? $object->availability : '');
920  $lib_availability = str_replace('\n', "\n", $lib_availability);
921  $pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
922 
923  $posy = $pdf->GetY() + 1;
924  }
925 
926  // Show payment mode
927  if ($object->mode_reglement_code
928  && $object->mode_reglement_code != 'CHQ'
929  && $object->mode_reglement_code != 'VIR') {
930  $pdf->SetFont('', 'B', $default_font_size - 2);
931  $pdf->SetXY($this->marge_gauche, $posy);
932  $titre = $outputlangs->transnoentities("PaymentMode").':';
933  $pdf->MultiCell(80, 5, $titre, 0, 'L');
934 
935  $pdf->SetFont('', '', $default_font_size - 2);
936  $pdf->SetXY($posxval, $posy);
937  $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);
938  $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
939 
940  $posy = $pdf->GetY() + 2;
941  }
942 
943  // Show payment mode CHQ
944  if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') {
945  // Si mode reglement non force ou si force a CHQ
946  if (!empty($conf->global->FACTURE_CHQ_NUMBER)) {
947  if ($conf->global->FACTURE_CHQ_NUMBER > 0) {
948  $account = new Account($this->db);
949  $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
950 
951  $pdf->SetXY($this->marge_gauche, $posy);
952  $pdf->SetFont('', 'B', $default_font_size - 3);
953  $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0);
954  $posy = $pdf->GetY() + 1;
955 
956  if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) {
957  $pdf->SetXY($this->marge_gauche, $posy);
958  $pdf->SetFont('', '', $default_font_size - 3);
959  $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
960  $posy = $pdf->GetY() + 2;
961  }
962  }
963  if ($conf->global->FACTURE_CHQ_NUMBER == -1) {
964  $pdf->SetXY($this->marge_gauche, $posy);
965  $pdf->SetFont('', 'B', $default_font_size - 3);
966  $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
967  $posy = $pdf->GetY() + 1;
968 
969  if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) {
970  $pdf->SetXY($this->marge_gauche, $posy);
971  $pdf->SetFont('', '', $default_font_size - 3);
972  $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
973  $posy = $pdf->GetY() + 2;
974  }
975  }
976  }
977  }
978 
979  // If payment mode not forced or forced to VIR, show payment with BAN
980  if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') {
981  if (!empty($object->fk_account) || !empty($object->fk_bank) || getDolGlobalInt('FACTURE_RIB_NUMBER')) {
982  $bankid = (empty($object->fk_account) ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
983  if (!empty($object->fk_bank)) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
984  $account = new Account($this->db);
985  $account->fetch($bankid);
986 
987  $curx = $this->marge_gauche;
988  $cury = $posy;
989 
990  $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
991 
992  $posy += 2;
993  }
994  }
995 
996  return $posy;
997  }
998 
999 
1010  protected function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
1011  {
1012  global $conf, $mysoc;
1013 
1014  $default_font_size = pdf_getPDFFontSize($outputlangs);
1015 
1016  $tab2_top = $posy;
1017  $tab2_hl = 4;
1018  $pdf->SetFont('', '', $default_font_size - 1);
1019 
1020  // Tableau total
1021  $col1x = 120; $col2x = 170;
1022  if ($this->page_largeur < 210) { // To work with US executive format
1023  $col2x -= 20;
1024  }
1025  $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
1026  $useborder = 0;
1027  $index = 0;
1028 
1029  $outputlangsbis = null;
1030  if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
1031  $outputlangsbis = new Translate('', $conf);
1032  $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
1033  $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
1034  }
1035 
1036  // Total HT
1037  /*$pdf->SetFillColor(255, 255, 255);
1038  $pdf->SetXY($col1x, $tab2_top + 0);
1039  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1);
1040  $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
1041  $pdf->SetXY($col2x, $tab2_top + 0);
1042  $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0), 0, $outputlangs), 0, 'R', 1);*/
1043 
1044  // Show VAT by rates and total
1045  $pdf->SetFillColor(248, 248, 248);
1046 
1047  $total_ttc = $object->getValorisationTotale();
1048 
1049  $this->atleastoneratenotnull = 0;
1050 
1051  // Total TTC
1052  $index++;
1053  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1054  $pdf->SetTextColor(0, 0, 60);
1055  $pdf->SetFillColor(224, 224, 224);
1056  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("Total").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("Total", $mysoc->country_code) : ''), $useborder, 'L', 1);
1057 
1058  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1059  $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
1060 
1061  $pdf->SetTextColor(0, 0, 0);
1062 
1063  $creditnoteamount = 0;
1064  $depositsamount = 0;
1065  //$creditnoteamount=$object->getSumCreditNotesUsed();
1066  //$depositsamount=$object->getSumDepositsUsed();
1067  //print "x".$creditnoteamount."-".$depositsamount;exit;
1068  $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
1069  if (!empty($object->paye)) $resteapayer = 0;
1070 
1071  if ($deja_regle > 0) {
1072  // Already paid + Deposits
1073  $index++;
1074 
1075  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1076  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), 0, 'L', 0);
1077  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1078  $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
1079 
1080  $index++;
1081  $pdf->SetTextColor(0, 0, 60);
1082  $pdf->SetFillColor(224, 224, 224);
1083  $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
1084  $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), $useborder, 'L', 1);
1085 
1086  $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
1087  $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
1088 
1089  $pdf->SetFont('', '', $default_font_size - 1);
1090  $pdf->SetTextColor(0, 0, 0);
1091  }
1092 
1093  $index++;
1094  return ($tab2_top + ($tab2_hl * $index));
1095  }
1096 
1097  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1111  protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
1112  {
1113  global $conf;
1114 
1115  // Force to disable hidetop and hidebottom
1116  $hidebottom = 0;
1117  if ($hidetop) $hidetop = -1;
1118 
1119  $currency = !empty($currency) ? $currency : $conf->currency;
1120  $default_font_size = pdf_getPDFFontSize($outputlangs);
1121 
1122  // Amount in (at tab_top - 1)
1123  $pdf->SetTextColor(0, 0, 0);
1124  $pdf->SetFont('', '', $default_font_size - 2);
1125 
1126  if (empty($hidetop)) {
1127  $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
1128  $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
1129  $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
1130 
1131  //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
1132  if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) {
1133  $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));
1134  }
1135  }
1136 
1137  $pdf->SetDrawColor(128, 128, 128);
1138  $pdf->SetFont('', '', $default_font_size - 1);
1139 
1140  // Output Rect
1141  $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
1142 
1143 
1144  $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
1145 
1146  if (empty($hidetop)) {
1147  $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
1148  }
1149  }
1150 
1151  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1152  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1163  protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey = "StockTransferSheetProforma")
1164  {
1165  // phpcs:enable
1166  global $conf, $langs, $hookmanager;
1167 
1168  // Load traductions files required by page
1169  $outputlangs->loadLangs(array("main", "bills", "propal", "orders", "companies"));
1170 
1171  $default_font_size = pdf_getPDFFontSize($outputlangs);
1172 
1173  pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
1174 
1175  // Show Draft Watermark
1176  if ($object->statut == 0 && (!empty($conf->global->COMMANDE_DRAFT_WATERMARK))) {
1177  pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->COMMANDE_DRAFT_WATERMARK);
1178  }
1179 
1180  $pdf->SetTextColor(0, 0, 60);
1181  $pdf->SetFont('', 'B', $default_font_size + 3);
1182 
1183  $posy = $this->marge_haute;
1184  $posx = $this->page_largeur - $this->marge_droite - 100;
1185 
1186  $pdf->SetXY($this->marge_gauche, $posy);
1187 
1188  // Logo
1189  if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) {
1190  if ($this->emetteur->logo) {
1191  $logodir = $conf->mycompany->dir_output;
1192  if (!empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity];
1193  if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) {
1194  $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
1195  } else {
1196  $logo = $logodir.'/logos/'.$this->emetteur->logo;
1197  }
1198  if (is_readable($logo)) {
1199  $height = pdf_getHeightForLogo($logo);
1200  $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
1201  } else {
1202  $pdf->SetTextColor(200, 0, 0);
1203  $pdf->SetFont('', 'B', $default_font_size - 2);
1204  $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
1205  $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
1206  }
1207  } else {
1208  $text = $this->emetteur->name;
1209  $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
1210  }
1211  }
1212 
1213  $pdf->SetFont('', 'B', $default_font_size + 3);
1214  $pdf->SetXY($posx, $posy);
1215  $pdf->SetTextColor(0, 0, 60);
1216  $title = $outputlangs->transnoentities($titlekey);
1217  $pdf->MultiCell(100, 3, $title, '', 'R');
1218 
1219  $pdf->SetFont('', 'B', $default_font_size);
1220 
1221  $posy += 5;
1222  $pdf->SetXY($posx, $posy);
1223  $pdf->SetTextColor(0, 0, 60);
1224  $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref), '', 'R');
1225 
1226  $posy += 1;
1227  $pdf->SetFont('', '', $default_font_size - 1);
1228 
1229  // Date prévue depart
1230  if (!empty($object->date_prevue_depart)) {
1231  $posy += 4;
1232  $pdf->SetXY($posx, $posy);
1233  $pdf->SetTextColor(0, 0, 60);
1234  $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DatePrevueDepart")." : ".dol_print_date($object->date_prevue_depart, "day", false, $outputlangs, true), '', 'R');
1235  }
1236 
1237  // Date prévue arrivée
1238  if (!empty($object->date_prevue_arrivee)) {
1239  $posy += 4;
1240  $pdf->SetXY($posx, $posy);
1241  $pdf->SetTextColor(0, 0, 60);
1242  $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DatePrevueArrivee")." : ".dol_print_date($object->date_prevue_arrivee, "day", false, $outputlangs, true), '', 'R');
1243  }
1244 
1245  // Date reelle depart
1246  if (!empty($object->date_reelle_depart)) {
1247  $posy += 4;
1248  $pdf->SetXY($posx, $posy);
1249  $pdf->SetTextColor(0, 0, 60);
1250  $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleDepart")." : ".dol_print_date($object->date_reelle_depart, "day", false, $outputlangs, true), '', 'R');
1251  }
1252 
1253  // Date reelle arrivée
1254  if (!empty($object->date_reelle_arrivee)) {
1255  $posy += 4;
1256  $pdf->SetXY($posx, $posy);
1257  $pdf->SetTextColor(0, 0, 60);
1258  $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateReelleArrivee")." : ".dol_print_date($object->date_reelle_arrivee, "day", false, $outputlangs, true), '', 'R');
1259  }
1260 
1261  if ($object->ref_client) {
1262  $posy += 5;
1263  $pdf->SetXY($posx, $posy);
1264  $pdf->SetTextColor(0, 0, 60);
1265  $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R');
1266  }
1267 
1268  if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) {
1269  $object->fetch_projet();
1270  if (!empty($object->project->ref)) {
1271  $posy += 3;
1272  $pdf->SetXY($posx, $posy);
1273  $pdf->SetTextColor(0, 0, 60);
1274  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R');
1275  }
1276  }
1277 
1278  if (!empty($conf->global->PDF_SHOW_PROJECT)) {
1279  $object->fetch_projet();
1280  if (!empty($object->project->ref)) {
1281  $posy += 3;
1282  $pdf->SetXY($posx, $posy);
1283  $pdf->SetTextColor(0, 0, 60);
1284  $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R');
1285  }
1286  }
1287 
1288  if (!empty($conf->global->DOC_SHOW_CUSTOMER_CODE) && !empty($object->thirdparty->code_client)) {
1289  $posy += 4;
1290  $pdf->SetXY($posx, $posy);
1291  $pdf->SetTextColor(0, 0, 60);
1292  $pdf->MultiCell(100, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
1293  }
1294 
1295  // Get contact
1296  if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) {
1297  $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
1298  if (count($arrayidcontact) > 0) {
1299  $usertmp = new User($this->db);
1300  $usertmp->fetch($arrayidcontact[0]);
1301  $posy += 4;
1302  $pdf->SetXY($posx, $posy);
1303  $pdf->SetTextColor(0, 0, 60);
1304  $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
1305  }
1306  }
1307 
1308  $posy += 2;
1309 
1310  $top_shift = 0;
1311  // Show list of linked objects
1312  $current_y = $pdf->getY();
1313  $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
1314  if ($current_y < $pdf->getY()) {
1315  $top_shift = $pdf->getY() - $current_y;
1316  }
1317 
1318  if ($showaddress) {
1319  // Sender properties
1320  $carac_emetteur = '';
1321  // Add internal contact of origin element if defined
1322  $arrayidcontact = array();
1323  $arrayidcontact = $object->getIdContact('external', 'STFROM');
1324 
1325  $usecontact = false;
1326  if (count($arrayidcontact) > 0) {
1327  /*$object->fetch_user(reset($arrayidcontact));
1328  $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";*/
1329  $usecontact = true;
1330  $result = $object->fetch_contact($arrayidcontact[0]);
1331  }
1332 
1333  if ($usecontact) $thirdparty = $object->contact;
1334  else $thirdparty = $this->emetteur;
1335 
1336  if (!empty($thirdparty)) $carac_emetteur_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1337 
1338  if ($usecontact) $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, $object->contact, 1, 'targetwithdetails', $object);
1339  else $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
1340 
1341  // Show sender
1342  $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
1343  $posx = $this->marge_gauche;
1344  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->page_largeur - $this->marge_droite - 80;
1345 
1346  $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
1347  $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
1348 
1349  // Show sender frame
1350  $pdf->SetTextColor(0, 0, 0);
1351  $pdf->SetFont('', '', $default_font_size - 2);
1352  $pdf->SetXY($posx, $posy - 5);
1353  $pdf->MultiCell(66, 5, $outputlangs->transnoentities("Sender").":", 0, 'L');
1354  $pdf->SetXY($posx, $posy);
1355  $pdf->SetFillColor(230, 230, 230);
1356  $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
1357  $pdf->SetTextColor(0, 0, 60);
1358  $pdf->SetFillColor(255, 255, 255);
1359 
1360  // Show sender name
1361  $pdf->SetXY($posx + 2, $posy + 3);
1362  $pdf->SetFont('', 'B', $default_font_size);
1363  $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($carac_emetteur_name), 0, 'L');
1364  $posy = $pdf->getY();
1365 
1366  // Show sender information
1367  $pdf->SetXY($posx + 2, $posy);
1368  $pdf->SetFont('', '', $default_font_size - 1);
1369  $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, 'L');
1370 
1371 
1372  // If SHIPPING contact defined, we use it
1373  $usecontact = false;
1374  $arrayidcontact = $object->getIdContact('external', 'STDEST');
1375  if (count($arrayidcontact) > 0) {
1376  $usecontact = true;
1377  $result = $object->fetch_contact($arrayidcontact[0]);
1378  }
1379 
1380  //Recipient name
1381  // On peut utiliser le nom de la societe du contact
1382  if ($usecontact/* && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)*/) {
1383  $thirdparty = $object->contact;
1384  } else {
1385  $thirdparty = $object->thirdparty;
1386  }
1387 
1388  if (!empty($thirdparty)) $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
1389 
1390  $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (!empty($object->contact) ? $object->contact : null), $usecontact, 'targetwithdetails', $object);
1391 
1392  // Show recipient
1393  $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
1394  if ($this->page_largeur < 210) $widthrecbox = 84; // To work with US executive format
1395  $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
1396  $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
1397  if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->marge_gauche;
1398 
1399  // Show recipient frame
1400  $pdf->SetTextColor(0, 0, 0);
1401  $pdf->SetFont('', '', $default_font_size - 2);
1402  $pdf->SetXY($posx + 2, $posy - 5);
1403  $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("Recipient").":", 0, 'L');
1404  $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
1405 
1406  // Show recipient name
1407  $pdf->SetXY($posx + 2, $posy + 3);
1408  $pdf->SetFont('', 'B', $default_font_size);
1409  $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L');
1410 
1411  $posy = $pdf->getY();
1412 
1413  // Show recipient information
1414  $pdf->SetFont('', '', $default_font_size - 1);
1415  $pdf->SetXY($posx + 2, $posy);
1416  $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
1417  }
1418 
1419  $pdf->SetTextColor(0, 0, 0);
1420  return $top_shift;
1421  }
1422 
1423  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1424  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1434  protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1435  {
1436  // phpcs:enable
1437  $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1438  return pdf_pagefoot($pdf, $outputlangs, 'ORDER_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1439  }
1440 
1441 
1442 
1453  public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1454  {
1455  global $conf, $hookmanager;
1456 
1457  // Default field style for content
1458  $this->defaultContentsFieldsStyle = array(
1459  'align' => 'R', // R,C,L
1460  'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1461  );
1462 
1463  // Default field style for content
1464  $this->defaultTitlesFieldsStyle = array(
1465  'align' => 'C', // R,C,L
1466  'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1467  );
1468 
1469  /*
1470  * For exemple
1471  $this->cols['theColKey'] = array(
1472  'rank' => $rank, // int : use for ordering columns
1473  'width' => 20, // the column width in mm
1474  'title' => array(
1475  'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1476  'label' => ' ', // the final label : used fore final generated text
1477  'align' => 'L', // text alignement : R,C,L
1478  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1479  ),
1480  'content' => array(
1481  'align' => 'L', // text alignement : R,C,L
1482  'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1483  ),
1484  );
1485  */
1486 
1487  $rank = 0; // do not use negative rank
1488  $this->cols['desc'] = array(
1489  'rank' => $rank,
1490  'width' => false, // only for desc
1491  'status' => true,
1492  'title' => array(
1493  'textkey' => 'Designation', // use lang key is usefull in somme case with module
1494  'align' => 'L',
1495  // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
1496  // 'label' => ' ', // the final label
1497  'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1498  ),
1499  'content' => array(
1500  'align' => 'L',
1501  'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1502  ),
1503  );
1504 
1505  $rank = $rank + 10;
1506  $this->cols['photo'] = array(
1507  'rank' => $rank,
1508  'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
1509  'status' => false,
1510  'title' => array(
1511  'textkey' => 'Photo',
1512  'label' => ' '
1513  ),
1514  'content' => array(
1515  'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
1516  ),
1517  'border-left' => false, // remove left line separator
1518  );
1519 
1520  if (!empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) {
1521  $this->cols['photo']['status'] = true;
1522  }
1523 
1524 
1525  $rank = $rank + 10;
1526  $this->cols['vat'] = array(
1527  'rank' => $rank,
1528  'status' => false,
1529  'width' => 16, // in mm
1530  'title' => array(
1531  'textkey' => 'VAT'
1532  ),
1533  'border-left' => true, // add left line separator
1534  );
1535 
1536  /*if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
1537  {
1538  $this->cols['vat']['status'] = true;
1539  }*/
1540 
1541  $rank = $rank + 10;
1542  $this->cols['subprice'] = array(
1543  'rank' => $rank,
1544  'width' => 19, // in mm
1545  'status' => true,
1546  'title' => array(
1547  'textkey' => 'PMPValueShort'
1548  ),
1549  'border-left' => true, // add left line separator
1550  );
1551 
1552  // Adapt dynamically the width of subprice, if text is too long.
1553  $tmpwidth = 0;
1554  $nblines = count($object->lines);
1555  for ($i = 0; $i < $nblines; $i++) {
1556  $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails)));
1557  $tmpwidth = max($tmpwidth, $tmpwidth2);
1558  }
1559  if ($tmpwidth > 10) {
1560  $this->cols['subprice']['width'] += (2 * ($tmpwidth - 10));
1561  }
1562 
1563  $rank = $rank + 10;
1564  $this->cols['qty'] = array(
1565  'rank' => $rank,
1566  'width' => 16, // in mm
1567  'status' => true,
1568  'title' => array(
1569  'textkey' => 'Qty'
1570  ),
1571  'border-left' => true, // add left line separator
1572  );
1573 
1574  $rank = $rank + 10;
1575  $this->cols['unit'] = array(
1576  'rank' => $rank,
1577  'width' => 11, // in mm
1578  'status' => false,
1579  'title' => array(
1580  'textkey' => 'Unit'
1581  ),
1582  'border-left' => true, // add left line separator
1583  );
1584  if ($conf->global->PRODUCT_USE_UNITS) {
1585  $this->cols['unit']['status'] = true;
1586  }
1587 
1588  $rank = $rank + 10;
1589  $this->cols['discount'] = array(
1590  'rank' => $rank,
1591  'width' => 13, // in mm
1592  'status' => false,
1593  'title' => array(
1594  'textkey' => 'ReductionShort'
1595  ),
1596  'border-left' => true, // add left line separator
1597  );
1598  if ($this->atleastonediscount) {
1599  $this->cols['discount']['status'] = true;
1600  }
1601 
1602  $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
1603  $this->cols['totalexcltax'] = array(
1604  'rank' => $rank,
1605  'width' => 26, // in mm
1606  'status' => true,
1607  'title' => array(
1608  'textkey' => 'PMPValue'
1609  ),
1610  'border-left' => true, // add left line separator
1611  );
1612 
1613  // Add extrafields cols
1614  if (!empty($object->lines)) {
1615  $line = reset($object->lines);
1616  $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
1617  }
1618 
1619  $parameters = array(
1620  'object' => $object,
1621  'outputlangs' => $outputlangs,
1622  'hidedetails' => $hidedetails,
1623  'hidedesc' => $hidedesc,
1624  'hideref' => $hideref
1625  );
1626 
1627  $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
1628  if ($reshook < 0) {
1629  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1630  } elseif (empty($reshook)) {
1631  $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
1632  } else {
1633  $this->cols = $hookmanager->resArray;
1634  }
1635  }
1636 }
Class to manage bank accounts.
prepareArrayColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Prepare Array Column Field.
getColumnStatus($colKey)
get column status from column key
printStdColumnContent($pdf, &$curY, $colKey, $columnText='')
print standard column content
pdfTabTitles(&$pdf, $tab_top, $tab_height, $outputlangs, $hidetop=0)
Print standard column content.
printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref=0, $hidedesc=0, $issupplierline=0)
print description column content
getColumnContentXStart($colKey)
get column content X (abscissa) left position from column key
printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
Rect pdf.
getExtrafieldContent($object, $extrafieldKey, $outputlangs=null)
get extrafield content for pdf writeHtmlCell compatibility usage for PDF line columns and object note...
defineColumnExtrafield($object, $outputlangs, $hidedetails=0)
Define Array Column Field for extrafields.
Class to manage hooks.
Parent class for orders models.
Class to manage products or services.
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:47
Class to generate PDF orders with template Eagle.
drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
Show total to pay.
drawInfoTable(&$pdf, $object, $posy, $outputlangs)
Show miscellaneous information (payment mode, payment term, ...)
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
Show table for lines.
_pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey="StockTransferSheetProforma")
Show top header of page.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
Show payments table.
defineColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Define Array Column Field.
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
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...
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
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.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
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...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
isModEnabled($module)
Is Dolibarr module enabled.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
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:2514
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition: pdf.lib.php:288
pdf_getFormat(Translate $outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition: pdf.lib.php:84
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition: pdf.lib.php:313
pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails=0, $hidefreetext=0, $page_largeur=0, $watermark='')
Show footer of page for PDF generation.
Definition: pdf.lib.php:1001
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition: pdf.lib.php:1886
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition: pdf.lib.php:1824
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0, $hookmanager=false)
Return line unit.
Definition: pdf.lib.php:2132
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:749
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition: pdf.lib.php:723
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition: pdf.lib.php:1323
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank informations for PDF generation.
Definition: pdf.lib.php:824
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition: pdf.lib.php:265
pdf_build_address($outputlangs, $sourcecompany, $targetcompany='', $targetcontact='', $usecontact=0, $mode='source', $object=null)
Return a string with full address formated for output on documents.
Definition: pdf.lib.php:434
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition: pdf.lib.php:2175
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition: pdf.lib.php:1971
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition: pdf.lib.php:126
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition: pdf.lib.php:386
pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition: pdf.lib.php:769
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:119
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:122
$conf db
API class for accounts.
Definition: inc.php:41