dolibarr  19.0.0-dev
pdf_beluga.modules.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com>
3  * Copyright (C) 2015-2018 Charlene Benke <charlie@patas-monkey.com>
4  * Copyright (C) 2018 Laurent Destailleur <eldy@users.sourceforge.net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  * or see https://www.gnu.org/
19  */
20 
27 require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
28 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
36 
37 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
38 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
39 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
40 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
41 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
42 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
43 require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
44 require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
45 require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
46 require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
47 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
48 
49 
50 
56 {
60  public $db;
61 
65  public $name;
66 
70  public $description;
71 
75  public $update_main_doc_field;
76 
80  public $type;
81 
86  public $version = 'dolibarr';
87 
91  public $page_largeur;
92 
96  public $page_hauteur;
97 
101  public $format;
102 
106  public $marge_gauche;
107 
111  public $marge_droite;
112 
116  public $marge_haute;
117 
121  public $marge_basse;
122 
127  private $orientation;
128 
133  public $emetteur;
134 
135  public $posxref;
136  public $posxdate;
137  public $posxsociete;
138  public $posxamountht;
139  public $posxamountttc;
140  public $posstatut;
141 
142 
148  public function __construct($db)
149  {
150  global $conf, $langs, $mysoc;
151 
152  // Translations
153  $langs->loadLangs(array("main", "projects", "companies"));
154 
155  $this->db = $db;
156  $this->name = "beluga";
157  $this->description = $langs->trans("DocumentModelBeluga");
158  $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
159 
160  // Page size for A4 format
161  $this->type = 'pdf';
162  $formatarray = pdf_getFormat();
163  $this->orientation = 'L';
164  if ($this->orientation == 'L' || $this->orientation == 'Landscape') {
165  $this->page_largeur = $formatarray['height'];
166  $this->page_hauteur = $formatarray['width'];
167  } else {
168  $this->page_largeur = $formatarray['width'];
169  $this->page_hauteur = $formatarray['height'];
170  }
171  $this->format = array($this->page_largeur, $this->page_hauteur);
172  $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
173  $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
174  $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
175  $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
176 
177  $this->option_logo = 1; // Display logo FAC_PDF_LOGO
178  $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
179 
180  // Get source company
181  $this->emetteur = $mysoc;
182  if (!$this->emetteur->country_code) {
183  $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default if not defined
184  }
185 
186  // Define position of columns
187  if ($this->orientation == 'L' || $this->orientation == 'Landscape') {
188  $this->posxref = $this->marge_gauche + 1;
189  $this->posxdate = $this->marge_gauche + 105;
190  $this->posxsociety = $this->marge_gauche + 126;
191  $this->posxamountht = $this->marge_gauche + 190;
192  $this->posxamountttc = $this->marge_gauche + 215;
193  $this->posxstatut = $this->marge_gauche + 245;
194  } else {
195  $this->posxref = $this->marge_gauche + 1;
196  $this->posxdate = $this->marge_gauche + 25;
197  $this->posxsociety = $this->marge_gauche + 46;
198  $this->posxamountht = $this->marge_gauche + 110;
199  $this->posxamountttc = $this->marge_gauche + 135;
200  $this->posxstatut = $this->marge_gauche + 165;
201  }
202  if ($this->page_largeur < 210) { // To work with US executive format
203  $this->posxref -= 20;
204  $this->posxdate -= 20;
205  $this->posxsociete -= 20;
206  $this->posxamountht -= 20;
207  $this->posxamountttc -= 20;
208  $this->posstatut -= 20;
209  }
210  }
211 
212 
213  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
221  public function write_file($object, $outputlangs)
222  {
223  // phpcs:enable
224  global $conf, $hookmanager, $langs, $user;
225 
226  $formproject = new FormProjets($this->db);
227 
228  if (!is_object($outputlangs)) {
229  $outputlangs = $langs;
230  }
231  // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
232  if (!empty($conf->global->MAIN_USE_FPDF)) {
233  $outputlangs->charset_output = 'ISO-8859-1';
234  }
235 
236  // Load traductions files required by page
237  $outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
238 
239  if ($conf->project->multidir_output[$object->entity]) {
240  //$nblines = count($object->lines); // This is set later with array of tasks
241 
242  $objectref = dol_sanitizeFileName($object->ref);
243  $dir = $conf->project->multidir_output[$object->entity];
244  if (!preg_match('/specimen/i', $objectref)) {
245  $dir .= "/".$objectref;
246  }
247  $file = $dir."/".$objectref.".pdf";
248 
249  if (!file_exists($dir)) {
250  if (dol_mkdir($dir) < 0) {
251  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
252  return 0;
253  }
254  }
255 
256  if (file_exists($dir)) {
257  // Add pdfgeneration hook
258  if (!is_object($hookmanager)) {
259  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
260  $hookmanager = new HookManager($this->db);
261  }
262  $hookmanager->initHooks(array('pdfgeneration'));
263  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
264  global $action;
265  $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
266 
267  // Create pdf instance
268  $pdf = pdf_getInstance($this->format);
269  $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
270  $pdf->SetAutoPageBreak(1, 0);
271 
272  $heightforinfotot = 40; // Height reserved to output the info and total part
273  $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
274  $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
275  if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)) {
276  $heightforfooter += 6;
277  }
278 
279  if (class_exists('TCPDF')) {
280  $pdf->setPrintHeader(false);
281  $pdf->setPrintFooter(false);
282  }
283  $pdf->SetFont(pdf_getPDFFont($outputlangs));
284  // Set path to the background PDF File
285  if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) {
286  $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
287  $tplidx = $pdf->importPage(1);
288  }
289 
290  // Complete object by loading several other informations
291  $task = new Task($this->db);
292  $tasksarray = array();
293  $tasksarray = $task->getTasksArray(0, 0, $object->id);
294 
295  // Special case when used with object = specimen, we may return all lines
296  if (!$object->id > 0) {
297  $tasksarray = array_slice($tasksarray, 0, min(5, count($tasksarray)));
298  }
299 
300  $object->lines = $tasksarray;
301  $nblines = count($object->lines);
302 
303  $pdf->Open();
304  $pagenb = 0;
305  $pdf->SetDrawColor(128, 128, 128);
306 
307  $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
308  $pdf->SetSubject($outputlangs->transnoentities("Project"));
309  $pdf->SetCreator("Dolibarr ".DOL_VERSION);
310  $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
311  $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Project"));
312  if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
313  $pdf->SetCompression(false);
314  }
315 
316  $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
317 
318  // New page
319  $pdf->AddPage($this->orientation);
320  if (!empty($tplidx)) {
321  $pdf->useTemplate($tplidx);
322  }
323  $pagenb++;
324  $this->_pagehead($pdf, $object, 1, $outputlangs);
325  $pdf->SetFont('', '', $default_font_size - 1);
326  $pdf->MultiCell(0, 3, ''); // Set interline to 3
327  $pdf->SetTextColor(0, 0, 0);
328 
329  $tab_top = 50;
330  $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 : 10);
331 
332  $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
333 
334  // Show public note
335  $notetoshow = empty($object->note_public) ? '' : $object->note_public;
336  if ($notetoshow) {
337  $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
338  complete_substitutions_array($substitutionarray, $outputlangs, $object);
339  $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
340  $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
341 
342  $tab_top -= 2;
343 
344  $pdf->SetFont('', '', $default_font_size - 1);
345  $pdf->writeHTMLCell(190, 3, $this->posxref - 1, $tab_top - 2, dol_htmlentitiesbr($notetoshow), 0, 1);
346  $nexY = $pdf->GetY();
347  $height_note = $nexY - $tab_top;
348 
349  // Rect takes a length in 3rd parameter
350  $pdf->SetDrawColor(192, 192, 192);
351  $pdf->Rect($this->marge_gauche, $tab_top - 2, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 2);
352 
353  $tab_height = $tab_height - $height_note;
354  $tab_top = $nexY + 6;
355  } else {
356  $height_note = 0;
357  }
358 
359  $heightoftitleline = 10;
360  $iniY = $tab_top + $heightoftitleline + 1;
361  $curY = $tab_top + $heightoftitleline + 1;
362  $nexY = $tab_top + $heightoftitleline + 1;
363 
364  $listofreferent = array(
365  'propal'=>array(
366  'name'=>"Proposals",
367  'title'=>"ListProposalsAssociatedProject",
368  'class'=>'Propal',
369  'table'=>'propal',
370  'datefieldname'=>'datep',
371  'test'=> isModEnabled('propal') && $user->hasRight('propal', 'lire'),
372  'lang'=>'propal'),
373  'order'=>array(
374  'name'=>"CustomersOrders",
375  'title'=>"ListOrdersAssociatedProject",
376  'class'=>'Commande',
377  'table'=>'commande',
378  'datefieldname'=>'date_commande',
379  'test'=> isModEnabled('commande') && $user->hasRight('commande', 'lire'),
380  'lang'=>'orders'),
381  'invoice'=>array(
382  'name'=>"CustomersInvoices",
383  'title'=>"ListInvoicesAssociatedProject",
384  'class'=>'Facture',
385  'margin'=>'add',
386  'table'=>'facture',
387  'datefieldname'=>'datef',
388  'test'=> isModEnabled('facture') && $user->hasRight('facture', 'lire'),
389  'lang'=>'bills'),
390  'invoice_predefined'=>array(
391  'name'=>"PredefinedInvoices",
392  'title'=>"ListPredefinedInvoicesAssociatedProject",
393  'class'=>'FactureRec',
394  'table'=>'facture_rec',
395  'datefieldname'=>'datec',
396  'test'=> isModEnabled('facture') && $user->hasRight('facture', 'lire'),
397  'lang'=>'bills'),
398  'order_supplier'=>array(
399  'name'=>"SuppliersOrders",
400  'title'=>"ListSupplierOrdersAssociatedProject",
401  'class'=>'CommandeFournisseur',
402  'table'=>'commande_fournisseur',
403  'datefieldname'=>'date_commande',
404  'test'=>(isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->commande->lire) || (isModEnabled("supplier_order") && $user->rights->supplier_order->lire),
405  'lang'=>'orders'),
406  'invoice_supplier'=>array(
407  'name'=>"BillsSuppliers",
408  'title'=>"ListSupplierInvoicesAssociatedProject",
409  'class'=>'FactureFournisseur',
410  'margin'=>'minus',
411  'table'=>'facture_fourn',
412  'datefieldname'=>'datef',
413  'test'=>(isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (isModEnabled("supplier_invoice") && $user->rights->supplier_invoice->lire),
414  'lang'=>'bills'),
415  'contract'=>array(
416  'name'=>"Contracts",
417  'title'=>"ListContractAssociatedProject",
418  'class'=>'Contrat',
419  'table'=>'contrat',
420  'datefieldname'=>'date_contrat',
421  'test'=> isModEnabled('contrat') && $user->hasRight('contrat', 'lire'),
422  'lang'=>'contract'),
423  'intervention'=>array(
424  'name'=>"Interventions",
425  'title'=>"ListFichinterAssociatedProject",
426  'class'=>'Fichinter',
427  'table'=>'fichinter',
428  'datefieldname'=>'date_valid',
429  'disableamount'=>1,
430  'test'=>isModEnabled('ficheinter') && $user->hasRight('ficheinter', 'lire'),
431  'lang'=>'interventions'),
432  'trip'=>array(
433  'name'=>"TripsAndExpenses",
434  'title'=>"ListExpenseReportsAssociatedProject",
435  'class'=>'Deplacement',
436  'table'=>'deplacement',
437  'datefieldname'=>'dated',
438  'margin'=>'minus',
439  'disableamount'=>1,
440  'test'=>isModEnabled('deplacement') && $user->rights->deplacement->lire,
441  'lang'=>'trip'),
442  'expensereport'=>array(
443  'name'=>"ExpensesReports",
444  'title'=>"ListExpenseReportsAssociatedProject",
445  'class'=>'ExpenseReport',
446  'table'=>'expensereport',
447  'datefieldname'=>'dated',
448  'margin'=>'minus',
449  'disableamount'=>1,
450  'test'=>isModEnabled('expensereport') && $user->rights->expensereport->lire,
451  'lang'=>'trip'),
452  'agenda'=>array(
453  'name'=>"Agenda",
454  'title'=>"ListActionsAssociatedProject",
455  'class'=>'ActionComm',
456  'table'=>'actioncomm',
457  'datefieldname'=>'datep',
458  'disableamount'=>1,
459  'test'=> isModEnabled('agenda') && $user->rights->agenda->allactions->read,
460  'lang'=>'agenda')
461  );
462 
463  $hookmanager->initHooks(array('completeListOfReferent'));
464  $hookmanager->executeHooks('completeListOfReferent', ['listofreferent'=>$listofreferent], $object, $action);
465  if (!empty($hookmanager->resArray)) {
466  $listofreferent = array_merge($listofreferent, $hookmanager->resArray);
467  }
468 
469  foreach ($listofreferent as $key => $value) {
470  $title = $value['title'];
471  $classname = $value['class'];
472  $tablename = $value['table'];
473  $datefieldname = $value['datefieldname'];
474  $qualified = $value['test'];
475  $langstoload = $value['lang'];
476  $projectField = isset($value['project_field']) ? $value['project_field'] : 'fk_projet';
477  $langs->load($langstoload);
478 
479  if (!$qualified) {
480  continue;
481  }
482 
483  //var_dump("$key, $tablename, $datefieldname, $dates, $datee");
484  $elementarray = $object->get_element_list($key, $tablename, $datefieldname, '', '', $projectField);
485 
486  $num = count($elementarray);
487  if ($num >= 0) {
488  $nexY = $pdf->GetY() + 5;
489 
490  $curY = $nexY;
491  $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
492  $pdf->SetTextColor(0, 0, 0);
493 
494  $pdf->SetXY($this->posxref, $curY);
495  $pdf->MultiCell($this->posxstatut - $this->posxref, 3, $outputlangs->transnoentities($title), 0, 'L');
496 
497  $selectList = $formproject->select_element($tablename, $object->thirdparty->id, '', -2, $projectField);
498  $nexY = $pdf->GetY() + 1;
499  $curY = $nexY;
500  $pdf->SetXY($this->posxref, $curY);
501  $pdf->MultiCell($this->posxdate - $this->posxref, 3, $outputlangs->transnoentities("Ref"), 1, 'L');
502  $pdf->SetXY($this->posxdate, $curY);
503  $pdf->MultiCell($this->posxsociety - $this->posxdate, 3, $outputlangs->transnoentities("Date"), 1, 'C');
504  $pdf->SetXY($this->posxsociety, $curY);
505  $titlethirdparty = $outputlangs->transnoentities("ThirdParty");
506  if ($classname == 'ExpenseReport') {
507  $titlethirdparty = $langs->trans("User");
508  }
509  $pdf->MultiCell($this->posxamountht - $this->posxsociety, 3, $titlethirdparty, 1, 'L');
510  if (empty($value['disableamount'])) {
511  $pdf->SetXY($this->posxamountht, $curY);
512  $pdf->MultiCell($this->posxamountttc - $this->posxamountht, 3, $outputlangs->transnoentities("AmountHTShort"), 1, 'R');
513  $pdf->SetXY($this->posxamountttc, $curY);
514  $pdf->MultiCell($this->posxstatut - $this->posxamountttc, 3, $outputlangs->transnoentities("AmountTTCShort"), 1, 'R');
515  } else {
516  $pdf->SetXY($this->posxamountht, $curY);
517  $pdf->MultiCell($this->posxstatut - $this->posxamountht, 3, "", 1, 'R');
518  }
519  $pdf->SetXY($this->posxstatut, $curY);
520  $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxstatut, 3, $outputlangs->transnoentities("Status"), 1, 'R');
521 
522  if (is_array($elementarray) && count($elementarray) > 0) {
523  $nexY = $pdf->GetY();
524 
525  $total_ht = 0;
526  $total_ttc = 0;
527  $num = count($elementarray);
528 
529  // Loop on each lines
530  for ($i = 0; $i < $num; $i++) {
531  $curY = $nexY;
532  $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
533  $pdf->SetTextColor(0, 0, 0);
534 
535  $pdf->setTopMargin($tab_top_newpage);
536  $pdf->setPageOrientation($this->orientation, 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
537  $pageposbefore = $pdf->getPage();
538 
539  // Description of line
540  $idofelement = $elementarray[$i];
541  if ($classname == 'ExpenseReport') {
542  // We get id of expense report
543  $expensereportline = new ExpenseReportLine($this->db);
544  $expensereportline->fetch($idofelement);
545  $idofelement = $expensereportline->fk_expensereport;
546  }
547 
548  $element = new $classname($this->db);
549  $element->fetch($idofelement);
550  $element->fetch_thirdparty();
551  // print $classname;
552 
553  $qualifiedfortotal = true;
554  if ($key == 'invoice') {
555  if ($element->close_code == 'replaced') {
556  $qualifiedfortotal = false; // Replacement invoice
557  }
558  }
559 
560  $showpricebeforepagebreak = 1;
561 
562  $pdf->startTransaction();
563  // Label
564  $pdf->SetXY($this->posxref, $curY);
565  $pdf->MultiCell($this->posxdate - $this->posxref, 3, $element->ref, 1, 'L');
566  $pageposafter = $pdf->getPage();
567  if ($pageposafter > $pageposbefore) { // There is a pagebreak
568  $pdf->rollbackTransaction(true);
569  $pageposafter = $pageposbefore;
570  //print $pageposafter.'-'.$pageposbefore;exit;
571  $pdf->setPageOrientation($this->orientation, 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
572  // Label
573  $pdf->SetXY($this->posxref, $curY);
574  $posybefore = $pdf->GetY();
575  $pdf->MultiCell($this->posxdate - $this->posxref, 3, $element->ref, 1, 'L');
576  $pageposafter = $pdf->getPage();
577  $posyafter = $pdf->GetY();
578  if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
579  if ($i == ($num - 1)) { // No more lines, and no space left to show total, so we create a new page
580  $pdf->AddPage($this->orientation, '', true);
581  if (!empty($tplidx)) {
582  $pdf->useTemplate($tplidx);
583  }
584  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
585  $this->_pagehead($pdf, $object, 0, $outputlangs);
586  }
587  $pdf->setPage($pageposafter + 1);
588  }
589  } else {
590  // We found a page break
591 
592  // Allows data in the first page if description is long enough to break in multiples pages
593  if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
594  $showpricebeforepagebreak = 1;
595  } else {
596  $showpricebeforepagebreak = 0;
597  }
598 
599  $forcedesconsamepage = 1;
600  if ($forcedesconsamepage) {
601  $pdf->rollbackTransaction(true);
602  $pageposafter = $pageposbefore;
603  $pdf->setPageOrientation($this->orientation, 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
604 
605  $pdf->AddPage($this->orientation, '', true);
606  if (!empty($tplidx)) {
607  $pdf->useTemplate($tplidx);
608  }
609  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
610  $this->_pagehead($pdf, $object, 0, $outputlangs);
611  }
612  $pdf->setPage($pageposafter + 1);
613  $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut
614  $pdf->MultiCell(0, 3, ''); // Set interline to 3
615  $pdf->SetTextColor(0, 0, 0);
616 
617  $pdf->setPageOrientation($this->orientation, 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
618  $curY = $tab_top_newpage + $heightoftitleline + 1;
619 
620  // Label
621  $pdf->SetXY($this->posxref, $curY);
622  $posybefore = $pdf->GetY();
623  $pdf->MultiCell($this->posxdate - $this->posxref, 3, $element->ref, 1, 'L');
624  $pageposafter = $pdf->getPage();
625  $posyafter = $pdf->GetY();
626  }
627  }
628  //var_dump($i.' '.$posybefore.' '.$posyafter.' '.($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot)).' '.$showpricebeforepagebreak);
629  } else // No pagebreak
630  {
631  $pdf->commitTransaction();
632  }
633  $posYAfterDescription = $pdf->GetY();
634 
635  $nexY = $pdf->GetY();
636  $pageposafter = $pdf->getPage();
637  $pdf->setPage($pageposbefore);
638  $pdf->setTopMargin($this->marge_haute);
639  $pdf->setPageOrientation($this->orientation, 1, 0); // The only function to edit the bottom margin of current page to set it.
640 
641  // We suppose that a too long description is moved completely on next page
642  if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
643  //var_dump($pageposbefore.'-'.$pageposafter.'-'.$showpricebeforepagebreak);
644  $pdf->setPage($pageposafter);
645  $curY = $tab_top_newpage + $heightoftitleline + 1;
646  }
647 
648  $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut
649 
650  // Date
651  if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_order') {
652  $date = $element->date_commande;
653  } else {
654  $date = $element->date;
655  if (empty($date)) {
656  $date = $element->datep;
657  }
658  if (empty($date)) {
659  $date = $element->date_contrat;
660  }
661  if (empty($date)) {
662  $date = $element->datev; // Fiche inter
663  }
664  }
665 
666  $pdf->SetXY($this->posxdate, $curY);
667  $pdf->MultiCell($this->posxsociety - $this->posxdate, 3, dol_print_date($date, 'day'), 1, 'C');
668 
669  $pdf->SetXY($this->posxsociety, $curY);
670  if ($classname == 'ExpenseReport') {
671  $fuser = new User($this->db);
672  $fuser->fetch($element->fk_user_author);
673  $pdf->MultiCell($this->posxamountht - $this->posxsociety, 3, $fuser->getFullName($outputlangs), 1, 'L');
674  } else {
675  $pdf->MultiCell($this->posxamountht - $this->posxsociety, 3, (is_object($element->thirdparty) ? $element->thirdparty->name : ''), 1, 'L');
676  }
677 
678  // Amount without tax
679  if (empty($value['disableamount'])) {
680  $pdf->SetXY($this->posxamountht, $curY);
681  $pdf->MultiCell($this->posxamountttc - $this->posxamountht, 3, (isset($element->total_ht) ? price($element->total_ht) : ''), 1, 'R');
682  $pdf->SetXY($this->posxamountttc, $curY);
683  $pdf->MultiCell($this->posxstatut - $this->posxamountttc, 3, (isset($element->total_ttc) ? price($element->total_ttc) : ''), 1, 'R');
684  } else {
685  $pdf->SetXY($this->posxamountht, $curY);
686  if ($key == 'agenda') {
687  $textforamount = dol_trunc($element->label, 26);
688  $pdf->MultiCell($this->posxstatut - $this->posxamountht, 3, $textforamount, 1, 'L');
689  } else {
690  $pdf->MultiCell($this->posxstatut - $this->posxamountht, 3, "", 1, 'R');
691  }
692  }
693 
694  // Status
695  if ($element instanceof CommonInvoice) {
696  // This applies for Facture and FactureFournisseur
697  $outputstatut = $element->getLibStatut(1, $element->getSommePaiement());
698  } else {
699  $outputstatut = $element->getLibStatut(1);
700  }
701  $pdf->SetXY($this->posxstatut, $curY);
702  $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxstatut, 3, $outputstatut, 1, 'R', false, 1, '', '', true, 0, true);
703 
704  if ($qualifiedfortotal) {
705  $total_ht = $total_ht + $element->total_ht;
706  $total_ttc = $total_ttc + $element->total_ttc;
707  }
708  $nexY = $pdf->GetY();
709  $curY = $nexY;
710  }
711 
712  if (empty($value['disableamount'])) {
713  $curY = $nexY;
714  $pdf->SetXY($this->posxref, $curY);
715  $pdf->MultiCell($this->posxamountttc - $this->posxref, 3, "TOTAL", 1, 'L');
716  $pdf->SetXY($this->posxamountht, $curY);
717  $pdf->MultiCell($this->posxamountttc - $this->posxamountht, 3, (isset($element->total_ht) ? price($total_ht) : ''), 1, 'R');
718  $pdf->SetXY($this->posxamountttc, $curY);
719  $pdf->MultiCell($this->posxstatut - $this->posxamountttc, 3, (isset($element->total_ttc) ? price($total_ttc) : ''), 1, 'R');
720  $pdf->SetXY($this->posxstatut, $curY);
721  $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxstatut, 3, $outputlangs->transnoentities("Nb")." ".$num, 1, 'L');
722  }
723  $nexY = $pdf->GetY() + 5;
724  $curY = $nexY;
725  }
726  }
727 
728  $nexY += 2; // Add space between lines
729 
730  // Detect if some page were added automatically and output _tableau for past pages
731  while ($pagenb < $pageposafter) {
732  $pdf->setPage($pagenb);
733  $this->_pagefoot($pdf, $object, $outputlangs, 1);
734  $pagenb++;
735  $pdf->setPage($pagenb);
736  $pdf->setPageOrientation($this->orientation, 1, 0); // The only function to edit the bottom margin of current page to set it.
737  if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
738  $this->_pagehead($pdf, $object, 0, $outputlangs);
739  }
740  if (!empty($tplidx)) {
741  $pdf->useTemplate($tplidx);
742  }
743  }
744  }
745 
746  // Pied de page
747  $this->_pagefoot($pdf, $object, $outputlangs);
748  if (method_exists($pdf, 'AliasNbPages')) {
749  $pdf->AliasNbPages();
750  }
751 
752  $pdf->Close();
753 
754  $pdf->Output($file, 'F');
755 
756  // Add pdfgeneration hook
757  $hookmanager->initHooks(array('pdfgeneration'));
758  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
759  global $action;
760  $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
761  if ($reshook < 0) {
762  $this->error = $hookmanager->error;
763  $this->errors = $hookmanager->errors;
764  }
765 
766  dolChmod($file);
767 
768  $this->result = array('fullpath'=>$file);
769 
770  return 1; // No error
771  } else {
772  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
773  return 0;
774  }
775  } else {
776  $this->error = $langs->transnoentities("ErrorConstantNotDefined", "PROJECT_OUTPUTDIR");
777  return 0;
778  }
779  }
780 
781  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
794  protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0)
795  {
796  $heightoftitleline = 10;
797 
798  $default_font_size = pdf_getPDFFontSize($outputlangs);
799 
800  $pdf->SetDrawColor(128, 128, 128);
801 
802  // Draw rect of all tab (title + lines). Rect takes a length in 3rd parameter
803  $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height);
804 
805  // line prend une position y en 3eme param
806  $pdf->line($this->marge_gauche, $tab_top + $heightoftitleline, $this->page_largeur - $this->marge_droite, $tab_top + $heightoftitleline);
807 
808  $pdf->SetTextColor(0, 0, 0);
809  $pdf->SetFont('', '', $default_font_size);
810  }
811 
812  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
822  protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
823  {
824  global $langs, $conf, $mysoc;
825 
826  $default_font_size = pdf_getPDFFontSize($outputlangs);
827 
828  pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
829 
830  $pdf->SetTextColor(0, 0, 60);
831  $pdf->SetFont('', 'B', $default_font_size + 3);
832 
833  $posx = $this->page_largeur - $this->marge_droite - 100;
834  $posy = $this->marge_haute;
835 
836  $pdf->SetXY($this->marge_gauche, $posy);
837 
838  // Logo
839  $logo = $conf->mycompany->dir_output.'/logos/'.$mysoc->logo;
840  if ($mysoc->logo) {
841  if (is_readable($logo)) {
842  $height = pdf_getHeightForLogo($logo);
843  $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
844  } else {
845  $pdf->SetTextColor(200, 0, 0);
846  $pdf->SetFont('', 'B', $default_font_size - 2);
847  $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
848  $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorGoToModuleSetup"), 0, 'L');
849  }
850  } else {
851  $pdf->MultiCell(100, 4, $outputlangs->transnoentities($this->emetteur->name), 0, 'L');
852  }
853 
854  $pdf->SetFont('', 'B', $default_font_size + 3);
855  $pdf->SetXY($posx, $posy);
856  $pdf->SetTextColor(0, 0, 60);
857  $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Project")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R');
858  $pdf->SetFont('', '', $default_font_size + 2);
859 
860  $posy += 6;
861  $pdf->SetXY($posx, $posy);
862  $pdf->SetTextColor(0, 0, 60);
863  $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateStart")." : ".dol_print_date($object->date_start, 'day', false, $outputlangs, true), '', 'R');
864 
865  $posy += 6;
866  $pdf->SetXY($posx, $posy);
867  $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateEnd")." : ".dol_print_date($object->date_end, 'day', false, $outputlangs, true), '', 'R');
868 
869  if (is_object($object->thirdparty)) {
870  $posy += 6;
871  $pdf->SetXY($posx, $posy);
872  $pdf->MultiCell(100, 4, $outputlangs->transnoentities("ThirdParty")." : ".$object->thirdparty->getFullName($outputlangs), '', 'R');
873  }
874 
875  $pdf->SetTextColor(0, 0, 60);
876  }
877 
878  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
888  protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
889  {
890  $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
891  return pdf_pagefoot($pdf, $outputlangs, 'PROJECT_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
892  }
893 }
Superclass for invoices classes.
Class of expense report details lines.
Class to manage building of HTML components.
Class to manage hooks.
Parent class for projects models.
Class to manage tasks.
Definition: task.class.php:40
Class to manage Dolibarr users.
Definition: user.class.php:48
Class to manage generation of project document Beluga.
write_file($object, $outputlangs)
Fonction generant le projet sur le disque.
__construct($db)
Constructor.
_pagehead(&$pdf, $object, $showaddress, $outputlangs)
Show top header of page.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
Show table for lines.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
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...
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).
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
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...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
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.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition: pdf.lib.php:289
pdf_getFormat(Translate $outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition: pdf.lib.php:85
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition: pdf.lib.php:314
pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails=0, $hidefreetext=0, $page_largeur=0, $watermark='')
Show footer of page for PDF generation.
Definition: pdf.lib.php:1005
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition: pdf.lib.php:721
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition: pdf.lib.php:266
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:753
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition: pdf.lib.php:127
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:120
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:123