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