dolibarr 19.0.4
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;
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=".(!getDolGlobalString('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' || !getDolGlobalString('MAIN_PDF_FORMAT') || getDolGlobalString('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 (getDolGlobalString('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 (!getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 = (getDolGlobalString('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 = (getDolGlobalString('PDF_SECURITY_ENCRYPTION_USERPASS') ? $conf->global->PDF_SECURITY_ENCRYPTION_USERPASS : '');
212
213 // Password of the owner, created randomly if not defined
214 $pdfownerpass = (getDolGlobalString('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 = (getDolGlobalString('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 = (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 = (!getDolGlobalString('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 (!getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('PDF_ADD_MORE_AFTER_SOURCE_ADDRESS')) {
539 $stringaddress .= ($stringaddress ? "\n" : '') . getDolGlobalString('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 (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
569 // Phone
570 if (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) {
615 // Phone
616 if (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (!getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF') && (getDolGlobalString('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/' . getDolGlobalString('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')) {
736 $pdf->SetAlpha($conf->global->MAIN_USE_BACKGROUND_ON_PDF_ALPHA);
737 } // Option for change opacity of background
738 $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);
739 if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) {
740 $pdf->SetAlpha(1);
741 }
742 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
743 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
744 }
745 }
746 if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') != '-1') {
747 $pdf->SetPageMark(); // This option avoid to have the images missing on some pages
748 }
749}
750
751
762function pdf_getSubstitutionArray($outputlangs, $exclude = null, $object = null, $onlykey = 0, $include = null)
763{
764 $substitutionarray = getCommonSubstitutionArray($outputlangs, $onlykey, $exclude, $object, $include);
765 $substitutionarray['__FROM_NAME__'] = '__FROM_NAME__';
766 $substitutionarray['__FROM_EMAIL__'] = '__FROM_EMAIL__';
767 return $substitutionarray;
768}
769
770
782function pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
783{
784 global $langs, $mysoc, $user;
785
786 // Print Draft Watermark
787 if ($unit == 'pt') {
788 $k = 1;
789 } elseif ($unit == 'mm') {
790 $k = 72 / 25.4;
791 } elseif ($unit == 'cm') {
792 $k = 72 / 2.54;
793 } elseif ($unit == 'in') {
794 $k = 72;
795 }
796
797 // Make substitution
798 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, null);
799 complete_substitutions_array($substitutionarray, $outputlangs, null);
800 $text = make_substitutions($text, $substitutionarray, $outputlangs);
801 $text = $outputlangs->convToOutputCharset($text);
802
803 $savx = $pdf->getX();
804 $savy = $pdf->getY();
805
806 $watermark_angle = atan($h / $w) / 2;
807 $watermark_x_pos = 0;
808 $watermark_y_pos = $h / 3;
809 $watermark_x = $w / 2;
810 $watermark_y = $h / 3;
811 $pdf->SetFont('', 'B', 40);
812 $pdf->SetTextColor(255, 192, 203);
813 //rotate
814 $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));
815 //print watermark
816 $pdf->SetXY($watermark_x_pos, $watermark_y_pos);
817 $pdf->Cell($w - 20, 25, $outputlangs->convToOutputCharset($text), "", 2, "C", 0);
818 //antirotate
819 $pdf->_out('Q');
820
821 $pdf->SetXY($savx, $savy);
822}
823
824
837function pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, $default_font_size = 10)
838{
839 global $mysoc, $conf;
840
841 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbank.class.php';
842
843 $diffsizetitle = (!getDolGlobalString('PDF_DIFFSIZE_TITLE') ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
844 $diffsizecontent = (!getDolGlobalString('PDF_DIFFSIZE_CONTENT') ? 4 : $conf->global->PDF_DIFFSIZE_CONTENT);
845 $pdf->SetXY($curx, $cury);
846
847 if (empty($onlynumber)) {
848 $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
849 $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByTransferOnThisBankAccount').':', 0, 'L', 0);
850 $cury += 4;
851 }
852
853 $outputlangs->load("banks");
854
855 // Use correct name of bank id according to country
856 $bickey = "BICNumber";
857 if ($account->getCountryCode() == 'IN') {
858 $bickey = "SWIFT";
859 }
860
861 // Get format of bank account according to its country
862 $usedetailedbban = $account->useDetailedBBAN();
863
864 //$onlynumber=0; $usedetailedbban=1; // For tests
865 if ($usedetailedbban) {
866 $savcurx = $curx;
867
868 if (empty($onlynumber)) {
869 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
870 $pdf->SetXY($curx, $cury);
871 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
872 $cury += 3;
873 }
874
875 if (!getDolGlobalString('PDF_BANK_HIDE_NUMBER_SHOW_ONLY_BICIBAN')) { // Note that some countries still need bank number, BIC/IBAN not enougth for them
876 // Note:
877 // bank = code_banque (FR), sort code (GB, IR. Example: 12-34-56)
878 // desk = code guichet (FR), used only when $usedetailedbban = 1
879 // number = account number
880 // key = check control key used only when $usedetailedbban = 1
881 if (empty($onlynumber)) {
882 $pdf->line($curx + 1, $cury + 1, $curx + 1, $cury + 6);
883 }
884
885
886 foreach ($account->getFieldsToShow() as $val) {
887 $pdf->SetXY($curx, $cury + 4);
888 $pdf->SetFont('', '', $default_font_size - 3);
889
890 if ($val == 'BankCode') {
891 // Bank code
892 $tmplength = 18;
893 $content = $account->code_banque;
894 } elseif ($val == 'DeskCode') {
895 // Desk
896 $tmplength = 18;
897 $content = $account->code_guichet;
898 } elseif ($val == 'BankAccountNumber') {
899 // Number
900 $tmplength = 24;
901 $content = $account->number;
902 } elseif ($val == 'BankAccountNumberKey') {
903 // Key
904 $tmplength = 15;
905 $content = $account->cle_rib;
906 } elseif ($val == 'IBAN' || $val == 'BIC') {
907 // Key
908 $tmplength = 0;
909 $content = '';
910 } else {
911 dol_print_error($account->db, 'Unexpected value for getFieldsToShow: '.$val);
912 break;
913 }
914
915 $pdf->MultiCell($tmplength, 3, $outputlangs->convToOutputCharset($content), 0, 'C', 0);
916 $pdf->SetXY($curx, $cury + 1);
917 $curx += $tmplength;
918 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
919 $pdf->MultiCell($tmplength, 3, $outputlangs->transnoentities($val), 0, 'C', 0);
920 if (empty($onlynumber)) {
921 $pdf->line($curx, $cury + 1, $curx, $cury + 7);
922 }
923 }
924
925 $curx = $savcurx;
926 $cury += 8;
927 }
928 } else {
929 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
930 $pdf->SetXY($curx, $cury);
931 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
932 $cury += 3;
933
934 $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
935 $pdf->SetXY($curx, $cury);
936 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("BankAccountNumber").': '.$outputlangs->convToOutputCharset($account->number), 0, 'L', 0);
937 $cury += 3;
938
939 if ($diffsizecontent <= 2) {
940 $cury += 1;
941 }
942 }
943
944 $pdf->SetFont('', '', $default_font_size - $diffsizecontent);
945
946 if (empty($onlynumber) && !empty($account->domiciliation)) {
947 $pdf->SetXY($curx, $cury);
948 $val = $outputlangs->transnoentities("Residence").': '.$outputlangs->convToOutputCharset($account->domiciliation);
949 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
950 //$nboflines=dol_nboflines_bis($val,120);
951 //$cury+=($nboflines*3)+2;
952 $tmpy = $pdf->getStringHeight(100, $val);
953 $cury += $tmpy;
954 }
955
956 if (!empty($account->proprio)) {
957 $pdf->SetXY($curx, $cury);
958 $val = $outputlangs->transnoentities("BankAccountOwner").': '.$outputlangs->convToOutputCharset($account->proprio);
959 $pdf->MultiCell(100, 3, $val, 0, 'L', 0);
960 $tmpy = $pdf->getStringHeight(100, $val);
961 $cury += $tmpy;
962 } elseif (!$usedetailedbban) {
963 $cury += 1;
964 }
965
966 // Use correct name of bank id according to country
967 $ibankey = FormBank::getIBANLabel($account);
968
969 if (!empty($account->iban)) {
970 //Remove whitespaces to ensure we are dealing with the format we expect
971 $ibanDisplay_temp = str_replace(' ', '', $outputlangs->convToOutputCharset($account->iban));
972 $ibanDisplay = "";
973
974 $nbIbanDisplay_temp = dol_strlen($ibanDisplay_temp);
975 for ($i = 0; $i < $nbIbanDisplay_temp; $i++) {
976 $ibanDisplay .= $ibanDisplay_temp[$i];
977 if ($i % 4 == 3 && $i > 0) {
978 $ibanDisplay .= " ";
979 }
980 }
981
982 $pdf->SetFont('', 'B', $default_font_size - 3);
983 $pdf->SetXY($curx, $cury);
984 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($ibankey).': '.$ibanDisplay, 0, 'L', 0);
985 $cury += 3;
986 }
987
988 if (!empty($account->bic)) {
989 $pdf->SetFont('', 'B', $default_font_size - 3);
990 $pdf->SetXY($curx, $cury);
991 $pdf->MultiCell(100, 3, $outputlangs->transnoentities($bickey).': '.$outputlangs->convToOutputCharset($account->bic), 0, 'L', 0);
992 }
993
994 return $pdf->getY();
995}
996
1014function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_basse, $marge_gauche, $page_hauteur, $object, $showdetails = 0, $hidefreetext = 0, $page_largeur = 0, $watermark = '')
1015{
1016 global $conf, $user, $mysoc, $hookmanager;
1017
1018 $outputlangs->load("dict");
1019 $line = '';
1020 $reg = array();
1021
1022 $dims = $pdf->getPageDimensions();
1023
1024 // Line of free text
1025 if (empty($hidefreetext) && !empty($conf->global->$paramfreetext)) {
1026 $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
1027 // More substitution keys
1028 $substitutionarray['__FROM_NAME__'] = $fromcompany->name;
1029 $substitutionarray['__FROM_EMAIL__'] = $fromcompany->email;
1030 complete_substitutions_array($substitutionarray, $outputlangs, $object);
1031 $newfreetext = make_substitutions(getDolGlobalString($paramfreetext), $substitutionarray, $outputlangs);
1032
1033 // Make a change into HTML code to allow to include images from medias directory.
1034 // <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1035 // become
1036 // <img alt="" src="'.DOL_DATA_ROOT.'/medias/image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
1037 $newfreetext = preg_replace('/(<img.*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)("[^\/]*\/>)/', '\1file:/'.DOL_DATA_ROOT.'/medias/\2\3', $newfreetext);
1038
1039 $line .= $outputlangs->convToOutputCharset($newfreetext);
1040 }
1041
1042 // First line of company infos
1043 $line1 = "";
1044 $line2 = "";
1045 $line3 = "";
1046 $line4 = "";
1047
1048 if ($showdetails == 1 || $showdetails == 3) {
1049 // Company name
1050 if ($fromcompany->name) {
1051 $line1 .= ($line1 ? " - " : "").$outputlangs->transnoentities("RegisteredOffice").": ".$fromcompany->name;
1052 }
1053 // Address
1054 if ($fromcompany->address) {
1055 $line1 .= ($line1 ? " - " : "").str_replace("\n", ", ", $fromcompany->address);
1056 }
1057 // Zip code
1058 if ($fromcompany->zip) {
1059 $line1 .= ($line1 ? " - " : "").$fromcompany->zip;
1060 }
1061 // Town
1062 if ($fromcompany->town) {
1063 $line1 .= ($line1 ? " " : "").$fromcompany->town;
1064 }
1065 // Country
1066 if ($fromcompany->country) {
1067 $line1 .= ($line1 ? ", " : "").$fromcompany->country;
1068 }
1069 // Phone
1070 if ($fromcompany->phone) {
1071 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Phone").": ".$fromcompany->phone;
1072 }
1073 // Fax
1074 if ($fromcompany->fax) {
1075 $line2 .= ($line2 ? " - " : "").$outputlangs->transnoentities("Fax").": ".$fromcompany->fax;
1076 }
1077
1078 // URL
1079 if ($fromcompany->url) {
1080 $line2 .= ($line2 ? " - " : "").$fromcompany->url;
1081 }
1082 // Email
1083 if ($fromcompany->email) {
1084 $line2 .= ($line2 ? " - " : "").$fromcompany->email;
1085 }
1086 }
1087 if ($showdetails == 2 || $showdetails == 3 || (!empty($fromcompany->country_code) && $fromcompany->country_code == 'DE')) {
1088 // Managers
1089 if ($fromcompany->managers) {
1090 $line2 .= ($line2 ? " - " : "").$fromcompany->managers;
1091 }
1092 }
1093
1094 // Line 3 of company infos
1095 // Juridical status
1096 if (!empty($fromcompany->forme_juridique_code) && $fromcompany->forme_juridique_code) {
1097 $line3 .= ($line3 ? " - " : "").$outputlangs->convToOutputCharset(getFormeJuridiqueLabel($fromcompany->forme_juridique_code));
1098 }
1099 // Capital
1100 if (!empty($fromcompany->capital)) {
1101 $tmpamounttoshow = price2num($fromcompany->capital); // This field is a free string or a float
1102 if (is_numeric($tmpamounttoshow) && $tmpamounttoshow > 0) {
1103 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", price($tmpamounttoshow, 0, $outputlangs, 0, 0, 0, $conf->currency));
1104 } elseif (!empty($fromcompany->capital)) {
1105 $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", $fromcompany->capital, $outputlangs);
1106 }
1107 }
1108 // Prof Id 1
1109 if (!empty($fromcompany->idprof1) && $fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || !$fromcompany->idprof2)) {
1110 $field = $outputlangs->transcountrynoentities("ProfId1", $fromcompany->country_code);
1111 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1112 $field = $reg[1];
1113 }
1114 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof1);
1115 }
1116 // Prof Id 2
1117 if (!empty($fromcompany->idprof2) && $fromcompany->idprof2) {
1118 $field = $outputlangs->transcountrynoentities("ProfId2", $fromcompany->country_code);
1119 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1120 $field = $reg[1];
1121 }
1122 $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof2);
1123 }
1124
1125 // Line 4 of company infos
1126 // Prof Id 3
1127 if (!empty($fromcompany->idprof3) && $fromcompany->idprof3) {
1128 $field = $outputlangs->transcountrynoentities("ProfId3", $fromcompany->country_code);
1129 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1130 $field = $reg[1];
1131 }
1132 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof3);
1133 }
1134 // Prof Id 4
1135 if (!empty($fromcompany->idprof4) && $fromcompany->idprof4) {
1136 $field = $outputlangs->transcountrynoentities("ProfId4", $fromcompany->country_code);
1137 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1138 $field = $reg[1];
1139 }
1140 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof4);
1141 }
1142 // Prof Id 5
1143 if (!empty($fromcompany->idprof5) && $fromcompany->idprof5) {
1144 $field = $outputlangs->transcountrynoentities("ProfId5", $fromcompany->country_code);
1145 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1146 $field = $reg[1];
1147 }
1148 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof5);
1149 }
1150 // Prof Id 6
1151 if (!empty($fromcompany->idprof6) && $fromcompany->idprof6) {
1152 $field = $outputlangs->transcountrynoentities("ProfId6", $fromcompany->country_code);
1153 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1154 $field = $reg[1];
1155 }
1156 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof6);
1157 }
1158 // Prof Id 7
1159 if (!empty($fromcompany->idprof7) && $fromcompany->idprof7) {
1160 $field = $outputlangs->transcountrynoentities("ProfId7", $fromcompany->country_code);
1161 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1162 $field = $reg[1];
1163 }
1164 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof7);
1165 }
1166 // Prof Id 8
1167 if (!empty($fromcompany->idprof8) && $fromcompany->idprof8) {
1168 $field = $outputlangs->transcountrynoentities("ProfId8", $fromcompany->country_code);
1169 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1170 $field = $reg[1];
1171 }
1172 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof8);
1173 }
1174 // Prof Id 9
1175 if (!empty($fromcompany->idprof9) && $fromcompany->idprof9) {
1176 $field = $outputlangs->transcountrynoentities("ProfId9", $fromcompany->country_code);
1177 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1178 $field = $reg[1];
1179 }
1180 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof9);
1181 }
1182 // Prof Id 10
1183 if (!empty($fromcompany->idprof10) && $fromcompany->idprof10) {
1184 $field = $outputlangs->transcountrynoentities("ProfId10", $fromcompany->country_code);
1185 if (preg_match('/\‍((.*)\‍)/i', $field, $reg)) {
1186 $field = $reg[1];
1187 }
1188 $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof10);
1189 }
1190 // IntraCommunautary VAT
1191 if (!empty($fromcompany->tva_intra) && $fromcompany->tva_intra != '') {
1192 $line4 .= ($line4 ? " - " : "").$outputlangs->transnoentities("VATIntraShort").": ".$outputlangs->convToOutputCharset($fromcompany->tva_intra);
1193 }
1194
1195 $pdf->SetFont('', '', 7);
1196 $pdf->SetDrawColor(224, 224, 224);
1197 // Option for footer text color
1198 if (getDolGlobalString('PDF_FOOTER_TEXT_COLOR')) {
1199 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_TEXT_COLOR, '%d, %d, %d');
1200 $pdf->SetTextColor($r, $g, $b);
1201 }
1202
1203 // The start of the bottom of this page footer is positioned according to # of lines
1204 $freetextheight = 0;
1205 if ($line) { // Free text
1206 //$line="sample text<br>\nfd<strong>sf</strong>sdf<br>\nghfghg<br>";
1207 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) {
1208 $width = 20000;
1209 $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.
1210 if (getDolGlobalString('MAIN_USE_AUTOWRAP_ON_FREETEXT')) {
1211 $width = 200;
1212 $align = 'C';
1213 }
1214 $freetextheight = $pdf->getStringHeight($width, $line);
1215 } else {
1216 $freetextheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); // New method (works for HTML content)
1217 //print '<br>'.$freetextheight;exit;
1218 }
1219 }
1220
1221 // For customize footer
1222 if (is_object($hookmanager)) {
1223 $parameters = array('line1' => $line1, 'line2' => $line2, 'line3' => $line3, 'line4' => $line4, 'outputlangs'=>$outputlangs);
1224 $action = '';
1225 $hookmanager->executeHooks('pdf_pagefoot', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1226 if (!empty($hookmanager->resPrint) && $hidefreetext == 0) {
1227 $mycustomfooter = $hookmanager->resPrint;
1228 $mycustomfooterheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1229
1230 $marginwithfooter = $marge_basse + $freetextheight + $mycustomfooterheight;
1231 $posy = (float) $marginwithfooter;
1232
1233 // Option for footer background color (without freetext zone)
1234 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1235 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1236 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1237 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b));
1238 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1239 }
1240
1241 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1242 $pdf->SetAutoPageBreak(0, 0);
1243 } // Option for disable auto pagebreak
1244 if ($line) { // Free text
1245 $pdf->SetXY($dims['lm'], -$posy);
1246 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1247 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1248 } else {
1249 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1250 }
1251 $posy -= $freetextheight;
1252 }
1253 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1254 $pdf->SetAutoPageBreak(1, 0);
1255 } // Restore pagebreak
1256
1257 $pdf->SetY(-$posy);
1258
1259 // Hide footer line if footer background color is set
1260 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1261 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1262 }
1263
1264 // Option for set top margin height of footer after freetext
1265 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1266 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1267 } else {
1268 $posy--;
1269 }
1270
1271 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1272 $pdf->SetAutoPageBreak(0, 0);
1273 } // Option for disable auto pagebreak
1274 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0));
1275 if (getDolGlobalInt('PDF_FOOTER_DISABLE_PAGEBREAK') === 1) {
1276 $pdf->SetAutoPageBreak(1, 0);
1277 } // Restore pagebreak
1278
1279 $posy -= $mycustomfooterheight - 3;
1280 } else {
1281 // Else default footer
1282 $marginwithfooter = $marge_basse + $freetextheight + (!empty($line1) ? 3 : 0) + (!empty($line2) ? 3 : 0) + (!empty($line3) ? 3 : 0) + (!empty($line4) ? 3 : 0);
1283 $posy = (float) $marginwithfooter;
1284
1285 // Option for footer background color (without freetext zone)
1286 if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1287 list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d');
1288 $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak
1289 $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b));
1290 $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak
1291 }
1292
1293 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1294 $pdf->SetAutoPageBreak(0, 0);
1295 } // Option for disable auto pagebreak
1296 if ($line) { // Free text
1297 $pdf->SetXY($dims['lm'], -$posy);
1298 if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default
1299 $pdf->MultiCell(0, 3, $line, 0, $align, 0);
1300 } else {
1301 $pdf->writeHTMLCell($dims['wk'] - $dims['lm'] - $dims['rm'], $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
1302 }
1303 $posy -= $freetextheight;
1304 }
1305 if (getDolGlobalInt('PDF_FREETEXT_DISABLE_PAGEBREAK') === 1) {
1306 $pdf->SetAutoPageBreak(1, 0);
1307 } // Restore pagebreak
1308
1309 $pdf->SetY(-$posy);
1310
1311 // Option for hide all footer (page number will no hidden)
1312 if (!getDolGlobalInt('PDF_FOOTER_HIDDEN')) {
1313 // Hide footer line if footer background color is set
1314 if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) {
1315 $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy);
1316 }
1317
1318 // Option for set top margin height of footer after freetext
1319 if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) {
1320 $posy -= (float) getDolGlobalString('PDF_FOOTER_TOP_MARGIN');
1321 } else {
1322 $posy--;
1323 }
1324
1325 if (!empty($line1)) {
1326 $pdf->SetFont('', 'B', 7);
1327 $pdf->SetXY($dims['lm'], -$posy);
1328 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line1, 0, 'C', 0);
1329 $posy -= 3;
1330 $pdf->SetFont('', '', 7);
1331 }
1332
1333 if (!empty($line2)) {
1334 $pdf->SetFont('', 'B', 7);
1335 $pdf->SetXY($dims['lm'], -$posy);
1336 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line2, 0, 'C', 0);
1337 $posy -= 3;
1338 $pdf->SetFont('', '', 7);
1339 }
1340
1341 if (!empty($line3)) {
1342 $pdf->SetXY($dims['lm'], -$posy);
1343 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line3, 0, 'C', 0);
1344 }
1345
1346 if (!empty($line4)) {
1347 $posy -= 3;
1348 $pdf->SetXY($dims['lm'], -$posy);
1349 $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line4, 0, 'C', 0);
1350 }
1351 }
1352 }
1353 }
1354
1355 // Show page nb and apply correction for some font.
1356 $pdf->SetXY($dims['wk'] - $dims['rm'] - 18 - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_X', 0), -$posy - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_Y', 0));
1357 $pagination = $pdf->PageNo().' / '.$pdf->getAliasNbPages();
1358 $fontRenderCorrection = 0;
1359 if (in_array(pdf_getPDFFont($outputlangs), array('freemono', 'DejaVuSans'))) {
1360 $fontRenderCorrection = 10;
1361 }
1362 $pdf->MultiCell(18 + $fontRenderCorrection, 2, $pagination, 0, 'R', 0);
1363
1364 // Show Draft Watermark
1365 if (!empty($watermark)) {
1366 pdf_watermark($pdf, $outputlangs, $page_hauteur, $page_largeur, 'mm', $watermark);
1367 }
1368
1369 return $marginwithfooter;
1370}
1371
1386function pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, $h, $align, $default_font_size)
1387{
1388 $linkedobjects = pdf_getLinkedObjects($object, $outputlangs);
1389 if (!empty($linkedobjects)) {
1390 foreach ($linkedobjects as $linkedobject) {
1391 $reftoshow = $linkedobject["ref_title"].' : '.$linkedobject["ref_value"];
1392 if (!empty($linkedobject["date_value"])) {
1393 $reftoshow .= ' / '.$linkedobject["date_value"];
1394 }
1395
1396 $posy += 3;
1397 $pdf->SetXY($posx, $posy);
1398 $pdf->SetFont('', '', $default_font_size - 2);
1399 $pdf->MultiCell($w, $h, $reftoshow, '', $align);
1400 }
1401 }
1402
1403 return $pdf->getY();
1404}
1405
1422function pdf_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $posy, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1423{
1424 global $db, $conf, $langs, $hookmanager;
1425
1426 $reshook = 0;
1427 $result = '';
1428 //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) ) )
1429 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
1430 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1431 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1432 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1433 }
1434 $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);
1435 $action = '';
1436 $reshook = $hookmanager->executeHooks('pdf_writelinedesc', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1437
1438 if (!empty($hookmanager->resPrint)) {
1439 $result .= $hookmanager->resPrint;
1440 }
1441 }
1442 if (empty($reshook)) {
1443 $labelproductservice = pdf_getlinedesc($object, $i, $outputlangs, $hideref, $hidedesc, $issupplierline);
1444
1445 //var_dump($labelproductservice);exit;
1446
1447 // 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"
1448 // We make the reverse, so PDF generation has the real URL.
1449 $nbrep = 0;
1450 $labelproductservice = preg_replace('/(<img[^>]*src=")([^"]*)(&amp;)([^"]*")/', '\1\2&\4', $labelproductservice, -1, $nbrep);
1451
1452 if (getDolGlobalString('MARGIN_TOP_ZERO_UL')) {
1453 $pdf->setListIndentWidth(5);
1454 $TMarginList = ['ul' => [['h'=>0.1, ],['h'=>0.1, ]], 'li' => [['h'=>0.1, ],],];
1455 $pdf->setHtmlVSpace($TMarginList);
1456 }
1457
1458 // Description
1459 $pdf->writeHTMLCell($w, $h, $posx, $posy, $outputlangs->convToOutputCharset($labelproductservice), 0, 1, false, true, 'J', true);
1460 $result .= $labelproductservice;
1461 }
1462 return $result;
1463}
1464
1476function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
1477{
1478 global $db, $conf, $langs;
1479
1480 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1481 $label = (!empty($object->lines[$i]->label) ? $object->lines[$i]->label : (!empty($object->lines[$i]->product_label) ? $object->lines[$i]->product_label : ''));
1482 $product_barcode = (!empty($object->lines[$i]->product_barcode) ? $object->lines[$i]->product_barcode : "");
1483 $desc = (!empty($object->lines[$i]->desc) ? $object->lines[$i]->desc : (!empty($object->lines[$i]->description) ? $object->lines[$i]->description : ''));
1484 $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
1485 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1486 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1487
1488 $multilangsactive = getDolGlobalInt('MAIN_MULTILANGS');
1489
1490 if ($issupplierline) {
1491 include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
1492 $prodser = new ProductFournisseur($db);
1493 } else {
1494 include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1495 $prodser = new Product($db);
1496
1497 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
1498 include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
1499 }
1500 }
1501
1502 //id
1503 $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false);
1504 if ($idprod) {
1505 $prodser->fetch($idprod);
1506 //load multilangs
1507 if ($multilangsactive) {
1508 $prodser->getMultiLangs();
1509 $object->lines[$i]->multilangs = $prodser->multilangs;
1510 }
1511 }
1512 //label
1513 if (!empty($object->lines[$i]->label)) {
1514 $label = $object->lines[$i]->label;
1515 } else {
1516 if (!empty($object->lines[$i]->multilangs[$outputlangs->defaultlang]['label']) && $multilangsactive) {
1517 $label = $object->lines[$i]->multilangs[$outputlangs->defaultlang]['label'];
1518 } else {
1519 if (!empty($object->lines[$i]->product_label)) {
1520 $label = $object->lines[$i]->product_label;
1521 } else {
1522 $label = '';
1523 }
1524 }
1525 }
1526 //description
1527 if (!empty($object->lines[$i]->desc)) {
1528 $desc = $object->lines[$i]->desc;
1529 } else {
1530 if (!empty($object->lines[$i]->multilangs[$outputlangs->defaultlang]['description']) && $multilangsactive) {
1531 $desc = $object->lines[$i]->multilangs[$outputlangs->defaultlang]['description'];
1532 } else {
1533 if (!empty($object->lines[$i]->description)) {
1534 $desc = $object->lines[$i]->description;
1535 } else {
1536 $desc = '';
1537 }
1538 }
1539 }
1540 //ref supplier
1541 $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
1542 //note
1543 $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
1544 //dbatch
1545 $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
1546
1547 if ($idprod) {
1548 // If a predefined product and multilang and on other lang, we renamed label with label translated
1549 if ($multilangsactive && ($outputlangs->defaultlang != $langs->defaultlang)) {
1550 $translatealsoifmodified = getDolGlobalString('MAIN_MULTILANG_TRANSLATE_EVEN_IF_MODIFIED'); // By default if value was modified manually, we keep it (no translation because we don't have it)
1551
1552 // 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
1553 // ($textwasnotmodified is replaced with $textwasmodifiedorcompleted and we add completion).
1554
1555 // Set label
1556 // 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.
1557 //var_dump($outputlangs->defaultlang.' - '.$langs->defaultlang.' - '.$label.' - '.$prodser->label);exit;
1558 $textwasnotmodified = ($label == $prodser->label);
1559 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["label"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1560 $label = $prodser->multilangs[$outputlangs->defaultlang]["label"];
1561 }
1562
1563 // Set desc
1564 // Manage HTML entities description test because $prodser->description is store with htmlentities but $desc no
1565 $textwasnotmodified = false;
1566 if (!empty($desc) && dol_textishtml($desc) && !empty($prodser->description) && dol_textishtml($prodser->description)) {
1567 $textwasnotmodified = (strpos(dol_html_entity_decode($desc, ENT_QUOTES | ENT_HTML5), dol_html_entity_decode($prodser->description, ENT_QUOTES | ENT_HTML5)) !== false);
1568 } else {
1569 $textwasnotmodified = ($desc == $prodser->description);
1570 }
1571 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["description"])) {
1572 if ($textwasnotmodified) {
1573 $desc = str_replace($prodser->description, $prodser->multilangs[$outputlangs->defaultlang]["description"], $desc);
1574 } elseif ($translatealsoifmodified) {
1575 $desc = $prodser->multilangs[$outputlangs->defaultlang]["description"];
1576 }
1577 }
1578
1579 // Set note
1580 $textwasnotmodified = ($note == $prodser->note_public);
1581 if (!empty($prodser->multilangs[$outputlangs->defaultlang]["other"]) && ($textwasnotmodified || $translatealsoifmodified)) {
1582 $note = $prodser->multilangs[$outputlangs->defaultlang]["other"];
1583 }
1584 }
1585 } 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
1586 $desc = str_replace('(DEPOSIT)', $outputlangs->trans('Deposit'), $desc);
1587 }
1588
1589 if (!getDolGlobalString('PDF_HIDE_PRODUCT_LABEL_IN_SUPPLIER_LINES')) {
1590 // Description short of product line
1591 $libelleproduitservice = $label;
1592 if (!empty($libelleproduitservice) && getDolGlobalString('PDF_BOLD_PRODUCT_LABEL')) {
1593 // Adding <b> may convert the original string into a HTML string. Sowe have to first
1594 // convert \n into <br> we text is not already HTML.
1595 if (!dol_textishtml($libelleproduitservice)) {
1596 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1597 }
1598 $libelleproduitservice = '<b>'.$libelleproduitservice.'</b>';
1599 }
1600 }
1601
1602
1603 // Add ref of subproducts
1604 if (getDolGlobalString('SHOW_SUBPRODUCT_REF_IN_PDF')) {
1605 $prodser->get_sousproduits_arbo();
1606 if (!empty($prodser->sousprods) && is_array($prodser->sousprods) && count($prodser->sousprods)) {
1607 $outputlangs->load('mrp');
1608 $tmparrayofsubproducts = reset($prodser->sousprods);
1609
1610 $qtyText = null;
1611 if (isset($object->lines[$i]->qty) && !empty($object->lines[$i]->qty)) {
1612 $qtyText = $object->lines[$i]->qty;
1613 } elseif (isset($object->lines[$i]->qty_shipped) && !empty($object->lines[$i]->qty_shipped)) {
1614 $qtyText = $object->lines[$i]->qty;
1615 }
1616
1617 if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF')) {
1618 foreach ($tmparrayofsubproducts as $subprodval) {
1619 $libelleproduitservice = dol_concatdesc(
1620 dol_concatdesc($libelleproduitservice, " * ".$subprodval[3]),
1621 (!empty($qtyText) ?
1622 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1]*$qtyText :
1623 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1624 );
1625 }
1626 } else {
1627 foreach ($tmparrayofsubproducts as $subprodval) {
1628 $libelleproduitservice = dol_concatdesc(
1629 dol_concatdesc($libelleproduitservice, " * ".$subprodval[5].(($subprodval[5] && $subprodval[3]) ? ' - ' : '').$subprodval[3]),
1630 (!empty($qtyText) ?
1631 $outputlangs->trans('Qty').':'.$qtyText.' x '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1].'= '.$outputlangs->trans('QtyTot').':'.$subprodval[1]*$qtyText :
1632 $outputlangs->trans('Qty').' '.$outputlangs->trans('AssociatedProducts').':'.$subprodval[1])
1633 );
1634 }
1635 }
1636 }
1637 }
1638
1639 if (isModEnabled('barcode') && getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_PRODUCT_BARCODE') && !empty($product_barcode)) {
1640 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $outputlangs->trans("BarCode")." ".$product_barcode);
1641 }
1642
1643 // Description long of product line
1644 if (!empty($desc) && ($desc != $label)) {
1645 if ($desc == '(CREDIT_NOTE)' && $object->lines[$i]->fk_remise_except) {
1646 $discount = new DiscountAbsolute($db);
1647 $discount->fetch($object->lines[$i]->fk_remise_except);
1648 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1649 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromCreditNote", $sourceref);
1650 } elseif ($desc == '(DEPOSIT)' && $object->lines[$i]->fk_remise_except) {
1651 $discount = new DiscountAbsolute($db);
1652 $discount->fetch($object->lines[$i]->fk_remise_except);
1653 $sourceref = !empty($discount->discount_type) ? $discount->ref_invoice_supplier_source : $discount->ref_facture_source;
1654 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromDeposit", $sourceref);
1655 // Add date of deposit
1656 if (getDolGlobalString('INVOICE_ADD_DEPOSIT_DATE')) {
1657 $libelleproduitservice .= ' ('.dol_print_date($discount->datec, 'day', '', $outputlangs).')';
1658 }
1659 } elseif ($desc == '(EXCESS RECEIVED)' && $object->lines[$i]->fk_remise_except) {
1660 $discount = new DiscountAbsolute($db);
1661 $discount->fetch($object->lines[$i]->fk_remise_except);
1662 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived", $discount->ref_facture_source);
1663 } elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except) {
1664 $discount = new DiscountAbsolute($db);
1665 $discount->fetch($object->lines[$i]->fk_remise_except);
1666 $libelleproduitservice = $outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid", $discount->ref_invoice_supplier_source);
1667 } else {
1668 if ($idprod) {
1669 // Check if description must be output
1670 if (!empty($object->element)) {
1671 $tmpkey = 'MAIN_DOCUMENTS_HIDE_DESCRIPTION_FOR_'.strtoupper($object->element);
1672 if (!empty($conf->global->$tmpkey)) {
1673 $hidedesc = 1;
1674 }
1675 }
1676 if (empty($hidedesc)) {
1677 if (getDolGlobalString('MAIN_DOCUMENTS_DESCRIPTION_FIRST')) {
1678 $libelleproduitservice = dol_concatdesc($desc, $libelleproduitservice);
1679 } else {
1680 if (getDolGlobalString('HIDE_LABEL_VARIANT_PDF') && $prodser->isVariant()) {
1681 $libelleproduitservice = $desc;
1682 } else {
1683 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1684 }
1685 }
1686 }
1687 } else {
1688 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desc);
1689 }
1690 }
1691 }
1692
1693 // We add ref of product (and supplier ref if defined)
1694 $prefix_prodserv = "";
1695 $ref_prodserv = "";
1696 if (getDolGlobalString('PRODUCT_ADD_TYPE_IN_DOCUMENTS')) { // In standard mode, we do not show this
1697 if ($prodser->isService()) {
1698 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." ";
1699 } else {
1700 $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." ";
1701 }
1702 }
1703
1704 if (empty($hideref)) {
1705 if ($issupplierline) {
1706 if (!getDolGlobalString('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES')) { // Common case
1707 $ref_prodserv = $prodser->ref; // Show local ref
1708 if ($ref_supplier) {
1709 $ref_prodserv .= ($prodser->ref ? ' (' : '').$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.($prodser->ref ? ')' : '');
1710 }
1711 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 1) {
1712 $ref_prodserv = $ref_supplier;
1713 } elseif (getDolGlobalInt('PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES') == 2) {
1714 $ref_prodserv = $ref_supplier.' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')';
1715 }
1716 } else {
1717 $ref_prodserv = $prodser->ref; // Show local ref only
1718
1719 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
1720 $productCustomerPriceStatic = new ProductCustomerPrice($db);
1721 $filter = array('fk_product' => $idprod, 'fk_soc' => $object->socid);
1722
1723 $nbCustomerPrices = $productCustomerPriceStatic->fetchAll('', '', 1, 0, $filter);
1724
1725 if ($nbCustomerPrices > 0) {
1726 $productCustomerPrice = $productCustomerPriceStatic->lines[0];
1727
1728 if (!empty($productCustomerPrice->ref_customer)) {
1729 switch ($conf->global->PRODUIT_CUSTOMER_PRICES_PDF_REF_MODE) {
1730 case 1:
1731 $ref_prodserv = $productCustomerPrice->ref_customer;
1732 break;
1733
1734 case 2:
1735 $ref_prodserv = $productCustomerPrice->ref_customer . ' (' . $outputlangs->transnoentitiesnoconv('InternalRef') . ' ' . $ref_prodserv . ')';
1736 break;
1737
1738 default:
1739 $ref_prodserv = $ref_prodserv . ' (' . $outputlangs->transnoentitiesnoconv('RefCustomer') . ' ' . $productCustomerPrice->ref_customer . ')';
1740 }
1741 }
1742 }
1743 }
1744 }
1745
1746 if (!empty($libelleproduitservice) && !empty($ref_prodserv)) {
1747 $ref_prodserv .= " - ";
1748 }
1749 }
1750
1751 if (!empty($ref_prodserv) && getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1752 if (!dol_textishtml($libelleproduitservice)) {
1753 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1754 }
1755 $ref_prodserv = '<b>'.$ref_prodserv.'</b>';
1756 // $prefix_prodserv and $ref_prodser are not HTML var
1757 }
1758 $libelleproduitservice = $prefix_prodserv.$ref_prodserv.$libelleproduitservice;
1759
1760 // Add an additional description for the category products
1761 if (getDolGlobalString('CATEGORY_ADD_DESC_INTO_DOC') && $idprod && isModEnabled('categorie')) {
1762 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1763 $categstatic = new Categorie($db);
1764 // recovering the list of all the categories linked to product
1765 $tblcateg = $categstatic->containing($idprod, Categorie::TYPE_PRODUCT);
1766 foreach ($tblcateg as $cate) {
1767 // Adding the descriptions if they are filled
1768 $desccateg = $cate->description;
1769 if ($desccateg) {
1770 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $desccateg);
1771 }
1772 }
1773 }
1774
1775 if (!empty($object->lines[$i]->date_start) || !empty($object->lines[$i]->date_end)) {
1776 $format = 'day';
1777 $period = '';
1778 // Show duration if exists
1779 if ($object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1780 $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)).')';
1781 }
1782 if ($object->lines[$i]->date_start && !$object->lines[$i]->date_end) {
1783 $period = '('.$outputlangs->transnoentitiesnoconv('DateFrom', dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs)).')';
1784 }
1785 if (!$object->lines[$i]->date_start && $object->lines[$i]->date_end) {
1786 $period = '('.$outputlangs->transnoentitiesnoconv('DateUntil', dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
1787 }
1788 //print '>'.$outputlangs->charset_output.','.$period;
1789 if (getDolGlobalString('PDF_BOLD_PRODUCT_REF_AND_PERIOD')) {
1790 if (!dol_textishtml($libelleproduitservice)) {
1791 $libelleproduitservice = str_replace("\n", '<br>', $libelleproduitservice);
1792 }
1793 $libelleproduitservice .= '<br><b style="color:#333666;" ><em>'.$period.'</em></b>';
1794 } else {
1795 $libelleproduitservice = dol_concatdesc($libelleproduitservice, $period);
1796 }
1797 //print $libelleproduitservice;
1798 }
1799
1800 // Show information for lot
1801 if (!empty($dbatch)) {
1802 // $object is a shipment.
1803 //var_dump($object->lines[$i]->details_entrepot); // array from llx_expeditiondet (we can have several lines for one fk_origin_line)
1804 //var_dump($object->lines[$i]->detail_batch); // array from llx_expeditiondet_batch (each line with a lot is linked to llx_expeditiondet)
1805
1806 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1807 include_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
1808 $tmpwarehouse = new Entrepot($db);
1809 $tmpproductbatch = new Productbatch($db);
1810
1811 $format = 'day';
1812 foreach ($dbatch as $detail) {
1813 $dte = array();
1814 if ($detail->eatby) {
1815 $dte[] = $outputlangs->transnoentitiesnoconv('printEatby', dol_print_date($detail->eatby, $format, false, $outputlangs));
1816 }
1817 if ($detail->sellby) {
1818 $dte[] = $outputlangs->transnoentitiesnoconv('printSellby', dol_print_date($detail->sellby, $format, false, $outputlangs));
1819 }
1820 if ($detail->batch) {
1821 $dte[] = $outputlangs->transnoentitiesnoconv('printBatch', $detail->batch);
1822 }
1823 $dte[] = $outputlangs->transnoentitiesnoconv('printQty', $detail->qty);
1824
1825 // Add also info of planned warehouse for lot
1826 if ($object->element == 'shipping' && $detail->fk_origin_stock > 0 && getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1827 $resproductbatch = $tmpproductbatch->fetch($detail->fk_origin_stock);
1828 if ($resproductbatch > 0) {
1829 $reswarehouse = $tmpwarehouse->fetch($tmpproductbatch->warehouseid);
1830 if ($reswarehouse > 0) {
1831 $dte[] = $tmpwarehouse->ref;
1832 }
1833 }
1834 }
1835
1836 $libelleproduitservice .= "__N__ ".implode(" - ", $dte);
1837 }
1838 } else {
1839 if (getDolGlobalInt('PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT')) {
1840 // TODO Show warehouse for shipment line without batch
1841 }
1842 }
1843
1844 // Now we convert \n into br
1845 if (dol_textishtml($libelleproduitservice)) {
1846 $libelleproduitservice = preg_replace('/__N__/', '<br>', $libelleproduitservice);
1847 } else {
1848 $libelleproduitservice = preg_replace('/__N__/', "\n", $libelleproduitservice);
1849 }
1850 $libelleproduitservice = dol_htmlentitiesbr($libelleproduitservice, 1);
1851
1852 return $libelleproduitservice;
1853}
1854
1864function pdf_getlinenum($object, $i, $outputlangs, $hidedetails = 0)
1865{
1866 global $hookmanager;
1867
1868 $reshook = 0;
1869 $result = '';
1870 //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) ) )
1871 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
1872 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1873 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1874 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1875 }
1876 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1877 $action = '';
1878 $reshook = $hookmanager->executeHooks('pdf_getlinenum', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1879 $result .= $hookmanager->resPrint;
1880 }
1881 if (empty($reshook)) {
1882 $result .= dol_htmlentitiesbr($object->lines[$i]->num);
1883 }
1884 return $result;
1885}
1886
1887
1897function pdf_getlineref($object, $i, $outputlangs, $hidedetails = 0)
1898{
1899 global $hookmanager;
1900
1901 $reshook = 0;
1902 $result = '';
1903 //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) ) )
1904 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
1905 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1906 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1907 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1908 }
1909 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1910 $action = '';
1911 $reshook = $hookmanager->executeHooks('pdf_getlineref', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1912 $result .= $hookmanager->resPrint;
1913 }
1914 if (empty($reshook)) {
1915 $result .= dol_htmlentitiesbr($object->lines[$i]->product_ref);
1916 }
1917 return $result;
1918}
1919
1929function pdf_getlineref_supplier($object, $i, $outputlangs, $hidedetails = 0)
1930{
1931 global $hookmanager;
1932
1933 $reshook = 0;
1934 $result = '';
1935 //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) ) )
1936 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
1937 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1938 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1939 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1940 }
1941 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1942 $action = '';
1943 $reshook = $hookmanager->executeHooks('pdf_getlineref_supplier', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1944 $result .= $hookmanager->resPrint;
1945 }
1946 if (empty($reshook)) {
1947 $result .= dol_htmlentitiesbr($object->lines[$i]->ref_supplier);
1948 }
1949 return $result;
1950}
1951
1961function pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails = 0)
1962{
1963 global $conf, $hookmanager, $mysoc;
1964
1965 $result = '';
1966 $reshook = 0;
1967 //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) ) )
1968 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
1969 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
1970 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
1971 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1972 }
1973 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
1974 $action = '';
1975 $reshook = $hookmanager->executeHooks('pdf_getlinevatrate', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1976
1977 if (!empty($hookmanager->resPrint)) {
1978 $result .= $hookmanager->resPrint;
1979 }
1980 }
1981 if (empty($reshook)) {
1982 if (empty($hidedetails) || $hidedetails > 1) {
1983 $tmpresult = '';
1984
1985 $tmpresult .= vatrate($object->lines[$i]->tva_tx, 0, $object->lines[$i]->info_bits, -1);
1986 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_SECOND_TAX')) {
1987 if ($object->lines[$i]->total_localtax1 != 0) {
1988 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
1989 $tmpresult .= '/';
1990 } else {
1991 $tmpresult = '';
1992 }
1993 $tmpresult .= vatrate(abs($object->lines[$i]->localtax1_tx), 0);
1994 }
1995 }
1996 if (!getDolGlobalString('MAIN_PDF_MAIN_HIDE_THIRD_TAX')) {
1997 if ($object->lines[$i]->total_localtax2 != 0) {
1998 if (preg_replace('/[\s0%]/', '', $tmpresult)) {
1999 $tmpresult .= '/';
2000 } else {
2001 $tmpresult = '';
2002 }
2003 $tmpresult .= vatrate(abs($object->lines[$i]->localtax2_tx), 0);
2004 }
2005 }
2006 $tmpresult .= '%';
2007
2008 $result .= $tmpresult;
2009 }
2010 }
2011 return $result;
2012}
2013
2023function pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails = 0)
2024{
2025 global $conf, $hookmanager;
2026
2027 $sign = 1;
2028 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2029 $sign = -1;
2030 }
2031
2032 $result = '';
2033 $reshook = 0;
2034 //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) ) )
2035 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
2036 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2037 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2038 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2039 }
2040 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2041 $action = '';
2042 $reshook = $hookmanager->executeHooks('pdf_getlineupexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2043
2044 if (!empty($hookmanager->resPrint)) {
2045 $result .= $hookmanager->resPrint;
2046 }
2047 }
2048 if (empty($reshook)) {
2049 if (empty($hidedetails) || $hidedetails > 1) {
2050 $subprice = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_subprice : $object->lines[$i]->subprice);
2051 $result .= price($sign * $subprice, 0, $outputlangs);
2052 }
2053 }
2054 return $result;
2055}
2056
2066function pdf_getlineupwithtax($object, $i, $outputlangs, $hidedetails = 0)
2067{
2068 global $hookmanager, $conf;
2069
2070 $sign = 1;
2071 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2072 $sign = -1;
2073 }
2074
2075 $result = '';
2076 $reshook = 0;
2077 //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) ) )
2078 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
2079 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2080 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2081 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2082 }
2083 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2084 $action = '';
2085 $reshook = $hookmanager->executeHooks('pdf_getlineupwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2086
2087 if (!empty($hookmanager->resPrint)) {
2088 $result .= $hookmanager->resPrint;
2089 }
2090 }
2091 if (empty($reshook)) {
2092 if (empty($hidedetails) || $hidedetails > 1) {
2093 $result .= price($sign * (($object->lines[$i]->subprice) + ($object->lines[$i]->subprice) * ($object->lines[$i]->tva_tx) / 100), 0, $outputlangs);
2094 }
2095 }
2096 return $result;
2097}
2098
2108function pdf_getlineqty($object, $i, $outputlangs, $hidedetails = 0)
2109{
2110 global $hookmanager;
2111
2112 $result = '';
2113 $reshook = 0;
2114 //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) ) )
2115 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
2116 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2117 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2118 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2119 }
2120 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2121 $action = '';
2122 $reshook = $hookmanager->executeHooks('pdf_getlineqty', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2123
2124 if (!empty($hookmanager->resPrint)) {
2125 $result = $hookmanager->resPrint;
2126 }
2127 }
2128 if (empty($reshook)) {
2129 if ($object->lines[$i]->special_code == 3) {
2130 return '';
2131 }
2132 if (empty($hidedetails) || $hidedetails > 1) {
2133 $result .= $object->lines[$i]->qty;
2134 }
2135 }
2136 return $result;
2137}
2138
2148function pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails = 0)
2149{
2150 global $hookmanager;
2151
2152 $reshook = 0;
2153 $result = '';
2154 //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) ) )
2155 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
2156 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2157 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2158 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2159 }
2160 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2161 $action = '';
2162 $reshook = $hookmanager->executeHooks('pdf_getlineqty_asked', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2163
2164 if (!empty($hookmanager->resPrint)) {
2165 $result .= $hookmanager->resPrint;
2166 }
2167 }
2168 if (empty($reshook)) {
2169 if ($object->lines[$i]->special_code == 3) {
2170 return '';
2171 }
2172 if (empty($hidedetails) || $hidedetails > 1) {
2173 $result .= $object->lines[$i]->qty_asked;
2174 }
2175 }
2176 return $result;
2177}
2178
2188function pdf_getlineqty_shipped($object, $i, $outputlangs, $hidedetails = 0)
2189{
2190 global $hookmanager;
2191
2192 $reshook = 0;
2193 $result = '';
2194 //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) ) )
2195 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
2196 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2197 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2198 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2199 }
2200 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2201 $action = '';
2202 $reshook = $hookmanager->executeHooks('pdf_getlineqty_shipped', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2203
2204 if (!empty($hookmanager->resPrint)) {
2205 $result .= $hookmanager->resPrint;
2206 }
2207 }
2208 if (empty($reshook)) {
2209 if ($object->lines[$i]->special_code == 3) {
2210 return '';
2211 }
2212 if (empty($hidedetails) || $hidedetails > 1) {
2213 $result .= $object->lines[$i]->qty_shipped;
2214 }
2215 }
2216 return $result;
2217}
2218
2228function pdf_getlineqty_keeptoship($object, $i, $outputlangs, $hidedetails = 0)
2229{
2230 global $hookmanager;
2231
2232 $reshook = 0;
2233 $result = '';
2234 //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) ) )
2235 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
2236 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2237 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2238 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2239 }
2240 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2241 $action = '';
2242 $reshook = $hookmanager->executeHooks('pdf_getlineqty_keeptoship', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2243
2244 if (!empty($hookmanager->resPrint)) {
2245 $result .= $hookmanager->resPrint;
2246 }
2247 }
2248 if (empty($reshook)) {
2249 if ($object->lines[$i]->special_code == 3) {
2250 return '';
2251 }
2252 if (empty($hidedetails) || $hidedetails > 1) {
2253 $result .= ($object->lines[$i]->qty_asked - $object->lines[$i]->qty_shipped);
2254 }
2255 }
2256 return $result;
2257}
2258
2269function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = false)
2270{
2271 global $langs;
2272
2273 $reshook = 0;
2274 $result = '';
2275 //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) ) )
2276 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
2277 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2278 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2279 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2280 }
2281 $parameters = array(
2282 'i' => $i,
2283 'outputlangs' => $outputlangs,
2284 'hidedetails' => $hidedetails,
2285 'special_code' => $special_code
2286 );
2287 $action = '';
2288 $reshook = $hookmanager->executeHooks('pdf_getlineunit', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2289
2290 if (!empty($hookmanager->resPrint)) {
2291 $result .= $hookmanager->resPrint;
2292 }
2293 }
2294 if (empty($reshook)) {
2295 if (empty($hidedetails) || $hidedetails > 1) {
2296 $result .= $langs->transnoentitiesnoconv($object->lines[$i]->getLabelOfUnit('short'));
2297 }
2298 }
2299 return $result;
2300}
2301
2302
2312function pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails = 0)
2313{
2314 global $hookmanager;
2315
2316 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2317
2318 $reshook = 0;
2319 $result = '';
2320 //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) ) )
2321 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
2322 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2323 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2324 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2325 }
2326 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2327 $action = '';
2328 $reshook = $hookmanager->executeHooks('pdf_getlineremisepercent', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2329
2330 if (!empty($hookmanager->resPrint)) {
2331 $result .= $hookmanager->resPrint;
2332 }
2333 }
2334 if (empty($reshook)) {
2335 if ($object->lines[$i]->special_code == 3) {
2336 return '';
2337 }
2338 if (empty($hidedetails) || $hidedetails > 1) {
2339 $result .= dol_print_reduction($object->lines[$i]->remise_percent, $outputlangs);
2340 }
2341 }
2342 return $result;
2343}
2344
2355function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = null)
2356{
2357 if (empty($hookmanager)) {
2358 global $hookmanager;
2359 }
2360 global $conf;
2361
2362 $reshook = 0;
2363 $result = '';
2364 //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) ) )
2365 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
2366 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2367 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2368 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2369 }
2370 $parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
2371 $action = '';
2372 $reshook = $hookmanager->executeHooks('pdf_getlineprogress', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2373
2374 if (!empty($hookmanager->resPrint)) {
2375 return $hookmanager->resPrint;
2376 }
2377 }
2378 if (empty($reshook)) {
2379 if ($object->lines[$i]->special_code == 3) {
2380 return '';
2381 }
2382 if (empty($hidedetails) || $hidedetails > 1) {
2383 if (getDolGlobalString('SITUATION_DISPLAY_DIFF_ON_PDF')) {
2384 $prev_progress = 0;
2385 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2386 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2387 }
2388 $result = round($object->lines[$i]->situation_percent - $prev_progress, 1).'%';
2389 } else {
2390 $result = round($object->lines[$i]->situation_percent, 1).'%';
2391 }
2392 }
2393 }
2394 return $result;
2395}
2396
2406function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0)
2407{
2408 global $conf, $hookmanager;
2409
2410 $sign = 1;
2411 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2412 $sign = -1;
2413 }
2414
2415 $reshook = 0;
2416 $result = '';
2417 //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) ) )
2418 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
2419 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2420 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2421 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2422 }
2423 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code, 'sign'=>$sign);
2424 $action = '';
2425 $reshook = $hookmanager->executeHooks('pdf_getlinetotalexcltax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2426
2427 if (!empty($hookmanager->resPrint)) {
2428 $result .= $hookmanager->resPrint;
2429 }
2430 }
2431 if (empty($reshook)) {
2432 if (!empty($object->lines[$i]) && $object->lines[$i]->special_code == 3) {
2433 $result .= $outputlangs->transnoentities("Option");
2434 } elseif (empty($hidedetails) || $hidedetails > 1) {
2435 $total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht);
2436 if (!empty($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2437 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2438 $prev_progress = 0;
2439 $progress = 1;
2440 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2441 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2442 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2443 }
2444 $result .= price($sign * ($total_ht / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2445 } else {
2446 $result .= price($sign * $total_ht, 0, $outputlangs);
2447 }
2448 }
2449 }
2450 return $result;
2451}
2452
2462function pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails = 0)
2463{
2464 global $hookmanager, $conf;
2465
2466 $sign = 1;
2467 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2468 $sign = -1;
2469 }
2470
2471 $reshook = 0;
2472 $result = '';
2473 //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) ) )
2474 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
2475 $special_code = empty($object->lines[$i]->special_code) ? '' : $object->lines[$i]->special_code;
2476 if (!empty($object->lines[$i]->fk_parent_line) && $object->lines[$i]->fk_parent_line > 0) {
2477 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2478 }
2479 $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code);
2480 $action = '';
2481 $reshook = $hookmanager->executeHooks('pdf_getlinetotalwithtax', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2482
2483 if (!empty($hookmanager->resPrint)) {
2484 $result .= $hookmanager->resPrint;
2485 }
2486 }
2487 if (empty($reshook)) {
2488 if ($object->lines[$i]->special_code == 3) {
2489 $result .= $outputlangs->transnoentities("Option");
2490 } elseif (empty($hidedetails) || $hidedetails > 1) {
2491 $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ttc : $object->lines[$i]->total_ttc);
2492 if (isset($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
2493 // TODO Remove this. The total should be saved correctly in database instead of being modified here.
2494 $prev_progress = 0;
2495 $progress = 1;
2496 if (method_exists($object->lines[$i], 'get_prev_progress')) {
2497 $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
2498 $progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
2499 }
2500 $result .= price($sign * ($total_ttc / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
2501 } else {
2502 $result .= price($sign * $total_ttc, 0, $outputlangs);
2503 }
2504 }
2505 }
2506 return $result;
2507}
2508
2517function pdf_getLinkedObjects(&$object, $outputlangs)
2518{
2519 global $db, $hookmanager;
2520
2521 $linkedobjects = array();
2522
2523 $object->fetchObjectLinked();
2524
2525 foreach ($object->linkedObjects as $objecttype => $objects) {
2526 if ($objecttype == 'facture') {
2527 // 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.
2528 } elseif ($objecttype == 'propal' || $objecttype == 'supplier_proposal') {
2529 $outputlangs->load('propal');
2530
2531 foreach ($objects as $elementobject) {
2532 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefProposal");
2533 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2534 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DatePropal");
2535 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2536 }
2537 } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order') {
2538 $outputlangs->load('orders');
2539
2540 if (count($objects) > 1 && count($objects) <= (getDolGlobalInt("MAXREFONDOC") ? getDolGlobalInt("MAXREFONDOC") : 10)) {
2541 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' :');
2542 foreach ($objects as $elementobject) {
2543 $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.')').' ');
2544 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("OrderDate").' : '.dol_print_date($elementobject->date, 'day', '', $outputlangs));
2545 }
2546 } elseif (count($objects) == 1) {
2547 $elementobject = array_shift($objects);
2548 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder");
2549 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref).(!empty($elementobject->ref_client) ? ' ('.$elementobject->ref_client.')' : '').(!empty($elementobject->ref_supplier) ? ' ('.$elementobject->ref_supplier.')' : '');
2550 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate");
2551 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date, 'day', '', $outputlangs);
2552 }
2553 } elseif ($objecttype == 'contrat') {
2554 $outputlangs->load('contracts');
2555 foreach ($objects as $elementobject) {
2556 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefContract");
2557 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2558 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateContract");
2559 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat, 'day', '', $outputlangs);
2560 }
2561 } elseif ($objecttype == 'fichinter') {
2562 $outputlangs->load('interventions');
2563 foreach ($objects as $elementobject) {
2564 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("InterRef");
2565 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2566 $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("InterDate");
2567 $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->datec, 'day', '', $outputlangs);
2568 }
2569 } elseif ($objecttype == 'shipping') {
2570 $outputlangs->loadLangs(array("orders", "sendings"));
2571
2572 if (count($objects) > 1) {
2573 $order = null;
2574 if (empty($object->linkedObjects['commande']) && $object->element != 'commande') {
2575 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :');
2576 } else {
2577 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefSending").' :');
2578 }
2579 // We concat this record info into fields xxx_value. title is overwrote.
2580 foreach ($objects as $elementobject) {
2581 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
2582 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2583 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2584 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2585 $order = new Commande($db);
2586 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2587 if ($ret < 1) {
2588 $order = null;
2589 }
2590 }
2591 }
2592
2593 if (! is_object($order)) {
2594 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref));
2595 } else {
2596 $object->note_public = dol_concatdesc($object->note_public, $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : ''));
2597 $object->note_public = dol_concatdesc($object->note_public, ' / '.$outputlangs->transnoentities($elementobject->ref));
2598 }
2599 }
2600 } elseif (count($objects) == 1) {
2601 $elementobject = array_shift($objects);
2602 $order = null;
2603 // We concat this record info into fields xxx_value. title is overwrote.
2604 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
2605 $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0);
2606 if (!empty($elementobject->linkedObjectsIds['commande'])) {
2607 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
2608 $order = new Commande($db);
2609 $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande']));
2610 if ($ret < 1) {
2611 $order = null;
2612 }
2613 }
2614 }
2615
2616 if (! is_object($order)) {
2617 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
2618 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2619 $linkedobjects[$objecttype]['ref_value'] = '';
2620 } else {
2621 $linkedobjects[$objecttype]['ref_value'] .= ' / ';
2622 }
2623 $linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref);
2624 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2625 } else {
2626 $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending");
2627 if (empty($linkedobjects[$objecttype]['ref_value'])) {
2628 $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
2629 }
2630 $linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref);
2631 $linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
2632 }
2633 }
2634 }
2635 }
2636
2637 // For add external linked objects
2638 if (is_object($hookmanager)) {
2639 $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs'=>$outputlangs);
2640 $action = '';
2641 $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2642 if (!empty($hookmanager->resArray)) {
2643 $linkedobjects = $hookmanager->resArray;
2644 }
2645 }
2646
2647 return $linkedobjects;
2648}
2649
2657function pdf_getSizeForImage($realpath)
2658{
2659 global $conf;
2660
2661 $maxwidth = (!getDolGlobalString('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH') ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH);
2662 $maxheight = (!getDolGlobalString('MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT') ? 32 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT);
2663 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2664 $tmp = dol_getImageSize($realpath);
2665 $width = 0;
2666 $height = 0;
2667 if ($tmp['height']) {
2668 $width = (int) round($maxheight * $tmp['width'] / $tmp['height']); // I try to use maxheight
2669 if ($width > $maxwidth) { // Pb with maxheight, so i use maxwidth
2670 $width = $maxwidth;
2671 $height = (int) round($maxwidth * $tmp['height'] / $tmp['width']);
2672 } else { // No pb with maxheight
2673 $height = $maxheight;
2674 }
2675 }
2676 return array('width'=>$width, 'height'=>$height);
2677}
2678
2688function pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails = 0)
2689{
2690 global $conf, $hookmanager;
2691
2692 $sign = 1;
2693 if (isset($object->type) && $object->type == 2 && getDolGlobalString('INVOICE_POSITIVE_CREDIT_NOTE')) {
2694 $sign = -1;
2695 }
2696 if ($object->lines[$i]->special_code == 3) {
2697 return $outputlangs->transnoentities("Option");
2698 } else {
2699 if (is_object($hookmanager)) {
2700 $special_code = $object->lines[$i]->special_code;
2701 if (!empty($object->lines[$i]->fk_parent_line)) {
2702 $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
2703 }
2704
2705 $parameters = array(
2706 'i'=>$i,
2707 'outputlangs'=>$outputlangs,
2708 'hidedetails'=>$hidedetails,
2709 'special_code'=>$special_code
2710 );
2711
2712 $action = '';
2713
2714 if ($hookmanager->executeHooks('getlinetotalremise', $parameters, $object, $action) > 0) { // Note that $action and $object may have been modified by some hooks
2715 if (isset($hookmanager->resArray['linetotalremise'])) {
2716 return $hookmanager->resArray['linetotalremise'];
2717 } else {
2718 return (float) $hookmanager->resPrint; // For backward compatibility
2719 }
2720 }
2721 }
2722
2723 if (empty($hidedetails) || $hidedetails > 1) {
2724 return $sign * (($object->lines[$i]->subprice * $object->lines[$i]->qty) - $object->lines[$i]->total_ht);
2725 }
2726 }
2727 return 0;
2728}
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.
File of class to manage predefined price products or services by customer.
Class to manage predefined suppliers products.
Class to manage products or services.
Manage record for batch number management.
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 a 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:2657
pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line total excluding tax.
Definition pdf.lib.php:2406
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:1476
pdfGetLineTotalDiscountAmount($object, $i, $outputlangs, $hidedetails=0)
Return line total amount discount.
Definition pdf.lib.php:2688
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:2188
pdf_getlinenum($object, $i, $outputlangs, $hidedetails=0)
Return line num.
Definition pdf.lib.php:1864
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:2066
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:1422
pdf_getLinkedObjects(&$object, $outputlangs)
Return linked objects to use for document generation.
Definition pdf.lib.php:2517
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:1929
pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails=0)
Return line total including tax.
Definition pdf.lib.php:2462
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:1014
pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails=0)
Return line unit price excluding tax.
Definition pdf.lib.php:2023
pdf_getlineprogress($object, $i, $outputlangs, $hidedetails=0, $hookmanager=null)
Return line percent.
Definition pdf.lib.php:2355
pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails=0)
Return line vat rate.
Definition pdf.lib.php:1961
pdf_getlineunit($object, $i, $outputlangs, $hidedetails=0, $hookmanager=false)
Return line unit.
Definition pdf.lib.php:2269
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:1386
pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber=0, $default_font_size=10)
Show bank informations for PDF generation.
Definition pdf.lib.php:837
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:2228
pdf_getlineref($object, $i, $outputlangs, $hidedetails=0)
Return line product ref.
Definition pdf.lib.php:1897
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:2312
pdf_getlineqty_asked($object, $i, $outputlangs, $hidedetails=0)
Return line quantity asked.
Definition pdf.lib.php:2148
pdf_getlineqty($object, $i, $outputlangs, $hidedetails=0)
Return line quantity.
Definition pdf.lib.php:2108
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:762
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:782