1<?php 2/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> 3 * Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net> 4 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com> 5 * Copyright (C) 2008 Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr> 6 * Copyright (C) 2011 Fabrice CHERRIER 7 * Copyright (C) 2013-2020 Philippe Grand <philippe.grand@atoo-net.com> 8 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com> 9 * Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr> 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 3 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program. If not, see <https://www.gnu.org/licenses/>. 23 * or see https://www.gnu.org/ 24 */ 25 26/** 27 * \file htdocs/core/modules/contract/doc/pdf_strato.modules.php 28 * \ingroup ficheinter 29 * \brief Strato contracts template class file 30 */ 31require_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php'; 32require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; 33require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; 34require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; 35require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; 36 37 38/** 39 * Class to build contracts documents with model Strato 40 */ 41class pdf_strato extends ModelePDFContract 42{ 43 /** 44 * @var DoliDb Database handler 45 */ 46 public $db; 47 48 /** 49 * @var string model name 50 */ 51 public $name; 52 53 /** 54 * @var string model description (short text) 55 */ 56 public $description; 57 58 /** 59 * @var string document type 60 */ 61 public $type; 62 63 /** 64 * @var array Minimum version of PHP required by module. 65 * e.g.: PHP ≥ 5.6 = array(5, 6) 66 */ 67 public $phpmin = array(5, 6); 68 69 /** 70 * Dolibarr version of the loaded document 71 * @var string 72 */ 73 public $version = 'dolibarr'; 74 75 /** 76 * @var int page_largeur 77 */ 78 public $page_largeur; 79 80 /** 81 * @var int page_hauteur 82 */ 83 public $page_hauteur; 84 85 /** 86 * @var array format 87 */ 88 public $format; 89 90 /** 91 * @var int marge_gauche 92 */ 93 public $marge_gauche; 94 95 /** 96 * @var int marge_droite 97 */ 98 public $marge_droite; 99 100 /** 101 * @var int marge_haute 102 */ 103 public $marge_haute; 104 105 /** 106 * @var int marge_basse 107 */ 108 public $marge_basse; 109 110 /** 111 * Issuer 112 * @var Societe 113 */ 114 public $emetteur; 115 116 /** 117 * Recipient 118 * @var Societe 119 */ 120 public $recipient; 121 122 /** 123 * Constructor 124 * 125 * @param DoliDB $db Database handler 126 */ 127 public function __construct($db) 128 { 129 global $conf, $langs, $mysoc; 130 131 $this->db = $db; 132 $this->name = 'strato'; 133 $this->description = $langs->trans("StandardContractsTemplate"); 134 135 // Page size for A4 format 136 $this->type = 'pdf'; 137 $formatarray = pdf_getFormat(); 138 139 $this->page_largeur = $formatarray['width']; 140 $this->page_hauteur = $formatarray['height']; 141 $this->format = array($this->page_largeur, $this->page_hauteur); 142 $this->marge_gauche = isset($conf->global->MAIN_PDF_MARGIN_LEFT) ? $conf->global->MAIN_PDF_MARGIN_LEFT : 10; 143 $this->marge_droite = isset($conf->global->MAIN_PDF_MARGIN_RIGHT) ? $conf->global->MAIN_PDF_MARGIN_RIGHT : 10; 144 $this->marge_haute = isset($conf->global->MAIN_PDF_MARGIN_TOP) ? $conf->global->MAIN_PDF_MARGIN_TOP : 10; 145 $this->marge_basse = isset($conf->global->MAIN_PDF_MARGIN_BOTTOM) ? $conf->global->MAIN_PDF_MARGIN_BOTTOM : 10; 146 147 $this->option_logo = 1; // Display logo 148 $this->option_tva = 0; // Manage the vat option FACTURE_TVAOPTION 149 $this->option_modereg = 0; // Display payment mode 150 $this->option_condreg = 0; // Display payment terms 151 $this->option_codeproduitservice = 0; // Display product-service code 152 $this->option_multilang = 0; // Available in several languages 153 $this->option_draft_watermark = 1; // Support add of a watermark on drafts 154 155 // Get source company 156 $this->emetteur = $mysoc; 157 if (empty($this->emetteur->country_code)) $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if not defined 158 159 // Define position of columns 160 $this->posxdesc = $this->marge_gauche + 1; 161 } 162 163 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 164 /** 165 * Function to build pdf onto disk 166 * 167 * @param Contrat $object Object to generate 168 * @param Translate $outputlangs Lang output object 169 * @param string $srctemplatepath Full path of source filename for generator using a template file 170 * @param int $hidedetails Do not show line details 171 * @param int $hidedesc Do not show desc 172 * @param int $hideref Do not show ref 173 * @return int 1=OK, 0=KO 174 */ 175 public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0) 176 { 177 // phpcs:enable 178 global $user, $langs, $conf, $hookmanager, $mysoc; 179 180 if (!is_object($outputlangs)) $outputlangs = $langs; 181 // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO 182 if (!empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output = 'ISO-8859-1'; 183 184 // Load traductions files required by page 185 $outputlangs->loadLangs(array("main", "dict", "companies", "contracts")); 186 187 if ($conf->contrat->dir_output) 188 { 189 $object->fetch_thirdparty(); 190 191 // Definition of $dir and $file 192 if ($object->specimen) 193 { 194 $dir = $conf->contrat->dir_output; 195 $file = $dir."/SPECIMEN.pdf"; 196 } else { 197 $objectref = dol_sanitizeFileName($object->ref); 198 $dir = $conf->contrat->multidir_output[$object->entity]."/".$objectref; 199 $file = $dir."/".$objectref.".pdf"; 200 } 201 202 if (!file_exists($dir)) 203 { 204 if (dol_mkdir($dir) < 0) 205 { 206 $this->error = $outputlangs->trans("ErrorCanNotCreateDir", $dir); 207 return 0; 208 } 209 } 210 211 if (file_exists($dir)) 212 { 213 // Add pdfgeneration hook 214 if (!is_object($hookmanager)) 215 { 216 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; 217 $hookmanager = new HookManager($this->db); 218 } 219 $hookmanager->initHooks(array('pdfgeneration')); 220 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); 221 global $action; 222 $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks 223 224 $pdf = pdf_getInstance($this->format); 225 $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance 226 $heightforinfotot = 50; // Height reserved to output the info and total part 227 $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page 228 $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin) 229 if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)) $heightforfooter += 6; 230 $pdf->SetAutoPageBreak(1, 0); 231 232 if (class_exists('TCPDF')) 233 { 234 $pdf->setPrintHeader(false); 235 $pdf->setPrintFooter(false); 236 } 237 $pdf->SetFont(pdf_getPDFFont($outputlangs)); 238 // Set path to the background PDF File 239 if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) 240 { 241 $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); 242 $tplidx = $pdf->importPage(1); 243 } 244 245 $pdf->Open(); 246 $pagenb = 0; 247 $pdf->SetDrawColor(128, 128, 128); 248 249 $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); 250 $pdf->SetSubject($outputlangs->transnoentities("ContractCard")); 251 $pdf->SetCreator("Dolibarr ".DOL_VERSION); 252 $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); 253 $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("ContractCard")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); 254 if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); 255 256 $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right 257 258 // New page 259 $pdf->AddPage(); 260 if (!empty($tplidx)) $pdf->useTemplate($tplidx); 261 $pagenb++; 262 $this->_pagehead($pdf, $object, 1, $outputlangs); 263 $pdf->SetFont('', '', $default_font_size - 1); 264 $pdf->MultiCell(0, 3, ''); // Set interline to 3 265 $pdf->SetTextColor(0, 0, 0); 266 267 $tab_top = 90; 268 $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 : 10); 269 270 // Display notes 271 if (!empty($object->note_public)) 272 { 273 $tab_top -= 2; 274 275 $pdf->SetFont('', '', $default_font_size - 1); 276 $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($object->note_public), 0, 1); 277 $nexY = $pdf->GetY(); 278 $height_note = $nexY - $tab_top; 279 280 // Rect takes a length in 3rd parameter 281 $pdf->SetDrawColor(192, 192, 192); 282 $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 1); 283 284 $tab_top = $nexY + 6; 285 } 286 287 $iniY = $tab_top + 7; 288 $curY = $tab_top + 7; 289 $nexY = $tab_top + 2; 290 291 $pdf->SetXY($this->marge_gauche, $tab_top); 292 293 $pdf->MultiCell(0, 2, ''); // Set interline to 3. Then writeMultiCell must use 3 also. 294 295 $nblines = count($object->lines); 296 297 // Loop on each lines 298 for ($i = 0; $i < $nblines; $i++) 299 { 300 $objectligne = $object->lines[$i]; 301 302 $valide = $objectligne->id ? 1 : 0; 303 304 if ($valide > 0 || $object->specimen) 305 { 306 $curX = $this->posxdesc - 1; 307 $curY = $nexY; 308 $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage 309 $pdf->SetTextColor(0, 0, 0); 310 311 $pdf->setTopMargin($tab_top_newpage); 312 $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it. 313 $pageposbefore = $pdf->getPage(); 314 315 // Description of product line 316 317 if ($objectligne->date_ouverture_prevue) { 318 $datei = dol_print_date($objectligne->date_ouverture_prevue, 'day', false, $outputlangs, true); 319 } else { 320 $datei = $langs->trans("Unknown"); 321 } 322 323 if ($objectligne->date_fin_validite) { 324 $durationi = convertSecondToTime($objectligne->date_fin_validite - $objectligne->date_ouverture_prevue, 'allwithouthour'); 325 $datee = dol_print_date($objectligne->date_fin_validite, 'day', false, $outputlangs, true); 326 } else { 327 $durationi = $langs->trans("Unknown"); 328 $datee = $langs->trans("Unknown"); 329 } 330 331 if ($objectligne->date_ouverture) { 332 $daters = dol_print_date($objectligne->date_ouverture, 'day', false, $outputlangs, true); 333 } else { 334 $daters = $langs->trans("Unknown"); 335 } 336 337 if ($objectligne->date_cloture) { 338 $datere = dol_print_date($objectligne->date_cloture, 'day', false, $outputlangs, true); 339 } else { 340 $datere = $langs->trans("Unknown"); 341 } 342 343 $txtpredefinedservice = $objectligne->product_ref; 344 if ($objectligne->product_label) 345 { 346 $txtpredefinedservice .= ' - '; 347 $txtpredefinedservice .= $objectligne->product_label; 348 } 349 350 $desc = dol_htmlentitiesbr($objectligne->desc, 1); // Desc (not empty for free lines) 351 $txt = ''; 352 $txt .= $outputlangs->transnoentities("Quantity").' : <strong>'.$objectligne->qty.'</strong> - '.$outputlangs->transnoentities("UnitPrice").' : <strong>'.price($objectligne->subprice).'</strong>'; // Desc (not empty for free lines) 353 if (empty($conf->global->CONTRACT_HIDE_PLANNED_DATE_ON_PDF)) 354 { 355 $txt .= '<br>'; 356 $txt .= $outputlangs->transnoentities("DateStartPlannedShort")." : <strong>".$datei."</strong> - ".$outputlangs->transnoentities("DateEndPlanned")." : <strong>".$datee.'</strong>'; 357 } 358 if (empty($conf->global->CONTRACT_HIDE_REAL_DATE_ON_PDF)) 359 { 360 $txt .= '<br>'; 361 $txt .= $outputlangs->transnoentities("DateStartRealShort")." : <strong>".$daters.'</strong>'; 362 if ($objectligne->date_cloture) $txt .= " - ".$outputlangs->transnoentities("DateEndRealShort")." : '<strong>'".$datere.'</strong>'; 363 } 364 365 $pdf->startTransaction(); 366 $pdf->writeHTMLCell(0, 0, $curX, $curY, dol_concatdesc($txtpredefinedservice, dol_concatdesc($txt, $desc)), 0, 1, 0); 367 $pageposafter = $pdf->getPage(); 368 if ($pageposafter > $pageposbefore) // There is a pagebreak 369 { 370 $pdf->rollbackTransaction(true); 371 $pageposafter = $pageposbefore; 372 //print $pageposafter.'-'.$pageposbefore;exit; 373 $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. 374 $pdf->writeHTMLCell(0, 0, $curX, $curY, dol_concatdesc($txtpredefinedservice, dol_concatdesc($txt, $desc)), 0, 1, 0); 375 $pageposafter = $pdf->getPage(); 376 $posyafter = $pdf->GetY(); 377 378 if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text 379 { 380 if ($i == ($nblines - 1)) // No more lines, and no space left to show total, so we create a new page 381 { 382 $pdf->AddPage('', '', true); 383 if (!empty($tplidx)) $pdf->useTemplate($tplidx); 384 if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); 385 $pdf->setPage($pageposafter + 1); 386 } 387 } else { 388 // We found a page break 389 390 // Allows data in the first page if description is long enough to break in multiples pages 391 if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) 392 $showpricebeforepagebreak = 1; 393 else $showpricebeforepagebreak = 0; 394 } 395 } else // No pagebreak 396 { 397 $pdf->commitTransaction(); 398 } 399 400 $nexY = $pdf->GetY() + 2; 401 $pageposafter = $pdf->getPage(); 402 403 $pdf->setPage($pageposbefore); 404 $pdf->setTopMargin($this->marge_haute); 405 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. 406 407 // We suppose that a too long description is moved completely on next page 408 if ($pageposafter > $pageposbefore) { 409 $pdf->setPage($pageposafter); $curY = $tab_top_newpage; 410 } 411 412 $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font 413 414 // Detect if some page were added automatically and output _tableau for past pages 415 while ($pagenb < $pageposafter) 416 { 417 $pdf->setPage($pagenb); 418 if ($pagenb == 1) 419 { 420 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext, 0, $outputlangs, 0, 1); 421 } else { 422 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter - $heightforfreetext, 0, $outputlangs, 1, 1); 423 } 424 $this->_pagefoot($pdf, $object, $outputlangs, 1); 425 $pagenb++; 426 $pdf->setPage($pagenb); 427 $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. 428 } 429 430 if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) 431 { 432 if ($pagenb == 1) 433 { 434 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext, 0, $outputlangs, 0, 1); 435 } else { 436 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter - $heightforfreetext, 0, $outputlangs, 1, 1); 437 } 438 $this->_pagefoot($pdf, $object, $outputlangs, 1); 439 // New page 440 $pdf->AddPage(); 441 if (!empty($tplidx)) $pdf->useTemplate($tplidx); 442 $pagenb++; 443 } 444 } 445 } 446 447 // Show square 448 if ($pagenb == 1) 449 { 450 $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); 451 $this->tabSignature($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, $outputlangs); 452 $bottomlasttab = $this->page_hauteur - $heightforfooter - $heightforfooter + 1; 453 } else { 454 $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); 455 $this->tabSignature($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, $outputlangs); 456 $bottomlasttab = $this->page_hauteur - $heightforfooter - $heightforfooter + 1; 457 } 458 459 $this->_pagefoot($pdf, $object, $outputlangs); 460 if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages(); 461 462 $pdf->Close(); 463 464 $pdf->Output($file, 'F'); 465 466 // Add pdfgeneration hook 467 if (!is_object($hookmanager)) 468 { 469 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; 470 $hookmanager = new HookManager($this->db); 471 } 472 $hookmanager->initHooks(array('pdfgeneration')); 473 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); 474 global $action; 475 $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks 476 if ($reshook < 0) 477 { 478 $this->error = $hookmanager->error; 479 $this->errors = $hookmanager->errors; 480 } 481 482 if (!empty($conf->global->MAIN_UMASK)) 483 @chmod($file, octdec($conf->global->MAIN_UMASK)); 484 485 $this->result = array('fullpath'=>$file); 486 487 return 1; 488 } else { 489 $this->error = $langs->trans("ErrorCanNotCreateDir", $dir); 490 return 0; 491 } 492 } else { 493 $this->error = $langs->trans("ErrorConstantNotDefined", "CONTRACT_OUTPUTDIR"); 494 return 0; 495 } 496 } 497 498 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore 499 /** 500 * Show table for lines 501 * 502 * @param TCPDF $pdf Object PDF 503 * @param string $tab_top Top position of table 504 * @param string $tab_height Height of table (rectangle) 505 * @param int $nexY Y 506 * @param Translate $outputlangs Langs object 507 * @param int $hidetop Hide top bar of array 508 * @param int $hidebottom Hide bottom bar of array 509 * @return void 510 */ 511 protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0) 512 { 513 global $conf; 514 515 // Force to disable hidetop and hidebottom 516 $hidebottom = 0; 517 if ($hidetop) $hidetop = -1; 518 519 $default_font_size = pdf_getPDFFontSize($outputlangs); 520 /* 521 $pdf->SetXY($this->marge_gauche, $tab_top); 522 $pdf->MultiCell(190,8,$outputlangs->transnoentities("Description"),0,'L',0); 523 $pdf->line($this->marge_gauche, $tab_top + 8, $this->page_largeur-$this->marge_droite, $tab_top + 8); 524 525 $pdf->SetFont('','', $default_font_size - 1); 526 527 $pdf->MultiCell(0, 3, ''); // Set interline to 3 528 $pdf->SetXY($this->marge_gauche, $tab_top + 8); 529 $text=$object->description; 530 if ($object->duree > 0) 531 { 532 $totaltime=convertSecondToTime($object->duree,'all',$conf->global->MAIN_DURATION_OF_WORKDAY); 533 $text.=($text?' - ':'').$langs->trans("Total").": ".$totaltime; 534 } 535 $desc=dol_htmlentitiesbr($text,1); 536 //print $outputlangs->convToOutputCharset($desc); exit; 537 538 $pdf->writeHTMLCell(180, 3, 10, $tab_top + 8, $outputlangs->convToOutputCharset($desc), 0, 1); 539 $nexY = $pdf->GetY(); 540 541 $pdf->line($this->marge_gauche, $nexY, $this->page_largeur-$this->marge_droite, $nexY); 542 543 $pdf->MultiCell(0, 3, ''); // Set interline to 3. Then writeMultiCell must use 3 also. 544 */ 545 546 // Output Rect 547 $this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height + 3); // Rect takes a length in 3rd parameter and 4th parameter 548 } 549 550 /** 551 * Show footer signature of page 552 * @param TCPDF $pdf Object PDF 553 * @param int $tab_top tab height position 554 * @param int $tab_height tab height 555 * @param Translate $outputlangs Object language for output 556 * @return void 557 */ 558 protected function tabSignature(&$pdf, $tab_top, $tab_height, $outputlangs) 559 { 560 $pdf->SetDrawColor(128, 128, 128); 561 $posmiddle = $this->marge_gauche + round(($this->page_largeur - $this->marge_gauche - $this->marge_droite) / 2); 562 $posy = $tab_top + $tab_height + 3 + 3; 563 564 $pdf->SetXY($this->marge_gauche, $posy); 565 $pdf->MultiCell($posmiddle - $this->marge_gauche - 5, 5, $outputlangs->transnoentities("ContactNameAndSignature", $this->emetteur->name), 0, 'L', 0); 566 567 $pdf->SetXY($this->marge_gauche, $posy + 5); 568 $pdf->MultiCell($posmiddle - $this->marge_gauche - 5, 20, '', 1); 569 570 $pdf->SetXY($posmiddle + 5, $posy); 571 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $posmiddle - 5, 5, $outputlangs->transnoentities("ContactNameAndSignature", $this->recipient->name), 0, 'L', 0); 572 573 $pdf->SetXY($posmiddle + 5, $posy + 5); 574 $pdf->MultiCell($this->page_largeur - $this->marge_droite - $posmiddle - 5, 20, '', 1); 575 } 576 577 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore 578 /** 579 * Show top header of page. 580 * 581 * @param TCPDF $pdf Object PDF 582 * @param Contrat $object Object to show 583 * @param int $showaddress 0=no, 1=yes 584 * @param Translate $outputlangs Object lang for output 585 * @return void 586 */ 587 protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs) 588 { 589 global $conf, $langs; 590 591 $default_font_size = pdf_getPDFFontSize($outputlangs); 592 593 // Load traductions files required by page 594 $outputlangs->loadLangs(array("main", "dict", "contract", "companies")); 595 596 pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); 597 598 //Affiche le filigrane brouillon - Print Draft Watermark 599 if ($object->statut == 0 && (!empty($conf->global->CONTRACT_DRAFT_WATERMARK))) 600 { 601 pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->CONTRACT_DRAFT_WATERMARK); 602 } 603 604 //Prepare next 605 $pdf->SetTextColor(0, 0, 60); 606 $pdf->SetFont('', 'B', $default_font_size + 3); 607 608 $posx = $this->page_largeur - $this->marge_droite - 100; 609 $posy = $this->marge_haute; 610 611 $pdf->SetXY($this->marge_gauche, $posy); 612 613 // Logo 614 $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; 615 if ($this->emetteur->logo) 616 { 617 if (is_readable($logo)) 618 { 619 $height = pdf_getHeightForLogo($logo); 620 $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) 621 } else { 622 $pdf->SetTextColor(200, 0, 0); 623 $pdf->SetFont('', 'B', $default_font_size - 2); 624 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); 625 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); 626 } 627 } else { 628 $text = $this->emetteur->name; 629 $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); 630 } 631 632 $pdf->SetFont('', 'B', $default_font_size + 3); 633 $pdf->SetXY($posx, $posy); 634 $pdf->SetTextColor(0, 0, 60); 635 $title = $outputlangs->transnoentities("ContractCard"); 636 $pdf->MultiCell(100, 4, $title, '', 'R'); 637 638 $pdf->SetFont('', 'B', $default_font_size + 2); 639 640 $posy += 5; 641 $pdf->SetXY($posx, $posy); 642 $pdf->SetTextColor(0, 0, 60); 643 $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref), '', 'R'); 644 645 $posy += 1; 646 $pdf->SetFont('', '', $default_font_size); 647 648 $posy += 4; 649 $pdf->SetXY($posx, $posy); 650 $pdf->SetTextColor(0, 0, 60); 651 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Date")." : ".dol_print_date($object->date_contrat, "day", false, $outputlangs, true), '', 'R'); 652 653 if ($object->thirdparty->code_client) 654 { 655 $posy += 4; 656 $pdf->SetXY($posx, $posy); 657 $pdf->SetTextColor(0, 0, 60); 658 $pdf->MultiCell(100, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R'); 659 } 660 661 if ($showaddress) 662 { 663 // Sender properties 664 $carac_emetteur = ''; 665 // Add internal contact of proposal if defined 666 $arrayidcontact = $object->getIdContact('internal', 'INTERREPFOLL'); 667 if (count($arrayidcontact) > 0) 668 { 669 $object->fetch_user($arrayidcontact[0]); 670 $carac_emetteur .= ($carac_emetteur ? "\n" : '').$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n"; 671 } 672 673 $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); 674 675 // Show sender 676 $posy = 42; 677 $posx = $this->marge_gauche; 678 if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->page_largeur - $this->marge_droite - 80; 679 $hautcadre = 40; 680 681 // Show sender frame 682 $pdf->SetTextColor(0, 0, 0); 683 $pdf->SetFont('', '', $default_font_size - 2); 684 $pdf->SetXY($posx, $posy - 5); 685 $pdf->SetXY($posx, $posy); 686 $pdf->SetFillColor(230, 230, 230); 687 $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1); 688 689 // Show sender name 690 $pdf->SetXY($posx + 2, $posy + 3); 691 $pdf->SetTextColor(0, 0, 60); 692 $pdf->SetFont('', 'B', $default_font_size); 693 $pdf->MultiCell(80, 3, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); 694 $posy = $pdf->getY(); 695 696 // Show sender information 697 $pdf->SetFont('', '', $default_font_size - 1); 698 $pdf->SetXY($posx + 2, $posy); 699 $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); 700 701 702 // If CUSTOMER contact defined, we use it 703 $usecontact = false; 704 $arrayidcontact = $object->getIdContact('external', 'CUSTOMER'); 705 if (count($arrayidcontact) > 0) 706 { 707 $usecontact = true; 708 $result = $object->fetch_contact($arrayidcontact[0]); 709 } 710 711 $this->recipient = $object->thirdparty; 712 713 // Recipient name 714 if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { 715 $thirdparty = $object->contact; 716 } else { 717 $thirdparty = $object->thirdparty; 718 } 719 720 $this->recipient->name = pdfBuildThirdpartyName($thirdparty, $outputlangs); 721 722 $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, (isset($object->contact) ? $object->contact : ''), $usecontact, 'target', $object); 723 724 // Show recipient 725 $widthrecbox = 100; 726 if ($this->page_largeur < 210) $widthrecbox = 84; // To work with US executive format 727 $posy = 42; 728 $posx = $this->page_largeur - $this->marge_droite - $widthrecbox; 729 if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx = $this->marge_gauche; 730 731 // Show recipient frame 732 $pdf->SetTextColor(0, 0, 0); 733 $pdf->SetFont('', '', $default_font_size - 2); 734 $pdf->SetXY($posx + 2, $posy - 5); 735 $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre); 736 $pdf->SetTextColor(0, 0, 0); 737 738 // Show recipient name 739 $pdf->SetXY($posx + 2, $posy + 3); 740 $pdf->SetFont('', 'B', $default_font_size); 741 $pdf->MultiCell($widthrecbox, 4, $this->recipient->name, 0, 'L'); 742 743 $posy = $pdf->getY(); 744 745 // Show recipient information 746 $pdf->SetFont('', '', $default_font_size - 1); 747 $pdf->SetXY($posx + 2, $posy); 748 $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); 749 } 750 } 751 752 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore 753 /** 754 * Show footer of page. Need this->emetteur object 755 * 756 * @param PDF $pdf PDF 757 * @param Contrat $object Object to show 758 * @param Translate $outputlangs Object lang for output 759 * @param int $hidefreetext 1=Hide free text 760 * @return integer 761 */ 762 protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0) 763 { 764 global $conf; 765 $showdetails = empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 0 : $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; 766 return pdf_pagefoot($pdf, $outputlangs, 'CONTRACT_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext); 767 } 768} 769