dolibarr 22.0.5
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->getFullName($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 if ($reshook < 0) {
549 $this->error = $hookmanager->error;
550 $this->errors = $hookmanager->errors;
551 }
552
553 dolChmod($file);
554
555 $this->result = array('fullpath' => $file);
556
557 return 1; // No error
558 } else {
559 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
560 return 0;
561 }
562 } else {
563 $this->error = $langs->trans("ErrorConstantNotDefined", "EXPENSEREPORT_OUTPUTDIR");
564 return 0;
565 }
566 }
567
578 protected function printLine(&$pdf, $object, $linenumber, $curY, $default_font_size, $outputlangs, $hidedetails = 0)
579 {
580 global $conf;
581 $pdf->SetFont('', '', $default_font_size - 1);
582 $pdf->SetTextColor(0, 0, 0);
583
584 // Accountancy piece
585 $pdf->SetXY($this->posxpiece, $curY);
586 $pdf->writeHTMLCell($this->posxcomment - $this->posxpiece - 0.8, 4, $this->posxpiece - 1, $curY, (string) ($linenumber + 1), 0, 1);
587
588 // Date
589 //$pdf->SetXY($this->posxdate -1, $curY);
590 //$pdf->MultiCell($this->posxtype-$this->posxdate-0.8, 4, dol_print_date($object->lines[$linenumber]->date,"day",false,$outputlangs), 0, 'C');
591
592 // Type
593 $pdf->SetXY($this->posxtype - 1, $curY);
594 $nextColumnPosX = $this->posxup;
595 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
596 $nextColumnPosX = $this->posxtva;
597 }
598 if (isModEnabled('project')) {
599 $nextColumnPosX = $this->posxprojet;
600 }
601
602 $expensereporttypecode = $object->lines[$linenumber]->type_fees_code;
603 $expensereporttypecodetoshow = ($outputlangs->trans(($expensereporttypecode)) == $expensereporttypecode ? $object->lines[$linenumber]->type_fees_libelle : $outputlangs->trans($expensereporttypecode));
604
605
606 if ($expensereporttypecodetoshow == $expensereporttypecode) {
607 $expensereporttypecodetoshow = preg_replace('/^(EX_|TF_)/', '', $expensereporttypecodetoshow);
608 }
609 //$expensereporttypecodetoshow = dol_trunc($expensereporttypecodetoshow, 9);
610
611 //$pdf->MultiCell($nextColumnPosX-$this->posxtype-0.8, 4, $expensereporttypecodetoshow, 0, 'C');
612
613 // Project
614 //if (isModEnabled('project'))
615 //{
616 // $pdf->SetFont('','', $default_font_size - 1);
617 // $pdf->SetXY($this->posxprojet, $curY);
618 // $pdf->MultiCell($this->posxtva-$this->posxprojet-0.8, 4, $object->lines[$linenumber]->projet_ref, 0, 'C');
619 //}
620
621 // VAT Rate
622 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
623 $vat_rate = pdf_getlinevatrate($object, $linenumber, $outputlangs, $hidedetails);
624 $pdf->SetXY($this->posxtva, $curY);
625 $pdf->MultiCell($this->posxup - $this->posxtva - 0.8, 4, $vat_rate, 0, 'C');
626 }
627
628 // Unit price
629 $pdf->SetXY($this->posxup, $curY);
630 $pdf->MultiCell($this->posxqty - $this->posxup - 0.8, 4, price($object->lines[$linenumber]->value_unit), 0, 'C');
631
632 // Quantity
633 $pdf->SetXY($this->posxqty, $curY);
634 $pdf->MultiCell($this->postotalht - $this->posxqty - 0.8, 4, (string) $object->lines[$linenumber]->qty, 0, 'C');
635
636 // Total without taxes
637 $pdf->SetXY($this->postotalht, $curY);
638 $pdf->MultiCell($this->postotalttc - $this->postotalht - 0.8, 4, price($object->lines[$linenumber]->total_ht), 0, 'C');
639
640 // Total with all taxes
641 $pdf->SetXY($this->postotalttc - 1, $curY);
642 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalttc + 1, 4, price($object->lines[$linenumber]->total_ttc), 0, 'C');
643
644 // Comments
645 $pdf->SetXY($this->posxcomment, $curY);
646 $comment = $outputlangs->trans("Date").':'.dol_print_date($object->lines[$linenumber]->date, "day", false, $outputlangs).' ';
647 $comment .= $outputlangs->trans("Type").':'.$expensereporttypecodetoshow.'<br>';
648 if (!empty($object->lines[$linenumber]->projet_ref)) {
649 $comment .= $outputlangs->trans("Project").':'.$object->lines[$linenumber]->projet_ref.'<br>';
650 }
651 $comment .= $object->lines[$linenumber]->comments;
652 $pdf->writeHTMLCell($this->posxtva - $this->posxcomment - 0.8, 4, $this->posxcomment - 1, $curY, $comment, 0, 1);
653 }
654
655 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
665 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
666 {
667 // global $conf, $langs, $hookmanager;
668 global $user, $langs, $conf, $mysoc, $db, $hookmanager;
669
670 // Load traductions files required by page
671 $outputlangs->loadLangs(array("main", "trips", "companies"));
672
673 $default_font_size = pdf_getPDFFontSize($outputlangs);
674
675 /*
676 // ajout du fondu vert en bas de page à droite
677 $image_fondue = $conf->mycompany->dir_output.'/fondu_vert_.jpg';
678 $pdf->Image($image_fondue,20,107,200,190);
679
680 pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
681 */
682
683 // Draft watermark
684 if ($object->fk_statut == 0 && getDolGlobalString('EXPENSEREPORT_DRAFT_WATERMARK')) {
685 pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->EXPENSEREPORT_DRAFT_WATERMARK);
686 }
687
688 $pdf->SetTextColor(0, 0, 60);
689 $pdf->SetFont('', 'B', $default_font_size + 3);
690
691 $posy = $this->marge_haute;
692 $posx = $this->page_largeur - $this->marge_droite - 100;
693
694 $pdf->SetXY($this->marge_gauche, $posy);
695
696 // Logo
697 $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
698 if ($this->emetteur->logo) {
699 if (is_readable($logo)) {
700 $height = pdf_getHeightForLogo($logo);
701 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
702 } else {
703 $pdf->SetTextColor(200, 0, 0);
704 $pdf->SetFont('', 'B', $default_font_size - 2);
705 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
706 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
707 }
708 } else {
709 $text = $this->emetteur->name;
710 $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
711 }
712
713 $pdf->SetFont('', 'B', $default_font_size + 4);
714 $pdf->SetXY($posx, $posy);
715 $pdf->SetTextColor(0, 0, 60);
716 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $posx, 6, $outputlangs->trans("ExpenseReport"), 0, 'R');
717
718 $pdf->SetFont('', '', $default_font_size - 1);
719
720 // Ref complete
721 $posy += 8;
722 $pdf->SetXY($posx, $posy);
723 $pdf->SetTextColor(0, 0, 60);
724 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $posx, 3, $outputlangs->transnoentities("Ref")." : ".$object->ref, '', 'R');
725
726 // Date start period
727 $posy += 5;
728 $pdf->SetXY($posx, $posy);
729 $pdf->SetTextColor(0, 0, 60);
730 $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');
731
732 // Date end period
733 $posy += 5;
734 $pdf->SetXY($posx, $posy);
735 $pdf->SetTextColor(0, 0, 60);
736 $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');
737
738 // Status Expense Report
739 $posy += 6;
740 $pdf->SetXY($posx, $posy);
741 $pdf->SetFont('', 'B', $default_font_size + 2);
742 $pdf->SetTextColor(111, 81, 124);
743 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $posx, 3, $outputlangs->transnoentities($object->labelStatusShort[$object->status]), '', 'R');
744
745 if ($showaddress) {
746 // Sender properties
747 $carac_emetteur = '';
748 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->convToOutputCharset($this->emetteur->address);
749 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->convToOutputCharset($this->emetteur->zip).' '.$outputlangs->convToOutputCharset($this->emetteur->town);
750 $carac_emetteur .= "\n";
751 if ($this->emetteur->phone) {
752 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Phone")." : ".$outputlangs->convToOutputCharset($this->emetteur->phone);
753 }
754 if ($this->emetteur->fax) {
755 $carac_emetteur .= ($carac_emetteur ? ($this->emetteur->tel ? " - " : "\n") : '').$outputlangs->transnoentities("Fax")." : ".$outputlangs->convToOutputCharset($this->emetteur->fax);
756 }
757 if ($this->emetteur->email) {
758 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Email")." : ".$outputlangs->convToOutputCharset($this->emetteur->email);
759 }
760 if ($this->emetteur->url) {
761 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Web")." : ".$outputlangs->convToOutputCharset($this->emetteur->url);
762 }
763
764 // Receiver Properties
765 $receiver = new User($this->db);
766 $receiver->fetch($object->fk_user_author);
767 $receiver_account = new UserBankAccount($this->db);
768 $receiver_account->fetch(0, '', $object->fk_user_author);
769 $expense_receiver = '';
770 $expense_receiver .= ($expense_receiver ? "\n" : '').$outputlangs->convToOutputCharset($receiver->address);
771 $expense_receiver .= ($expense_receiver ? "\n" : '').$outputlangs->convToOutputCharset($receiver->zip).' '.$outputlangs->convToOutputCharset($receiver->town);
772 $expense_receiver .= "\n";
773 if ($receiver->email) {
774 $expense_receiver .= ($expense_receiver ? "\n" : '').$outputlangs->transnoentities("Email")." : ".$outputlangs->convToOutputCharset($receiver->email);
775 }
776 if ($receiver_account->iban) {
777 $expense_receiver .= ($expense_receiver ? "\n" : '').$outputlangs->transnoentities("IBAN")." : ".$outputlangs->convToOutputCharset($receiver_account->iban);
778 }
779
780 // Show sender
781 $posy = 50;
782 $posx = $this->marge_gauche;
783 $hautcadre = 40;
784 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
785 $posx = 118;
786 }
787
788 // Show sender frame
789 $pdf->SetTextColor(0, 0, 0);
790 $pdf->SetFont('', 'B', $default_font_size - 2);
791 $pdf->SetXY($posx, $posy - 5);
792 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("TripSociete"), '', 'L');
793 $pdf->SetXY($posx, $posy);
794 $pdf->SetFillColor(224, 224, 224);
795 $pdf->RoundedRect($posx, $posy, 82, $hautcadre, $this->corner_radius, '1234', 'F');
796 $pdf->SetTextColor(0, 0, 60);
797
798 // Show sender information
799 if (!getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
800 $pdf->SetXY($posx + 2, $posy + 3);
801 $pdf->SetFont('', 'B', $default_font_size);
802 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
803 $pdf->SetXY($posx + 2, $posy + 8);
804 $pdf->SetFont('', '', $default_font_size - 1);
805 $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
806 } else {
807 $pdf->SetXY($posx + 2, $posy + 3);
808 $pdf->SetFont('', 'B', $default_font_size);
809 $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset(dolGetFirstLastname($receiver->firstname, $receiver->lastname)), 0, 'L');
810 $pdf->SetXY($posx + 2, $posy + 8);
811 $pdf->SetFont('', '', $default_font_size - 1);
812 $pdf->MultiCell(80, 4, $expense_receiver, 0, 'L');
813 }
814
815 // Show recipient
816 $posy = 50;
817 $posx = 100;
818 if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) {
819 $posx = $this->marge_gauche;
820 }
821
822 // Show recipient frame
823 $pdf->SetTextColor(0, 0, 0);
824 $pdf->SetFont('', 'B', 8);
825 $pdf->SetXY($posx, $posy - 5);
826 $pdf->MultiCell(80, 5, $outputlangs->transnoentities("TripNDF")." :", 0, 'L');
827 $pdf->RoundedRect($posx, $posy, $this->page_largeur - $this->marge_gauche - $posx, $hautcadre, $this->corner_radius, '1234', 'D');
828
829 // Information for expense report (dates and users workflow)
830 if ($object->fk_user_author > 0) {
831 $userfee = new User($this->db);
832 $userfee->fetch($object->fk_user_author);
833 $posy += 3;
834 $pdf->SetXY($posx + 2, $posy);
835 $pdf->SetFont('', '', 10);
836 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("AUTHOR")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
837 $posy = $pdf->GetY() + 1;
838 $pdf->SetXY($posx + 2, $posy);
839 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("DateCreation")." : ".dol_print_date($object->date_create, "day", false, $outputlangs), 0, 'L');
840 }
841
842 if ($object->fk_statut == 99) {
843 if ($object->fk_user_refuse > 0) {
844 $userfee = new User($this->db);
845 $userfee->fetch($object->fk_user_refuse);
846 $posy += 6;
847 $pdf->SetXY($posx + 2, $posy);
848 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("REFUSEUR")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
849 $posy += 5;
850 $pdf->SetXY($posx + 2, $posy);
851 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("MOTIF_REFUS")." : ".$outputlangs->convToOutputCharset($object->detail_refuse), 0, 'L');
852 $posy += 5;
853 $pdf->SetXY($posx + 2, $posy);
854 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("DATE_REFUS")." : ".dol_print_date($object->date_refuse, "day", false, $outputlangs), 0, 'L');
855 }
856 } elseif ($object->fk_statut == 4) {
857 if ($object->fk_user_cancel > 0) {
858 $userfee = new User($this->db);
859 $userfee->fetch($object->fk_user_cancel);
860 $posy += 6;
861 $pdf->SetXY($posx + 2, $posy);
862 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("CANCEL_USER")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
863 $posy += 5;
864 $pdf->SetXY($posx + 2, $posy);
865 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("MOTIF_CANCEL")." : ".$outputlangs->convToOutputCharset($object->detail_cancel), 0, 'L');
866 $posy += 5;
867 $pdf->SetXY($posx + 2, $posy);
868 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("DATE_CANCEL")." : ".dol_print_date($object->date_cancel, "day", false, $outputlangs), 0, 'L');
869 }
870 } else {
871 if ($object->fk_user_approve > 0) {
872 $userfee = new User($this->db);
873 $userfee->fetch($object->fk_user_approve);
874 $posy += 6;
875 $pdf->SetXY($posx + 2, $posy);
876 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("VALIDOR")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
877 $posy += 5;
878 $pdf->SetXY($posx + 2, $posy);
879 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("DateApprove")." : ".dol_print_date($object->date_approve, "day", false, $outputlangs), 0, 'L');
880 }
881 }
882
883 if ($object->fk_statut == 6) {
884 if ($object->fk_user_paid > 0) {
885 $userfee = new User($this->db);
886 $userfee->fetch($object->fk_user_paid);
887 $posy += 6;
888 $pdf->SetXY($posx + 2, $posy);
889 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("AUTHORPAIEMENT")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
890 $posy += 5;
891 $pdf->SetXY($posx + 2, $posy);
892 $pdf->MultiCell(96, 4, $outputlangs->transnoentities("DATE_PAIEMENT")." : ".dol_print_date($object->date_paiement, "day", false, $outputlangs), 0, 'L');
893 }
894 }
895 }
896
897 return 0;
898 }
899
900 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
914 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
915 {
916 global $conf;
917
918 // Force to disable hidetop and hidebottom
919 $hidebottom = 0;
920 if ($hidetop) {
921 $hidetop = -1;
922 }
923
924 $currency = !empty($currency) ? $currency : $conf->currency;
925 $default_font_size = pdf_getPDFFontSize($outputlangs);
926
927 // Amount in (at tab_top - 1)
928 $pdf->SetTextColor(0, 0, 0);
929 $pdf->SetFont('', '', $default_font_size - 2);
930 $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
931 $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 4), $tab_top - 4);
932 $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
933
934 $pdf->SetDrawColor(128, 128, 128);
935
936 // Rect takes a length in 3rd parameter
937 $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $this->corner_radius, '1234', 'D');
938 if (empty($hidetop)) {
939 $pdf->line($this->marge_gauche, $tab_top + 5, $this->page_largeur - $this->marge_droite, $tab_top + 5);
940 }
941
942 $pdf->SetFont('', '', 8);
943
944 // Accountancy piece
945 if (empty($hidetop)) {
946 $pdf->SetXY($this->posxpiece - 1, $tab_top + 1);
947 $pdf->MultiCell($this->posxcomment - $this->posxpiece - 0.8, 1, '', '', 'R');
948 }
949
950 // Comments
951 $pdf->line($this->posxcomment - 1, $tab_top, $this->posxcomment - 1, $tab_top + $tab_height);
952 if (empty($hidetop)) {
953 $pdf->SetXY($this->posxcomment - 1, $tab_top + 1);
954 $pdf->MultiCell($this->posxdate - $this->posxcomment - 0.8, 1, $outputlangs->transnoentities("Description"), '', 'L');
955 }
956
957 // Date
958 //$pdf->line($this->posxdate-1, $tab_top, $this->posxdate-1, $tab_top + $tab_height);
959 //if (empty($hidetop))
960 //{
961 // $pdf->SetXY($this->posxdate-1, $tab_top+1);
962 // $pdf->MultiCell($this->posxtype-$this->posxdate-1,2, $outputlangs->transnoentities("Date"),'','C');
963 //}
964
965 // Type
966 //$pdf->line($this->posxtype-1, $tab_top, $this->posxtype-1, $tab_top + $tab_height);
967 //if (empty($hidetop))
968 //{
969 // $pdf->SetXY($this->posxtype-1, $tab_top+1);
970 // $pdf->MultiCell($this->posxprojet-$this->posxtype - 1, 2, $outputlangs->transnoentities("Type"), '', 'C');
971 //}
972
973 //if (isModEnabled('project'))
974 //{
975 // // Project
976 // $pdf->line($this->posxprojet - 1, $tab_top, $this->posxprojet - 1, $tab_top + $tab_height);
977 // if (empty($hidetop)) {
978 // $pdf->SetXY($this->posxprojet - 1, $tab_top + 1);
979 // $pdf->MultiCell($this->posxtva - $this->posxprojet - 1, 2, $outputlangs->transnoentities("Project"), '', 'C');
980 // }
981 //}
982
983 // VAT
984 if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) {
985 $pdf->line($this->posxtva - 1, $tab_top, $this->posxtva - 1, $tab_top + $tab_height);
986 if (empty($hidetop)) {
987 $pdf->SetXY($this->posxtva - 0.8, $tab_top + 1);
988 $pdf->MultiCell($this->posxup - $this->posxtva - 1, 2, $outputlangs->transnoentities("VAT"), '', 'C');
989 }
990 }
991
992 // Unit price
993 $pdf->line($this->posxup - 1, $tab_top, $this->posxup - 1, $tab_top + $tab_height);
994 if (empty($hidetop)) {
995 $pdf->SetXY($this->posxup - 0.8, $tab_top + 1);
996 $pdf->MultiCell($this->posxqty - $this->posxup - 1, 2, $outputlangs->transnoentities("PriceUTTC"), '', 'C');
997 }
998
999 // Quantity
1000 $pdf->line($this->posxqty - 1, $tab_top, $this->posxqty - 1, $tab_top + $tab_height);
1001 if (empty($hidetop)) {
1002 $pdf->SetXY($this->posxqty - 0.8, $tab_top + 1);
1003 $pdf->MultiCell($this->postotalht - $this->posxqty - 1, 2, $outputlangs->transnoentities("Qty"), '', 'C');
1004 }
1005
1006 // Total without taxes
1007 $pdf->line($this->postotalht - 1, $tab_top, $this->postotalht - 1, $tab_top + $tab_height);
1008 if (empty($hidetop)) {
1009 $pdf->SetXY($this->postotalht - 0.8, $tab_top + 1);
1010 $pdf->MultiCell($this->postotalttc - $this->postotalht + 1, 2, $outputlangs->transnoentities("TotalHT"), '', 'C');
1011 }
1012
1013 // Total with all taxes
1014 $pdf->line($this->postotalttc, $tab_top, $this->postotalttc, $tab_top + $tab_height);
1015 if (empty($hidetop)) {
1016 $pdf->SetXY($this->postotalttc - 0.8, $tab_top + 1);
1017 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalttc + 1, 2, $outputlangs->transnoentities("TotalTTC"), '', 'R');
1018 }
1019
1020 $pdf->SetTextColor(0, 0, 0);
1021 }
1022
1032 protected function tablePayments(&$pdf, $object, $posy, $outputlangs)
1033 {
1034 global $conf;
1035
1036 $sign = 1;
1037 $tab3_posx = $this->marge_gauche;
1038 $tab3_top = $posy;
1039 $tab3_width = 100;
1040 $tab3_height = 5;
1041
1042 $default_font_size = pdf_getPDFFontSize($outputlangs);
1043
1044 $title = $outputlangs->transnoentities("PaymentsAlreadyDone");
1045 $pdf->SetFont('', '', $default_font_size - 2);
1046 $pdf->SetXY($tab3_posx, $tab3_top - 4);
1047 $pdf->SetTextColor(0, 0, 0);
1048 $pdf->MultiCell(60, 3, $title, 0, 'L', false);
1049
1050 $pdf->line($tab3_posx, $tab3_top, $tab3_posx + $tab3_width + 2, $tab3_top); // Top border line of table title
1051
1052 $pdf->SetXY($tab3_posx, $tab3_top + 1);
1053 $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Date"), 0, 'L', false);
1054 $pdf->SetXY($tab3_posx + 19, $tab3_top + 1); // Old value 17
1055 $pdf->MultiCell(15, 3, $outputlangs->transnoentities("Amount"), 0, 'C', false);
1056 $pdf->SetXY($tab3_posx + 45, $tab3_top + 1);
1057 $pdf->MultiCell(35, 3, $outputlangs->transnoentities("Type"), 0, 'L', false);
1058 if (isModEnabled("bank")) {
1059 $pdf->SetXY($tab3_posx + 65, $tab3_top + 1);
1060 $pdf->MultiCell(25, 3, $outputlangs->transnoentities("BankAccount"), 0, 'L', false);
1061 }
1062 $pdf->line($tab3_posx, $tab3_top + $tab3_height, $tab3_posx + $tab3_width + 2, $tab3_top + $tab3_height); // Bottom border line of table title
1063
1064 $y = 0;
1065
1066 // Loop on each payment
1067 // TODO create method on expensereport class to get payments
1068 // Payments already done (from payment on this expensereport)
1069 $sql = "SELECT p.rowid, p.num_payment, p.datep as dp, p.amount, p.fk_bank,";
1070 $sql .= "c.code as p_code, c.libelle as payment_type,";
1071 $sql .= "ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal";
1072 $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."payment_expensereport as p";
1073 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_typepayment = c.id";
1074 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
1075 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
1076 $sql .= " WHERE e.rowid = ".((int) $object->id);
1077 $sql .= " AND p.fk_expensereport = e.rowid";
1078 $sql .= ' AND e.entity IN ('.getEntity('expensereport').')';
1079 $sql .= " ORDER BY dp";
1080
1081 $resql = $this->db->query($sql);
1082 if ($resql) {
1083 $num = $this->db->num_rows($resql);
1084 $totalpaid = 0;
1085 $i = 0;
1086 while ($i < $num) {
1087 $y += $tab3_height;
1088 $row = $this->db->fetch_object($resql);
1089
1090 $pdf->SetXY($tab3_posx, $tab3_top + $y + 1);
1091 $pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($row->dp), 'day', false, $outputlangs, true), 0, 'L', false);
1092 $pdf->SetXY($tab3_posx + 20, $tab3_top + $y + 1);
1093 $pdf->MultiCell(20, 3, price($sign * $row->amount, 0, $outputlangs), 0, 'L', false);
1094 $pdf->SetXY($tab3_posx + 45, $tab3_top + $y + 1);
1095 $oper = $outputlangs->transnoentitiesnoconv("PaymentTypeShort".$row->p_code);
1096
1097 $pdf->MultiCell(40, 3, $oper, 0, 'L', false);
1098 if (isModEnabled("bank")) {
1099 $pdf->SetXY($tab3_posx + 65, $tab3_top + $y + 1);
1100 $pdf->MultiCell(30, 3, $row->baref, 0, 'L', false);
1101 }
1102
1103 $pdf->line($tab3_posx, $tab3_top + $y + $tab3_height, $tab3_posx + $tab3_width + 2, $tab3_top + $y + $tab3_height); // Bottom line border of table
1104 $totalpaid += $row->amount;
1105 $i++;
1106 }
1107 if ($num > 0 && $object->paid == 0) {
1108 $y += $tab3_height;
1109
1110 $pdf->SetXY($tab3_posx + 17, $tab3_top + $y);
1111 $pdf->MultiCell(20, 3, price($totalpaid), 0, 'R', false);
1112 $pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1113 $pdf->MultiCell(30, 4, $outputlangs->transnoentitiesnoconv("AlreadyPaid"), 0, 'L', false);
1114 $y += $tab3_height - 2;
1115 $pdf->SetXY($tab3_posx + 17, $tab3_top + $y);
1116 $pdf->MultiCell(20, 3, price($object->total_ttc), 0, 'R', false);
1117 $pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1118 $pdf->MultiCell(30, 4, $outputlangs->transnoentitiesnoconv("AmountExpected"), 0, 'L', false);
1119 $y += $tab3_height - 2;
1120 $remaintopay = $object->total_ttc - $totalpaid;
1121 $pdf->SetXY($tab3_posx + 17, $tab3_top + $y);
1122 $pdf->MultiCell(20, 3, price($remaintopay), 0, 'R', false);
1123 $pdf->SetXY($tab3_posx + 40, $tab3_top + $y);
1124 $pdf->MultiCell(30, 4, $outputlangs->transnoentitiesnoconv("RemainderToPay"), 0, 'L', false);
1125 }
1126 } else {
1127 $this->error = $this->db->lasterror();
1128 return -1;
1129 }
1130 return -1;
1131 }
1132
1133 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1143 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
1144 {
1145 $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
1146 return pdf_pagefoot($pdf, $outputlangs, 'EXPENSEREPORT_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
1147 }
1148}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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.
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).
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_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:87
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:289
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:314
pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails=0, $hidefreetext=0, $page_largeur=0, $watermark='')
Show footer of page for PDF generation.
Definition pdf.lib.php:1047
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:2018
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:266
pdf_getSubstitutionArray($outputlangs, $exclude=null, $object=null, $onlykey=0, $include=null)
Return array of possible substitutions for PDF content (without external module substitutions).
Definition pdf.lib.php:778
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:129
pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition pdf.lib.php:798
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:158
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:161