dolibarr 18.0.6
pdf.lib.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2006-2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
4 * Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com>
5 * Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2010-2017 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
8 * Copyright (C) 2012 Cédric Salvador <csalvador@gpcsolutions.fr>
9 * Copyright (C) 2012-2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
10 * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
11 * Copyright (C) 2014 Teddy Andreotti <125155@supinfo.com>
12 * Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
13 * Copyright (C) 2019 Lenin Rivas <lenin.rivas@servcom-it.com>
14 * Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com>
15 * Copyright (C) 2021-2022 Anthony Berton <anthony.berton@bb2a.fr>
16 * Copyright (C) 2023 Frédéric France <frederic.france@netlogic.fr>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 3 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program. If not, see <https://www.gnu.org/licenses/>.
30 * or see https://www.gnu.org/
31 */
32
39include_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php';
40
41
48{
49 global $langs, $conf, $user;
50
51 $h = 0;
52 $head = array();
53
54 $head[$h][0] = DOL_URL_ROOT.'/admin/pdf.php';
55 $head[$h][1] = $langs->trans("Parameters");
56 $head[$h][2] = 'general';
57 $h++;
58
59 // Show more tabs from modules
60 // Entries must be declared in modules descriptor with line
61 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
62 // $this->tabs = array('entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to remove a tab
63 complete_head_from_modules($conf, $langs, null, $head, $h, 'pdf_admin');
64
65 if (isModEnabled("propal") || isModEnabled('facture') || isModEnabled('reception')) {
66 $head[$h][0] = DOL_URL_ROOT.'/admin/pdf_other.php';
67 $head[$h][1] = $langs->trans("Others");
68 $head[$h][2] = 'other';
69 $h++;
70 }
71
72 complete_head_from_modules($conf, $langs, null, $head, $h, 'pdf_admin', 'remove');
73
74 return $head;
75}
76
77
85function pdf_getFormat(Translate $outputlangs = null, $mode = 'setup')
86{
87 global $conf, $db, $langs;
88
89 dol_syslog("pdf_getFormat Get paper format with mode=".$mode." MAIN_PDF_FORMAT=".(empty($conf->global->MAIN_PDF_FORMAT) ? 'null' : $conf->global->MAIN_PDF_FORMAT)." outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null')." and langs->defaultlang=".(is_object($langs) ? $langs->defaultlang : 'null'));
90
91 // Default value if setup was not done and/or entry into c_paper_format not defined
92 $width = 210;
93 $height = 297;
94 $unit = 'mm';
95
96 if ($mode == 'auto' || empty($conf->global->MAIN_PDF_FORMAT) || $conf->global->MAIN_PDF_FORMAT == 'auto') {
97 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
98 $pdfformat = dol_getDefaultFormat($outputlangs);
99 } else {
100 $pdfformat = $conf->global->MAIN_PDF_FORMAT;
101 }
102
103 $sql = "SELECT code, label, width, height, unit FROM ".MAIN_DB_PREFIX."c_paper_format";
104 $sql .= " WHERE code = '".$db->escape($pdfformat)."'";
105 $resql = $db->query($sql);
106 if ($resql) {
107 $obj = $db->fetch_object($resql);
108 if ($obj) {
109 $width = (int) $obj->width;
110 $height = (int) $obj->height;
111 $unit = $obj->unit;
112 }
113 }
114
115 //print "pdfformat=".$pdfformat." width=".$width." height=".$height." unit=".$unit;
116 return array('width'=>$width, 'height'=>$height, 'unit'=>$unit);
117}
118
127function pdf_getInstance($format = '', $metric = 'mm', $pagetype = 'P')
128{
129 global $conf;
130
131 // Define constant for TCPDF
132 if (!defined('K_TCPDF_EXTERNAL_CONFIG')) {
133 define('K_TCPDF_EXTERNAL_CONFIG', 1); // this avoid using tcpdf_config file
134 define('K_PATH_CACHE', DOL_DATA_ROOT.'/admin/temp/');
135 define('K_PATH_URL_CACHE', DOL_DATA_ROOT.'/admin/temp/');
136 dol_mkdir(K_PATH_CACHE);
137 define('K_BLANK_IMAGE', '_blank.png');
138 define('PDF_PAGE_FORMAT', 'A4');
139 define('PDF_PAGE_ORIENTATION', 'P');
140 define('PDF_CREATOR', 'TCPDF');
141 define('PDF_AUTHOR', 'TCPDF');
142 define('PDF_HEADER_TITLE', 'TCPDF Example');
143 define('PDF_HEADER_STRING', "by Dolibarr ERP CRM");
144 define('PDF_UNIT', 'mm');
145 define('PDF_MARGIN_HEADER', 5);
146 define('PDF_MARGIN_FOOTER', 10);
147 define('PDF_MARGIN_TOP', 27);
148 define('PDF_MARGIN_BOTTOM', 25);
149 define('PDF_MARGIN_LEFT', 15);
150 define('PDF_MARGIN_RIGHT', 15);
151 define('PDF_FONT_NAME_MAIN', 'helvetica');
152 define('PDF_FONT_SIZE_MAIN', 10);
153 define('PDF_FONT_NAME_DATA', 'helvetica');
154 define('PDF_FONT_SIZE_DATA', 8);
155 define('PDF_FONT_MONOSPACED', 'courier');
156 define('PDF_IMAGE_SCALE_RATIO', 1.25);
157 define('HEAD_MAGNIFICATION', 1.1);
158 define('K_CELL_HEIGHT_RATIO', 1.25);
159 define('K_TITLE_MAGNIFICATION', 1.3);
160 define('K_SMALL_RATIO', 2 / 3);
161 define('K_THAI_TOPCHARS', true);
162 define('K_TCPDF_CALLS_IN_HTML', true);
163 if (!empty($conf->global->TCPDF_THROW_ERRORS_INSTEAD_OF_DIE)) {
164 define('K_TCPDF_THROW_EXCEPTION_ERROR', true);
165 } else {
166 define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
167 }
168 }
169
170 // Load TCPDF
171 require_once TCPDF_PATH.'tcpdf.php';
172
173 // We need to instantiate tcpdi object (instead of tcpdf) to use merging features. But we can disable it (this will break all merge features).
174 if (empty($conf->global->MAIN_DISABLE_TCPDI)) {
175 require_once TCPDI_PATH.'tcpdi.php';
176 }
177
178 //$arrayformat=pdf_getFormat();
179 //$format=array($arrayformat['width'],$arrayformat['height']);
180 //$metric=$arrayformat['unit'];
181
182 $pdfa = false; // PDF-1.3
183 if (!empty($conf->global->PDF_USE_A)) {
184 $pdfa = $conf->global->PDF_USE_A; // PDF/A-1 ou PDF/A-3
185 }
186
187 if (class_exists('TCPDI')) {
188 $pdf = new TCPDI($pagetype, $metric, $format, true, 'UTF-8', false, $pdfa);
189 } else {
190 $pdf = new TCPDF($pagetype, $metric, $format, true, 'UTF-8', false, $pdfa);
191 }
192
193 // Protection and encryption of pdf
194 if (!empty($conf->global->PDF_SECURITY_ENCRYPTION)) {
195 /* Permission supported by TCPDF
196 - print : Print the document;
197 - modify : Modify the contents of the document by operations other than those controlled by 'fill-forms', 'extract' and 'assemble';
198 - copy : Copy or otherwise extract text and graphics from the document;
199 - annot-forms : Add or modify text annotations, fill in interactive form fields, and, if 'modify' is also set, create or modify interactive form fields (including signature fields);
200 - fill-forms : Fill in existing interactive form fields (including signature fields), even if 'annot-forms' is not specified;
201 - extract : Extract text and graphics (in support of accessibility to users with disabilities or for other purposes);
202 - assemble : Assemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even if 'modify' is not set;
203 - print-high : Print the document to a representation from which a faithful digital copy of the PDF content could be generated. When this is not set, printing is limited to a low-level representation of the appearance, possibly of degraded quality.
204 - owner : (inverted logic - only for public-key) when set permits change of encryption and enables all other permissions.
205 */
206
207 // For TCPDF, we specify permission we want to block
208 $pdfrights = (!empty($conf->global->PDF_SECURITY_ENCRYPTION_RIGHTS) ?json_decode($conf->global->PDF_SECURITY_ENCRYPTION_RIGHTS, true) : array('modify', 'copy')); // Json format in llx_const
209
210 // Password for the end user
211 $pdfuserpass = (!empty($conf->global->PDF_SECURITY_ENCRYPTION_USERPASS) ? $conf->global->PDF_SECURITY_ENCRYPTION_USERPASS : '');
212
213 // Password of the owner, created randomly if not defined
214 $pdfownerpass = (!empty($conf->global->PDF_SECURITY_ENCRYPTION_OWNERPASS) ? $conf->global->PDF_SECURITY_ENCRYPTION_OWNERPASS : null);
215
216 // For encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit
217 $encstrength = (!empty($conf->global->PDF_SECURITY_ENCRYPTION_STRENGTH) ? $conf->global->PDF_SECURITY_ENCRYPTION_STRENGTH : 0);
218
219 // Array of recipients containing public-key certificates ('c') and permissions ('p').
220 // For example: array(array('c' => 'file://../examples/data/cert/tcpdf.crt', 'p' => array('print')))
221 $pubkeys = (!empty($conf->global->PDF_SECURITY_ENCRYPTION_PUBKEYS) ?json_decode($conf->global->PDF_SECURITY_ENCRYPTION_PUBKEYS, true) : null); // Json format in llx_const
222
223 $pdf->SetProtection($pdfrights, $pdfuserpass, $pdfownerpass, $encstrength, $pubkeys);
224 }
225
226 return $pdf;
227}
228
235function pdf_getEncryption($pathoffile)
236{
237 require_once TCPDF_PATH.'tcpdf_parser.php';
238
239 $isencrypted = false;
240
241 $content = file_get_contents($pathoffile);
242
243 //ob_start();
244 @($parser = new TCPDF_PARSER(ltrim($content)));
245 list($xref, $data) = $parser->getParsedData();
246 unset($parser);
247 //ob_end_clean();
248
249 if (isset($xref['trailer']['encrypt'])) {
250 $isencrypted = true; // Secured pdf file are currently not supported
251 }
252
253 if (empty($data)) {
254 $isencrypted = true; // Object list not found. Possible secured file
255 }
256
257 return $isencrypted;
258}
259
266function pdf_getPDFFont($outputlangs)
267{
268 global $conf;
269
270 if (!empty($conf->global->MAIN_PDF_FORCE_FONT)) {
271 return $conf->global->MAIN_PDF_FORCE_FONT;
272 }
273
274 $font = 'Helvetica'; // By default, for FPDI, or ISO language on TCPDF
275 if (class_exists('TCPDF')) { // If TCPDF on, we can use an UTF8 one like DejaVuSans if required (slower)
276 if ($outputlangs->trans('FONTFORPDF') != 'FONTFORPDF') {
277 $font = $outputlangs->trans('FONTFORPDF');
278 }
279 }
280 return $font;
281}
282
289function pdf_getPDFFontSize($outputlangs)
290{
291 global $conf;
292
293 $size = 10; // By default, for FPDI or ISO language on TCPDF
294 if (class_exists('TCPDF')) { // If TCPDF on, we can use an UTF8 font like DejaVuSans if required (slower)
295 if ($outputlangs->trans('FONTSIZEFORPDF') != 'FONTSIZEFORPDF') {
296 $size = (int) $outputlangs->trans('FONTSIZEFORPDF');
297 }
298 }
299 if (!empty($conf->global->MAIN_PDF_FORCE_FONT_SIZE)) {
300 $size = $conf->global->MAIN_PDF_FORCE_FONT_SIZE;
301 }
302
303 return $size;
304}
305
306
314function pdf_getHeightForLogo($logo, $url = false)
315{
316 global $conf;
317 $height = (empty($conf->global->MAIN_DOCUMENTS_LOGO_HEIGHT) ? 20 : $conf->global->MAIN_DOCUMENTS_LOGO_HEIGHT);
318 $maxwidth = 130;
319 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
320 $tmp = dol_getImageSize($logo, $url);
321 if ($tmp['height']) {
322 $width = round($height * $tmp['width'] / $tmp['height']);
323 if ($width > $maxwidth) {
324 $height = $height * $maxwidth / $width;
325 }
326 }
327 //print $tmp['width'].' '.$tmp['height'].' '.$width; exit;
328 return $height;
329}
330
339function pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
340{
341 // store current object
342 $pdf->startTransaction();
343 // store starting values
344 $start_y = $pdf->GetY();
345 //var_dump($start_y);
346 $start_page = $pdf->getPage();
347 // call printing functions with content
348 $pdf->writeHTMLCell(0, 0, 0, $start_y, $htmlcontent, 0, 1, false, true, 'J', true);
349 // get the new Y
350 $end_y = $pdf->GetY();
351 $end_page = $pdf->getPage();
352 // calculate height
353 $height = 0;
354 if ($end_page == $start_page) {
355 $height = $end_y - $start_y;
356 } else {
357 for ($page = $start_page; $page <= $end_page; ++$page) {
358 $pdf->setPage($page);
359 $tmpm = $pdf->getMargins();
360 $tMargin = $tmpm['top'];
361 if ($page == $start_page) {
362 // first page
363 $height = $pdf->getPageHeight() - $start_y - $pdf->getBreakMargin();
364 } elseif ($page == $end_page) {
365 // last page
366 $height = $end_y - $tMargin;
367 } else {
368 $height = $pdf->getPageHeight() - $tMargin - $pdf->getBreakMargin();
369 }
370 }
371 }
372 // restore previous object
373 $pdf = $pdf->rollbackTransaction();
374
375 return $height;
376}
377
378
387function pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias = 0)
388{
389 global $conf;
390
391 // Recipient name
392 $socname = '';
393
394 if ($thirdparty instanceof Societe) {
395 $socname = $thirdparty->name;
396 if (($includealias || getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME')) && !empty($thirdparty->name_alias)) {
397 if (getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME') == 2) {
398 $socname = $thirdparty->name_alias." - ".$thirdparty->name;
399 } else {
400 $socname = $thirdparty->name." - ".$thirdparty->name_alias;
401 }
402 }
403 } elseif ($thirdparty instanceof Contact) {
404 if ($thirdparty->socid > 0) {
405 $thirdparty->fetch_thirdparty();
406 $socname = $thirdparty->thirdparty->name;
407 if (($includealias || getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME')) && !empty($thirdparty->thirdparty->name_alias)) {
408 if (getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME') == 2) {
409 $socname = $thirdparty->thirdparty->name_alias." - ".$thirdparty->thirdparty->name;
410 } else {
411 $socname = $thirdparty->thirdparty->name." - ".$thirdparty->thirdparty->name_alias;
412 }
413 }
414 }
415 } else {
416 throw new InvalidArgumentException('Parameter 1 $thirdparty is not a Societe nor Contact');
417 }
418
419 return $outputlangs->convToOutputCharset($socname);
420}
421
422
435function pdf_build_address($outputlangs, $sourcecompany, $targetcompany = '', $targetcontact = '', $usecontact = 0, $mode = 'source', $object = null)
436{
437 global $conf, $hookmanager;
438
439 if ($mode == 'source' && !is_object($sourcecompany)) {
440 return -1;
441 }
442 if ($mode == 'target' && !is_object($targetcompany)) {
443 return -1;
444 }
445
446 if (!empty($sourcecompany->state_id) && empty($sourcecompany->state)) {
447 $sourcecompany->state = getState($sourcecompany->state_id);
448 }
449 if (!empty($targetcompany->state_id) && empty($targetcompany->state)) {
450 $targetcompany->state = getState($targetcompany->state_id);
451 }
452
453 $reshook = 0;
454 $stringaddress = '';
455 if (is_object($hookmanager)) {
456 $parameters = array('sourcecompany' => &$sourcecompany, 'targetcompany' => &$targetcompany, 'targetcontact' => &$targetcontact, 'outputlangs' => $outputlangs, 'mode' => $mode, 'usecontact' => $usecontact);
457 $action = '';
458 $reshook = $hookmanager->executeHooks('pdf_build_address', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
459 $stringaddress .= $hookmanager->resPrint;
460 }
461 if (empty($reshook)) {
462 if ($mode == 'source') {
463 $withCountry = 0;
464 if (isset($targetcompany->country_code) && !empty($sourcecompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
465 $withCountry = 1;
466 }
467
468 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($sourcecompany, $withCountry, "\n", $outputlangs))."\n";
469
470 if (empty($conf->global->MAIN_PDF_DISABLESOURCEDETAILS)) {
471 // Phone
472 if ($sourcecompany->phone) {
473 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("PhoneShort").": ".$outputlangs->convToOutputCharset($sourcecompany->phone);
474 }
475 // Fax
476 if ($sourcecompany->fax) {
477 $stringaddress .= ($stringaddress ? ($sourcecompany->phone ? " - " : "\n") : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($sourcecompany->fax);
478 }
479 // EMail
480 if ($sourcecompany->email) {
481 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($sourcecompany->email);
482 }
483 // Web
484 if ($sourcecompany->url) {
485 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($sourcecompany->url);
486 }
487 }
488 // Intra VAT
489 if (!empty($conf->global->MAIN_TVAINTRA_IN_SOURCE_ADDRESS)) {
490 if ($sourcecompany->tva_intra) {
491 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($sourcecompany->tva_intra);
492 }
493 }
494 // Professionnal Ids
495 $reg = array();
496 if (!empty($conf->global->MAIN_PROFID1_IN_SOURCE_ADDRESS) && !empty($sourcecompany->idprof1)) {
497 $tmp = $outputlangs->transcountrynoentities("ProfId1", $sourcecompany->country_code);
498 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
499 $tmp = $reg[1];
500 }
501 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof1);
502 }
503 if (!empty($conf->global->MAIN_PROFID2_IN_SOURCE_ADDRESS) && !empty($sourcecompany->idprof2)) {
504 $tmp = $outputlangs->transcountrynoentities("ProfId2", $sourcecompany->country_code);
505 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
506 $tmp = $reg[1];
507 }
508 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof2);
509 }
510 if (!empty($conf->global->MAIN_PROFID3_IN_SOURCE_ADDRESS) && !empty($sourcecompany->idprof3)) {
511 $tmp = $outputlangs->transcountrynoentities("ProfId3", $sourcecompany->country_code);
512 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
513 $tmp = $reg[1];
514 }
515 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof3);
516 }
517 if (!empty($conf->global->MAIN_PROFID4_IN_SOURCE_ADDRESS) && !empty($sourcecompany->idprof4)) {
518 $tmp = $outputlangs->transcountrynoentities("ProfId4", $sourcecompany->country_code);
519 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
520 $tmp = $reg[1];
521 }
522 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof4);
523 }
524 if (!empty($conf->global->MAIN_PROFID5_IN_SOURCE_ADDRESS) && !empty($sourcecompany->idprof5)) {
525 $tmp = $outputlangs->transcountrynoentities("ProfId5", $sourcecompany->country_code);
526 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
527 $tmp = $reg[1];
528 }
529 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof5);
530 }
531 if (!empty($conf->global->MAIN_PROFID6_IN_SOURCE_ADDRESS) && !empty($sourcecompany->idprof6)) {
532 $tmp = $outputlangs->transcountrynoentities("ProfId6", $sourcecompany->country_code);
533 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
534 $tmp = $reg[1];
535 }
536 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($sourcecompany->idprof6);
537 }
538 if (!empty($conf->global->PDF_ADD_MORE_AFTER_SOURCE_ADDRESS)) {
539 $stringaddress .= ($stringaddress ? "\n" : '').$conf->global->PDF_ADD_MORE_AFTER_SOURCE_ADDRESS;
540 }
541 }
542
543 if ($mode == 'target' || preg_match('/targetwithdetails/', $mode)) {
544 if ($usecontact) {
545 if (is_object($targetcontact)) {
546 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($targetcontact->getFullName($outputlangs, 1));
547
548 if (!empty($targetcontact->address)) {
549 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcontact))."\n";
550 } else {
551 $companytouseforaddress = $targetcompany;
552
553 // Contact on a thirdparty that is a different thirdparty than the thirdparty of object
554 if ($targetcontact->socid > 0 && $targetcontact->socid != $targetcompany->id) {
555 $targetcontact->fetch_thirdparty();
556 $companytouseforaddress = $targetcontact->thirdparty;
557 }
558
559 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($companytouseforaddress))."\n";
560 }
561 // Country
562 if (!empty($targetcontact->country_code) && $targetcontact->country_code != $sourcecompany->country_code) {
563 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcontact->country_code));
564 } elseif (empty($targetcontact->country_code) && !empty($targetcompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
565 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
566 }
567
568 if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || preg_match('/targetwithdetails/', $mode)) {
569 // Phone
570 if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) {
571 if (!empty($targetcontact->phone_pro) || !empty($targetcontact->phone_mobile)) {
572 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": ";
573 }
574 if (!empty($targetcontact->phone_pro)) {
575 $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_pro);
576 }
577 if (!empty($targetcontact->phone_pro) && !empty($targetcontact->phone_mobile)) {
578 $stringaddress .= " / ";
579 }
580 if (!empty($targetcontact->phone_mobile)) {
581 $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_mobile);
582 }
583 }
584 // Fax
585 if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) {
586 if ($targetcontact->fax) {
587 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcontact->fax);
588 }
589 }
590 // EMail
591 if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) {
592 if ($targetcontact->email) {
593 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcontact->email);
594 }
595 }
596 // Web
597 if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) {
598 if ($targetcontact->url) {
599 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcontact->url);
600 }
601 }
602 }
603 }
604 } else {
605 if (is_object($targetcompany)) {
606 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcompany));
607 // Country
608 if (!empty($targetcompany->country_code) && $targetcompany->country_code != $sourcecompany->country_code) {
609 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
610 } else {
611 $stringaddress .= ($stringaddress ? "\n" : '');
612 }
613
614 if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || preg_match('/targetwithdetails/', $mode)) {
615 // Phone
616 if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) {
617 if (!empty($targetcompany->phone)) {
618 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": ";
619 }
620 if (!empty($targetcompany->phone)) {
621 $stringaddress .= $outputlangs->convToOutputCharset($targetcompany->phone);
622 }
623 }
624 // Fax
625 if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) {
626 if ($targetcompany->fax) {
627 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcompany->fax);
628 }
629 }
630 // EMail
631 if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) {
632 if ($targetcompany->email) {
633 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcompany->email);
634 }
635 }
636 // Web
637 if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) {
638 if ($targetcompany->url) {
639 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcompany->url);
640 }
641 }
642 }
643 }
644 }
645
646 // Intra VAT
647 if (empty($conf->global->MAIN_TVAINTRA_NOT_IN_ADDRESS)) {
648 if ($usecontact && is_object($targetcontact) && getDolGlobalInt('MAIN_USE_COMPANY_NAME_OF_CONTACT')) {
649 $targetcontact->fetch_thirdparty();
650 if (!empty($targetcontact->thirdparty->id) && $targetcontact->thirdparty->tva_intra) {
651 $stringaddress .= ($stringaddress ? "\n" : '') . $outputlangs->transnoentities("VATIntraShort") . ': ' . $outputlangs->convToOutputCharset($targetcontact->thirdparty->tva_intra);
652 }
653 } elseif ($targetcompany->tva_intra) {
654 $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($targetcompany->tva_intra);
655 }
656 }
657
658 // Professionnal Ids
659 if (!empty($conf->global->MAIN_PROFID1_IN_ADDRESS) && !empty($targetcompany->idprof1)) {
660 $tmp = $outputlangs->transcountrynoentities("ProfId1", $targetcompany->country_code);
661 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
662 $tmp = $reg[1];
663 }
664 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof1);
665 }
666 if (!empty($conf->global->MAIN_PROFID2_IN_ADDRESS) && !empty($targetcompany->idprof2)) {
667 $tmp = $outputlangs->transcountrynoentities("ProfId2", $targetcompany->country_code);
668 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
669 $tmp = $reg[1];
670 }
671 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof2);
672 }
673 if (!empty($conf->global->MAIN_PROFID3_IN_ADDRESS) && !empty($targetcompany->idprof3)) {
674 $tmp = $outputlangs->transcountrynoentities("ProfId3", $targetcompany->country_code);
675 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
676 $tmp = $reg[1];
677 }
678 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof3);
679 }
680 if (!empty($conf->global->MAIN_PROFID4_IN_ADDRESS) && !empty($targetcompany->idprof4)) {
681 $tmp = $outputlangs->transcountrynoentities("ProfId4", $targetcompany->country_code);
682 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
683 $tmp = $reg[1];
684 }
685 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof4);
686 }
687 if (!empty($conf->global->MAIN_PROFID5_IN_ADDRESS) && !empty($targetcompany->idprof5)) {
688 $tmp = $outputlangs->transcountrynoentities("ProfId5", $targetcompany->country_code);
689 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
690 $tmp = $reg[1];
691 }
692 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof5);
693 }
694 if (!empty($conf->global->MAIN_PROFID6_IN_ADDRESS) && !empty($targetcompany->idprof6)) {
695 $tmp = $outputlangs->transcountrynoentities("ProfId6", $targetcompany->country_code);
696 if (preg_match('/\‍((.+)\‍)/', $tmp, $reg)) {
697 $tmp = $reg[1];
698 }
699 $stringaddress .= ($stringaddress ? "\n" : '').$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof6);
700 }
701
702 // Public note
703 if (!empty($conf->global->MAIN_PUBLIC_NOTE_IN_ADDRESS)) {
704 if ($mode == 'source' && !empty($sourcecompany->note_public)) {
705 $stringaddress .= ($stringaddress ? "\n" : '').dol_string_nohtmltag($sourcecompany->note_public);
706 }
707 if (($mode == 'target' || preg_match('/targetwithdetails/', $mode)) && !empty($targetcompany->note_public)) {
708 $stringaddress .= ($stringaddress ? "\n" : '').dol_string_nohtmltag($targetcompany->note_public);
709 }
710 }
711 }
712 }
713
714 return $stringaddress;
715}
716
717
726function pdf_pagehead(&$pdf, $outputlangs, $page_height)
727{
728 global $conf;
729
730 // Add a background image on document only if good setup of const
731 if (!empty($conf->global->MAIN_USE_BACKGROUND_ON_PDF) && ($conf->global->MAIN_USE_BACKGROUND_ON_PDF != '-1')) { // Warning, this option make TCPDF generation being crazy and some content disappeared behind the image
732 $filepath = $conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_USE_BACKGROUND_ON_PDF;
733 if (file_exists($filepath)) {
734 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak before adding image
735 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) { $pdf->SetAlpha($conf->global->MAIN_USE_BACKGROUND_ON_PDF_ALPHA); } // Option for change opacity of background
736 $pdf->Image($filepath, (isset($conf->global->MAIN_USE_BACKGROUND_ON_PDF_X) ? $conf->global->MAIN_USE_BACKGROUND_ON_PDF_X : 0), (isset($conf->global->MAIN_USE_BACKGROUND_ON_PDF_Y) ? $conf->global->MAIN_USE_BACKGROUND_ON_PDF_Y : 0), 0, $page_height);
737 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) { $pdf->SetAlpha(1); }
738 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
739 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
740 }
741 }
742 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') != '-1') {
743 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
744 }
745}
746
747
758function pdf_getSubstitutionArray($outputlangs, $exclude = null, $object = null, $onlykey = 0, $include = null)
759{
760 $substitutionarray = getCommonSubstitutionArray($outputlangs, $onlykey, $exclude, $object, $include);
761 $substitutionarray['__FROM_NAME__'] = '__FROM_NAME__';
762 $substitutionarray['__FROM_EMAIL__'] = '__FROM_EMAIL__';
763 return $substitutionarray;
764}
765
766
778function pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
779{
780 global $langs, $mysoc, $user;
781
782 // Print Draft Watermark
783 if ($unit == 'pt') {
784 $k = 1;
785 } elseif ($unit == 'mm') {
786 $k = 72 / 25.4;
787 } elseif ($unit == 'cm') {
788 $k = 72 / 2.54;
789 } elseif ($unit == 'in') {
790 $k = 72;
791 }
792
793 // Make substitution
794 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, null);
795 complete_substitutions_array($substitutionarray, $outputlangs, null);
796 $text = make_substitutions($text, $substitutionarray, $outputlangs);
797 $text = $outputlangs->convToOutputCharset($text);
798
799 $savx = $pdf->getX();
800 $savy = $pdf->getY();
801
802 $watermark_angle = atan($h / $w) / 2;
803 $watermark_x_pos = 0;
804 $watermark_y_pos = $h / 3;
805 $watermark_x = $w / 2;
806 $watermark_y = $h / 3;
807 $pdf->SetFont('', 'B', 40);
808 $pdf->SetTextColor(255, 192, 203);
809 //rotate
810 $pdf->_out(sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm', cos($watermark_angle), sin($watermark_angle), -sin($watermark_angle), cos($watermark_angle), $watermark_x * $k, ($h - $watermark_y) * $k, -$watermark_x * $k, -($h - $watermark_y) * $k));
811 //print watermark
812 $pdf->SetXY($watermark_x_pos, $watermark_y_pos);
813 $pdf->Cell($w - 20, 25, $outputlangs->convToOutputCharset($text), "", 2, "C", 0);
814 //antirotate
815 $pdf->_out('Q');
816
817 $pdf->SetXY($savx, $savy);
818}
819
820
833function pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, $default_font_size = 10)
834{
835 global $mysoc, $conf;
836
837 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbank.class.php';
838
839 $diffsizetitle = (empty($conf->global->PDF_DIFFSIZE_TITLE) ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
840 $diffsizecontent = (empty($conf->global->PDF_DIFFSIZE_CONTENT) ? 4 : $conf->global->PDF_DIFFSIZE_CONTENT);
841 $pdf->SetXY($curx, $cury);
842
843 if (empty($onlynumber)) {
844 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
845 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByTransferOnThisBankAccount').':', 0, 'L', 0);
846 $cury += 4;
847 }
848
849 $outputlangs->load("banks");
850
851 // Use correct name of bank id according to country
852 $bickey = "BICNumber";
853 if ($account->getCountryCode() == 'IN') {
854 $bickey = "SWIFT";
855 }
856
857 // Get format of bank account according to its country
858 $usedetailedbban = $account->useDetailedBBAN();
859
860 //$onlynumber=0; $usedetailedbban=1; // For tests
861 if ($usedetailedbban) {
862 $savcurx = $curx;
863
864 if (empty($onlynumber)) {
865 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
866 $pdf->SetXY($curx, $cury);
867 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
868 $cury += 3;
869 }
870
871 if (empty($conf->global->PDF_BANK_HIDE_NUMBER_SHOW_ONLY_BICIBAN)) { // Note that some countries still need bank number, BIC/IBAN not enougth for them
872 // Note:
873 // bank = code_banque (FR), sort code (GB, IR. Example: 12-34-56)
874 // desk = code guichet (FR), used only when $usedetailedbban = 1
875 // number = account number
876 // key = check control key used only when $usedetailedbban = 1
877 if (empty($onlynumber)) {
878 $pdf->line($curx + 1, $cury + 1, $curx + 1, $cury + 6);
879 }
880
881
882 foreach ($account->getFieldsToShow() as $val) {
883 $pdf->SetXY($curx, $cury + 4);
884 $pdf->SetFont('', '', $default_font_size - 3);
885
886 if ($val == 'BankCode') {
887 // Bank code
888 $tmplength = 18;
889 $content = $account->code_banque;
890 } elseif ($val == 'DeskCode') {
891 // Desk
892 $tmplength = 18;
893 $content = $account->code_guichet;
894 } elseif ($val == 'BankAccountNumber') {
895 // Number
896 $tmplength = 24;
897 $content = $account->number;
898 } elseif ($val == 'BankAccountNumberKey') {
899 // Key
900 $tmplength = 15;
901 $content = $account->cle_rib;
902 } elseif ($val == 'IBAN' || $val == 'BIC') {
903 // Key
904 $tmplength = 0;
905 $content = '';
906 } else {
907 dol_print_error($account->db, 'Unexpected value for getFieldsToShow: '.$val);
908 break;
909 }
910
911 $pdf->MultiCell($tmplength, 3, $outputlangs->convToOutputCharset($content), 0, 'C', 0);
912 $pdf->SetXY($curx, $cury + 1);
913 $curx += $tmplength;
914 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
915 $pdf->MultiCell($tmplength, 3, $outputlangs->transnoentities($val), 0, 'C', 0);
916 if (empty($onlynumber)) {
917 $pdf->line($curx, $cury + 1, $curx, $cury + 7);
918 }
919 }
920
921 $curx = $savcurx;
922 $cury += 8;
923 }
924 } else {
925 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
926 $pdf->SetXY($curx, $cury);
927 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
928 $cury += 3;
929
930 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
931 $pdf->SetXY($curx, $cury);
932 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("BankAccountNumber").': '.$outputlangs->convToOutputCharset($account->number), 0, 'L', 0);
933 $cury += 3;
934
935 if ($diffsizecontent <= 2) {
936 $cury += 1;
937 }
938 }
939
940 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
941
942 if (empty($onlynumber) && !empty($account->domiciliation)) {
943 $pdf->SetXY($curx, $cury);
944 $val = $outputlangs->transnoentities("Residence").': '.$outputlangs->convToOutputCharset($account->domiciliation);
945 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
946 //$nboflines=dol_nboflines_bis($val,120);
947 //$cury+=($nboflines*3)+2;
948 $tmpy = $pdf->getStringHeight(100, $val);
949 $cury += $tmpy;
950 }
951
952 if (!empty($account->proprio)) {
953 $pdf->SetXY($curx, $cury);
954 $val = $outputlangs->transnoentities("BankAccountOwner").': '.$outputlangs->convToOutputCharset($account->proprio);
955 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
956 $tmpy = $pdf->getStringHeight(100, $val);
957 $cury += $tmpy;
958 } elseif (!$usedetailedbban) {
959 $cury += 1;
960 }
961
962 // Use correct name of bank id according to country
963 $ibankey = FormBank::getIBANLabel($account);
964
965 if (!empty($account->iban)) {
966 //Remove whitespaces to ensure we are dealing with the format we expect
967 $ibanDisplay_temp = str_replace(' ', '', $outputlangs->convToOutputCharset($account->iban));
968 $ibanDisplay = "";
969
970 $nbIbanDisplay_temp = dol_strlen($ibanDisplay_temp);
971 for ($i = 0; $i < $nbIbanDisplay_temp; $i++) {
972 $ibanDisplay .= $ibanDisplay_temp[$i];
973 if ($i % 4 == 3 && $i > 0) {
974 $ibanDisplay .= " ";
975 }
976 }
977
978 $pdf->SetFont('', 'B', $default_font_size - 3);
979 $pdf->SetXY($curx, $cury);
980 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($ibankey).': '.$ibanDisplay, 0, 'L', 0);
981 $cury += 3;
982 }
983
984 if (!empty($account->bic)) {
985 $pdf->SetFont('', 'B', $default_font_size - 3);
986 $pdf->SetXY($curx, $cury);
987 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($bickey).': '.$outputlangs->convToOutputCharset($account->bic), 0, 'L', 0);
988 }
989
990 return $pdf->getY();
991}
992
1010function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails = 0, $hidefreetext = 0, $page_largeur = 0, $watermark = '')
1011{
1012 global $conf, $user, $mysoc, $hookmanager;
1013
1014 $outputlangs->load("dict");
1015 $line = '';
1016 $reg = array();
1017
1018 $dims = $pdf->getPageDimensions();
1019
1020 // Line of free text
1021 if (empty($hidefreetext) && !empty($conf->global->$paramfreetext)) {
1022 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
1023 // More substitution keys
1024 $substitutionarray['__FROM_NAME__'] = $fromcompany->name;
1025 $substitutionarray['__FROM_EMAIL__'] = $fromcompany->email;
1026 complete_substitutions_array($substitutionarray, $outputlangs, $object);
1027 $newfreetext = make_substitutions($conf->global->$paramfreetext, $substitutionarray, $outputlangs);
1028
1029 // Make a change into HTML code to allow to include images from medias directory.
1030 // <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1031 // become
1032 // <img alt="" src="'.DOL_DATA_ROOT.'/medias/image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1033 $newfreetext = preg_replace('/(<img.*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)("[^\/]*\/>)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $newfreetext);
1034
1035 $line .= $outputlangs->convToOutputCharset($newfreetext);
1036 }
1037
1038 // First line of company infos
1039 $line1 = "";
1040 $line2 = "";
1041 $line3 = "";
1042 $line4 = "";
1043
1044 if ($showdetails == 1 || $showdetails == 3) {
1045 // Company name
1046 if ($fromcompany->name) {
1047 $line1 .= ($line1 ? " - " : "").$outputlangs->transnoentities("RegisteredOffice").": ".$fromcompany->name;
1048 }
1049 // Address
1050 if ($fromcompany->address) {
1051 $line1 .= ($line1 ? " - " : "").str_replace("\n", ", ", $fromcompany->address);
1052 }
1053 // Zip code
1054 if ($fromcompany->zip) {
1055 $line1 .= ($line1 ? " - " : "").$fromcompany->zip;
1056 }
1057 // Town
1058 if ($fromcompany->town) {
1059 $line1 .= ($line1 ? " " : "").$fromcompany->town;
1060 }
1061 // Country
1062 if ($fromcompany->country) {
1063 $line1 .= ($line1 ? ", " : "").$fromcompany->country;
1064 }
1065 // Phone
1066 if ($fromcompany->phone) {
1067 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Phone").": ".$fromcompany->phone;
1068 }
1069 // Fax
1070 if ($fromcompany->fax) {
1071 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Fax").": ".$fromcompany->fax;
1072 }
1073
1074 // URL
1075 if ($fromcompany->url) {
1076 $line2 .= ($line2 ? " - " : "").$fromcompany->url;
1077 }
1078 // Email
1079 if ($fromcompany->email) {
1080 $line2 .= ($line2 ? " - " : "").$fromcompany->email;
1081 }
1082 }
1083 if ($showdetails == 2 || $showdetails == 3 || (!empty($fromcompany->country_code) && $fromcompany->country_code == 'DE')) {
1084 // Managers
1085 if ($fromcompany->managers) {
1086 $line2 .= ($line2 ? " - " : "").$fromcompany->managers;
1087 }
1088 }
1089
1090 // Line 3 of company infos
1091 // Juridical status
1092 if (!empty($fromcompany->forme_juridique_code) && $fromcompany->forme_juridique_code) {
1093 $line3 .= ($line3 ? " - " : "").$outputlangs->convToOutputCharset(getFormeJuridiqueLabel($fromcompany->forme_juridique_code));
1094 }
1095 // Capital
1096 if (!empty($fromcompany->capital)) {
1097 $tmpamounttoshow = price2num($fromcompany->capital); // This field is a free string or a float
1098 if (is_numeric($tmpamounttoshow) && $tmpamounttoshow > 0) {
1099 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", price($tmpamounttoshow, 0, $outputlangs, 0, 0, 0, $conf->currency));
1100 } elseif (!empty($fromcompany->capital)) {
1101 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", $fromcompany->capital, $outputlangs);
1102 }
1103 }
1104 // Prof Id 1
1105 if (!empty($fromcompany->idprof1) && $fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || !$fromcompany->idprof2)) {
1106 $field = $outputlangs->transcountrynoentities("ProfId1", $fromcompany->country_code);
1107 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1108 $field = $reg[1];
1109 }
1110 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof1);
1111 }
1112 // Prof Id 2
1113 if (!empty($fromcompany->idprof2) && $fromcompany->idprof2) {
1114 $field = $outputlangs->transcountrynoentities("ProfId2", $fromcompany->country_code);
1115 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1116 $field = $reg[1];
1117 }
1118 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof2);
1119 }
1120
1121 // Line 4 of company infos
1122 // Prof Id 3
1123 if (!empty($fromcompany->idprof3) && $fromcompany->idprof3) {
1124 $field = $outputlangs->transcountrynoentities("ProfId3", $fromcompany->country_code);
1125 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1126 $field = $reg[1];
1127 }
1128 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof3);
1129 }
1130 // Prof Id 4
1131 if (!empty($fromcompany->idprof4) && $fromcompany->idprof4) {
1132 $field = $outputlangs->transcountrynoentities("ProfId4", $fromcompany->country_code);
1133 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1134 $field = $reg[1];
1135 }
1136 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof4);
1137 }
1138 // Prof Id 5
1139 if (!empty($fromcompany->idprof5) && $fromcompany->idprof5) {
1140 $field = $outputlangs->transcountrynoentities("ProfId5", $fromcompany->country_code);
1141 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1142 $field = $reg[1];
1143 }
1144 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof5);
1145 }
1146 // Prof Id 6
1147 if (!empty($fromcompany->idprof6) && $fromcompany->idprof6) {
1148 $field = $outputlangs->transcountrynoentities("ProfId6", $fromcompany->country_code);
1149 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1150 $field = $reg[1];
1151 }
1152 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof6);
1153 }
1154 // IntraCommunautary VAT
1155 if (!empty($fromcompany->tva_intra) && $fromcompany->tva_intra != '') {
1156 $line4 .= ($line4 ? " - " : "").$outputlangs->transnoentities("VATIntraShort").": ".$outputlangs->convToOutputCharset($fromcompany->tva_intra);
1157 }
1158
1159 $pdf->SetFont('', '', 7);
1160 $pdf->SetDrawColor(224, 224, 224);
1161 // Option for footer text color
1162 if (!empty($conf->global->PDF_FOOTER_TEXT_COLOR)) {
1163 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_TEXT_COLOR, '%d, %d, %d');
1164 $pdf->SetTextColor($r, $g, $b);
1165 }
1166
1167 // The start of the bottom of this page footer is positioned according to # of lines
1168 $freetextheight = 0;
1169 if ($line) { // Free text
1170 //$line="sample text<br>\nfd<strong>sf</strong>sdf<br>\nghfghg<br>";
1171 if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) {
1172 $width = 20000;
1173 $align = 'L'; // By default, ask a manual break: We use a large value 20000, to not have automatic wrap. This make user understand, he need to add CR on its text.
1174 if (!empty($conf->global->MAIN_USE_AUTOWRAP_ON_FREETEXT)) {
1175 $width = 200;
1176 $align = 'C';
1177 }
1178 $freetextheight = $pdf->getStringHeight($width, $line);
1179 } else {
1180 $freetextheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); // New method (works for HTML content)
1181 //print '<br>'.$freetextheight;exit;
1182 }
1183 }
1184
1185 // For customize footer
1186 if (is_object($hookmanager)) {
1187 $parameters = array('line1' => $line1, 'line2' => $line2, 'line3' => $line3, 'line4' => $line4, 'outputlangs'=>$outputlangs);
1188 $action = '';
1189 $hookmanager->executeHooks('pdf_pagefoot', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1190 if (!empty($hookmanager->resPrint) && $hidefreetext == 0) {
1191 $mycustomfooter = $hookmanager->resPrint;
1192 $mycustomfooterheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1193
1194 $marginwithfooter = $marge_basse + $freetextheight + $mycustomfooterheight;
1195 $posy = (float) $marginwithfooter;
1196
1197 // Option for footer background color (without freetext zone)
1198 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1199 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1200 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1201 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b));
1202 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1203 }
1204
1205 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) { $pdf->SetAutoPageBreak(0, 0); } // Option for disable auto pagebreak
1206 if ($line) { // Free text
1207 $pdf->SetXY($dims['lm'], -$posy);
1208 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1209 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1210 } else {
1211 $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1212 }
1213 $posy -= $freetextheight;
1214 }
1215 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) { $pdf->SetAutoPageBreak(1, 0); } // Restore pagebreak
1216
1217 $pdf->SetY(-$posy);
1218
1219 // Hide footer line if footer background color is set
1220 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1221 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1222 }
1223
1224 // Option for set top margin height of footer after freetext
1225 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1226 $posy -= floatval(getDolGlobalString('PDF_FOOTER_TOP_MARGIN'));
1227 } else {
1228 $posy--;
1229 }
1230
1231 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) { $pdf->SetAutoPageBreak(0, 0); } // Option for disable auto pagebreak
1232 $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1233 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) { $pdf->SetAutoPageBreak(1, 0); } // Restore pagebreak
1234
1235 $posy -= $mycustomfooterheight - 3;
1236 } else {
1237 // Else default footer
1238 $marginwithfooter = $marge_basse + $freetextheight + (!empty($line1) ? 3 : 0) + (!empty($line2) ? 3 : 0) + (!empty($line3) ? 3 : 0) + (!empty($line4) ? 3 : 0);
1239 $posy = (float) $marginwithfooter;
1240
1241 // Option for footer background color (without freetext zone)
1242 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1243 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1244 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1245 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b));
1246 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1247 }
1248
1249 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) { $pdf->SetAutoPageBreak(0, 0); } // Option for disable auto pagebreak
1250 if ($line) { // Free text
1251 $pdf->SetXY($dims['lm'], -$posy);
1252 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1253 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1254 } else {
1255 $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1256 }
1257 $posy -= $freetextheight;
1258 }
1259 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) { $pdf->SetAutoPageBreak(1, 0); } // Restore pagebreak
1260
1261 $pdf->SetY(-$posy);
1262
1263 // Option for hide all footer (page number will no hidden)
1264 if (!getDolGlobalInt('PDF_FOOTER_HIDDEN')) {
1265 // Hide footer line if footer background color is set
1266 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1267 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1268 }
1269
1270 // Option for set top margin height of footer after freetext
1271 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1272 $posy -= floatval(getDolGlobalString('PDF_FOOTER_TOP_MARGIN'));
1273 } else {
1274 $posy--;
1275 }
1276
1277 if (!empty($line1)) {
1278 $pdf->SetFont('', 'B', 7);
1279 $pdf->SetXY($dims['lm'], -$posy);
1280 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line1, 0, 'C', 0);
1281 $posy -= 3;
1282 $pdf->SetFont('', '', 7);
1283 }
1284
1285 if (!empty($line2)) {
1286 $pdf->SetFont('', 'B', 7);
1287 $pdf->SetXY($dims['lm'], -$posy);
1288 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line2, 0, 'C', 0);
1289 $posy -= 3;
1290 $pdf->SetFont('', '', 7);
1291 }
1292
1293 if (!empty($line3)) {
1294 $pdf->SetXY($dims['lm'], -$posy);
1295 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line3, 0, 'C', 0);
1296 }
1297
1298 if (!empty($line4)) {
1299 $posy -= 3;
1300 $pdf->SetXY($dims['lm'], -$posy);
1301 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line4, 0, 'C', 0);
1302 }
1303 }
1304 }
1305 }
1306
1307 // Show page nb and apply correction for some font.
1308 $pdf->SetXY($dims['wk'] - $dims['rm'] - 18 - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_X', 0), -$posy - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_Y', 0));
1309 $pagination = $pdf->PageNo().' / '.$pdf->getAliasNbPages();
1310 $fontRenderCorrection = 0;
1311 if (in_array(pdf_getPDFFont($outputlangs), array('freemono', 'DejaVuSans'))) {
1312 $fontRenderCorrection = 10;
1313 }
1314 $pdf->MultiCell(18 + $fontRenderCorrection, 2, $pagination, 0, 'R', 0);
1315
1316 // Show Draft Watermark
1317 if (!empty($watermark)) {
1318 pdf_watermark($pdf, $outputlangs, $page_hauteur, $page_largeur, 'mm', $watermark);
1319 }
1320
1321 return $marginwithfooter;
1322}
1323
1338function pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
1339{
1340 $linkedobjects = pdf_getLinkedObjects($object, $outputlangs);
1341 if (!empty($linkedobjects)) {
1342 foreach ($linkedobjects as $linkedobject) {
1343 $reftoshow = $linkedobject["ref_title"].' : '.$linkedobject["ref_value"];
1344 if (!empty($linkedobject["date_value"])) {
1345 $reftoshow .= ' / '.$linkedobject["date_value"];
1346 }
1347
1348 $posy += 3;
1349 $pdf->SetXY($posx, $posy);
1350 $pdf->SetFont('', '', $default_font_size - 2);
1351 $pdf->MultiCell($w, $h, $reftoshow, '', $align);
1352 }
1353 }
1354
1355 return $pdf->getY();
1356}
1357
1374function pdf_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1375{
1376 global $db, $conf, $langs, $hookmanager;
1377
1378 $reshook = 0;
1379 $result = '';
1380 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
1381 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1382 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1383 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1384 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1385 }
1386 $parameters = array('pdf'=>$pdf, 'i'=>$i, 'outputlangs'=>$outputlangs, 'w'=>$w, 'h'=>$h, 'posx'=>$posx, 'posy'=>$posy, 'hideref'=>$hideref, 'hidedesc'=>$hidedesc, 'issupplierline'=>$issupplierline, 'special_code'=>$special_code);
1387 $action = '';
1388 $reshook = $hookmanager->executeHooks('pdf_writelinedesc', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1389
1390 if (!empty($hookmanager->resPrint)) {
1391 $result .= $hookmanager->resPrint;
1392 }
1393 }
1394 if (empty($reshook)) {
1395 $labelproductservice = pdf_getlinedesc($object, $i, $outputlangs, $hideref, $hidedesc, $issupplierline);
1396
1397 //var_dump($labelproductservice);exit;
1398
1399 // Fix bug of some HTML editors that replace links <img src="http://localhostgit/viewimage.php?modulepart=medias&file=image/efd.png" into <img src="http://localhostgit/viewimage.php?modulepart=medias&amp;file=image/efd.png"
1400 // We make the reverse, so PDF generation has the real URL.
1401 $nbrep = 0;
1402 $labelproductservice = preg_replace('/(<img[^>]*src=")([^"]*)(&amp;)([^"]*")/', '\1\2&\4', $labelproductservice, -1, $nbrep);
1403
1404 //var_dump($labelproductservice);exit;
1405
1406 // Description
1407 $pdf->writeHTMLCell($w, $h, $posx, $posy, $outputlangs->convToOutputCharset($labelproductservice), 0, 1, false, true, 'J', true);
1408 $result .= $labelproductservice;
1409 }
1410 return $result;
1411}
1412
1424function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1425{
1426 global $db, $conf, $langs;
1427
1428 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1429 $label = (!empty($object->lines[$i]->label) ? $object->lines[$i]->label : (!empty($object->lines[$i]->product_label) ? $object->lines[$i]->product_label : ''));
1430 $desc = (!empty($object->lines[$i]->desc) ? $object->lines[$i]->desc : (!empty($object->lines[$i]->description) ? $object->lines[$i]->description : ''));
1431 $ref_supplier = (!empty($object->lines[$i]->ref_supplier) ? $object->lines[$i]->ref_supplier : (!empty($object->lines[$i]->ref_fourn) ? $object->lines[$i]->ref_fourn : '')); // TODO Not yet saved for supplier invoices, only supplier orders
1432 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1433 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1434
1435 if ($issupplierline) {
1436 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
1437 $prodser = new ProductFournisseur($db);
1438 } else {
1439 include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1440 $prodser = new Product($db);
1441
1442 if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
1443 include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
1444 }
1445 }
1446
1447 if ($idprod) {
1448 $prodser->fetch($idprod);
1449 // If a predefined product and multilang and on other lang, we renamed label with label translated
1450 if (getDolGlobalInt('MAIN_MULTILANGS') && ($outputlangs->defaultlang != $langs->defaultlang)) {
1451 $translatealsoifmodified = (!empty($conf->global->MAIN_MULTILANG_TRANSLATE_EVEN_IF_MODIFIED)); // By default if value was modified manually, we keep it (no translation because we don't have it)
1452
1453 // TODO Instead of making a compare to see if param was modified, check that content contains reference translation. If yes, add the added part to the new translation
1454 // ($textwasnotmodified is replaced with $textwasmodifiedorcompleted and we add completion).
1455
1456 // Set label
1457 // If we want another language, and if label is same than default language (we did not force it to a specific value), we can use translation.
1458 //var_dump($outputlangs->defaultlang.' - '.$langs->defaultlang.' - '.$label.' - '.$prodser->label);exit;
1459 $textwasnotmodified = ($label == $prodser->label);
1460 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["label"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1461 $label = $prodser->multilangs[$outputlangs->defaultlang]["label"];
1462 }
1463
1464 // Set desc
1465 // Manage HTML entities description test because $prodser->description is store with htmlentities but $desc no
1466 $textwasnotmodified = false;
1467 if (!empty($desc) && dol_textishtml($desc) && !empty($prodser->description) && dol_textishtml($prodser->description)) {
1468 $textwasnotmodified = (strpos(dol_html_entity_decode($desc, ENT_QUOTES | ENT_HTML5), dol_html_entity_decode($prodser->description, ENT_QUOTES | ENT_HTML5)) !== false);
1469 } else {
1470 $textwasnotmodified = ($desc == $prodser->description);
1471 }
1472 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["description"])) {
1473 if ($textwasnotmodified) {
1474 $desc = str_replace($prodser->description, $prodser->multilangs[$outputlangs->defaultlang]["description"], $desc);
1475 } elseif ($translatealsoifmodified) {
1476 $desc = $prodser->multilangs[$outputlangs->defaultlang]["description"];
1477 }
1478 }
1479
1480 // Set note
1481 $textwasnotmodified = ($note == $prodser->note_public);
1482 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["other"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1483 $note = $prodser->multilangs[$outputlangs->defaultlang]["other"];
1484 }
1485 }
1486 } elseif (($object->element == 'facture' || $object->element == 'facturefourn') && preg_match('/^\‍(DEPOSIT\‍).+/', $desc)) { // We must not replace '(DEPOSIT)' when it is alone, it will be translated and detailed later
1487 $desc = str_replace('(DEPOSIT)', $outputlangs->trans('Deposit'), $desc);
1488 }
1489
1490 if (empty($conf->global->PDF_HIDE_PRODUCT_LABEL_IN_SUPPLIER_LINES)) {
1491 // Description short of product line
1492 $libelleproduitservice = $label;
1493 if (!empty($libelleproduitservice) && !empty($conf->global->PDF_BOLD_PRODUCT_LABEL)) {
1494 // Adding <b> may convert the original string into a HTML string. Sowe have to first
1495 // convert \n into <br> we text is not already HTML.
1496 if (!dol_textishtml($libelleproduitservice)) {
1497 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1498 }
1499 $libelleproduitservice = '<b>'.$libelleproduitservice.'</b>';
1500 }
1501 }
1502
1503
1504 // Add ref of subproducts
1505 if (!empty($conf->global->SHOW_SUBPRODUCT_REF_IN_PDF)) {
1506 $prodser->get_sousproduits_arbo();
1507 if (!empty($prodser->sousprods) && is_array($prodser->sousprods) && count($prodser->sousprods)) {
1508 $tmparrayofsubproducts = reset($prodser->sousprods);
1509 if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF)) {
1510 foreach ($tmparrayofsubproducts as $subprodval) {
1511 $libelleproduitservice = dol_concatdesc($libelleproduitservice, " * ".$subprodval[3].' ('.$subprodval[1].')');
1512 }
1513 } else {
1514 foreach ($tmparrayofsubproducts as $subprodval) {
1515 $libelleproduitservice = dol_concatdesc($libelleproduitservice, " * ".$subprodval[5].(($subprodval[5] && $subprodval[3]) ? ' - ' : '').$subprodval[3].' ('.$subprodval[1].')');
1516 }
1517 }
1518 }
1519 }
1520
1521 // Description long of product line
1522 if (!empty($desc) && ($desc != $label)) {
1523 if ($desc == '(CREDIT_NOTE)' && $object->lines[$i]->fk_remise_except) {
1524 $discount = new DiscountAbsolute($db);
1525 $discount->fetch($object->lines[$i]->fk_remise_except);
1526 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1527 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromCreditNote", $sourceref);
1528 } elseif ($desc == '(DEPOSIT)' && $object->lines[$i]->fk_remise_except) {
1529 $discount = new DiscountAbsolute($db);
1530 $discount->fetch($object->lines[$i]->fk_remise_except);
1531 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1532 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromDeposit", $sourceref);
1533 // Add date of deposit
1534 if (!empty($conf->global->INVOICE_ADD_DEPOSIT_DATE)) {
1535 $libelleproduitservice .= ' ('.dol_print_date($discount->datec, 'day', '', $outputlangs).')';
1536 }
1537 } elseif ($desc == '(EXCESS RECEIVED)' && $object->lines[$i]->fk_remise_except) {
1538 $discount = new DiscountAbsolute($db);
1539 $discount->fetch($object->lines[$i]->fk_remise_except);
1540 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived", $discount->ref_facture_source);
1541 } elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except) {
1542 $discount = new DiscountAbsolute($db);
1543 $discount->fetch($object->lines[$i]->fk_remise_except);
1544 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid", $discount->ref_invoice_supplier_source);
1545 } else {
1546 if ($idprod) {
1547 // Check if description must be output
1548 if (!empty($object->element)) {
1549 $tmpkey = 'MAIN_DOCUMENTS_HIDE_DESCRIPTION_FOR_'.strtoupper($object->element);
1550 if (!empty($conf->global->$tmpkey)) {
1551 $hidedesc = 1;
1552 }
1553 }
1554 if (empty($hidedesc)) {
1555 if (!empty($conf->global->MAIN_DOCUMENTS_DESCRIPTION_FIRST)) {
1556 $libelleproduitservice = dol_concatdesc($desc, $libelleproduitservice);
1557 } else {
1558 if (!empty($conf->global->HIDE_LABEL_VARIANT_PDF) && $prodser->isVariant()) {
1559 $libelleproduitservice = $desc;
1560 } else {
1561 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1562 }
1563 }
1564 }
1565 } else {
1566 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1567 }
1568 }
1569 }
1570
1571 // We add ref of product (and supplier ref if defined)
1572 $prefix_prodserv = "";
1573 $ref_prodserv = "";
1574 if (!empty($conf->global->PRODUCT_ADD_TYPE_IN_DOCUMENTS)) { // In standard mode, we do not show this
1575 if ($prodser->isService()) {
1576 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." ";
1577 } else {
1578 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." ";
1579 }
1580 }
1581
1582 if (empty($hideref)) {
1583 if ($issupplierline) {
1584 if (empty($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES)) { // Common case
1585 $ref_prodserv = $prodser->ref; // Show local ref
1586 if ($ref_supplier) {
1587 $ref_prodserv .= ($prodser->ref ? ' (' : '').$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.($prodser->ref ? ')' : '');
1588 }
1589 } elseif ($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES == 1) {
1590 $ref_prodserv = $ref_supplier;
1591 } elseif ($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES == 2) {
1592 $ref_prodserv = $ref_supplier.' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')';
1593 }
1594 } else {
1595 $ref_prodserv = $prodser->ref; // Show local ref only
1596
1597 if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
1598 $productCustomerPriceStatic = new Productcustomerprice($db);
1599 $filter = array('fk_product' => $idprod, 'fk_soc' => $object->socid);
1600
1601 $nbCustomerPrices = $productCustomerPriceStatic->fetchAll('', '', 1, 0, $filter);
1602
1603 if ($nbCustomerPrices > 0) {
1604 $productCustomerPrice = $productCustomerPriceStatic->lines[0];
1605
1606 if (!empty($productCustomerPrice->ref_customer)) {
1607 switch ($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
1608 case 1:
1609 $ref_prodserv = $productCustomerPrice->ref_customer;
1610 break;
1611
1612 case 2:
1613 $ref_prodserv = $productCustomerPrice->ref_customer . ' (' . $outputlangs->transnoentitiesnoconv('InternalRef') . ' ' . $ref_prodserv . ')';
1614 break;
1615
1616 default:
1617 $ref_prodserv = $ref_prodserv . ' (' . $outputlangs->transnoentitiesnoconv('RefCustomer') . ' ' . $productCustomerPrice->ref_customer . ')';
1618 }
1619 }
1620 }
1621 }
1622 }
1623
1624 if (!empty($libelleproduitservice) && !empty($ref_prodserv)) {
1625 $ref_prodserv .= " - ";
1626 }
1627 }
1628
1629 if (!empty($ref_prodserv) && !empty($conf->global->PDF_BOLD_PRODUCT_REF_AND_PERIOD)) {
1630 if (!dol_textishtml($libelleproduitservice)) {
1631 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1632 }
1633 $ref_prodserv = '<b>'.$ref_prodserv.'</b>';
1634 // $prefix_prodserv and $ref_prodser are not HTML var
1635 }
1636 $libelleproduitservice = $prefix_prodserv.$ref_prodserv.$libelleproduitservice;
1637
1638 // Add an additional description for the category products
1639 if (!empty($conf->global->CATEGORY_ADD_DESC_INTO_DOC) && $idprod && isModEnabled('categorie')) {
1640 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1641 $categstatic = new Categorie($db);
1642 // recovering the list of all the categories linked to product
1643 $tblcateg = $categstatic->containing($idprod, Categorie::TYPE_PRODUCT);
1644 foreach ($tblcateg as $cate) {
1645 // Adding the descriptions if they are filled
1646 $desccateg = $cate->description;
1647 if ($desccateg) {
1648 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desccateg);
1649 }
1650 }
1651 }
1652
1653 if (!empty($object->lines[$i]->date_start) || !empty($object->lines[$i]->date_end)) {
1654 $format = 'day';
1655 $period = '';
1656 // Show duration if exists
1657 if ($object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1658 $period = '('.$outputlangs->transnoentitiesnoconv('DateFromTo', dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs), dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
1659 }
1660 if ($object->lines[$i]->date_start && !$object->lines[$i]->date_end) {
1661 $period = '('.$outputlangs->transnoentitiesnoconv('DateFrom', dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs)).')';
1662 }
1663 if (!$object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1664 $period = '('.$outputlangs->transnoentitiesnoconv('DateUntil', dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
1665 }
1666 //print '>'.$outputlangs->charset_output.','.$period;
1667 if (!empty($conf->global->PDF_BOLD_PRODUCT_REF_AND_PERIOD)) {
1668 if (!dol_textishtml($libelleproduitservice)) {
1669 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1670 }
1671 $libelleproduitservice .= '<br><b style="color:#333666;" ><em>'.$period.'</em></b>';
1672 } else {
1673 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $period);
1674 }
1675 //print $libelleproduitservice;
1676 }
1677
1678 // Show information for lot
1679 if (!empty($dbatch)) {
1680 // $object is a shipment.
1681 //var_dump($object->lines[$i]->details_entrepot); // array from llx_expeditiondet (we can have several lines for one fk_origin_line)
1682 //var_dump($object->lines[$i]->detail_batch); // array from llx_expeditiondet_batch (each line with a lot is linked to llx_expeditiondet)
1683
1684 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1685 include_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
1686 $tmpwarehouse = new Entrepot($db);
1687 $tmpproductbatch = new Productbatch($db);
1688
1689 $format = 'day';
1690 foreach ($dbatch as $detail) {
1691 $dte = array();
1692 if ($detail->eatby) {
1693 $dte[] = $outputlangs->transnoentitiesnoconv('printEatby', dol_print_date($detail->eatby, $format, false, $outputlangs));
1694 }
1695 if ($detail->sellby) {
1696 $dte[] = $outputlangs->transnoentitiesnoconv('printSellby', dol_print_date($detail->sellby, $format, false, $outputlangs));
1697 }
1698 if ($detail->batch) {
1699 $dte[] = $outputlangs->transnoentitiesnoconv('printBatch', $detail->batch);
1700 }
1701 $dte[] = $outputlangs->transnoentitiesnoconv('printQty', $detail->qty);
1702
1703 // Add also info of planned warehouse for lot
1704 if ($object->element == 'shipping' && $detail->fk_origin_stock > 0 && getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1705 $resproductbatch = $tmpproductbatch->fetch($detail->fk_origin_stock);
1706 if ($resproductbatch > 0) {
1707 $reswarehouse = $tmpwarehouse->fetch($tmpproductbatch->warehouseid);
1708 if ($reswarehouse > 0) {
1709 $dte[] = $tmpwarehouse->ref;
1710 }
1711 }
1712 }
1713
1714 $libelleproduitservice .= "__N__ ".implode(" - ", $dte);
1715 }
1716 } else {
1717 if (getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1718 // TODO Show warehouse for shipment line without batch
1719 }
1720 }
1721
1722 // Now we convert \n into br
1723 if (dol_textishtml($libelleproduitservice)) {
1724 $libelleproduitservice = preg_replace('/__N__/', '<br>', $libelleproduitservice);
1725 } else {
1726 $libelleproduitservice = preg_replace('/__N__/', "\n", $libelleproduitservice);
1727 }
1728 $libelleproduitservice = dol_htmlentitiesbr($libelleproduitservice, 1);
1729
1730 return $libelleproduitservice;
1731}
1732
1742function pdf_getlinenum($object, $i, $outputlangs, $hidedetails = 0)
1743{
1744 global $hookmanager;
1745
1746 $reshook = 0;
1747 $result = '';
1748 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
1749 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1750 $special_code = $object->lines[$i]->special_code;
1751 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1752 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1753 }
1754 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1755 $action = '';
1756 $reshook = $hookmanager->executeHooks('pdf_getlinenum', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1757 $result .= $hookmanager->resPrint;
1758 }
1759 if (empty($reshook)) {
1760 $result .= dol_htmlentitiesbr($object->lines[$i]->num);
1761 }
1762 return $result;
1763}
1764
1765
1775function pdf_getlineref($object, $i, $outputlangs, $hidedetails = 0)
1776{
1777 global $hookmanager;
1778
1779 $reshook = 0;
1780 $result = '';
1781 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
1782 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1783 $special_code = $object->lines[$i]->special_code;
1784 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1785 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1786 }
1787 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1788 $action = '';
1789 $reshook = $hookmanager->executeHooks('pdf_getlineref', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1790 $result .= $hookmanager->resPrint;
1791 }
1792 if (empty($reshook)) {
1793 $result .= dol_htmlentitiesbr($object->lines[$i]->product_ref);
1794 }
1795 return $result;
1796}
1797
1807function pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails = 0)
1808{
1809 global $hookmanager;
1810
1811 $reshook = 0;
1812 $result = '';
1813 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
1814 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1815 $special_code = $object->lines[$i]->special_code;
1816 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1817 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1818 }
1819 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1820 $action = '';
1821 $reshook = $hookmanager->executeHooks('pdf_getlineref_supplier', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1822 $result .= $hookmanager->resPrint;
1823 }
1824 if (empty($reshook)) {
1825 $result .= dol_htmlentitiesbr($object->lines[$i]->ref_supplier);
1826 }
1827 return $result;
1828}
1829
1839function pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails = 0)
1840{
1841 global $conf, $hookmanager, $mysoc;
1842
1843 $result = '';
1844 $reshook = 0;
1845 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
1846 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
1847 $special_code = empty($object->lines[$i]) ? '' : $object->lines[$i]->special_code;
1848 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1849 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1850 }
1851 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1852 $action = '';
1853 $reshook = $hookmanager->executeHooks('pdf_getlinevatrate', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1854
1855 if (!empty($hookmanager->resPrint)) {
1856 $result .= $hookmanager->resPrint;
1857 }
1858 }
1859 if (empty($reshook)) {
1860 if (empty($hidedetails) || $hidedetails > 1) {
1861 $tmpresult = '';
1862
1863 $tmpresult .= vatrate($object->lines[$i]->tva_tx, 0, $object->lines[$i]->info_bits, -1);
1864 if (empty($conf->global->MAIN_PDF_MAIN_HIDE_SECOND_TAX)) {
1865 if ($object->lines[$i]->total_localtax1 != 0) {
1866 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
1867 $tmpresult .= '/';
1868 } else {
1869 $tmpresult = '';
1870 }
1871 $tmpresult .= vatrate(abs($object->lines[$i]->localtax1_tx), 0);
1872 }
1873 }
1874 if (empty($conf->global->MAIN_PDF_MAIN_HIDE_THIRD_TAX)) {
1875 if ($object->lines[$i]->total_localtax2 != 0) {
1876 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
1877 $tmpresult .= '/';
1878 } else {
1879 $tmpresult = '';
1880 }
1881 $tmpresult .= vatrate(abs($object->lines[$i]->localtax2_tx), 0);
1882 }
1883 }
1884 $tmpresult .= '%';
1885
1886 $result .= $tmpresult;
1887 }
1888 }
1889 return $result;
1890}
1891
1901function pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails = 0)
1902{
1903 global $conf, $hookmanager;
1904
1905 $sign = 1;
1906 if (isset($object->type) && $object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) {
1907 $sign = -1;
1908 }
1909
1910 $result = '';
1911 $reshook = 0;
1912 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
1913 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1914 $special_code = empty($object->lines[$i]) ? '' : $object->lines[$i]->special_code;
1915 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1916 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1917 }
1918 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1919 $action = '';
1920 $reshook = $hookmanager->executeHooks('pdf_getlineupexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1921
1922 if (!empty($hookmanager->resPrint)) {
1923 $result .= $hookmanager->resPrint;
1924 }
1925 }
1926 if (empty($reshook)) {
1927 if (empty($hidedetails) || $hidedetails > 1) {
1928 $subprice = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_subprice : $object->lines[$i]->subprice);
1929 $result .= price($sign * $subprice, 0, $outputlangs);
1930 }
1931 }
1932 return $result;
1933}
1934
1944function pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails = 0)
1945{
1946 global $hookmanager, $conf;
1947
1948 $sign = 1;
1949 if (isset($object->type) && $object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) {
1950 $sign = -1;
1951 }
1952
1953 $result = '';
1954 $reshook = 0;
1955 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
1956 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1957 $special_code = $object->lines[$i]->special_code;
1958 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1959 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1960 }
1961 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1962 $action = '';
1963 $reshook = $hookmanager->executeHooks('pdf_getlineupwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1964
1965 if (!empty($hookmanager->resPrint)) {
1966 $result .= $hookmanager->resPrint;
1967 }
1968 }
1969 if (empty($reshook)) {
1970 if (empty($hidedetails) || $hidedetails > 1) {
1971 $result .= price($sign * (($object->lines[$i]->subprice) + ($object->lines[$i]->subprice) * ($object->lines[$i]->tva_tx) / 100), 0, $outputlangs);
1972 }
1973 }
1974 return $result;
1975}
1976
1986function pdf_getlineqty($object, $i, $outputlangs, $hidedetails = 0)
1987{
1988 global $hookmanager;
1989
1990 $result = '';
1991 $reshook = 0;
1992 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
1993 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1994 $special_code = empty($object->lines[$i]) ? '' : $object->lines[$i]->special_code;
1995 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1996 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1997 }
1998 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1999 $action = '';
2000 $reshook = $hookmanager->executeHooks('pdf_getlineqty', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2001
2002 if (!empty($hookmanager->resPrint)) {
2003 $result = $hookmanager->resPrint;
2004 }
2005 }
2006 if (empty($reshook)) {
2007 if ($object->lines[$i]->special_code == 3) {
2008 return '';
2009 }
2010 if (empty($hidedetails) || $hidedetails > 1) {
2011 $result .= $object->lines[$i]->qty;
2012 }
2013 }
2014 return $result;
2015}
2016
2026function pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails = 0)
2027{
2028 global $hookmanager;
2029
2030 $reshook = 0;
2031 $result = '';
2032 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2033 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2034 $special_code = $object->lines[$i]->special_code;
2035 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2036 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2037 }
2038 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2039 $action = '';
2040 $reshook = $hookmanager->executeHooks('pdf_getlineqty_asked', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2041
2042 if (!empty($hookmanager->resPrint)) {
2043 $result .= $hookmanager->resPrint;
2044 }
2045 }
2046 if (empty($reshook)) {
2047 if ($object->lines[$i]->special_code == 3) {
2048 return '';
2049 }
2050 if (empty($hidedetails) || $hidedetails > 1) {
2051 $result .= $object->lines[$i]->qty_asked;
2052 }
2053 }
2054 return $result;
2055}
2056
2066function pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails = 0)
2067{
2068 global $hookmanager;
2069
2070 $reshook = 0;
2071 $result = '';
2072 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2073 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2074 $special_code = $object->lines[$i]->special_code;
2075 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2076 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2077 }
2078 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2079 $action = '';
2080 $reshook = $hookmanager->executeHooks('pdf_getlineqty_shipped', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2081
2082 if (!empty($hookmanager->resPrint)) {
2083 $result .= $hookmanager->resPrint;
2084 }
2085 }
2086 if (empty($reshook)) {
2087 if ($object->lines[$i]->special_code == 3) {
2088 return '';
2089 }
2090 if (empty($hidedetails) || $hidedetails > 1) {
2091 $result .= $object->lines[$i]->qty_shipped;
2092 }
2093 }
2094 return $result;
2095}
2096
2106function pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails = 0)
2107{
2108 global $hookmanager;
2109
2110 $reshook = 0;
2111 $result = '';
2112 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2113 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2114 $special_code = $object->lines[$i]->special_code;
2115 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2116 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2117 }
2118 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2119 $action = '';
2120 $reshook = $hookmanager->executeHooks('pdf_getlineqty_keeptoship', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2121
2122 if (!empty($hookmanager->resPrint)) {
2123 $result .= $hookmanager->resPrint;
2124 }
2125 }
2126 if (empty($reshook)) {
2127 if ($object->lines[$i]->special_code == 3) {
2128 return '';
2129 }
2130 if (empty($hidedetails) || $hidedetails > 1) {
2131 $result .= ($object->lines[$i]->qty_asked - $object->lines[$i]->qty_shipped);
2132 }
2133 }
2134 return $result;
2135}
2136
2147function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = false)
2148{
2149 global $langs;
2150
2151 $reshook = 0;
2152 $result = '';
2153 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2154 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2155 $special_code = $object->lines[$i]->special_code;
2156 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2157 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2158 }
2159 $parameters = array(
2160 'i' => $i,
2161 'outputlangs' => $outputlangs,
2162 'hidedetails' => $hidedetails,
2163 'special_code' => $special_code
2164 );
2165 $action = '';
2166 $reshook = $hookmanager->executeHooks('pdf_getlineunit', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2167
2168 if (!empty($hookmanager->resPrint)) {
2169 $result .= $hookmanager->resPrint;
2170 }
2171 }
2172 if (empty($reshook)) {
2173 if (empty($hidedetails) || $hidedetails > 1) {
2174 $result .= $langs->transnoentitiesnoconv($object->lines[$i]->getLabelOfUnit('short'));
2175 }
2176 }
2177 return $result;
2178}
2179
2180
2190function pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails = 0)
2191{
2192 global $hookmanager;
2193
2194 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2195
2196 $reshook = 0;
2197 $result = '';
2198 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2199 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2200 $special_code = $object->lines[$i]->special_code;
2201 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2202 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2203 }
2204 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2205 $action = '';
2206 $reshook = $hookmanager->executeHooks('pdf_getlineremisepercent', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2207
2208 if (!empty($hookmanager->resPrint)) {
2209 $result .= $hookmanager->resPrint;
2210 }
2211 }
2212 if (empty($reshook)) {
2213 if ($object->lines[$i]->special_code == 3) {
2214 return '';
2215 }
2216 if (empty($hidedetails) || $hidedetails > 1) {
2217 $result .= dol_print_reduction($object->lines[$i]->remise_percent, $outputlangs);
2218 }
2219 }
2220 return $result;
2221}
2222
2233function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = null)
2234{
2235 if (empty($hookmanager)) {
2236 global $hookmanager;
2237 }
2238 global $conf;
2239
2240 $reshook = 0;
2241 $result = '';
2242 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2243 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2244 $special_code = $object->lines[$i]->special_code;
2245 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2246 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2247 }
2248 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2249 $action = '';
2250 $reshook = $hookmanager->executeHooks('pdf_getlineprogress', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2251
2252 if (!empty($hookmanager->resPrint)) {
2253 return $hookmanager->resPrint;
2254 }
2255 }
2256 if (empty($reshook)) {
2257 if ($object->lines[$i]->special_code == 3) {
2258 return '';
2259 }
2260 if (empty($hidedetails) || $hidedetails > 1) {
2261 if (!empty($conf->global->SITUATION_DISPLAY_DIFF_ON_PDF)) {
2262 $prev_progress = 0;
2263 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2264 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2265 }
2266 $result = round($object->lines[$i]->situation_percent - $prev_progress, 1).'%';
2267 } else {
2268 $result = round($object->lines[$i]->situation_percent, 1).'%';
2269 }
2270 }
2271 }
2272 return $result;
2273}
2274
2284function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0)
2285{
2286 global $conf, $hookmanager;
2287
2288 $sign = 1;
2289 if (isset($object->type) && $object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) {
2290 $sign = -1;
2291 }
2292
2293 $reshook = 0;
2294 $result = '';
2295 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2296 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2297 $special_code = empty($object->lines[$i]) ? '' : $object->lines[$i]->special_code;
2298 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2299 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2300 }
2301 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code, 'sign'=>$sign);
2302 $action = '';
2303 $reshook = $hookmanager->executeHooks('pdf_getlinetotalexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2304
2305 if (!empty($hookmanager->resPrint)) {
2306 $result .= $hookmanager->resPrint;
2307 }
2308 }
2309 if (empty($reshook)) {
2310 if (!empty($object->lines[$i]) && $object->lines[$i]->special_code == 3) {
2311 $result .= $outputlangs->transnoentities("Option");
2312 } elseif (empty($hidedetails) || $hidedetails > 1) {
2313 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht);
2314 if (!empty($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2315 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2316 $prev_progress = 0;
2317 $progress = 1;
2318 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2319 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2320 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2321 }
2322 $result .= price($sign * ($total_ht / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2323 } else {
2324 $result .= price($sign * $total_ht, 0, $outputlangs);
2325 }
2326 }
2327 }
2328 return $result;
2329}
2330
2340function pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails = 0)
2341{
2342 global $hookmanager, $conf;
2343
2344 $sign = 1;
2345 if (isset($object->type) && $object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) {
2346 $sign = -1;
2347 }
2348
2349 $reshook = 0;
2350 $result = '';
2351 //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line) ) )
2352 if (is_object($hookmanager)) { // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
2353 $special_code = $object->lines[$i]->special_code;
2354 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2355 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2356 }
2357 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2358 $action = '';
2359 $reshook = $hookmanager->executeHooks('pdf_getlinetotalwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2360
2361 if (!empty($hookmanager->resPrint)) {
2362 $result .= $hookmanager->resPrint;
2363 }
2364 }
2365 if (empty($reshook)) {
2366 if ($object->lines[$i]->special_code == 3) {
2367 $result .= $outputlangs->transnoentities("Option");
2368 } elseif (empty($hidedetails) || $hidedetails > 1) {
2369 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ttc : $object->lines[$i]->total_ttc);
2370 if ($object->lines[$i]->situation_percent > 0) {
2371 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2372 $prev_progress = 0;
2373 $progress = 1;
2374 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2375 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2376 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2377 }
2378 $result .= price($sign * ($total_ttc / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2379 } else {
2380 $result .= price($sign * $total_ttc, 0, $outputlangs);
2381 }
2382 }
2383 }
2384 return $result;
2385}
2386
2395function pdf_getLinkedObjects(&$object, $outputlangs)
2396{
2397 global $db, $hookmanager;
2398
2399 $linkedobjects = array();
2400
2401 $object->fetchObjectLinked();
2402
2403 foreach ($object->linkedObjects as $objecttype => $objects) {
2404 if ($objecttype == 'facture') {
2405 // For invoice, we don't want to have a reference line on document. Image we are using recuring invoice, we will have a line longer than document width.
2406 } elseif ($objecttype == 'propal' || $objecttype == 'supplier_proposal') {
2407 $outputlangs->load('propal');
2408
2409 foreach ($objects as $elementobject) {
2410 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefProposal");
2411 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2412 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DatePropal");
2413 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2414 }
2415 } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order') {
2416 $outputlangs->load('orders');
2417
2418 if (count($objects) > 1 && count($objects) <= (getDolGlobalInt("MAXREFONDOC") ? getDolGlobalInt("MAXREFONDOC") : 10)) {
2419 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' :');
2420 foreach ($objects as $elementobject) {
2421 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref).(empty($elementobject->ref_client) ?'' : ' ('.$elementobject->ref_client.')').(empty($elementobject->ref_supplier) ? '' : ' ('.$elementobject->ref_supplier.')').' ');
2422 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("OrderDate").' : '.dol_print_date($elementobject->date, 'day', '', $outputlangs));
2423 }
2424 } elseif (count($objects) == 1) {
2425 $elementobject = array_shift($objects);
2426 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder");
2427 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref).(!empty($elementobject->ref_client) ? ' ('.$elementobject->ref_client.')' : '').(!empty($elementobject->ref_supplier) ? ' ('.$elementobject->ref_supplier.')' : '');
2428 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate");
2429 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2430 }
2431 } elseif ($objecttype == 'contrat') {
2432 $outputlangs->load('contracts');
2433 foreach ($objects as $elementobject) {
2434 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefContract");
2435 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2436 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateContract");
2437 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat, 'day', '', $outputlangs);
2438 }
2439 } elseif ($objecttype == 'fichinter') {
2440 $outputlangs->load('interventions');
2441 foreach ($objects as $elementobject) {
2442 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("InterRef");
2443 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2444 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("InterDate");
2445 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->datec, 'day', '', $outputlangs);
2446 }
2447 } elseif ($objecttype == 'shipping') {
2448 $outputlangs->loadLangs(array("orders", "sendings"));
2449
2450 if (count($objects) > 1) {
2451 $order = null;
2452 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') {
2453 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :');
2454 } else {
2455 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefSending").' :');
2456 }
2457 // We concat this record info into fields xxx_value. title is overwrote.
2458 foreach ($objects as $elementobject) {
2459 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') { // There is not already a link to order and object is not the order, so we show also info with order
2460 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2461 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2462 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2463 $order = new Commande($db);
2464 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2465 if ($ret < 1) {
2466 $order = null;
2467 }
2468 }
2469 }
2470
2471 if (! is_object($order)) {
2472 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref));
2473 } else {
2474 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : ''));
2475 $object->note_public = dol_concatdesc($object->note_public, ' / '.$outputlangs->transnoentities($elementobject->ref));
2476 }
2477 }
2478 } elseif (count($objects) == 1) {
2479 $elementobject = array_shift($objects);
2480 $order = null;
2481 // We concat this record info into fields xxx_value. title is overwrote.
2482 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') { // There is not already a link to order and object is not the order, so we show also info with order
2483 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2484 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2485 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2486 $order = new Commande($db);
2487 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2488 if ($ret < 1) {
2489 $order = null;
2490 }
2491 }
2492 }
2493
2494 if (! is_object($order)) {
2495 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
2496 if (!empty($linkedobjects[$objecttype]['ref_value'])) $linkedobjects[$objecttype]['ref_value'] .= ' / ';
2497 $linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref);
2498 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2499 } else {
2500 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending");
2501 if (empty($linkedobjects[$objecttype]['ref_value'])) $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
2502 $linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref);
2503 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2504 }
2505 }
2506 }
2507 }
2508
2509 // For add external linked objects
2510 if (is_object($hookmanager)) {
2511 $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs'=>$outputlangs);
2512 $action = '';
2513 $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2514 if (!empty($hookmanager->resArray)) {
2515 $linkedobjects = $hookmanager->resArray;
2516 }
2517 }
2518
2519 return $linkedobjects;
2520}
2521
2529function pdf_getSizeForImage($realpath)
2530{
2531 global $conf;
2532
2533 $maxwidth = (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH);
2534 $maxheight = (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT) ? 32 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT);
2535 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2536 $tmp = dol_getImageSize($realpath);
2537 $width = 0;
2538 $height = 0;
2539 if ($tmp['height']) {
2540 $width = (int) round($maxheight * $tmp['width'] / $tmp['height']); // I try to use maxheight
2541 if ($width > $maxwidth) { // Pb with maxheight, so i use maxwidth
2542 $width = $maxwidth;
2543 $height = (int) round($maxwidth * $tmp['height'] / $tmp['width']);
2544 } else // No pb with maxheight
2545 {
2546 $height = $maxheight;
2547 }
2548 }
2549 return array('width'=>$width, 'height'=>$height);
2550}
2551
2561function pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails = 0)
2562{
2563 global $conf, $hookmanager;
2564
2565 $sign = 1;
2566 if (isset($object->type) && $object->type == 2 && !empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) {
2567 $sign = -1;
2568 }
2569 if ($object->lines[$i]->special_code == 3) {
2570 return $outputlangs->transnoentities("Option");
2571 } else {
2572 if (is_object($hookmanager)) {
2573 $special_code = $object->lines[$i]->special_code;
2574 if (!empty($object->lines[$i]->fk_parent_line)) {
2575 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2576 }
2577
2578 $parameters = array(
2579 'i'=>$i,
2580 'outputlangs'=>$outputlangs,
2581 'hidedetails'=>$hidedetails,
2582 'special_code'=>$special_code
2583 );
2584
2585 $action = '';
2586
2587 if ($hookmanager->executeHooks('getlinetotalremise', $parameters, $object, $action) > 0) { // Note that $action and $object may have been modified by some hooks
2588 if (isset($hookmanager->resArray['linetotalremise'])) {
2589 return $hookmanager->resArray['linetotalremise'];
2590 } else {
2591 return (float) $hookmanager->resPrint; // For backward compatibility
2592 }
2593 }
2594 }
2595
2596 if (empty($hidedetails) || $hidedetails > 1) {
2597 return $sign * (($object->lines[$i]->subprice * $object->lines[$i]->qty) - $object->lines[$i]->total_ht);
2598 }
2599 }
2600 return 0;
2601}
Class to manage categories.
Class to manage customers orders.
Class to manage contact/addresses.
Class to manage absolute discounts.
Class to manage warehouses.
static getIBANLabel(Account $account)
Returns the name of the Iban label.
Class to manage predefined suppliers products.
Class to manage products or services.
Manage record for batch number management.
File of class to manage predefined price products or services by customer.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
getState($id, $withcode='', $dbtouse=0, $withregion=0, $outputlangs='', $entconv=1)
Return state translated from an id.
getFormeJuridiqueLabel($code)
Return the name translated of juridical status.
dol_print_reduction($reduction, $langs)
Returns formated reduction.
dol_getDefaultFormat(Translate $outputlangs=null)
Try to guess default paper format according to language into $langs.
dol_html_entity_decode($a, $b, $c='UTF-8', $keepsomeentities=0)
Replace html_entity_decode functions to manage errors.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_format_address($object, $withcountry=0, $sep="\n", $outputlangs='', $mode=0, $extralangcode='')
Return a formated address (part address/zip/town/state) according to country rules.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
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.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
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_textishtml($msg, $option=0)
Return if a text is a html content.
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add', $filterorigmodule='')
Complete or removed entries into a head array (used to build tabs).
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...
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
getDolGlobalString($key, $default='')
Return 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)
dol_getImageSize($file, $url=false)
Return size of image file on disk (Supported extensions are gif, jpg, png, bmp and webp)
pdf_getSizeForImage($realpath)
Return dimensions to use for images onto PDF checking that width and height are not higher than maxim...
Definition pdf.lib.php:2529
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2284
pdf_getlinedesc($object, $i, $outputlangs, $hideref=0, $hidedesc=0, $issupplierline=0)
Return line description translated in outputlangs and encoded into htmlentities and with
Definition pdf.lib.php:1424
pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails=0)
Return line total amount discount.
Definition pdf.lib.php:2561
pdf_getPDFFontSize($outputlangs)
Return font size to use for PDF generation.
Definition pdf.lib.php:289
pdf_getFormat(Translate $outputlangs=null, $mode='setup')
Return array with format properties of default PDF format.
Definition pdf.lib.php:85
pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails=0)
Return line quantity shipped.
Definition pdf.lib.php:2066
pdf_getlinenum($object, $i, $outputlangs, $hidedetails=0)
Return line num.
Definition pdf.lib.php:1742
pdf_getEncryption($pathoffile)
Return if pdf file is protected/encrypted.
Definition pdf.lib.php:235
pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price including tax.
Definition pdf.lib.php:1944
pdf_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref=0, $hidedesc=0, $issupplierline=0)
Output line description into PDF.
Definition pdf.lib.php:1374
pdf_getLinkedObjects(&$object, $outputlangs)
Return linked objects to use for document generation.
Definition pdf.lib.php:2395
pdf_getHeightForLogo($logo, $url=false)
Return height to use for Logo onto PDF.
Definition pdf.lib.php:314
pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails=0)
Return line ref_supplier.
Definition pdf.lib.php:1807
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition pdf.lib.php:2340
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:1010
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:1901
pdf_getlineprogress($object, $i, $outputlangs, $hidedetails=0, $hookmanager=null)
Return line percent.
Definition pdf.lib.php:2233
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:1839
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0, $hookmanager=false)
Return line unit.
Definition pdf.lib.php:2147
pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
Function to try to calculate height of a HTML Content.
Definition pdf.lib.php:339
pdf_admin_prepare_head()
Return array head with list of tabs to view object informations.
Definition pdf.lib.php:47
pdf_pagehead(&$pdf, $outputlangs, $page_height)
Show header of page for PDF generation.
Definition pdf.lib.php:726
pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
Show linked objects for PDF generation.
Definition pdf.lib.php:1338
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank informations for PDF generation.
Definition pdf.lib.php:833
pdf_getPDFFont($outputlangs)
Return font name to use for PDF generation.
Definition pdf.lib.php:266
pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails=0)
Return line keep to ship quantity.
Definition pdf.lib.php:2106
pdf_getlineref($object, $i, $outputlangs, $hidedetails=0)
Return line product ref.
Definition pdf.lib.php:1775
pdf_build_address($outputlangs, $sourcecompany, $targetcompany='', $targetcontact='', $usecontact=0, $mode='source', $object=null)
Return a string with full address formated for output on documents.
Definition pdf.lib.php:435
pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails=0)
Return line remise percent.
Definition pdf.lib.php:2190
pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails=0)
Return line quantity asked.
Definition pdf.lib.php:2026
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:1986
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:758
pdf_getInstance($format='', $metric='mm', $pagetype='P')
Return a PDF instance object.
Definition pdf.lib.php:127
pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
Returns the name of the thirdparty.
Definition pdf.lib.php:387
pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
Add a draft watermark on PDF files.
Definition pdf.lib.php:778