dolibarr 24.0.0-beta
pdf_standard_expensereport.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2015 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
4 * Copyright (C) 2016-2023 Philippe Grand <philippe.grand@atoo-net.com>
5 * Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
6 * Copyright (C) 2018 Francis Appels <francis.appels@z-application.com>
7 * Copyright (C) 2019 Markus Welters <markus@welters.de>
8 * Copyright (C) 2019 Rafael Ingenleuf <ingenleuf@welters.de>
9 * Copyright (C) 2020 Marc Guenneugues <marc.guenneugues@simicar.fr>
10 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
11 * Copyright (C) 2024 Nick Fragoulis
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 * or see https://www.gnu.org/
26 */
27
34require_once DOL_DOCUMENT_ROOT.'/core/modules/expensereport/modules_expensereport.php';
35require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
36require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
41require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
42require_once DOL_DOCUMENT_ROOT.'/user/class/userbankaccount.class.php';
43
48{
52 public $db;
53
57 public $name;
58
62 public $description;
63
67 public $update_main_doc_field;
68
72 public $type;
73
78 public $version = 'dolibarr';
79
83 public $posxpiece;
87 public $posxcomment;
91 public $posxtva;
95 public $posxup;
99 public $posxqty;
103 public $posxtype;
104
108 public $posxdate;
112 public $posxprojet;
116 public $postotalht;
120 public $postotalttc;
121
122
128 public function __construct($db)
129 {
130 global $conf, $langs, $mysoc, $user;
131
132 // Translations
133 $langs->loadLangs(array("main", "trips", "projects"));
134
135 $this->db = $db;
136 $this->name = "";
137 $this->description = $langs->trans('PDFStandardExpenseReports');
138 $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
139
140 // Page size for A4 format
141 $this->type = 'pdf';
142 $formatarray = pdf_getFormat();
143 $this->page_largeur = $formatarray['width'];
144 $this->page_hauteur = $formatarray['height'];
145 $this->format = array($this->page_largeur, $this->page_hauteur);
146 $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
147 $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
148 $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
149 $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
150 $this->corner_radius = getDolGlobalInt('MAIN_PDF_FRAME_CORNER_RADIUS', 0);
151 $this->option_logo = 1; // Display logo
152 $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
153 $this->option_modereg = 1; // Display payment mode
154 $this->option_condreg = 1; // Display payment terms
155 $this->option_multilang = 1; // Available in several languages
156 $this->option_escompte = 0; // Displays if there has been a discount
157 $this->option_credit_note = 0; // Support credit notes
158 $this->option_freetext = 1; // Support add of a personalised text
159 $this->option_draft_watermark = 1; // Support add of a watermark on drafts
160
161 // Define position of columns
162 $this->posxpiece = $this->marge_gauche + 1;
163 $this->posxcomment = $this->marge_gauche + 10;
164 //$this->posxdate=88;
165 //$this->posxtype=107;
166 //$this->posxprojet=120;
167 $this->posxtva = 100;
168 $this->posxup = 120;
169 $this->posxqty = 146;
170 $this->postotalht = 154;
171 $this->postotalttc = 178;
172 // if (!isModEnabled('project')) {
173 // $this->posxtva-=20;
174 // $this->posxup-=20;
175 // $this->posxqty-=20;
176 // $this->postotalttc-=20;
177 // }
178 if ($this->page_largeur < 210) { // To work with US executive format
179 $this->posxdate -= 20;
180 $this->posxtype -= 20;
181 $this->posxprojet -= 20;
182 $this->posxtva -= 20;
183 $this->posxup -= 20;
184 $this->posxqty -= 20;
185 $this->postotalttc -= 20;
186 }
187
188 $this->tva = array();
189 $this->tva_array = array();
190 $this->localtax1 = array();
191 $this->localtax2 = array();
192 $this->atleastoneratenotnull = 0;
193 $this->atleastonediscount = 0;
194
195 if ($mysoc === null) {
196 dol_syslog(get_class($this).'::__construct() Global $mysoc should not be null.'. getCallerInfoString(), LOG_ERR);
197 return;
198 }
199
200 // Get source company
201 $this->emetteur = $mysoc;
202
203 if (empty($this->emetteur->country_code)) {
204 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
205 }
206 }
207
208
209 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
221 public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
222 {
223 // phpcs:enable
224 global $user, $langs, $conf, $mysoc, $db, $hookmanager;
225
226 if (!is_object($outputlangs)) {
227 $outputlangs = $langs;
228 }
229 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
230 if (getDolGlobalString('MAIN_USE_FPDF')) {
231 $outputlangs->charset_output = 'ISO-8859-1';
232 }
233
234 // Load traductions files required by page
235 $outputlangs->loadLangs(array("main", "trips", "projects", "dict", "bills", "banks"));
236
237 $nblines = count($object->lines);
238
239 if ($conf->expensereport->dir_output) {
240 // Definition of $dir and $file
241 if ($object->specimen) {
242 $dir = $conf->expensereport->dir_output;
243 $file = $dir."/SPECIMEN.pdf";
244 } else {
245 $objectref = dol_sanitizeFileName($object->ref);
246 $dir = $conf->expensereport->dir_output."/".$objectref;
247 $file = $dir."/".$objectref.".pdf";
248 }
249
250 if (!file_exists($dir)) {
251 if (dol_mkdir($dir) < 0) {
252 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
253 return 0;
254 }
255 }
256
257 if (file_exists($dir)) {
258 // Add pdfgeneration hook
259 if (!is_object($hookmanager)) {
260 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
261 $hookmanager = new HookManager($this->db);
262 }
263 $hookmanager->initHooks(array('pdfgeneration'));
264 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
265 global $action;
266 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
267
268 // Create pdf instance
269 $pdf = pdf_getInstance($this->format);
270 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
271 $heightforinfotot = 40; // Height reserved to output the info and total part
272 $heightforfreetext = getDolGlobalInt('MAIN_PDF_FREETEXT_HEIGHT', 5); // Height reserved to output the free text on last page
273 $heightforfooter = $this->marge_basse + 12; // Height reserved to output the footer (value include bottom margin)
274 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
275 $heightforfooter += 6;
276 }
277
278 $pdf->setAutoPageBreak(true, 0);
279
280 if (class_exists('TCPDF')) {
281 $pdf->setPrintHeader(false);
282 $pdf->setPrintFooter(false);
283 }
284 $pdf->SetFont(pdf_getPDFFont($outputlangs));
285 // Set path to the background PDF File
286 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND')) {
287 $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/' . getDolGlobalString('MAIN_ADD_PDF_BACKGROUND'));
288 $tplidx = $pdf->importPage(1);
289 }
290
291 $pdf->Open();
292 $pagenb = 0;
293 $pdf->SetDrawColor(128, 128, 128);
294
295 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
296 $pdf->SetSubject($outputlangs->transnoentities("Trips"));
297 $pdf->SetCreator("Dolibarr ".DOL_VERSION);
298 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getAnonymisableFullName($outputlangs)));
299 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Trips"));
300 if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
301 $pdf->SetCompression(false);
302 }
303
304 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
305 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
306
307 // New page
308 $pdf->AddPage();
309 if (!empty($tplidx)) {
310 $pdf->useTemplate($tplidx);
311 }
312 $pagenb++;
313 $this->_pagehead($pdf, $object, 1, $outputlangs);
314 $pdf->SetFont('', '', $default_font_size - 1);
315 $pdf->MultiCell(0, 3, ''); // Set interline to 3
316 $pdf->SetTextColor(0, 0, 0);
317
318 $tab_top = 95;
319 $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 65 : 10);
320
321 $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
322
323 // Show notes
324 $notetoshow = empty($object->note_public) ? '' : $object->note_public;
325 if (getDolGlobalString('MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE')) {
326 // Get first sale rep
327 if (is_object($object->thirdparty)) {
328 $salereparray = $object->thirdparty->getSalesRepresentatives($user);
329 $salerepobj = new User($this->db);
330 $salerepobj->fetch($salereparray[0]['id']);
331 if (!empty($salerepobj->signature)) {
332 $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
333 }
334 }
335 }
336 if ($notetoshow) {
337 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
338 complete_substitutions_array($substitutionarray, $outputlangs, $object);
339 $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
340 $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
341
342 $tab_top = 95;
343
344 $pdf->SetFont('', '', $default_font_size - 1);
345 $pdf->writeHTMLCell(190, 3, $this->posxpiece - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
346 $nexY = $pdf->GetY();
347 $height_note = $nexY - $tab_top;
348
349 // Rect takes a length in 3rd parameter
350 $pdf->SetDrawColor(192, 192, 192);
351 $pdf->RoundedRect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 1, $this->corner_radius, '1234', 'D');
352
353 $tab_height -= $height_note;
354 $tab_top = $nexY + 6;
355 } else {
356 $height_note = 0;
357 }
358
359 $iniY = $tab_top + 7;
360 $nexY = $tab_top + 7;
361
362 $showpricebeforepagebreak = 1;
363 $pdf->setTopMargin($tab_top_newpage);
364 // Loop on each lines
365 $i = 0;
366 while ($i < $nblines) {
367 $pdf->SetFont('', '', $default_font_size - 2); // Into loop to work with multipage
368 $pdf->SetTextColor(0, 0, 0);
369
370 $pdf->setTopMargin($tab_top_newpage);
371 if (empty($showpricebeforepagebreak) && ($i !== ($nblines - 1))) {
372 $pdf->setPageOrientation('', true, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
373 } else {
374 $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
375 }
376
377 $pageposbefore = $pdf->getPage();
378 $curY = $nexY;
379 $pdf->startTransaction();
380 $this->printLine($pdf, $object, $i, $curY, $default_font_size, $outputlangs, $hidedetails);
381 $pageposafter = $pdf->getPage();
382 if ($pageposafter > $pageposbefore) {
383 // There is a pagebreak
384 $pdf->rollbackTransaction(true);
385
386 $pageposafter = $pageposbefore;
387 //print $pageposafter.'-'.$pageposbefore;exit;
388 if (empty($showpricebeforepagebreak)) {
389 $pdf->AddPage('', '', true);
390 if (!empty($tplidx)) {
391 $pdf->useTemplate($tplidx);
392 }
393 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
394 $this->_pagehead($pdf, $object, 0, $outputlangs);
395 }
396 $pdf->setPage($pageposafter + 1);
397 $showpricebeforepagebreak = 1;
398 $nexY = $tab_top_newpage;
399 $nexY += ($pdf->getFontSize() * 1.3); // Add space between lines
400 $pdf->SetFont('', '', $default_font_size - 2); // Into loop to work with multipage
401 $pdf->SetTextColor(0, 0, 0);
402
403 $pdf->setTopMargin($tab_top_newpage);
404 continue;
405 } else {
406 $pdf->setPageOrientation('', true, $heightforfooter);
407 $showpricebeforepagebreak = 0;
408 }
409
410 $this->printLine($pdf, $object, $i, $curY, $default_font_size, $outputlangs, $hidedetails);
411 $pageposafter = $pdf->getPage();
412 $posyafter = $pdf->GetY();
413 //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
414 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) {
415 // There is no space left for total+free text
416 if ($i == ($nblines - 1)) {
417 // No more lines, and no space left to show total, so we create a new page
418 $pdf->AddPage('', '', true);
419 if (!empty($tplidx)) {
420 $pdf->useTemplate($tplidx);
421 }
422 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
423 $this->_pagehead($pdf, $object, 0, $outputlangs);
424 }
425 $pdf->setPage($pageposafter + 1);
426 }
427 } else {
428 // We found a page break
429 // Allows data in the first page if description is long enough to break in multiples pages
430 if (getDolGlobalString('MAIN_PDF_DATA_ON_FIRST_PAGE')) {
431 $showpricebeforepagebreak = 1;
432 } else {
433 $showpricebeforepagebreak = 0;
434 }
435 }
436 } else { // No pagebreak
437 $pdf->commitTransaction();
438 }
439 $i++;
440 //nexY
441 $nexY = $pdf->GetY();
442 $pageposafter = $pdf->getPage();
443 $pdf->setPage($pageposbefore);
444 $pdf->setTopMargin($this->marge_haute);
445 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
446
447 //$nexY+=$nblineFollowComment*($pdf->getFontSize()*1.3); // Add space between lines
448 $nexY += ($pdf->getFontSize() * 1.3); // Add space between lines
449
450 // Detect if some page were added automatically and output _tableau for past pages
451 while ($pagenb < $pageposafter) {
452 $pdf->setPage($pagenb);
453 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
454 if ($pagenb == 1) {
455 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
456 } else {
457 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
458 }
459 $this->_pagefoot($pdf, $object, $outputlangs, 1);
460 $pagenb++;
461 $pdf->setPage($pagenb);
462 $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it.
463 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
464 $this->_pagehead($pdf, $object, 0, $outputlangs);
465 }
466 if (!empty($tplidx)) {
467 $pdf->useTemplate($tplidx);
468 }
469 }
470 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { // @phan-suppress-current-line PhanUndeclaredProperty
471 if ($pagenb == 1) {
472 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
473 } else {
474 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
475 }
476 $this->_pagefoot($pdf, $object, $outputlangs, 1);
477 // New page
478 $pdf->AddPage();
479 if (!empty($tplidx)) {
480 $pdf->useTemplate($tplidx);
481 }
482 $pagenb++;
483 if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
484 $this->_pagehead($pdf, $object, 0, $outputlangs);
485 }
486 }
487 }
488
489 // Show square
490 if ($pagenb == 1) {
491 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0);
492 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
493 } else {
494 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0);
495 $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
496 }
497
498 $pdf->SetFont('', '', 10);
499
500 // Show total area box
501 $posy = $bottomlasttab + 5;
502 $posy_start_of_totals = $posy;
503 $pdf->SetXY(120, $posy);
504 $pdf->MultiCell(40, 5, $outputlangs->transnoentities("TotalHT"), 1, 'L');
505 $pdf->SetXY(160, $posy);
506 $pdf->MultiCell($this->page_largeur - $this->marge_gauche - 160, 5, price($object->total_ht), 1, 'C');
507 $pdf->SetFillColor(248, 248, 248);
508
509 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
510 // TODO Show vat amount per tax level
511 $posy += 5;
512 $pdf->SetXY(120, $posy);
513 $pdf->SetTextColor(0, 0, 60);
514 $pdf->MultiCell(40, 5, $outputlangs->transnoentities("TotalVAT"), 1, 'L');
515 $pdf->SetXY(160, $posy);
516 $pdf->MultiCell($this->page_largeur - $this->marge_gauche - 160, 5, price($object->total_tva), 1, 'C');
517 }
518
519 $posy += 5;
520 $pdf->SetXY(120, $posy);
521 $pdf->SetFont('', 'B', 10);
522 $pdf->SetTextColor(0, 0, 60);
523 $pdf->MultiCell(40, 5, $outputlangs->transnoentities("TotalTTC"), 1, 'L');
524 $pdf->SetXY(160, $posy);
525 $pdf->MultiCell($this->page_largeur - $this->marge_gauche - 160, 5, price($object->total_ttc), 1, 'C');
526
527 // show payments zone
528 $sumPayments = $object->getSumPayments();
529 if ($sumPayments > 0 && !getDolGlobalString('PDF_EXPENSEREPORT_NO_PAYMENT_DETAILS')) {
530 $posy = $this->tablePayments($pdf, $object, $posy_start_of_totals, $outputlangs);
531 }
532
533 // Page footer
534 $this->_pagefoot($pdf, $object, $outputlangs);
535 if (method_exists($pdf, 'AliasNbPages')) {
536 $pdf->AliasNbPages(); // @phan-suppress-current-line PhanUndeclaredMethod
537 }
538
539 $pdf->Close();
540
541 $pdf->Output($file, 'F');
542
543 // Add pdfgeneration hook
544 $hookmanager->initHooks(array('pdfgeneration'));
545 $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs);
546 global $action;
547 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
548 $this->warnings = $hookmanager->warnings;
549 if ($reshook < 0) {
550 $this->error = $hookmanager->error;
551 $this->errors = $hookmanager->errors;
552 dolChmod($file);
553 return -1;
554 }
555
556 dolChmod($file);
557
558 $this->result = array('fullpath' => $file);
559
560 return 1; // No error
561 } else {
562 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
563 return 0;
564 }
565 } else {
566 $this->error = $langs->trans("ErrorConstantNotDefined", "EXPENSEREPORT_OUTPUTDIR");
567 return 0;
568 }
569 }
570
581 protected function printLine(&$pdf, $object, $linenumber, $curY, $default_font_size, $outputlangs, $hidedetails = 0)
582 {
583 global $conf;
584 $pdf->SetFont('', '', $default_font_size - 1);
585 $pdf->SetTextColor(0, 0, 0);
586
587 // Accountancy piece
588 $pdf->SetXY($this->posxpiece, $curY);
589 $pdf->writeHTMLCell($this->posxcomment - $this->posxpiece - 0.8, 4, $this->posxpiece - 1, $curY, (string) ($linenumber + 1), 0, 1);
590
591 // Date
592 //$pdf->SetXY($this->posxdate -1, $curY);
593 //$pdf->MultiCell($this->posxtype-$this->posxdate-0.8, 4, dol_print_date($object->lines[$linenumber]->date,"day",false,$outputlangs), 0, 'C');
594
595 // Type
596 $pdf->SetXY($this->posxtype - 1, $curY);
597 $nextColumnPosX = $this->posxup;
598 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
599 $nextColumnPosX = $this->posxtva;
600 }
601 if (isModEnabled('project')) {
602 $nextColumnPosX = $this->posxprojet;
603 }
604
605 $expensereporttypecode = $object->lines[$linenumber]->type_fees_code;
606 $expensereporttypecodetoshow = ($outputlangs->trans(($expensereporttypecode)) == $expensereporttypecode ? $object->lines[$linenumber]->type_fees_libelle : $outputlangs->trans($expensereporttypecode));
607
608
609 if ($expensereporttypecodetoshow == $expensereporttypecode) {
610 $expensereporttypecodetoshow = preg_replace('/^(EX_|TF_)/', '', $expensereporttypecodetoshow);
611 }
612 //$expensereporttypecodetoshow = dol_trunc($expensereporttypecodetoshow, 9);
613
614 //$pdf->MultiCell($nextColumnPosX-$this->posxtype-0.8, 4, $expensereporttypecodetoshow, 0, 'C');
615
616 // Project
617 //if (isModEnabled('project'))
618 //{
619 // $pdf->SetFont('','', $default_font_size - 1);
620 // $pdf->SetXY($this->posxprojet, $curY);
621 // $pdf->MultiCell($this->posxtva-$this->posxprojet-0.8, 4, $object->lines[$linenumber]->projet_ref, 0, 'C');
622 //}
623
624 // VAT Rate
625 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
626 $vat_rate = pdf_getlinevatrate($object, $linenumber, $outputlangs, $hidedetails);
627 $pdf->SetXY($this->posxtva, $curY);
628 $pdf->MultiCell($this->posxup - $this->posxtva - 0.8, 4, $vat_rate, 0, 'C');
629 }
630
631 // Unit price
632 $pdf->SetXY($this->posxup, $curY);
633 $pdf->MultiCell($this->posxqty - $this->posxup - 0.8, 4, price($object->lines[$linenumber]->value_unit), 0, 'C');
634
635 // Quantity
636 $pdf->SetXY($this->posxqty, $curY);
637 $pdf->MultiCell($this->postotalht - $this->posxqty - 0.8, 4, (string) $object->lines[$linenumber]->qty, 0, 'C');
638
639 // Total without taxes
640 $pdf->SetXY($this->postotalht, $curY);
641 $pdf->MultiCell($this->postotalttc - $this->postotalht - 0.8, 4, price($object->lines[$linenumber]->total_ht), 0, 'C');
642
643 // Total with all taxes
644 $pdf->SetXY($this->postotalttc - 1, $curY);
645 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalttc + 1, 4, price($object->lines[$linenumber]->total_ttc), 0, 'C');
646
647 // Comments
648 $pdf->SetXY($this->posxcomment, $curY);
649 $comment = $outputlangs->trans("Date").':'.dol_print_date($object->lines[$linenumber]->date, "day", false, $outputlangs).' ';
650 $comment .= $outputlangs->trans("Type").':'.$expensereporttypecodetoshow.'<br>';
651 if (!empty($object->lines[$linenumber]->projet_ref)) {
652 $comment .= $outputlangs->trans("Project").':'.$object->lines[$linenumber]->projet_ref.'<br>';
653 }
654 $comment .= $object->lines[$linenumber]->comments;
655 $pdf->writeHTMLCell($this->posxtva - $this->posxcomment - 0.8, 4, $this->posxcomment - 1, $curY, $comment, 0, 1);
656 }
657
658 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
668 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
669 {
670 // global $conf, $langs, $hookmanager;
671 global $user, $langs, $conf, $mysoc, $db, $hookmanager;
672
673 // Load traductions files required by page
674 $outputlangs->loadLangs(array("main", "trips", "companies"));
675
676 $default_font_size = pdf_getPDFFontSize($outputlangs);
677
678 /*
679 // ajout du fondu vert en bas de page à droite
680 $image_fondue = $conf->mycompany->dir_output.'/fondu_vert_.jpg';
681 $pdf->Image($image_fondue,20,107,200,190);
682
683 pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
684 */
685
686 // Draft watermark
687 if ($object->fk_statut == 0 && getDolGlobalString('EXPENSEREPORT_DRAFT_WATERMARK')) {
688 pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->EXPENSEREPORT_DRAFT_WATERMARK);
689 }
690
691 $pdf->SetTextColor(0, 0, 60);
692 $pdf->SetFont('', 'B', $default_font_size + 3);
693
694 $posy = $this->marge_haute;
695 $posx = $this->page_largeur - $this->marge_droite - 100;
696
697 $pdf->SetXY($this->marge_gauche, $posy);
698
699 // Logo
700 $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
701 if ($this->emetteur->logo) {
702 if (is_readable($logo)) {
703 $height = pdf_getHeightForLogo($logo);
704 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
705 } else {
706 $pdf->SetTextColor(200, 0, 0);
707 $pdf->SetFont('', 'B', $default_font_size - 2);
708 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
709 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
710 }
711 } else {
712 $text = $this->emetteur->name;
713 $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
714 }
715
716 $pdf->SetFont('', 'B', $default_font_size + 4);
717 $pdf->SetXY($posx, $posy);
718 $pdf->SetTextColor(0, 0, 60);
719 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $posx, 6, $outputlangs->trans("ExpenseReport"), 0, 'R');
720
721 $pdf->SetFont('', '', $default_font_size - 1);
722
723 // Ref complete
724 $posy += 8;
725 $pdf->SetXY($posx, $posy);
726 $pdf->SetTextColor(0, 0, 60);
727 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $posx, 3, $outputlangs->transnoentities("Ref")." : ".$object->ref, '', 'R');
728
729 // Date start period
730 $posy += 5;
731 $pdf->SetXY($posx, $posy);
732 $pdf->SetTextColor(0, 0, 60);
733 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $posx, 3, $outputlangs->transnoentities("DateStart")." : ".($object->date_debut > 0 ? dol_print_date($object->date_debut, "day", false, $outputlangs) : ''), '', 'R');
734
735 // Date end period
736 $posy += 5;
737 $pdf->SetXY($posx, $posy);
738 $pdf->SetTextColor(0, 0, 60);
739 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $posx, 3, $outputlangs->transnoentities("DateEnd")." : ".($object->date_fin > 0 ? dol_print_date($object->date_fin, "day", false, $outputlangs) : ''), '', 'R');
740
741 // Status Expense Report
742 $posy += 6;
743 $pdf->SetXY($posx, $posy);
744 $pdf->SetFont('', 'B', $default_font_size + 2);
745 $pdf->SetTextColor(111, 81, 124);
746 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $posx, 3, $outputlangs->transnoentities($object->labelStatusShort[$object->status]), '', 'R');
747
748 if ($showaddress) {
749 // Sender properties
750 $carac_emetteur = '';
751 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->convToOutputCharset($this->emetteur->address);
752 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->convToOutputCharset($this->emetteur->zip).' '.$outputlangs->convToOutputCharset($this->emetteur->town);
753 $carac_emetteur .= "\n";
754 if ($this->emetteur->phone) {
755 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Phone")." : ".$outputlangs->convToOutputCharset($this->emetteur->phone);
756 }
757 if ($this->emetteur->fax) {
758 $carac_emetteur .= ($carac_emetteur ? ($this->emetteur->tel ? " - " : "\n") : '').$outputlangs->transnoentities("Fax")." : ".$outputlangs->convToOutputCharset($this->emetteur->fax);
759 }
760 if ($this->emetteur->email) {
761 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Email")." : ".$outputlangs->convToOutputCharset($this->emetteur->email);
762 }
763 if ($this->emetteur->url) {
764 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Web")." : ".$outputlangs->convToOutputCharset($this->emetteur->url);
765 }
766
767 // Receiver Properties
768 $receiver = new User($this->db);
769 $receiver->fetch($object->fk_user_author);
770 $receiver_account = new UserBankAccount($this->db);
771 $receiver_account->fetch(0, '', $object->fk_user_author);
772 $expense_receiver = '';
773 $expense_receiver .= ($expense_receiver ? "\n" : '').$outputlangs->convToOutputCharset($receiver->address);
774 $expense_receiver .= ($expense_receiver ? "\n" : '').$outputlangs->convToOutputCharset($receiver->zip).' '.$outputlangs->convToOutputCharset($receiver->town);
775 $expense_receiver .= "\n";
776 if ($receiver->email) {
777 $expense_receiver .= ($expense_receiver ? "\n" : '').$outputlangs->transnoentities("Email")." : ".$outputlangs->convToOutputCharset($receiver->email);
778 }
779 if ($receiver_account->iban) {
780 $expense_receiver .= ($expense_receiver ? "\n" : '').$outputlangs->transnoentities("IBAN")." : ".$outputlangs->convToOutputCharset($receiver_account->iban);
781 }
782
783 // Show sender
784 $posy = 50;
785 $posx = $this->marge_gauche;
786 $hautcadre = 40;
787 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
788 $posx = 118;
789 }
790
791 // Show sender frame
792 $pdf->SetTextColor(0, 0, 0);
793 $pdf->SetFont('', 'B', $default_font_size - 2);
794 $pdf->SetXY($posx, $posy - 5);
795 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("TripSociete"), '', 'L');
796 $pdf->SetXY($posx, $posy);
797 $pdf->SetFillColor(224, 224, 224);
798 $pdf->RoundedRect($posx, $posy, 82, $hautcadre, $this->corner_radius, '1234', 'F');
799 $pdf->SetTextColor(0, 0, 60);
800
801 // Show sender information
802 if (!getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
803 $pdf->SetXY($posx + 2, $posy + 3);
804 $pdf->SetFont('', 'B', $default_font_size);
805 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
806 $pdf->SetXY($posx + 2, $posy + 8);
807 $pdf->SetFont('', '', $default_font_size - 1);
808 $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
809 } else {
810 $pdf->SetXY($posx + 2, $posy + 3);
811 $pdf->SetFont('', 'B', $default_font_size);
812 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset(dolGetFirstLastname($receiver->firstname, $receiver->lastname)), 0, 'L');
813 $pdf->SetXY($posx + 2, $posy + 8);
814 $pdf->SetFont('', '', $default_font_size - 1);
815 $pdf->MultiCell(80, 4, $expense_receiver, 0, 'L');
816 }
817
818 // Show recipient
819 $posy = 50;
820 $posx = 100;
821 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
822 $posx = $this->marge_gauche;
823 }
824
825 // Show recipient frame
826 $pdf->SetTextColor(0, 0, 0);
827 $pdf->SetFont('', 'B', 8);
828 $pdf->SetXY($posx, $posy - 5);
829 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("TripNDF")." :", 0, 'L');
830 $pdf->RoundedRect($posx, $posy, $this->page_largeur - $this->marge_gauche - $posx, $hautcadre, $this->corner_radius, '1234', 'D');
831
832 // Information for expense report (dates and users workflow)
833 if ($object->fk_user_author > 0) {
834 $userfee = new User($this->db);
835 $userfee->fetch($object->fk_user_author);
836 $posy += 3;
837 $pdf->SetXY($posx + 2, $posy);
838 $pdf->SetFont('', '', 10);
839 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("AUTHOR")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
840 $posy = $pdf->GetY() + 1;
841 $pdf->SetXY($posx + 2, $posy);
842 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("DateCreation")." : ".dol_print_date($object->date_create, "day", false, $outputlangs), 0, 'L');
843 }
844
845 if ($object->fk_statut == 99) {
846 if ($object->fk_user_refuse > 0) {
847 $userfee = new User($this->db);
848 $userfee->fetch($object->fk_user_refuse);
849 $posy += 6;
850 $pdf->SetXY($posx + 2, $posy);
851 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("REFUSEUR")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
852 $posy += 5;
853 $pdf->SetXY($posx + 2, $posy);
854 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("MOTIF_REFUS")." : ".$outputlangs->convToOutputCharset($object->detail_refuse), 0, 'L');
855 $posy += 5;
856 $pdf->SetXY($posx + 2, $posy);
857 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("DATE_REFUS")." : ".dol_print_date($object->date_refuse, "day", false, $outputlangs), 0, 'L');
858 }
859 } elseif ($object->fk_statut == 4) {
860 if ($object->fk_user_cancel > 0) {
861 $userfee = new User($this->db);
862 $userfee->fetch($object->fk_user_cancel);
863 $posy += 6;
864 $pdf->SetXY($posx + 2, $posy);
865 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("CANCEL_USER")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
866 $posy += 5;
867 $pdf->SetXY($posx + 2, $posy);
868 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("MOTIF_CANCEL")." : ".$outputlangs->convToOutputCharset($object->detail_cancel), 0, 'L');
869 $posy += 5;
870 $pdf->SetXY($posx + 2, $posy);
871 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("DATE_CANCEL")." : ".dol_print_date($object->date_cancel, "day", false, $outputlangs), 0, 'L');
872 }
873 } else {
874 if ($object->fk_user_approve > 0) {
875 $userfee = new User($this->db);
876 $userfee->fetch($object->fk_user_approve);
877 $posy += 6;
878 $pdf->SetXY($posx + 2, $posy);
879 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("VALIDOR")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
880 $posy += 5;
881 $pdf->SetXY($posx + 2, $posy);
882 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("DateApprove")." : ".dol_print_date($object->date_approve, "day", false, $outputlangs), 0, 'L');
883 }
884 }
885
886 if ($object->fk_statut == 6) {
887 if ($object->fk_user_paid > 0) {
888 $userfee = new User($this->db);
889 $userfee->fetch($object->fk_user_paid);
890 $posy += 6;
891 $pdf->SetXY($posx + 2, $posy);
892 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("AUTHORPAIEMENT")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
893 $posy += 5;
894 $pdf->SetXY($posx + 2, $posy);
895 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("DATE_PAIEMENT")." : ".dol_print_date($object->date_paiement, "day", false, $outputlangs), 0, 'L');
896 }
897 }
898 }
899
900 return 0;
901 }
902
903 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
917 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
918 {
919 global $conf;
920
921 // Force to disable hidetop and hidebottom
922 $hidebottom = 0;
923 if ($hidetop) {
924 $hidetop = -1;
925 }
926
927 $currency = !empty($currency) ? $currency : $conf->currency;
928 $default_font_size = pdf_getPDFFontSize($outputlangs);
929
930 // Amount in (at tab_top - 1)
931 $pdf->SetTextColor(0, 0, 0);
932 $pdf->SetFont('', '', $default_font_size - 2);
933 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
934 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 4), $tab_top - 4);
935 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
936
937 $pdf->SetDrawColor(128, 128, 128);
938
939 // Rect takes a length in 3rd parameter
940 $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $this->corner_radius, '1234', 'D');
941 if (empty($hidetop)) {
942 $pdf->line($this->marge_gauche, $tab_top + 5, $this->page_largeur - $this->marge_droite, $tab_top + 5);
943 }
944
945 $pdf->SetFont('', '', 8);
946
947 // Accountancy piece
948 if (empty($hidetop)) {
949 $pdf->SetXY($this->posxpiece - 1, $tab_top + 1);
950 $pdf->MultiCell($this->posxcomment - $this->posxpiece - 0.8, 1, '', '', 'R');
951 }
952
953 // Comments
954 $pdf->line($this->posxcomment - 1, $tab_top, $this->posxcomment - 1, $tab_top + $tab_height);
955 if (empty($hidetop)) {
956 $pdf->SetXY($this->posxcomment - 1, $tab_top + 1);
957 $pdf->MultiCell($this->posxdate - $this->posxcomment - 0.8, 1, $outputlangs->transnoentities("Description"), '', 'L');
958 }
959
960 // Date
961 //$pdf->line($this->posxdate-1, $tab_top, $this->posxdate-1, $tab_top + $tab_height);
962 //if (empty($hidetop))
963 //{
964 // $pdf->SetXY($this->posxdate-1, $tab_top+1);
965 // $pdf->MultiCell($this->posxtype-$this->posxdate-1,2, $outputlangs->transnoentities("Date"),'','C');
966 //}
967
968 // Type
969 //$pdf->line($this->posxtype-1, $tab_top, $this->posxtype-1, $tab_top + $tab_height);
970 //if (empty($hidetop))
971 //{
972 // $pdf->SetXY($this->posxtype-1, $tab_top+1);
973 // $pdf->MultiCell($this->posxprojet-$this->posxtype - 1, 2, $outputlangs->transnoentities("Type"), '', 'C');
974 //}
975
976 //if (isModEnabled('project'))
977 //{
978 // // Project
979 // $pdf->line($this->posxprojet - 1, $tab_top, $this->posxprojet - 1, $tab_top + $tab_height);
980 // if (empty($hidetop)) {
981 // $pdf->SetXY($this->posxprojet - 1, $tab_top + 1);
982 // $pdf->MultiCell($this->posxtva - $this->posxprojet - 1, 2, $outputlangs->transnoentities("Project"), '', 'C');
983 // }
984 //}
985
986 // VAT
987 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
988 $pdf->line($this->posxtva - 1, $tab_top, $this->posxtva - 1, $tab_top + $tab_height);
989 if (empty($hidetop)) {
990 $pdf->SetXY($this->posxtva - 0.8, $tab_top + 1);
991 $pdf->MultiCell($this->posxup - $this->posxtva - 1, 2, $outputlangs->transnoentities("VAT"), '', 'C');
992 }
993 }
994
995 // Unit price
996 $pdf->line($this->posxup - 1, $tab_top, $this->posxup - 1, $tab_top + $tab_height);
997 if (empty($hidetop)) {
998 $pdf->SetXY($this->posxup - 0.8, $tab_top + 1);
999 $pdf->MultiCell($this->posxqty - $this->posxup - 1, 2, $outputlangs->transnoentities("PriceUTTC"), '', 'C');
1000 }
1001
1002 // Quantity
1003 $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height);
1004 if (empty($hidetop)) {
1005 $pdf->SetXY($this->posxqty - 0.8, $tab_top + 1);
1006 $pdf->MultiCell($this->postotalht - $this->posxqty - 1, 2, $outputlangs->transnoentities("Qty"), '', 'C');
1007 }
1008
1009 // Total without taxes
1010 $pdf->line($this->postotalht - 1, $tab_top, $this->postotalht - 1, $tab_top + $tab_height);
1011 if (empty($hidetop)) {
1012 $pdf->SetXY($this->postotalht - 0.8, $tab_top + 1);
1013 $pdf->MultiCell($this->postotalttc - $this->postotalht + 1, 2, $outputlangs->transnoentities("TotalHT"), '', 'C');
1014 }
1015
1016 // Total with all taxes
1017 $pdf->line($this->postotalttc, $tab_top, $this->postotalttc, $tab_top + $tab_height);
1018 if (empty($hidetop)) {
1019 $pdf->SetXY($this->postotalttc - 0.8, $tab_top + 1);
1020 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalttc + 1, 2, $outputlangs->transnoentities("TotalTTC"), '', 'R');
1021 }
1022
1023 $pdf->SetTextColor(0, 0, 0);
1024 }
1025
1035 protected function tablePayments(&$pdf, $object, $posy, $outputlangs)
1036 {
1037 global $conf;
1038
1039 $sign = 1;
1040 $tab3_posx = $this->marge_gauche;
1041 $tab3_top = $posy;
1042 $tab3_width = 100;
1043 $tab3_height = 5;
1044
1045 $default_font_size = pdf_getPDFFontSize($outputlangs);
1046
1047 $title = $outputlangs->transnoentities("PaymentsAlreadyDone");
1048 $pdf->SetFont('', '', $default_font_size - 2);
1049 $pdf->SetXY($tab3_posx, $tab3_top - 4);
1050 $pdf->SetTextColor(0, 0, 0);
1051 $pdf->MultiCell(60, 3, $title, 0, 'L', false);
1052
1053 $pdf->line($tab3_posx, $tab3_top, $tab3_posx + $tab3_width + 2, $tab3_top); // Top border line of table title
1054
1055 $pdf->SetXY($tab3_posx, $tab3_top + 1);
1056 $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Date"), 0, 'L', false);
1057 $pdf->SetXY($tab3_posx + 19, $tab3_top + 1); // Old value 17
1058 $pdf->MultiCell(15, 3, $outputlangs->transnoentities("Amount"), 0, 'C', false);
1059 $pdf->SetXY($tab3_posx + 45, $tab3_top + 1);
1060 $pdf->MultiCell(35, 3, $outputlangs->transnoentities("Type"), 0, 'L', false);
1061 if (isModEnabled("bank")) {
1062 $pdf->SetXY($tab3_posx + 65, $tab3_top + 1);
1063 $pdf->MultiCell(25, 3, $outputlangs->transnoentities("BankAccount"), 0, 'L', false);
1064 }
1065 $pdf->line($tab3_posx, $tab3_top + $tab3_height, $tab3_posx + $tab3_width + 2, $tab3_top + $tab3_height); // Bottom border line of table title
1066
1067 $y = 0;
1068
1069 // Loop on each payment
1070 // TODO create method on expensereport class to get payments
1071 // Payments already done (from payment on this expensereport)
1072 $sql = "SELECT p.rowid, p.num_payment, p.datep as dp, p.amount, p.fk_bank,";
1073 $sql .= "c.code as p_code, c.libelle as payment_type,";
1074 $sql .= "ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal";
1075 $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."payment_expensereport as p";
1076 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_typepayment = c.id";
1077 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
1078 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
1079 $sql .= " WHERE e.rowid = ".((int) $object->id);
1080 $sql .= " AND p.fk_expensereport = e.rowid";
1081 $sql .= ' AND e.entity IN ('.getEntity('expensereport').')';
1082 $sql .= " ORDER BY dp";
1083
1084 $resql = $this->db->query($sql);
1085 if ($resql) {
1086 $num = $this->db->num_rows($resql);
1087 $totalpaid = 0;
1088 $i = 0;
1089 while ($i < $num) {
1090 $y += $tab3_height;
1091 $row = $this->db->fetch_object($resql);
1092
1093 $pdf->SetXY($tab3_posx, $tab3_top + $y + 1);
1094 $pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($row->dp), 'day', false, $outputlangs, true), 0, 'L', false);
1095 $pdf->SetXY($tab3_posx + 20, $tab3_top + $y + 1);
1096 $pdf->MultiCell(20, 3, price($sign * $row->amount, 0, $outputlangs), 0, 'L', false);
1097 $pdf->SetXY($tab3_posx + 45, $tab3_top + $y + 1);
1098 $oper = $outputlangs->transnoentitiesnoconv("PaymentTypeShort".$row->p_code);
1099
1100 $pdf->MultiCell(40, 3, $oper, 0, 'L', false);
1101 if (isModEnabled("bank")) {
1102 $pdf->SetXY($tab3_posx + 65, $tab3_top + $y + 1);
1103 $pdf->MultiCell(30, 3, $row->baref, 0, 'L', false);
1104 }
1105
1106 $pdf->line($tab3_posx, $tab3_top + $y + $tab3_height, $tab3_posx + $tab3_width + 2, $tab3_top + $y + $tab3_height); // Bottom line border of table
1107 $totalpaid += $row->amount;
1108 $i++;
1109 }
1110 if ($num > 0 && $object->paid == 0) {
1111 $y += $tab3_height;
1112
1113 $pdf->SetXY($tab3_posx + 17, $tab3_top + $y);
1114 $pdf->MultiCell(20, 3, price($totalpaid), 0, 'R', false);
1115 $pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1116 $pdf->MultiCell(30, 4, $outputlangs->transnoentitiesnoconv("AlreadyPaid"), 0, 'L', false);
1117 $y += $tab3_height - 2;
1118 $pdf->SetXY($tab3_posx + 17, $tab3_top + $y);
1119 $pdf->MultiCell(20, 3, price($object->total_ttc), 0, 'R', false);
1120 $pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1121 $pdf->MultiCell(30, 4, $outputlangs->transnoentitiesnoconv("AmountExpected"), 0, 'L', false);
1122 $y += $tab3_height - 2;
1123 $remaintopay = $object->total_ttc - $totalpaid;
1124 $pdf->SetXY($tab3_posx + 17, $tab3_top + $y);
1125 $pdf->MultiCell(20, 3, price($remaintopay), 0, 'R', false);
1126 $pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1127 $pdf->MultiCell(30, 4, $outputlangs->transnoentitiesnoconv("RemainderToPay"), 0, 'L', false);
1128 }
1129 } else {
1130 $this->error = $this->db->lasterror();
1131 return -1;
1132 }
1133 return -1;
1134 }
1135
1136 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1146 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1147 {
1148 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1149 return pdf_pagefoot($pdf, $outputlangs, 'EXPENSEREPORT_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1150 }
1151}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class to manage hooks.
Parent class for trips and expenses templates.
Class to manage bank accounts description of users.
Class to manage Dolibarr users.
Class to generate expense report based on standard model.
_pagefoot(&$pdf, $object, $outputlangs, $hidefreetext=0)
Show footer of page.
_tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
Show table for lines.
_pagehead(&$pdf, $object, $showaddress, $outputlangs)
Show top header of page.
printLine(&$pdf, $object, $linenumber, $curY, $default_font_size, $outputlangs, $hidedetails=0)
write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
Function to build pdf onto disk.
tablePayments(&$pdf, $object, $posy, $outputlangs)
Show payments table.
global $mysoc
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(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
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.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
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_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
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 a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
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)
pdf_watermark($pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition pdf.lib.php:1155
pdf_getFormat($outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:87
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:294
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:317
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:2402
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:1421
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:273
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:1135
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:129
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:130
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:133