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