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