PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/core/modules/propale/pdf_propale_azur.modules.php

https://github.com/asterix14/dolibarr
PHP | 1057 lines | 723 code | 176 blank | 158 comment | 106 complexity | 6cf2e98038b3d4a96d6424554b87652f MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /* Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2005-2011 Regis Houssin <regis@dolibarr.fr>
  4. * Copyright (C) 2008 Raphael Bertrand <raphael.bertrand@resultic.fr>
  5. * Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. * or see http://www.gnu.org/
  20. */
  21. /**
  22. * \file htdocs/core/modules/propale/pdf_propale_azur.modules.php
  23. * \ingroup propale
  24. * \brief Fichier de la classe permettant de generer les propales au modele Azur
  25. * \author Laurent Destailleur
  26. */
  27. require_once(DOL_DOCUMENT_ROOT."/core/modules/propale/modules_propale.php");
  28. require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
  29. require_once(DOL_DOCUMENT_ROOT."/core/lib/company.lib.php");
  30. require_once(DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php");
  31. require_once(DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php');
  32. /**
  33. * \class pdf_propale_azur
  34. * \brief Classe permettant de generer les propales au modele Azur
  35. */
  36. class pdf_propale_azur extends ModelePDFPropales
  37. {
  38. var $emetteur; // Objet societe qui emet
  39. /**
  40. * Constructor
  41. *
  42. * @param DoliDB $DB Database handler
  43. */
  44. function pdf_propale_azur($db)
  45. {
  46. global $conf,$langs,$mysoc;
  47. $langs->load("main");
  48. $langs->load("bills");
  49. $this->db = $db;
  50. $this->name = "azur";
  51. $this->description = $langs->trans('DocModelAzurDescription');
  52. // Dimension page pour format A4
  53. $this->type = 'pdf';
  54. $formatarray=pdf_getFormat();
  55. $this->page_largeur = $formatarray['width'];
  56. $this->page_hauteur = $formatarray['height'];
  57. $this->format = array($this->page_largeur,$this->page_hauteur);
  58. $this->marge_gauche=10;
  59. $this->marge_droite=10;
  60. $this->marge_haute=10;
  61. $this->marge_basse=10;
  62. $this->option_logo = 1; // Affiche logo
  63. $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION
  64. $this->option_modereg = 1; // Affiche mode reglement
  65. $this->option_condreg = 1; // Affiche conditions reglement
  66. $this->option_codeproduitservice = 1; // Affiche code produit-service
  67. $this->option_multilang = 1; // Dispo en plusieurs langues
  68. $this->option_escompte = 1; // Affiche si il y a eu escompte
  69. $this->option_credit_note = 1; // Gere les avoirs
  70. $this->option_freetext = 1; // Support add of a personalised text
  71. $this->option_draft_watermark = 1; //Support add of a watermark on drafts
  72. $this->franchise=!$mysoc->tva_assuj;
  73. // Recupere emetteur
  74. $this->emetteur=$mysoc;
  75. if (! $this->emetteur->pays_code) $this->emetteur->pays_code=substr($langs->defaultlang,-2); // Par defaut, si n'etait pas defini
  76. // Defini position des colonnes
  77. $this->posxdesc=$this->marge_gauche+1;
  78. $this->posxtva=111;
  79. $this->posxup=126;
  80. $this->posxqty=145;
  81. $this->posxdiscount=162;
  82. $this->postotalht=174;
  83. $this->tva=array();
  84. $this->localtax1=array();
  85. $this->localtax2=array();
  86. $this->atleastoneratenotnull=0;
  87. $this->atleastonediscount=0;
  88. }
  89. /**
  90. * Function to build pdf onto disk
  91. *
  92. * @param int $object Id of object to generate
  93. * @param object $outputlangs Lang output object
  94. * @param string $srctemplatepath Full path of source filename for generator using a template file
  95. * @param int $hidedetails Do not show line details
  96. * @param int $hidedesc Do not show desc
  97. * @param int $hideref Do not show ref
  98. * @param object $hookmanager Hookmanager object
  99. * @return int 1=OK, 0=KO
  100. */
  101. function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0,$hookmanager=false)
  102. {
  103. global $user,$langs,$conf;
  104. $default_font_size = pdf_getPDFFontSize($outputlangs);
  105. if (! is_object($outputlangs)) $outputlangs=$langs;
  106. // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
  107. $sav_charset_output=$outputlangs->charset_output;
  108. if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
  109. $outputlangs->load("main");
  110. $outputlangs->load("dict");
  111. $outputlangs->load("companies");
  112. $outputlangs->load("bills");
  113. $outputlangs->load("propal");
  114. $outputlangs->load("products");
  115. if ($conf->propale->dir_output)
  116. {
  117. $object->fetch_thirdparty();
  118. $deja_regle = "";
  119. // Definition de $dir et $file
  120. if ($object->specimen)
  121. {
  122. $dir = $conf->propale->dir_output;
  123. $file = $dir . "/SPECIMEN.pdf";
  124. }
  125. else
  126. {
  127. $objectref = dol_sanitizeFileName($object->ref);
  128. $dir = $conf->propale->dir_output . "/" . $objectref;
  129. $file = $dir . "/" . $objectref . ".pdf";
  130. }
  131. if (! file_exists($dir))
  132. {
  133. if (create_exdir($dir) < 0)
  134. {
  135. $this->error=$langs->trans("ErrorCanNotCreateDir",$dir);
  136. return 0;
  137. }
  138. }
  139. if (file_exists($dir))
  140. {
  141. $nblignes = count($object->lines);
  142. // Create pdf instance
  143. $pdf=pdf_getInstance($this->format);
  144. if (class_exists('TCPDF'))
  145. {
  146. $pdf->setPrintHeader(false);
  147. $pdf->setPrintFooter(false);
  148. }
  149. $pdf->SetFont(pdf_getPDFFont($outputlangs));
  150. $pdf->Open();
  151. $pagenb=0;
  152. $pdf->SetDrawColor(128,128,128);
  153. $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
  154. $pdf->SetSubject($outputlangs->transnoentities("CommercialProposal"));
  155. $pdf->SetCreator("Dolibarr ".DOL_VERSION);
  156. $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
  157. $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("CommercialProposal"));
  158. if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
  159. $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
  160. $pdf->SetAutoPageBreak(1,0);
  161. // Positionne $this->atleastonediscount si on a au moins une remise
  162. for ($i = 0 ; $i < $nblignes ; $i++)
  163. {
  164. if ($object->lines[$i]->remise_percent)
  165. {
  166. $this->atleastonediscount++;
  167. }
  168. }
  169. // New page
  170. $pdf->AddPage();
  171. $pagenb++;
  172. $this->_pagehead($pdf, $object, 1, $outputlangs);
  173. $pdf->SetFont('','', $default_font_size - 1);
  174. $pdf->MultiCell(0, 4, ''); // Set interline to 4
  175. $pdf->SetTextColor(0,0,0);
  176. $tab_top = 90;
  177. $tab_top_middlepage = 50;
  178. $tab_top_newpage = 50;
  179. $tab_height = 130;
  180. $tab_height_middlepage = 200;
  181. $tab_height_endpage = 170;
  182. // Affiche notes
  183. if (! empty($object->note_public))
  184. {
  185. $tab_top = 88;
  186. $pdf->SetFont('','', $default_font_size - 1); // Dans boucle pour gerer multi-page
  187. $pdf->SetXY($this->posxdesc-1, $tab_top);
  188. $pdf->MultiCell(190, 4, $outputlangs->convToOutputCharset($object->note_public), 0, 'L');
  189. $nexY = $pdf->GetY();
  190. $height_note=$nexY-$tab_top;
  191. // Rect prend une longueur en 3eme param
  192. $pdf->SetDrawColor(192,192,192);
  193. $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_note+1);
  194. $tab_height = $tab_height - $height_note;
  195. $tab_top = $nexY+6;
  196. }
  197. else
  198. {
  199. $height_note=0;
  200. }
  201. $iniY = $tab_top + 7;
  202. $curY = $tab_top + 7;
  203. $nexY = $tab_top + 7;
  204. // Loop on each lines
  205. for ($i = 0 ; $i < $nblignes ; $i++)
  206. {
  207. $curY = $nexY;
  208. $pdf->SetFont('','', $default_font_size - 1); // Dans boucle pour gerer multi-page
  209. // Description de la ligne produit
  210. $curX = $this->posxdesc-1;
  211. pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxtva-$curX,4,$curX,$curY,$hideref,$hidedesc,0,$hookmanager);
  212. $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut
  213. $nexY = $pdf->GetY();
  214. // TVA
  215. if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
  216. {
  217. $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails, $hookmanager);
  218. $pdf->SetXY($this->posxtva, $curY);
  219. $pdf->MultiCell($this->posxup-$this->posxtva-1, 4, $vat_rate, 0, 'R');
  220. }
  221. // Prix unitaire HT avant remise
  222. $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails, $hookmanager);
  223. $pdf->SetXY($this->posxup, $curY);
  224. $pdf->MultiCell($this->posxqty-$this->posxup-1, 4, $up_excl_tax, 0, 'R', 0);
  225. // Quantity
  226. $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails, $hookmanager);
  227. $pdf->SetXY($this->posxqty, $curY);
  228. $pdf->MultiCell($this->posxdiscount-$this->posxqty-1, 4, $qty, 0, 'R');
  229. // Remise sur ligne
  230. $pdf->SetXY($this->posxdiscount, $curY);
  231. if ($object->lines[$i]->remise_percent)
  232. {
  233. $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails, $hookmanager);
  234. $pdf->MultiCell($this->postotalht-$this->posxdiscount-1, 4, $remise_percent, 0, 'R');
  235. }
  236. // Total HT ligne
  237. $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails, $hookmanager);
  238. $pdf->SetXY($this->postotalht, $curY);
  239. $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->postotalht, 4, $total_excl_tax, 0, 'R', 0);
  240. // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
  241. $tvaligne=$object->lines[$i]->total_tva;
  242. $localtax1ligne=$object->lines[$i]->total_localtax1;
  243. $localtax2ligne=$object->lines[$i]->total_localtax2;
  244. if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
  245. if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
  246. if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
  247. $vatrate=(string) $object->lines[$i]->tva_tx;
  248. $localtax1rate=(string) $object->lines[$i]->localtax1_tx;
  249. $localtax2rate=(string) $object->lines[$i]->localtax2_tx;
  250. if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
  251. $this->tva[$vatrate] += $tvaligne;
  252. $this->localtax1[$localtax1rate]+=$localtax1ligne;
  253. $this->localtax2[$localtax2rate]+=$localtax2ligne;
  254. $nexY+=2; // Passe espace entre les lignes
  255. // Cherche nombre de lignes a venir pour savoir si place suffisante
  256. if ($i < ($nblignes - 1) && empty($hidedesc)) // If it's not last line
  257. {
  258. //on recupere la description du produit suivant
  259. $follow_descproduitservice = $object->lines[$i+1]->desc;
  260. //on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
  261. $nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4);
  262. }
  263. else // If it's last line
  264. {
  265. $nblineFollowDesc = 0;
  266. }
  267. // Test if a new page is required
  268. if ($pagenb == 1)
  269. {
  270. $tab_top_in_current_page=$tab_top;
  271. $tab_height_in_current_page=$tab_height;
  272. }
  273. else
  274. {
  275. $tab_top_in_current_page=$tab_top_newpage;
  276. $tab_height_in_current_page=$tab_height_middlepage;
  277. }
  278. if (($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblignes - 1))
  279. {
  280. if ($pagenb == 1)
  281. {
  282. $this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs);
  283. }
  284. else
  285. {
  286. $this->_tableau($pdf, $tab_top_newpage, $tab_height_middlepage, $nexY, $outputlangs);
  287. }
  288. $this->_pagefoot($pdf,$object,$outputlangs);
  289. // New page
  290. $pdf->AddPage();
  291. $pagenb++;
  292. $this->_pagehead($pdf, $object, 0, $outputlangs);
  293. $pdf->SetFont('','', $default_font_size - 1);
  294. $pdf->MultiCell(0, 3, ''); // Set interline to 3
  295. $pdf->SetTextColor(0,0,0);
  296. $nexY = $tab_top_newpage + 7;
  297. }
  298. }
  299. // Show square
  300. if ($pagenb == 1)
  301. {
  302. $this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
  303. $bottomlasttab=$tab_top + $tab_height + 1;
  304. }
  305. else
  306. {
  307. $this->_tableau($pdf, $tab_top_newpage, $tab_height_endpage, $nexY, $outputlangs);
  308. $bottomlasttab=$tab_top_newpage + $tab_height_endpage + 1;
  309. }
  310. // Affiche zone infos
  311. $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
  312. // Affiche zone totaux
  313. $posy=$this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
  314. // Affiche zone versements
  315. if ($deja_regle)
  316. {
  317. $posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs);
  318. }
  319. // Pied de page
  320. $this->_pagefoot($pdf,$object,$outputlangs);
  321. $pdf->AliasNbPages();
  322. $pdf->Close();
  323. $pdf->Output($file,'F');
  324. // Actions on extra fields (by external module or standard code)
  325. include_once(DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php');
  326. $hookmanager=new HookManager($this->db);
  327. $hookmanager->callHooks(array('pdfgeneration'));
  328. $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
  329. global $action;
  330. $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
  331. if (! empty($conf->global->MAIN_UMASK))
  332. @chmod($file, octdec($conf->global->MAIN_UMASK));
  333. $outputlangs->charset_output=$sav_charset_output;
  334. return 1; // Pas d'erreur
  335. }
  336. else
  337. {
  338. $this->error=$langs->trans("ErrorCanNotCreateDir",$dir);
  339. return 0;
  340. }
  341. }
  342. else
  343. {
  344. $this->error=$langs->trans("ErrorConstantNotDefined","PROP_OUTPUTDIR");
  345. return 0;
  346. }
  347. $this->error=$langs->trans("ErrorUnknown");
  348. return 0; // Erreur par defaut
  349. }
  350. /*
  351. * Affiche tableau des versement
  352. *
  353. * @param pdf Objet PDF
  354. * @param object Objet propale
  355. */
  356. function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
  357. {
  358. }
  359. /**
  360. * Affiche infos divers
  361. *
  362. * @param pdf Objet PDF
  363. * @param object Objet facture
  364. * @param posy Position depart
  365. * @param outputlangs Objet langs
  366. * @return y Position pour suite
  367. */
  368. function _tableau_info(&$pdf, $object, $posy, $outputlangs)
  369. {
  370. global $conf;
  371. $default_font_size = pdf_getPDFFontSize($outputlangs);
  372. $pdf->SetFont('','', $default_font_size - 1);
  373. // If France, show VAT mention if not applicable
  374. if ($this->emetteur->pays_code == 'FR' && $this->franchise == 1)
  375. {
  376. $pdf->SetFont('','B', $default_font_size - 2);
  377. $pdf->SetXY($this->marge_gauche, $posy);
  378. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
  379. $posy=$pdf->GetY()+4;
  380. }
  381. // Show availability conditions
  382. if ($object->type != 2 && ($object->availability_code || $object->availability))
  383. {
  384. $pdf->SetFont('','B', $default_font_size - 2);
  385. $pdf->SetXY($this->marge_gauche, $posy);
  386. $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
  387. $pdf->MultiCell(80, 4, $titre, 0, 'L');
  388. $pdf->SetTextColor(0,0,0);
  389. $pdf->SetFont('','', $default_font_size - 2);
  390. $pdf->SetXY(82, $posy);
  391. $lib_availability=$outputlangs->transnoentities("AvailabilityType".$object->availability_code)!=('AvailabilityType'.$object->availability_code)?$outputlangs->transnoentities("AvailabilityType".$object->availability_code):$outputlangs->convToOutputCharset($object->availability);
  392. $lib_availability=str_replace('\n',"\n",$lib_availability);
  393. $pdf->MultiCell(80, 4, $lib_availability,0,'L');
  394. $posy=$pdf->GetY()+1;
  395. }
  396. // Show payments conditions
  397. if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement))
  398. {
  399. $pdf->SetFont('','B', $default_font_size - 2);
  400. $pdf->SetXY($this->marge_gauche, $posy);
  401. $titre = $outputlangs->transnoentities("PaymentConditions").':';
  402. $pdf->MultiCell(80, 4, $titre, 0, 'L');
  403. $pdf->SetFont('','', $default_font_size - 2);
  404. $pdf->SetXY(52, $posy);
  405. $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);
  406. $lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement);
  407. $pdf->MultiCell(80, 4, $lib_condition_paiement,0,'L');
  408. $posy=$pdf->GetY()+3;
  409. }
  410. if ($object->type != 2)
  411. {
  412. // Check a payment mode is defined
  413. if (empty($object->mode_reglement_code)
  414. && ! $conf->global->FACTURE_CHQ_NUMBER
  415. && ! $conf->global->FACTURE_RIB_NUMBER)
  416. {
  417. $pdf->SetXY($this->marge_gauche, $posy);
  418. $pdf->SetTextColor(200,0,0);
  419. $pdf->SetFont('','B', $default_font_size - 2);
  420. $pdf->MultiCell(90, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0);
  421. $pdf->SetTextColor(0,0,0);
  422. $posy=$pdf->GetY()+1;
  423. }
  424. // Shown payment mode
  425. if ($object->mode_reglement_code
  426. && $object->mode_reglement_code != 'CHQ'
  427. && $object->mode_reglement_code != 'VIR')
  428. {
  429. $pdf->SetFont('','B', $default_font_size - 2);
  430. $pdf->SetXY($this->marge_gauche, $posy);
  431. $titre = $outputlangs->transnoentities("PaymentMode").':';
  432. $pdf->MultiCell(80, 5, $titre, 0, 'L');
  433. $pdf->SetFont('','', $default_font_size - 2);
  434. $pdf->SetXY(50, $posy);
  435. $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);
  436. $pdf->MultiCell(80, 5, $lib_mode_reg,0,'L');
  437. $posy=$pdf->GetY()+2;
  438. }
  439. // Show payment mode CHQ
  440. if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
  441. {
  442. // Si mode reglement non force ou si force a CHQ
  443. if ($conf->global->FACTURE_CHQ_NUMBER)
  444. {
  445. if ($conf->global->FACTURE_CHQ_NUMBER > 0)
  446. {
  447. $account = new Account($this->db);
  448. $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
  449. $pdf->SetXY($this->marge_gauche, $posy);
  450. $pdf->SetFont('','B', $default_font_size - 2);
  451. $pdf->MultiCell(90, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio).':',0,'L',0);
  452. $posy=$pdf->GetY()+1;
  453. $pdf->SetXY($this->marge_gauche, $posy);
  454. $pdf->SetFont('','', $default_font_size - 2);
  455. $pdf->MultiCell(80, 3, $outputlangs->convToOutputCharset($account->adresse_proprio), 0, 'L', 0);
  456. $posy=$pdf->GetY()+2;
  457. }
  458. if ($conf->global->FACTURE_CHQ_NUMBER == -1)
  459. {
  460. $pdf->SetXY($this->marge_gauche, $posy);
  461. $pdf->SetFont('','B', $default_font_size - 2);
  462. $pdf->MultiCell(90, 3, $outputlangs->transnoentities('PaymentByChequeOrderedToShort').' '.$outputlangs->convToOutputCharset($this->emetteur->name).' '.$outputlangs->transnoentities('SendTo').':',0,'L',0);
  463. $posy=$pdf->GetY()+1;
  464. $pdf->SetXY($this->marge_gauche, $posy);
  465. $pdf->SetFont('','', $default_font_size - 2);
  466. $pdf->MultiCell(80, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
  467. $posy=$pdf->GetY()+2;
  468. }
  469. }
  470. }
  471. // If payment mode not forced or forced to VIR, show payment with BAN
  472. if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
  473. {
  474. if (! empty($conf->global->FACTURE_RIB_NUMBER))
  475. {
  476. $account = new Account($this->db);
  477. $account->fetch($conf->global->FACTURE_RIB_NUMBER);
  478. $curx=$this->marge_gauche;
  479. $cury=$posy;
  480. $posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account);
  481. $posy+=2;
  482. }
  483. }
  484. }
  485. return $posy;
  486. }
  487. /**
  488. * Show total to pay
  489. *
  490. * @param pdf Objet PDF
  491. * @param object Objet propale
  492. * @param deja_regle Montant deja regle
  493. * @param posy Position depart
  494. * @param outputlangs Objet langs
  495. * @return y Position pour suite
  496. */
  497. function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
  498. {
  499. global $conf,$mysoc;
  500. $default_font_size = pdf_getPDFFontSize($outputlangs);
  501. $tab2_top = $posy;
  502. $tab2_hl = 4;
  503. $pdf->SetFont('','', $default_font_size - 1);
  504. // Tableau total
  505. $lltot = 200; $col1x = 120; $col2x = 170; $largcol2 = $lltot - $col2x;
  506. // Total HT
  507. $pdf->SetFillColor(255,255,255);
  508. $pdf->SetXY($col1x, $tab2_top + 0);
  509. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
  510. $pdf->SetXY($col2x, $tab2_top + 0);
  511. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ht + $object->remise), 0, 'R', 1);
  512. $index = 0;
  513. // Show VAT by rates and total
  514. $pdf->SetFillColor(248,248,248);
  515. $this->atleastoneratenotnull=0;
  516. if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
  517. {
  518. foreach( $this->tva as $tvakey => $tvaval )
  519. {
  520. if ($tvakey > 0) // On affiche pas taux 0
  521. {
  522. $this->atleastoneratenotnull++;
  523. $index++;
  524. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  525. $tvacompl='';
  526. if (preg_match('/\*/',$tvakey))
  527. {
  528. $tvakey=str_replace('*','',$tvakey);
  529. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  530. }
  531. $totalvat =$outputlangs->transnoentities("TotalVAT").' ';
  532. $totalvat.=vatrate($tvakey,1).$tvacompl;
  533. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  534. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  535. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
  536. }
  537. }
  538. if (! $this->atleastoneratenotnull) // If not vat at all
  539. {
  540. $index++;
  541. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  542. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalVAT"), 0, 'L', 1);
  543. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  544. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_tva), 0, 'R', 1);
  545. // Total LocalTax1
  546. if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on' && $object->total_localtax1>0)
  547. {
  548. $index++;
  549. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  550. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalLT1".$mysoc->pays_code), $useborder, 'L', 1);
  551. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  552. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax1), $useborder, 'R', 1);
  553. }
  554. // Total LocalTax2
  555. if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on' && $object->total_localtax2>0)
  556. {
  557. $index++;
  558. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  559. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalLT2".$mysoc->pays_code), $useborder, 'L', 1);
  560. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  561. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_localtax2), $useborder, 'R', 1);
  562. }
  563. }
  564. else
  565. {
  566. //Local tax 1
  567. if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
  568. {
  569. foreach( $this->localtax1 as $tvakey => $tvaval )
  570. {
  571. if ($tvakey>0) // On affiche pas taux 0
  572. {
  573. //$this->atleastoneratenotnull++;
  574. $index++;
  575. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  576. $tvacompl='';
  577. if (preg_match('/\*/',$tvakey))
  578. {
  579. $tvakey=str_replace('*','',$tvakey);
  580. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  581. }
  582. $totalvat = $outputlangs->transnoentities("TotalLT1".$mysoc->pays_code).' ';
  583. $totalvat.=vatrate($tvakey,1).$tvacompl;
  584. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  585. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  586. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
  587. }
  588. }
  589. }
  590. //Local tax 2
  591. if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
  592. {
  593. foreach( $this->localtax2 as $tvakey => $tvaval )
  594. {
  595. if ($tvakey>0) // On affiche pas taux 0
  596. {
  597. //$this->atleastoneratenotnull++;
  598. $index++;
  599. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  600. $tvacompl='';
  601. if (preg_match('/\*/',$tvakey))
  602. {
  603. $tvakey=str_replace('*','',$tvakey);
  604. $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
  605. }
  606. $totalvat = $outputlangs->transnoentities("TotalLT2".$mysoc->pays_code).' ';
  607. $totalvat.=vatrate($tvakey,1).$tvacompl;
  608. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
  609. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  610. $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval), 0, 'R', 1);
  611. }
  612. }
  613. }
  614. }
  615. }
  616. $useborder=0;
  617. // Total TTC
  618. if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
  619. {
  620. $index++;
  621. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  622. $pdf->SetTextColor(0,0,60);
  623. $pdf->SetFillColor(224,224,224);
  624. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
  625. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  626. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc), $useborder, 'R', 1);
  627. $pdf->SetTextColor(0,0,0);
  628. }
  629. if ($deja_regle > 0)
  630. {
  631. $index++;
  632. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  633. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
  634. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  635. $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle), 0, 'R', 0);
  636. $resteapayer = $object->total_ttc - $deja_regle;
  637. if ($object->paye) $resteapayer=0;
  638. if ($object->close_code == 'discount_vat')
  639. {
  640. $index++;
  641. $pdf->SetFillColor(255,255,255);
  642. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  643. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOffered"), $useborder, 'L', 1);
  644. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  645. $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle), $useborder, 'R', 1);
  646. $resteapayer=0;
  647. }
  648. $index++;
  649. $pdf->SetTextColor(0,0,60);
  650. $pdf->SetFillColor(224,224,224);
  651. $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
  652. $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
  653. $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
  654. $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer), $useborder, 'R', 1);
  655. // Fin
  656. $pdf->SetFont('','', $default_font_size - 1);
  657. $pdf->SetTextColor(0,0,0);
  658. }
  659. $index++;
  660. return ($tab2_top + ($tab2_hl * $index));
  661. }
  662. /**
  663. * Affiche la grille des lignes de propales
  664. *
  665. * @param pdf objet PDF
  666. */
  667. function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
  668. {
  669. global $conf;
  670. $default_font_size = pdf_getPDFFontSize($outputlangs);
  671. // Montants exprimes en (en tab_top - 1)
  672. $pdf->SetTextColor(0,0,0);
  673. $pdf->SetFont('','',$default_font_size - 2);
  674. $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$conf->monnaie));
  675. $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
  676. $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
  677. $pdf->SetDrawColor(128,128,128);
  678. // Rect prend une longueur en 3eme param
  679. $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height);
  680. // line prend une position y en 3eme param
  681. $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);
  682. $pdf->SetFont('','',$default_font_size - 1);
  683. $pdf->SetXY($this->posxdesc-1, $tab_top+1);
  684. $pdf->MultiCell(108,2, $outputlangs->transnoentities("Designation"),'','L');
  685. if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
  686. {
  687. $pdf->line($this->posxtva-1, $tab_top, $this->posxtva-1, $tab_top + $tab_height);
  688. $pdf->SetXY($this->posxtva-3, $tab_top+1);
  689. $pdf->MultiCell($this->posxup-$this->posxtva+3,2, $outputlangs->transnoentities("VAT"),'','C');
  690. }
  691. $pdf->line($this->posxup-1, $tab_top, $this->posxup-1, $tab_top + $tab_height);
  692. $pdf->SetXY($this->posxup-1, $tab_top+1);
  693. $pdf->MultiCell($this->posxqty-$this->posxup-1,2, $outputlangs->transnoentities("PriceUHT"),'','C');
  694. $pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height);
  695. $pdf->SetXY($this->posxqty-1, $tab_top+1);
  696. $pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C');
  697. $pdf->line($this->posxdiscount-1, $tab_top, $this->posxdiscount-1, $tab_top + $tab_height);
  698. if ($this->atleastonediscount)
  699. {
  700. $pdf->SetXY($this->posxdiscount-1, $tab_top+1);
  701. $pdf->MultiCell($this->postotalht-$this->posxdiscount+1,2, $outputlangs->transnoentities("ReductionShort"),'','C');
  702. }
  703. if ($this->atleastonediscount)
  704. {
  705. $pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
  706. }
  707. $pdf->SetXY($this->postotalht-1, $tab_top+1);
  708. $pdf->MultiCell(30,2, $outputlangs->transnoentities("TotalHT"),'','C');
  709. }
  710. /**
  711. * Show header of document
  712. *
  713. * @param pdf Object PDF
  714. * @param object Object commercial proposal
  715. * @param showaddress 0=no, 1=yes
  716. * @param outputlangs Object lang for output
  717. */
  718. function _pagehead(&$pdf, $object, $showaddress=1, $outputlangs)
  719. {
  720. global $conf,$langs;
  721. $default_font_size = pdf_getPDFFontSize($outputlangs);
  722. $outputlangs->load("main");
  723. $outputlangs->load("bills");
  724. $outputlangs->load("propal");
  725. $outputlangs->load("companies");
  726. pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
  727. //Affiche le filigrane brouillon - Print Draft Watermark
  728. if($object->statut==0 && (! empty($conf->global->PROPALE_DRAFT_WATERMARK)) )
  729. {
  730. pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->PROPALE_DRAFT_WATERMARK);
  731. }
  732. //Prepare la suite
  733. $pdf->SetTextColor(0,0,60);
  734. $pdf->SetFont('','B', $default_font_size + 3);
  735. $posx=$this->page_largeur-$this->marge_droite-100;
  736. $posy=$this->marge_haute;
  737. $pdf->SetXY($this->marge_gauche,$posy);
  738. // Logo
  739. $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
  740. if ($this->emetteur->logo)
  741. {
  742. if (is_readable($logo))
  743. {
  744. $pdf->Image($logo, $this->marge_gauche, $posy, 0, 24);
  745. }
  746. else
  747. {
  748. $pdf->SetTextColor(200,0,0);
  749. $pdf->SetFont('','B',$default_font_size - 2);
  750. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
  751. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
  752. }
  753. }
  754. else
  755. {
  756. $text=$this->emetteur->name;
  757. $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
  758. }
  759. $pdf->SetFont('','B',$default_font_size + 3);
  760. $pdf->SetXY($posx,$posy);
  761. $pdf->SetTextColor(0,0,60);
  762. $title=$outputlangs->transnoentities("CommercialProposal");
  763. $pdf->MultiCell(100, 4, $title, '', 'R');
  764. $pdf->SetFont('','B',$default_font_size + 2);
  765. $posy+=5;
  766. $pdf->SetXY($posx,$posy);
  767. $pdf->SetTextColor(0,0,60);
  768. $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref), '', 'R');
  769. $posy+=1;
  770. $pdf->SetFont('','', $default_font_size);
  771. if ($object->ref_client)
  772. {
  773. $posy+=5;
  774. $pdf->SetXY($posx,$posy);
  775. $pdf->SetTextColor(0,0,60);
  776. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
  777. }
  778. $posy+=4;
  779. $pdf->SetXY($posx,$posy);
  780. $pdf->SetTextColor(0,0,60);
  781. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Date")." : " . dol_print_date($object->date,"day",false,$outputlangs,true), '', 'R');
  782. $posy+=4;
  783. $pdf->SetXY($posx,$posy);
  784. $pdf->SetTextColor(0,0,60);
  785. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DateEndPropal")." : " . dol_print_date($object->fin_validite,"day",false,$outputlangs,true), '', 'R');
  786. if ($object->client->code_client)
  787. {
  788. $posy+=4;
  789. $pdf->SetXY($posx,$posy);
  790. $pdf->SetTextColor(0,0,60);
  791. $pdf->MultiCell(100, 3, $outputlangs->transnoentities("CustomerCode")." : " . $outputlangs->transnoentities($object->client->code_client), '', 'R');
  792. }
  793. if ($showaddress)
  794. {
  795. // Sender properties
  796. $carac_emetteur='';
  797. // Add internal contact of proposal if defined
  798. $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
  799. if (count($arrayidcontact) > 0)
  800. {
  801. $object->fetch_user($arrayidcontact[0]);
  802. $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";
  803. }
  804. $carac_emetteur .= pdf_build_address($outputlangs,$this->emetteur);
  805. // Show sender
  806. $posy=42;
  807. $posx=$this->marge_gauche;
  808. if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
  809. $hautcadre=40;
  810. // Show sender frame
  811. $pdf->SetTextColor(0,0,0);
  812. $pdf->SetFont('','', $default_font_size - 2);
  813. $pdf->SetXY($posx,$posy-5);
  814. $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
  815. $pdf->SetXY($posx,$posy);
  816. $pdf->SetFillColor(230,230,230);
  817. $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
  818. // Show sender name
  819. $pdf->SetXY($posx+2,$posy+3);
  820. $pdf->SetTextColor(0,0,60);
  821. $pdf->SetFont('','B',$default_font_size);
  822. $pdf->MultiCell(80, 3, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
  823. // Show sender information
  824. $pdf->SetFont('','', $default_font_size - 1);
  825. $pdf->SetXY($posx+2,$posy+8);
  826. $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
  827. // If CUSTOMER contact defined, we use it
  828. $usecontact=false;
  829. $arrayidcontact=$object->getIdContact('external','CUSTOMER');
  830. if (count($arrayidcontact) > 0)
  831. {
  832. $usecontact=true;
  833. $result=$object->fetch_contact($arrayidcontact[0]);
  834. }
  835. // Recipient name
  836. if (! empty($usecontact))
  837. {
  838. // On peut utiliser le nom de la societe du contact
  839. if ($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) $socname = $object->contact->socname;
  840. else $socname = $object->client->nom;
  841. $carac_client_name=$outputlangs->convToOutputCharset($socname);
  842. }
  843. else
  844. {
  845. $carac_client_name=$outputlangs->convToOutputCharset($object->client->nom);
  846. }
  847. $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->client,$object->contact,$usecontact,'target');
  848. // Show recipient
  849. $posy=42;
  850. $posx=$this->page_largeur-$this->marge_droite-100;
  851. if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
  852. // Show recipient frame
  853. $pdf->SetTextColor(0,0,0);
  854. $pdf->SetFont('','', $default_font_size - 2);
  855. $pdf->SetXY($posx,$posy-5);
  856. $pdf->MultiCell(100, 4, $outputlangs->transnoentities("BillTo").":", 0, 'L');
  857. $pdf->rect($posx, $posy, 100, $hautcadre);
  858. $pdf->SetTextColor(0,0,0);
  859. // Show recipient name
  860. $pdf->SetXY($posx+2,$posy+3);
  861. $pdf->SetFont('','B', $default_font_size);
  862. $pdf->MultiCell(100,4, $carac_client_name, 0, 'L');
  863. // Show recipient information
  864. $pdf->SetFont('','', $default_font_size - 1);
  865. $pdf->SetXY($posx+2,$posy+8);
  866. $pdf->MultiCell(100,4, $carac_client, 0, 'L');
  867. }
  868. }
  869. /**
  870. * \brief Show footer of page
  871. * \param pdf PDF factory
  872. * \param object Object invoice
  873. * \param outputlangs Object lang for output
  874. * \remarks Need this->emetteur object
  875. */
  876. function _pagefoot(&$pdf,$object,$outputlangs)
  877. {
  878. return pdf_pagefoot($pdf,$outputlangs,'PROPALE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object);
  879. }
  880. }
  881. ?>