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