pdf_azur.modules.php 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635
  1. <?php
  2. /* Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
  4. * Copyright (C) 2008 Raphael Bertrand <raphael.bertrand@resultic.fr>
  5. * Copyright (C) 2010-2015 Juanjo Menent <jmenent@2byte.es>
  6. * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
  7. * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
  8. * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
  9. * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
  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 <http://www.gnu.org/licenses/>.
  23. * or see http://www.gnu.org/
  24. */
  25. /**
  26. * \file htdocs/core/modules/propale/doc/pdf_azur.modules.php
  27. * \ingroup propale
  28. * \brief Fichier de la classe permettant de generer les propales au modele Azur
  29. */
  30. require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
  31. require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
  32. require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
  33. require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
  34. require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
  35. /**
  36. * Class to generate PDF proposal Azur
  37. */
  38. class pdf_azur extends ModelePDFPropales
  39. {
  40. var $db;
  41. var $name;
  42. var $description;
  43. var $update_main_doc_field; // Save the name of generated file as the main doc when generating a doc with this template
  44. var $type;
  45. var $phpmin = array(4,3,0); // Minimum version of PHP required by module
  46. var $version = 'dolibarr';
  47. var $page_largeur;
  48. var $page_hauteur;
  49. var $format;
  50. var $marge_gauche;
  51. var $marge_droite;
  52. var $marge_haute;
  53. var $marge_basse;
  54. var $emetteur; // Objet societe qui emet
  55. /**
  56. * Constructor
  57. *
  58. * @param DoliDB $db Database handler
  59. */
  60. function __construct($db)
  61. {
  62. global $conf,$langs,$mysoc;
  63. $langs->load("main");
  64. $langs->load("bills");
  65. $this->db = $db;
  66. $this->name = "azur";
  67. $this->description = $langs->trans('DocModelAzurDescription');
  68. $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
  69. // Dimension page
  70. $this->type = 'pdf';
  71. $formatarray=pdf_getFormat();
  72. $this->page_largeur = $formatarray['width'];
  73. $this->page_hauteur = $formatarray['height'];
  74. $this->format = array($this->page_largeur,$this->page_hauteur);
  75. $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10;
  76. $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10;
  77. $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
  78. $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
  79. $this->option_logo = 1; // Affiche logo
  80. $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION
  81. $this->option_modereg = 1; // Affiche mode reglement
  82. $this->option_condreg = 1; // Affiche conditions reglement
  83. $this->option_codeproduitservice = 1; // Affiche code produit-service
  84. $this->option_multilang = 1; // Dispo en plusieurs langues
  85. $this->option_escompte = 0; // Affiche si il y a eu escompte
  86. $this->option_credit_note = 0; // Support credit notes
  87. $this->option_freetext = 1; // Support add of a personalised text
  88. $this->option_draft_watermark = 1; //Support add of a watermark on drafts
  89. $this->franchise=!$mysoc->tva_assuj;
  90. // Get source company
  91. $this->emetteur=$mysoc;
  92. if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined
  93. // Define position of columns
  94. $this->posxdesc=$this->marge_gauche+1;
  95. if($conf->global->PRODUCT_USE_UNITS)
  96. {
  97. $this->posxtva=99;
  98. $this->posxup=114;
  99. $this->posxqty=130;
  100. $this->posxunit=147;
  101. }
  102. else
  103. {
  104. $this->posxtva=110;
  105. $this->posxup=126;
  106. $this->posxqty=145;
  107. }
  108. $this->posxdiscount=162;
  109. $this->postotalht=174;
  110. if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) || ! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) $this->posxtva=$this->posxup;
  111. $this->posxpicture=$this->posxtva - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images
  112. if ($this->page_largeur < 210) // To work with US executive format
  113. {
  114. $this->posxpicture-=20;
  115. $this->posxtva-=20;
  116. $this->posxup-=20;
  117. $this->posxqty-=20;
  118. $this->posxunit-=20;
  119. $this->posxdiscount-=20;
  120. $this->postotalht-=20;
  121. }
  122. $this->tva=array();
  123. $this->localtax1=array();
  124. $this->localtax2=array();
  125. $this->atleastoneratenotnull=0;
  126. $this->atleastonediscount=0;
  127. }
  128. /**
  129. * Function to build pdf onto disk
  130. *
  131. * @param Object $object Object to generate
  132. * @param Translate $outputlangs Lang output object
  133. * @param string $srctemplatepath Full path of source filename for generator using a template file
  134. * @param int $hidedetails Do not show line details
  135. * @param int $hidedesc Do not show desc
  136. * @param int $hideref Do not show ref
  137. * @return int 1=OK, 0=KO
  138. */
  139. function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
  140. {
  141. global $user,$langs,$conf,$mysoc,$db,$hookmanager;
  142. if (! is_object($outputlangs)) $outputlangs=$langs;
  143. // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
  144. if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
  145. $outputlangs->load("main");
  146. $outputlangs->load("dict");
  147. $outputlangs->load("companies");
  148. $outputlangs->load("bills");
  149. $outputlangs->load("propal");
  150. $outputlangs->load("products");
  151. $nblignes = count($object->lines);
  152. // Loop on each lines to detect if there is at least one image to show
  153. $realpatharray=array();
  154. if (! empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE))
  155. {
  156. $objphoto = new Product($this->db);
  157. for ($i = 0 ; $i < $nblignes ; $i++)
  158. {
  159. if (empty($object->lines[$i]->fk_product)) continue;
  160. $objphoto->fetch($object->lines[$i]->fk_product);
  161. //var_dump($objphoto->ref);exit;
  162. if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
  163. {
  164. $pdir[0] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/";
  165. $pdir[1] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/';
  166. }
  167. else
  168. {
  169. $pdir[0] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/'; // default
  170. $pdir[1] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/"; // alternative
  171. }
  172. $arephoto = false;
  173. foreach ($pdir as $midir)
  174. {
  175. if (! $arephoto)
  176. {
  177. $dir = $conf->product->dir_output.'/'.$midir;
  178. foreach ($objphoto->liste_photos($dir,1) as $key => $obj)
  179. {
  180. if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
  181. {
  182. if ($obj['photo_vignette'])
  183. {
  184. $filename= $obj['photo_vignette'];
  185. }
  186. else
  187. {
  188. $filename=$obj['photo'];
  189. }
  190. }
  191. else
  192. {
  193. $filename=$obj['photo'];
  194. }
  195. $realpath = $dir.$filename;
  196. $arephoto = true;
  197. }
  198. }
  199. }
  200. if ($realpath && $arephoto) $realpatharray[$i]=$realpath;
  201. }
  202. }
  203. if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
  204. if ($conf->propal->dir_output)
  205. {
  206. $object->fetch_thirdparty();
  207. $deja_regle = 0;
  208. // Definition of $dir and $file
  209. if ($object->specimen)
  210. {
  211. $dir = $conf->propal->dir_output;
  212. $file = $dir . "/SPECIMEN.pdf";
  213. }
  214. else
  215. {
  216. $objectref = dol_sanitizeFileName($object->ref);
  217. $dir = $conf->propal->dir_output . "/" . $objectref;
  218. $file = $dir . "/" . $objectref . ".pdf";
  219. }
  220. if (! file_exists($dir))
  221. {
  222. if (dol_mkdir($dir) < 0)
  223. {
  224. $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
  225. return 0;
  226. }
  227. }
  228. if (file_exists($dir))
  229. {
  230. // Add pdfgeneration hook
  231. if (! is_object($hookmanager))
  232. {
  233. include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
  234. $hookmanager=new HookManager($this->db);
  235. }
  236. $hookmanager->initHooks(array('pdfgeneration'));
  237. $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
  238. global $action;
  239. $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
  240. // Create pdf instance
  241. $pdf=pdf_getInstance($this->format);
  242. $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
  243. $pdf->SetAutoPageBreak(1,0);
  244. if (class_exists('TCPDF'))
  245. {
  246. $pdf->setPrintHeader(false);
  247. $pdf->setPrintFooter(false);
  248. }
  249. $pdf->SetFont(pdf_getPDFFont($outputlangs));
  250. // Set path to the background PDF File
  251. if (empty($conf->global->MAIN_DISABLE_FPDI) && ! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
  252. {
  253. $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
  254. $tplidx = $pdf->importPage(1);
  255. }
  256. $pdf->Open();
  257. $pagenb=0;
  258. $pdf->SetDrawColor(128,128,128);
  259. $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
  260. $pdf->SetSubject($outputlangs->transnoentities("PdfCommercialProposalTitle"));
  261. $pdf->SetCreator("Dolibarr ".DOL_VERSION);
  262. $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
  263. $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfCommercialProposalTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
  264. if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
  265. $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
  266. // Positionne $this->atleastonediscount si on a au moins une remise
  267. for ($i = 0 ; $i < $nblignes ; $i++)
  268. {
  269. if ($object->lines[$i]->remise_percent)
  270. {
  271. $this->atleastonediscount++;
  272. }
  273. }
  274. if (empty($this->atleastonediscount) && empty($conf->global->PRODUCT_USE_UNITS))
  275. {
  276. $this->posxpicture+=($this->postotalht - $this->posxdiscount);
  277. $this->posxtva+=($this->postotalht - $this->posxdiscount);
  278. $this->posxup+=($this->postotalht - $this->posxdiscount);
  279. $this->posxqty+=($this->postotalht - $this->posxdiscount);
  280. $this->posxdiscount+=($this->postotalht - $this->posxdiscount);
  281. //$this->postotalht;
  282. }
  283. // New page
  284. $pdf->AddPage();
  285. if (! empty($tplidx)) $pdf->useTemplate($tplidx);
  286. $pagenb++;
  287. $heightforinfotot = 40; // Height reserved to output the info and total part
  288. $heightforsignature = empty($conf->global->PROPAL_DISABLE_SIGNATURE)?(pdfGetHeightForHtmlContent($pdf, $outputlangs->transnoentities("ProposalCustomerSignature"))+10):0;
  289. $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
  290. $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
  291. //print $heightforinfotot + $heightforsignature + $heightforfreetext + $heightforfooter;exit;
  292. $this->_pagehead($pdf, $object, 1, $outputlangs);
  293. $pdf->SetFont('','', $default_font_size - 1);
  294. $pdf->MultiCell(0, 3, ''); // Set interline to 3
  295. $pdf->SetTextColor(0,0,0);
  296. $tab_top = 90;
  297. $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42:10);
  298. $tab_height = 130;
  299. $tab_height_newpage = 150;
  300. // Incoterm
  301. $height_incoterms = 0;
  302. if ($conf->incoterm->enabled)
  303. {
  304. $desc_incoterms = $object->getIncotermsForPDF();
  305. if ($desc_incoterms)
  306. {
  307. $tab_top = 88;
  308. $pdf->SetFont('','', $default_font_size - 1);
  309. $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
  310. $nexY = $pdf->GetY();
  311. $height_incoterms=$nexY-$tab_top;
  312. // Rect prend une longueur en 3eme param
  313. $pdf->SetDrawColor(192,192,192);
  314. $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1);
  315. $tab_top = $nexY+6;
  316. $height_incoterms += 4;
  317. }
  318. }
  319. // Affiche notes
  320. $notetoshow=empty($object->note_public)?'':$object->note_public;
  321. if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
  322. {
  323. // Get first sale rep
  324. if (is_object($object->thirdparty))
  325. {
  326. $salereparray=$object->thirdparty->getSalesRepresentatives($user);
  327. $salerepobj=new User($this->db);
  328. $salerepobj->fetch($salereparray[0]['id']);
  329. if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature);
  330. }
  331. }
  332. if (! empty($conf->global->MAIN_ADD_CREATOR_IN_NOTE) && $object->user_author_id > 0)
  333. {
  334. $tmpuser=new User($this->db);
  335. $tmpuser->fetch($object->user_author_id);
  336. $notetoshow.='Affaire suivi par '.$tmpuser->getFullName($langs);
  337. if ($tmpuser->email) $notetoshow.=', Mail: '.$tmpuser->email;
  338. if ($tmpuser->office_phone) $notetoshow.=', Tel: '.$tmpuser->office_phone;
  339. }
  340. if ($notetoshow)
  341. {
  342. $tab_top = 88 + $height_incoterms;
  343. $pdf->SetFont('','', $default_font_size - 1);
  344. $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
  345. $nexY = $pdf->GetY();
  346. $height_note=$nexY-$tab_top;
  347. // Rect prend une longueur en 3eme param
  348. $pdf->SetDrawColor(192,192,192);
  349. $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_note+1);
  350. $tab_height = $tab_height - $height_note;
  351. $tab_top = $nexY+6;
  352. }
  353. else
  354. {
  355. $height_note=0;
  356. }
  357. $iniY = $tab_top + 7;
  358. $curY = $tab_top + 7;
  359. $nexY = $tab_top + 7;
  360. // Loop on each lines
  361. for ($i = 0; $i < $nblignes; $i++)
  362. {
  363. $curY = $nexY;
  364. $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage
  365. $pdf->SetTextColor(0,0,0);
  366. // Define size of image if we need it
  367. $imglinesize=array();
  368. if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]);
  369. $pdf->setTopMargin($tab_top_newpage);
  370. $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot); // The only function to edit the bottom margin of current page to set it.
  371. $pageposbefore=$pdf->getPage();
  372. $showpricebeforepagebreak=1;
  373. $posYAfterImage=0;
  374. $posYAfterDescription=0;
  375. // We start with Photo of product line
  376. if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur-($heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot))) // If photo too high, we moved completely on new page
  377. {
  378. $pdf->AddPage('','',true);
  379. if (! empty($tplidx)) $pdf->useTemplate($tplidx);
  380. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
  381. $pdf->setPage($pageposbefore+1);
  382. $curY = $tab_top_newpage;
  383. $showpricebeforepagebreak=0;
  384. }
  385. if (isset($imglinesize['width']) && isset($imglinesize['height']))
  386. {
  387. $curX = $this->posxpicture-1;
  388. $pdf->Image($realpatharray[$i], $curX + (($this->posxtva-$this->posxpicture-$imglinesize['width'])/2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
  389. // $pdf->Image does not increase value return by getY, so we save it manually
  390. $posYAfterImage=$curY+$imglinesize['height'];
  391. }
  392. // Description of product line
  393. $curX = $this->posxdesc-1;
  394. $pdf->startTransaction();
  395. pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxpicture-$curX,3,$curX,$curY,$hideref,$hidedesc);
  396. $pageposafter=$pdf->getPage();
  397. if ($pageposafter > $pageposbefore) // There is a pagebreak
  398. {
  399. $pdf->rollbackTransaction(true);
  400. $pageposafter=$pageposbefore;
  401. //print $pageposafter.'-'.$pageposbefore;exit;
  402. $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
  403. pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxpicture-$curX,3,$curX,$curY,$hideref,$hidedesc);
  404. $pageposafter=$pdf->getPage();
  405. $posyafter=$pdf->GetY();
  406. //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
  407. if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot))) // There is no space left for total+free text
  408. {
  409. if ($i == ($nblignes-1)) // No more lines, and no space left to show total, so we create a new page
  410. {
  411. $pdf->AddPage('','',true);
  412. if (! empty($tplidx)) $pdf->useTemplate($tplidx);
  413. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
  414. $pdf->setPage($pageposafter+1);
  415. }
  416. }
  417. else
  418. {
  419. // We found a page break
  420. $showpricebeforepagebreak=0;
  421. }
  422. }
  423. else // No pagebreak
  424. {
  425. $pdf->commitTransaction();
  426. }
  427. $posYAfterDescription=$pdf->GetY();
  428. $nexY = $pdf->GetY();
  429. $pageposafter=$pdf->getPage();
  430. $pdf->setPage($pageposbefore);
  431. $pdf->setTopMargin($this->marge_haute);
  432. $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
  433. // We suppose that a too long description or photo were moved completely on next page
  434. if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
  435. $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
  436. }
  437. $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut
  438. // VAT Rate
  439. if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
  440. {
  441. $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
  442. $pdf->SetXY($this->posxtva-5, $curY);
  443. $pdf->MultiCell($this->posxup-$this->posxtva+4, 3, $vat_rate, 0, 'R');
  444. }
  445. // Unit price before discount
  446. $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
  447. $pdf->SetXY($this->posxup, $curY);
  448. $pdf->MultiCell($this->posxqty-$this->posxup-0.8, 3, $up_excl_tax, 0, 'R', 0);
  449. // Quantity
  450. $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
  451. $pdf->SetXY($this->posxqty, $curY);
  452. // Enough for 6 chars
  453. if($conf->global->PRODUCT_USE_UNITS)
  454. {
  455. $pdf->MultiCell($this->posxunit-$this->posxqty-0.8, 4, $qty, 0, 'R');
  456. }
  457. else
  458. {
  459. $pdf->MultiCell($this->posxdiscount-$this->posxqty-0.8, 4, $qty, 0, 'R');
  460. }
  461. // Unit
  462. if($conf->global->PRODUCT_USE_UNITS)
  463. {
  464. $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
  465. $pdf->SetXY($this->posxunit, $curY);
  466. $pdf->MultiCell($this->posxdiscount-$this->posxunit-0.8, 4, $unit, 0, 'L');
  467. }
  468. // Discount on line
  469. $pdf->SetXY($this->posxdiscount, $curY);
  470. if ($object->lines[$i]->remise_percent)
  471. {
  472. $pdf->SetXY($this->posxdiscount-2, $curY);
  473. $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
  474. $pdf->MultiCell($this->postotalht-$this->posxdiscount+2, 3, $remise_percent, 0, 'R');
  475. }
  476. // Total HT line
  477. $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
  478. $pdf->SetXY($this->postotalht, $curY);
  479. $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->postotalht, 3, $total_excl_tax, 0, 'R', 0);
  480. // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
  481. if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva;
  482. else $tvaligne=$object->lines[$i]->total_tva;
  483. $localtax1ligne=$object->lines[$i]->total_localtax1;
  484. $localtax2ligne=$object->lines[$i]->total_localtax2;
  485. $localtax1_rate=$object->lines[$i]->localtax1_tx;
  486. $localtax2_rate=$object->lines[$i]->localtax2_tx;
  487. $localtax1_type=$object->lines[$i]->localtax1_type;
  488. $localtax2_type=$object->lines[$i]->localtax2_type;
  489. if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
  490. if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
  491. if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
  492. $vatrate=(string) $object->lines[$i]->tva_tx;
  493. // Retrieve type from database for backward compatibility with old records
  494. if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined
  495. && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax
  496. {
  497. $localtaxtmp_array=getLocalTaxesFromRate($vatrate,0,$object->thirdparty,$mysoc);
  498. $localtax1_type = $localtaxtmp_array[0];
  499. $localtax2_type = $localtaxtmp_array[2];
  500. }
  501. // retrieve global local tax
  502. if ($localtax1_type && $localtax1ligne != 0)
  503. $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne;
  504. if ($localtax2_type && $localtax2ligne != 0)
  505. $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne;
  506. if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
  507. if (! isset($this->tva[$vatrate])) $this->tva[$vatrate]=0;
  508. $this->tva[$vatrate] += $tvaligne;
  509. if ($posYAfterImage > $posYAfterDescription) $nexY=$posYAfterImage;
  510. // Add line
  511. if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1))
  512. {
  513. $pdf->setPage($pageposafter);
  514. $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80)));
  515. //$pdf->SetDrawColor(190,190,200);
  516. $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
  517. $pdf->SetLineStyle(array('dash'=>0));
  518. }
  519. $nexY+=2; // Passe espace entre les lignes
  520. // Detect if some page were added automatically and output _tableau for past pages
  521. while ($pagenb < $pageposafter)
  522. {
  523. $pdf->setPage($pagenb);
  524. if ($pagenb == 1)
  525. {
  526. $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
  527. }
  528. else
  529. {
  530. $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
  531. }
  532. $this->_pagefoot($pdf,$object,$outputlangs,1);
  533. $pagenb++;
  534. $pdf->setPage($pagenb);
  535. $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
  536. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
  537. }
  538. if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
  539. {
  540. if ($pagenb == 1)
  541. {
  542. $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
  543. }
  544. else
  545. {
  546. $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
  547. }
  548. $this->_pagefoot($pdf,$object,$outputlangs,1);
  549. // New page
  550. $pdf->AddPage();
  551. if (! empty($tplidx)) $pdf->useTemplate($tplidx);
  552. $pagenb++;
  553. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
  554. }
  555. }
  556. // Show square
  557. if ($pagenb == 1)
  558. {
  559. $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
  560. $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
  561. }
  562. else
  563. {
  564. $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
  565. $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
  566. }
  567. // Affiche zone infos
  568. $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
  569. // Affiche zone totaux
  570. $posy=$this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs);
  571. // Affiche zone versements
  572. /*
  573. if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included)
  574. {
  575. $posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs);
  576. }
  577. */
  578. // Customer signature area
  579. if (empty($conf->global->PROPAL_DISABLE_SIGNATURE))
  580. {
  581. $posy=$this->_signature_area($pdf, $object, $posy, $outputlangs);
  582. }
  583. // Pied de page
  584. $this->_pagefoot($pdf,$object,$outputlangs);
  585. if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages();
  586. //If propal merge product PDF is active
  587. if (!empty($conf->global->PRODUIT_PDF_MERGE_PROPAL))
  588. {
  589. require_once DOL_DOCUMENT_ROOT.'/product/class/propalmergepdfproduct.class.php';
  590. $already_merged = array ();
  591. foreach ( $object->lines as $line ) {
  592. if (! empty($line->fk_product) && ! (in_array($line->fk_product, $already_merged))) {
  593. // Find the desire PDF
  594. $filetomerge = new Propalmergepdfproduct($this->db);
  595. if ($conf->global->MAIN_MULTILANGS) {
  596. $filetomerge->fetch_by_product($line->fk_product, $outputlangs->defaultlang);
  597. } else {
  598. $filetomerge->fetch_by_product($line->fk_product);
  599. }
  600. $already_merged[] = $line->fk_product;
  601. $product = new Product($this->db);
  602. $product->fetch($line->fk_product);
  603. if ($product->entity!=$conf->entity) {
  604. $entity_product_file=$product->entity;
  605. } else {
  606. $entity_product_file=$conf->entity;
  607. }
  608. // If PDF is selected and file is not empty
  609. if (count($filetomerge->lines) > 0) {
  610. foreach ( $filetomerge->lines as $linefile ) {
  611. if (! empty($linefile->id) && ! empty($linefile->file_name)) {
  612. if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
  613. {
  614. if (! empty($conf->product->enabled)) {
  615. $filetomerge_dir = $conf->product->multidir_output[$entity_product_file] . '/' . get_exdir($product->id,2,0,0,$product,'product') . $product->id ."/photos";
  616. } elseif (! empty($conf->service->enabled)) {
  617. $filetomerge_dir = $conf->service->multidir_output[$entity_product_file] . '/' . get_exdir($product->id,2,0,0,$product,'product') . $product->id ."/photos";
  618. }
  619. }
  620. else
  621. {
  622. if (! empty($conf->product->enabled)) {
  623. $filetomerge_dir = $conf->product->multidir_output[$entity_product_file] . '/' . get_exdir(0,0,0,0,$product,'product') . dol_sanitizeFileName($product->ref);
  624. } elseif (! empty($conf->service->enabled)) {
  625. $filetomerge_dir = $conf->service->multidir_output[$entity_product_file] . '/' . get_exdir(0,0,0,0,$product,'product') . dol_sanitizeFileName($product->ref);
  626. }
  627. }
  628. dol_syslog(get_class($this) . ':: upload_dir=' . $filetomerge_dir, LOG_DEBUG);
  629. $infile = $filetomerge_dir . '/' . $linefile->file_name;
  630. if (file_exists($infile) && is_readable($infile)) {
  631. $pagecount = $pdf->setSourceFile($infile);
  632. for($i = 1; $i <= $pagecount; $i ++) {
  633. $tplIdx = $pdf->importPage($i);
  634. if ($tplIdx!==false) {
  635. $s = $pdf->getTemplatesize($tplIdx);
  636. $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
  637. $pdf->useTemplate($tplIdx);
  638. } else {
  639. setEventMessages(null, array($infile.' cannot be added, probably protected PDF'),'warnings');
  640. }
  641. }
  642. }
  643. }
  644. }
  645. }
  646. }
  647. }
  648. }
  649. $pdf->Close();
  650. $pdf->Output($file,'F');
  651. //Add pdfgeneration hook
  652. $hookmanager->initHooks(array('pdfgeneration'));
  653. $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
  654. global $action;
  655. $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
  656. if (! empty($conf->global->MAIN_UMASK))
  657. @chmod($file, octdec($conf->global->MAIN_UMASK));
  658. $this->result = array('fullpath'=>$file);
  659. return 1; // Pas d'erreur
  660. }
  661. else
  662. {
  663. $this->error=$langs->trans("ErrorCanNotCreateDir",$dir);
  664. return 0;
  665. }
  666. }
  667. else
  668. {
  669. $this->error=$langs->trans("ErrorConstantNotDefined","PROP_OUTPUTDIR");
  670. return 0;
  671. }
  672. }
  673. /**
  674. * Show payments table
  675. *
  676. * @param TCPDF $pdf Object PDF
  677. * @param Object $object Object proposal
  678. * @param int $posy Position y in PDF
  679. * @param Translate $outputlangs Object langs for output
  680. * @return int <0 if KO, >0 if OK
  681. */
  682. function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
  683. {
  684. }
  685. /**
  686. * Show miscellaneous information (payment mode, payment term, ...)
  687. *
  688. * @param TCPDF $pdf Object PDF
  689. * @param Object $object Object to show
  690. * @param int $posy Y
  691. * @param Translate $outputlangs Langs object
  692. * @return void
  693. */
  694. function _tableau_info(&$pdf, $object, $posy, $outputlangs)
  695. {
  696. global $conf;
  697. $default_font_size = pdf_getPDFFontSize($outputlangs);
  698. $pdf->SetFont('','', $default_font_size - 1);
  699. // If France, show VAT mention if not applicable
  700. if ($this->emetteur->country_code == 'FR' && $this->franchise == 1)
  701. {
  702. $pdf->SetFont('','B', $default_font_size - 2);
  703. $pdf->SetXY($this->marge_gauche, $posy);
  704. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
  705. $posy=$pdf->GetY()+4;
  706. }
  707. $posxval=52;
  708. // Show shipping date
  709. if (! empty($object->date_livraison))
  710. {
  711. $outputlangs->load("sendings");
  712. $pdf->SetFont('','B', $default_font_size - 2);
  713. $pdf->SetXY($this->marge_gauche, $posy);
  714. $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
  715. $pdf->MultiCell(80, 4, $titre, 0, 'L');
  716. $pdf->SetFont('','', $default_font_size - 2);
  717. $pdf->SetXY($posxval, $posy);
  718. $dlp=dol_print_date($object->date_livraison,"daytext",false,$outputlangs,true);
  719. $pdf->MultiCell(80, 4, $dlp, 0, 'L');
  720. $posy=$pdf->GetY()+1;
  721. }
  722. elseif ($object->availability_code || $object->availability) // Show availability conditions
  723. {
  724. $pdf->SetFont('','B', $default_font_size - 2);
  725. $pdf->SetXY($this->marge_gauche, $posy);
  726. $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
  727. $pdf->MultiCell(80, 4, $titre, 0, 'L');
  728. $pdf->SetTextColor(0,0,0);
  729. $pdf->SetFont('','', $default_font_size - 2);
  730. $pdf->SetXY($posxval, $posy);
  731. $lib_availability=$outputlangs->transnoentities("AvailabilityType".$object->availability_code)!=('AvailabilityType'.$object->availability_code)?$outputlangs->transnoentities("AvailabilityType".$object->availability_code):$outputlangs->convToOutputCharset($object->availability);
  732. $lib_availability=str_replace('\n',"\n",$lib_availability);
  733. $pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
  734. $posy=$pdf->GetY()+1;
  735. }
  736. // Show payments conditions
  737. if (empty($conf->global->PROPALE_PDF_HIDE_PAYMENTTERMCOND) && ($object->cond_reglement_code || $object->cond_reglement))
  738. {
  739. $pdf->SetFont('','B', $default_font_size - 2);
  740. $pdf->SetXY($this->marge_gauche, $posy);
  741. $titre = $outputlangs->transnoentities("PaymentConditions").':';
  742. $pdf->MultiCell(43, 4, $titre, 0, 'L');
  743. $pdf->SetFont('','', $default_font_size - 2);
  744. $pdf->SetXY($posxval, $posy);
  745. $lib_condition_paiement=$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code)!=('PaymentCondition'.$object->cond_reglement_code)?$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code):$outputlangs->convToOutputCharset($object->cond_reglement_doc);
  746. $lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement);
  747. $pdf->MultiCell(67, 4, $lib_condition_paiement,0,'L');
  748. $posy=$pdf->GetY()+3;
  749. }
  750. if (empty($conf->global->PROPALE_PDF_HIDE_PAYMENTTERMCOND))
  751. {
  752. // Check a payment mode is defined
  753. /* Not required on a proposal
  754. if (empty($object->mode_reglement_code)
  755. && ! $conf->global->FACTURE_CHQ_NUMBER
  756. && ! $conf->global->FACTURE_RIB_NUMBER)
  757. {
  758. $pdf->SetXY($this->marge_gauche, $posy);
  759. $pdf->SetTextColor(200,0,0);
  760. $pdf->SetFont('','B', $default_font_size - 2);
  761. $pdf->MultiCell(90, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0);
  762. $pdf->SetTextColor(0,0,0);
  763. $posy=$pdf->GetY()+1;
  764. }
  765. */
  766. // Show payment mode
  767. if ($object->mode_reglement_code
  768. && $object->mode_reglement_code != 'CHQ'
  769. && $object->mode_reglement_code != 'VIR')
  770. {
  771. $pdf->SetFont('','B', $default_font_size - 2);
  772. $pdf->SetXY($this->marge_gauche, $posy);
  773. $titre = $outputlangs->transnoentities("PaymentMode").':';
  774. $pdf->MultiCell(80, 5, $titre, 0, 'L');
  775. $pdf->SetFont('','', $default_font_size - 2);
  776. $pdf->SetXY($posxval, $posy);
  777. $lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement);
  778. $pdf->MultiCell(80, 5, $lib_mode_reg,0,'L');
  779. $posy=$pdf->GetY()+2;
  780. }
  781. // Show payment mode CHQ
  782. if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
  783. {
  784. // Si mode reglement non force ou si force a CHQ
  785. if (! empty($conf->global->FACTURE_CHQ_NUMBER))
  786. {
  787. $diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE);
  788. if ($conf->global->FACTURE_CHQ_NUMBER > 0)
  789. {
  790. $account = new Account($this->db);
  791. $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
  792. $pdf->SetXY($this->marge_gauche, $posy);
  793. $pdf->SetFont('','B', $default_font_size - $diffsizetitle);
  794. $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio),0,'L',0);
  795. $posy=$pdf->GetY()+1;
  796. if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
  797. {
  798. $pdf->SetXY($this->marge_gauche, $posy);
  799. $pdf->SetFont('','', $default_font_size - $diffsizetitle);
  800. $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
  801. $posy=$pdf->GetY()+2;
  802. }
  803. }
  804. if ($conf->global->FACTURE_CHQ_NUMBER == -1)
  805. {
  806. $pdf->SetXY($this->marge_gauche, $posy);
  807. $pdf->SetFont('','B', $default_font_size - $diffsizetitle);
  808. $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$this->emetteur->name),0,'L',0);
  809. $posy=$pdf->GetY()+1;
  810. if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
  811. {
  812. $pdf->SetXY($this->marge_gauche, $posy);
  813. $pdf->SetFont('','', $default_font_size - $diffsizetitle);
  814. $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
  815. $posy=$pdf->GetY()+2;
  816. }
  817. }
  818. }
  819. }
  820. // If payment mode not forced or forced to VIR, show payment with BAN
  821. if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
  822. {
  823. if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER))
  824. {
  825. $bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account);
  826. if (! empty($object->fk_bank)) $bankid=$object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
  827. $account = new Account($this->db);
  828. $account->fetch($bankid);
  829. $curx=$this->marge_gauche;
  830. $cury=$posy;
  831. $posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size);
  832. $posy+=2;
  833. }
  834. }
  835. }
  836. return $posy;
  837. }
  838. /**
  839. * Show total to pay
  840. *
  841. * @param PDF $pdf Object PDF
  842. * @param Facture $object Object invoice
  843. * @param int $deja_regle Montant deja regle
  844. * @param int $posy Position depart
  845. * @param Translate $outputlangs Objet langs
  846. * @return int Position pour suite
  847. */
  848. function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
  849. {
  850. global $conf,$mysoc;
  851. $default_font_size = pdf_getPDFFontSize($outputlangs);
  852. $tab2_top = $posy;
  853. $tab2_hl = 4;
  854. $pdf->SetFont('','', $default_font_size - 1);
  855. // Tableau total
  856. $col1x = 120; $col2x = 170;
  857. if ($this->page_largeur < 210) // To work with US executive format
  858. {
  859. $col2x-=20;
  860. }
  861. $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
  862. $useborder=0;
  863. $index = 0;
  864. // Total HT
  865. $pdf->SetFillColor(255,255,255);
  866. $pdf->SetXY($col1x, $tab2_top + 0);
  867. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
  868. $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
  869. $pdf->SetXY($col2x, $tab2_top + 0);
  870. $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (! empty($object->remise)?$object->remise:0), 0, $outputlangs), 0, 'R', 1);
  871. // Show VAT by rates and total
  872. $pdf->SetFillColor(248,248,248);
  873. $total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
  874. $this->atleastoneratenotnull=0;
  875. if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
  876. {
  877. $tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
  878. if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull)
  879. {
  880. // Nothing to do
  881. }
  882. else
  883. {
  884. //Local tax 1 before VAT
  885. //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
  886. //{
  887. foreach( $this->localtax1 as $localtax_type => $localtax_rate )
  888. {
  889. if (in_array((string) $localtax_type, array('1','3','5'))) continue;
  890. foreach( $localtax_rate as $tvakey => $tvaval )
  891. {
  892. if ($tvakey!=0) // On affiche pas taux 0
  893. {
  894. //$this->atleastoneratenotnull++;
  895. $index++;
  896. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  897. $tvacompl='';
  898. if (preg_match('/\*/',$tvakey))
  899. {
  900. $tvakey=str_replace('*','',$tvakey);
  901. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  902. }
  903. $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
  904. $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
  905. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  906. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  907. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
  908. }
  909. }
  910. }
  911. //}
  912. //Local tax 2 before VAT
  913. //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
  914. //{
  915. foreach( $this->localtax2 as $localtax_type => $localtax_rate )
  916. {
  917. if (in_array((string) $localtax_type, array('1','3','5'))) continue;
  918. foreach( $localtax_rate as $tvakey => $tvaval )
  919. {
  920. if ($tvakey!=0) // On affiche pas taux 0
  921. {
  922. //$this->atleastoneratenotnull++;
  923. $index++;
  924. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  925. $tvacompl='';
  926. if (preg_match('/\*/',$tvakey))
  927. {
  928. $tvakey=str_replace('*','',$tvakey);
  929. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  930. }
  931. $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
  932. $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
  933. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  934. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  935. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
  936. }
  937. }
  938. }
  939. //}
  940. // VAT
  941. foreach($this->tva as $tvakey => $tvaval)
  942. {
  943. if ($tvakey != 0) // On affiche pas taux 0
  944. {
  945. $this->atleastoneratenotnull++;
  946. $index++;
  947. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  948. $tvacompl='';
  949. if (preg_match('/\*/',$tvakey))
  950. {
  951. $tvakey=str_replace('*','',$tvakey);
  952. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  953. }
  954. $totalvat =$outputlangs->transcountrynoentities("TotalVAT",$mysoc->country_code).' ';
  955. $totalvat.=vatrate($tvakey,1).$tvacompl;
  956. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  957. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  958. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
  959. }
  960. }
  961. //Local tax 1 after VAT
  962. //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
  963. //{
  964. foreach( $this->localtax1 as $localtax_type => $localtax_rate )
  965. {
  966. if (in_array((string) $localtax_type, array('2','4','6'))) continue;
  967. foreach( $localtax_rate as $tvakey => $tvaval )
  968. {
  969. if ($tvakey != 0) // On affiche pas taux 0
  970. {
  971. //$this->atleastoneratenotnull++;
  972. $index++;
  973. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  974. $tvacompl='';
  975. if (preg_match('/\*/',$tvakey))
  976. {
  977. $tvakey=str_replace('*','',$tvakey);
  978. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  979. }
  980. $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
  981. $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
  982. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  983. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  984. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
  985. }
  986. }
  987. }
  988. //}
  989. //Local tax 2 after VAT
  990. //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
  991. //{
  992. foreach( $this->localtax2 as $localtax_type => $localtax_rate )
  993. {
  994. if (in_array((string) $localtax_type, array('2','4','6'))) continue;
  995. foreach( $localtax_rate as $tvakey => $tvaval )
  996. {
  997. // retrieve global local tax
  998. if ($tvakey != 0) // On affiche pas taux 0
  999. {
  1000. //$this->atleastoneratenotnull++;
  1001. $index++;
  1002. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  1003. $tvacompl='';
  1004. if (preg_match('/\*/',$tvakey))
  1005. {
  1006. $tvakey=str_replace('*','',$tvakey);
  1007. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  1008. }
  1009. $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
  1010. $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
  1011. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  1012. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  1013. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
  1014. }
  1015. }
  1016. }
  1017. //}
  1018. // Total TTC
  1019. $index++;
  1020. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  1021. $pdf->SetTextColor(0,0,60);
  1022. $pdf->SetFillColor(224,224,224);
  1023. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
  1024. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  1025. $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
  1026. }
  1027. }
  1028. $pdf->SetTextColor(0,0,0);
  1029. /*
  1030. $resteapayer = $object->total_ttc - $deja_regle;
  1031. if (! empty($object->paye)) $resteapayer=0;
  1032. */
  1033. if ($deja_regle > 0)
  1034. {
  1035. $index++;
  1036. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  1037. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
  1038. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  1039. $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
  1040. /*
  1041. if ($object->close_code == 'discount_vat')
  1042. {
  1043. $index++;
  1044. $pdf->SetFillColor(255,255,255);
  1045. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  1046. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1);
  1047. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  1048. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle, 0, $outputlangs), $useborder, 'R', 1);
  1049. $resteapayer=0;
  1050. }
  1051. */
  1052. $index++;
  1053. $pdf->SetTextColor(0,0,60);
  1054. $pdf->SetFillColor(224,224,224);
  1055. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  1056. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
  1057. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  1058. $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
  1059. $pdf->SetFont('','', $default_font_size - 1);
  1060. $pdf->SetTextColor(0,0,0);
  1061. }
  1062. $index++;
  1063. return ($tab2_top + ($tab2_hl * $index));
  1064. }
  1065. /**
  1066. * Show table for lines
  1067. *
  1068. * @param PDF $pdf Object PDF
  1069. * @param string $tab_top Top position of table
  1070. * @param string $tab_height Height of table (rectangle)
  1071. * @param int $nexY Y (not used)
  1072. * @param Translate $outputlangs Langs object
  1073. * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
  1074. * @param int $hidebottom Hide bottom bar of array
  1075. * @param string $currency Currency code
  1076. * @return void
  1077. */
  1078. function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
  1079. {
  1080. global $conf;
  1081. // Force to disable hidetop and hidebottom
  1082. $hidebottom=0;
  1083. if ($hidetop) $hidetop=-1;
  1084. $currency = !empty($currency) ? $currency : $conf->currency;
  1085. $default_font_size = pdf_getPDFFontSize($outputlangs);
  1086. // Amount in (at tab_top - 1)
  1087. $pdf->SetTextColor(0,0,0);
  1088. $pdf->SetFont('','',$default_font_size - 2);
  1089. if (empty($hidetop))
  1090. {
  1091. $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$currency));
  1092. $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
  1093. $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
  1094. //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
  1095. if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',',$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
  1096. }
  1097. $pdf->SetDrawColor(128,128,128);
  1098. $pdf->SetFont('','',$default_font_size - 1);
  1099. // Output Rect
  1100. $this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect prend une longueur en 3eme param et 4eme param
  1101. if (empty($hidetop))
  1102. {
  1103. $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); // line prend une position y en 2eme param et 4eme param
  1104. $pdf->SetXY($this->posxdesc-1, $tab_top+1);
  1105. $pdf->MultiCell(108,2, $outputlangs->transnoentities("Designation"),'','L');
  1106. }
  1107. if (! empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE))
  1108. {
  1109. $pdf->line($this->posxpicture-1, $tab_top, $this->posxpicture-1, $tab_top + $tab_height);
  1110. if (empty($hidetop))
  1111. {
  1112. //$pdf->SetXY($this->posxpicture-1, $tab_top+1);
  1113. //$pdf->MultiCell($this->posxtva-$this->posxpicture-1,2, $outputlangs->transnoentities("Photo"),'','C');
  1114. }
  1115. }
  1116. if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
  1117. {
  1118. $pdf->line($this->posxtva-1, $tab_top, $this->posxtva-1, $tab_top + $tab_height);
  1119. if (empty($hidetop))
  1120. {
  1121. // Not do -3 and +3 instead of -1 -1 to have more space for text 'Sales tax'
  1122. $pdf->SetXY($this->posxtva-3, $tab_top+1);
  1123. $pdf->MultiCell($this->posxup-$this->posxtva+3,2, $outputlangs->transnoentities("VAT"),'','C');
  1124. }
  1125. }
  1126. $pdf->line($this->posxup-1, $tab_top, $this->posxup-1, $tab_top + $tab_height);
  1127. if (empty($hidetop))
  1128. {
  1129. $pdf->SetXY($this->posxup-1, $tab_top+1);
  1130. $pdf->MultiCell($this->posxqty-$this->posxup-1,2, $outputlangs->transnoentities("PriceUHT"),'','C');
  1131. }
  1132. $pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height);
  1133. if (empty($hidetop))
  1134. {
  1135. $pdf->SetXY($this->posxqty-1, $tab_top+1);
  1136. if($conf->global->PRODUCT_USE_UNITS)
  1137. {
  1138. $pdf->MultiCell($this->posxunit-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C');
  1139. }
  1140. else
  1141. {
  1142. $pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C');
  1143. }
  1144. }
  1145. if($conf->global->PRODUCT_USE_UNITS) {
  1146. $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height);
  1147. if (empty($hidetop)) {
  1148. $pdf->SetXY($this->posxunit - 1, $tab_top + 1);
  1149. $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("Unit"), '',
  1150. 'C');
  1151. }
  1152. }
  1153. $pdf->line($this->posxdiscount-1, $tab_top, $this->posxdiscount-1, $tab_top + $tab_height);
  1154. if (empty($hidetop))
  1155. {
  1156. if ($this->atleastonediscount)
  1157. {
  1158. $pdf->SetXY($this->posxdiscount-1, $tab_top+1);
  1159. $pdf->MultiCell($this->postotalht-$this->posxdiscount+1,2, $outputlangs->transnoentities("ReductionShort"),'','C');
  1160. }
  1161. }
  1162. if ($this->atleastonediscount)
  1163. {
  1164. $pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
  1165. }
  1166. if (empty($hidetop))
  1167. {
  1168. $pdf->SetXY($this->postotalht-1, $tab_top+1);
  1169. $pdf->MultiCell(30,2, $outputlangs->transnoentities("TotalHT"),'','C');
  1170. }
  1171. }
  1172. /**
  1173. * Show top header of page.
  1174. *
  1175. * @param PDF $pdf Object PDF
  1176. * @param Object $object Object to show
  1177. * @param int $showaddress 0=no, 1=yes
  1178. * @param Translate $outputlangs Object lang for output
  1179. * @return void
  1180. */
  1181. function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
  1182. {
  1183. global $conf,$langs;
  1184. $outputlangs->load("main");
  1185. $outputlangs->load("bills");
  1186. $outputlangs->load("propal");
  1187. $outputlangs->load("companies");
  1188. $default_font_size = pdf_getPDFFontSize($outputlangs);
  1189. pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
  1190. // Show Draft Watermark
  1191. if($object->statut==0 && (! empty($conf->global->PROPALE_DRAFT_WATERMARK)) )
  1192. {
  1193. pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->PROPALE_DRAFT_WATERMARK);
  1194. }
  1195. $pdf->SetTextColor(0,0,60);
  1196. $pdf->SetFont('','B', $default_font_size + 3);
  1197. $posy=$this->marge_haute;
  1198. $posx=$this->page_largeur-$this->marge_droite-100;
  1199. $pdf->SetXY($this->marge_gauche,$posy);
  1200. // Logo
  1201. $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
  1202. if ($this->emetteur->logo)
  1203. {
  1204. if (is_readable($logo))
  1205. {
  1206. $height=pdf_getHeightForLogo($logo);
  1207. $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
  1208. }
  1209. else
  1210. {
  1211. $pdf->SetTextColor(200,0,0);
  1212. $pdf->SetFont('','B',$default_font_size - 2);
  1213. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
  1214. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
  1215. }
  1216. }
  1217. else
  1218. {
  1219. $text=$this->emetteur->name;
  1220. $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
  1221. }
  1222. $pdf->SetFont('','B',$default_font_size + 3);
  1223. $pdf->SetXY($posx,$posy);
  1224. $pdf->SetTextColor(0,0,60);
  1225. $title=$outputlangs->transnoentities("PdfCommercialProposalTitle");
  1226. $pdf->MultiCell(100, 4, $title, '', 'R');
  1227. $pdf->SetFont('','B',$default_font_size);
  1228. $posy+=5;
  1229. $pdf->SetXY($posx,$posy);
  1230. $pdf->SetTextColor(0,0,60);
  1231. $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref), '', 'R');
  1232. $posy+=1;
  1233. $pdf->SetFont('','', $default_font_size - 2);
  1234. if ($object->ref_client)
  1235. {
  1236. $posy+=4;
  1237. $pdf->SetXY($posx,$posy);
  1238. $pdf->SetTextColor(0,0,60);
  1239. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
  1240. }
  1241. $posy+=4;
  1242. $pdf->SetXY($posx,$posy);
  1243. $pdf->SetTextColor(0,0,60);
  1244. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Date")." : " . dol_print_date($object->date,"day",false,$outputlangs,true), '', 'R');
  1245. $posy+=4;
  1246. $pdf->SetXY($posx,$posy);
  1247. $pdf->SetTextColor(0,0,60);
  1248. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DateEndPropal")." : " . dol_print_date($object->fin_validite,"day",false,$outputlangs,true), '', 'R');
  1249. if ($object->thirdparty->code_client)
  1250. {
  1251. $posy+=4;
  1252. $pdf->SetXY($posx,$posy);
  1253. $pdf->SetTextColor(0,0,60);
  1254. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("CustomerCode")." : " . $outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
  1255. }
  1256. // Get contact
  1257. if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
  1258. {
  1259. $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
  1260. if (count($arrayidcontact) > 0)
  1261. {
  1262. $usertmp=new User($this->db);
  1263. $usertmp->fetch($arrayidcontact[0]);
  1264. $posy+=4;
  1265. $pdf->SetXY($posx,$posy);
  1266. $pdf->SetTextColor(0,0,60);
  1267. $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
  1268. }
  1269. }
  1270. $posy+=2;
  1271. // Show list of linked objects
  1272. $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
  1273. if ($showaddress)
  1274. {
  1275. // Sender properties
  1276. $carac_emetteur='';
  1277. // Add internal contact of proposal if defined
  1278. $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
  1279. if (count($arrayidcontact) > 0)
  1280. {
  1281. $object->fetch_user($arrayidcontact[0]);
  1282. $labelbeforecontactname=($outputlangs->transnoentities("FromContactName")!='FromContactName'?$outputlangs->transnoentities("FromContactName"):$outputlangs->transnoentities("Name"));
  1283. $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";
  1284. }
  1285. $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty);
  1286. // Show sender
  1287. $posy=42;
  1288. $posx=$this->marge_gauche;
  1289. if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
  1290. $hautcadre=40;
  1291. // Show sender frame
  1292. $pdf->SetTextColor(0,0,0);
  1293. $pdf->SetFont('','', $default_font_size - 2);
  1294. $pdf->SetXY($posx,$posy-5);
  1295. $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
  1296. $pdf->SetXY($posx,$posy);
  1297. $pdf->SetFillColor(230,230,230);
  1298. $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
  1299. $pdf->SetTextColor(0,0,60);
  1300. // Show sender name
  1301. $pdf->SetXY($posx+2,$posy+3);
  1302. $pdf->SetFont('','B', $default_font_size);
  1303. $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
  1304. $posy=$pdf->getY();
  1305. // Show sender information
  1306. $pdf->SetXY($posx+2,$posy);
  1307. $pdf->SetFont('','', $default_font_size - 1);
  1308. $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
  1309. // If CUSTOMER contact defined, we use it
  1310. $usecontact=false;
  1311. $arrayidcontact=$object->getIdContact('external','CUSTOMER');
  1312. if (count($arrayidcontact) > 0)
  1313. {
  1314. $usecontact=true;
  1315. $result=$object->fetch_contact($arrayidcontact[0]);
  1316. }
  1317. //Recipient name
  1318. // On peut utiliser le nom de la societe du contact
  1319. if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) {
  1320. $thirdparty = $object->contact;
  1321. } else {
  1322. $thirdparty = $object->thirdparty;
  1323. }
  1324. $carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs);
  1325. $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,($usecontact?$object->contact:''),$usecontact,'target',$object);
  1326. // Show recipient
  1327. $widthrecbox=100;
  1328. if ($this->page_largeur < 210) $widthrecbox=84; // To work with US executive format
  1329. $posy=42;
  1330. $posx=$this->page_largeur-$this->marge_droite-$widthrecbox;
  1331. if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
  1332. // Show recipient frame
  1333. $pdf->SetTextColor(0,0,0);
  1334. $pdf->SetFont('','', $default_font_size - 2);
  1335. $pdf->SetXY($posx+2,$posy-5);
  1336. $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":", 0, 'L');
  1337. $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
  1338. // Show recipient name
  1339. $pdf->SetXY($posx+2,$posy+3);
  1340. $pdf->SetFont('','B', $default_font_size);
  1341. $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L');
  1342. $posy = $pdf->getY();
  1343. // Show recipient information
  1344. $pdf->SetFont('','', $default_font_size - 1);
  1345. $pdf->SetXY($posx+2,$posy);
  1346. $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
  1347. }
  1348. $pdf->SetTextColor(0,0,0);
  1349. }
  1350. /**
  1351. * Show footer of page. Need this->emetteur object
  1352. *
  1353. * @param PDF $pdf PDF
  1354. * @param Object $object Object to show
  1355. * @param Translate $outputlangs Object lang for output
  1356. * @param int $hidefreetext 1=Hide free text
  1357. * @return int Return height of bottom margin including footer text
  1358. */
  1359. function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0)
  1360. {
  1361. global $conf;
  1362. $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
  1363. return pdf_pagefoot($pdf,$outputlangs,'PROPOSAL_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
  1364. }
  1365. /**
  1366. * Show area for the customer to sign
  1367. *
  1368. * @param PDF $pdf Object PDF
  1369. * @param Facture $object Object invoice
  1370. * @param int $posy Position depart
  1371. * @param Translate $outputlangs Objet langs
  1372. * @return int Position pour suite
  1373. */
  1374. function _signature_area(&$pdf, $object, $posy, $outputlangs)
  1375. {
  1376. $default_font_size = pdf_getPDFFontSize($outputlangs);
  1377. $tab_top = $posy + 4;
  1378. $tab_hl = 4;
  1379. $posx = 120;
  1380. $largcol = ($this->page_largeur - $this->marge_droite - $posx);
  1381. $useborder=0;
  1382. $index = 0;
  1383. // Total HT
  1384. $pdf->SetFillColor(255,255,255);
  1385. $pdf->SetXY($posx, $tab_top + 0);
  1386. $pdf->SetFont('','', $default_font_size - 2);
  1387. $pdf->MultiCell($largcol, $tab_hl, $outputlangs->transnoentities("ProposalCustomerSignature"), 0, 'L', 1);
  1388. $pdf->SetXY($posx, $tab_top + $tab_hl);
  1389. $pdf->MultiCell($largcol, $tab_hl*3, '', 1, 'R');
  1390. return ($tab_hl*7);
  1391. }
  1392. }