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