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