Extra price module

i want to change the amount (inc. tax) …
i want to apply discount % percent on total amount of invoice
how can i do that
please reply me…
i need urgent answer

1 Like

hi palak,
if you define a customer you can give him nn%.
after this every position you add to his invoice is filled with the nn%.

i searched for anything like “cache discount” to use this to set for example 10% instead of 3 or 2 what normal is, but i could not find a field like this.

if you find it, please post it here, thanks

:slight_smile: w.

i cant understand what u say…
where in customer… ?

i create one custom filed in customer invoice like discount in pdf i get excat value but in facture.php file the total value cant change using customfiled… thats y i want other solution

my installation is german but i made a screencopy

sorry, i dont know how to upload, i try again using atachment

if have any idea then help me… iwant to apply discount on total_ttc in invoice

you see, i’m fresh border, too.
i dont know how to send you the screencopy, lease send your email

what i did is nut a total cache discount, i defined in the customer tab 2 that he gets alwys (far example) 10%, so every position is preselected with 10 %.

i search for your problem too. i want to give some % to end-sum, but this, i do’nt know how.

There see,m to valuable arguments against this approach.

https://lists.gnu.org/archive/html/dolibarr-tasktrack/2013-11/msg00023.html

As a “quick & dirty” solution see below:

Selection_774.resized.png

Selection_775.resized.png

Best regards

thank you for your reply but i need absolute discount in percentage like relative discount… but relative discount apply per product but i need global discount in percentage without any tax …

Did you look here?

https://wiki.dolibarr.org/index.php/Module_CustomFields_Cases#Modify_the_total_global_price_with_a_coefficient_.28without_tampering_the_discount.29

Best regards

2 Likes

I can see this but i cant understand that what can i do?

i explain what i do using custom filed…
i create one custom file cf_entdiscount with text field in customer invoice…

in invoice i get discount using following code which i apply in pdf_crabe
price($object->total_ttc - (($object->total_ttc * (1 + $object->customfields->cf_entdiscount / 100)) - $object->total_ttc)

but i also change the global total ttc in invoice and billed amount…

please guide me where i m wrong…

hello palak,

i think i tra the same, would you please send me the php file generating your report ?
i don’t understand your question ? what’s your problem ???

should it change the ttc ? or not ? please describe your problem,

hi palak,
i have a solution.

go to setup->module->invoice and make a extrafield (i made “my_skonto” in the example-file)
(the difference between extrafield and customfield is that extrafield ist standard and customfield is a modul that hast to be installed)
or use customfield and do the same, but in this module
after this you modify the pdf_xxxx.module.php

for example see atached file, in the file you find my modifikations allways by searching for “// wolftec”

if you need more help, ask here or by PN
best regards
wolfgang :slight_smile: (ich spreche deutsch)

sorry,
it’s not possible to edit my last post and i’m to stupid to attach a file
if you tell me how to do this i’ll try

sorry

please send the attachment…

because i can not attach a file, here the code, search for “wolftec”:

<?php /\* Copyright (C) 2004-2014 Laurent Destailleur \* Copyright (C) 2005-2012 Regis Houssin \* Copyright (C) 2008 Raphael Bertrand \* Copyright (C) 2010-2015 Juanjo Menent \* Copyright (C) 2012 Christophe Battarel \* Copyright (C) 2012 Cedric Salvador \* Copyright (C) 2015 Marcos García * \* This program is free software; you can redistribute it and/or modify \* it under the terms of the GNU General Public License as published by \* the Free Software Foundation; either version 3 of the License, or \* (at your option) any later version. * \* This program is distributed in the hope that it will be useful, \* but WITHOUT ANY WARRANTY; without even the implied warranty of \* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \* GNU General Public License for more details. * \* You should have received a copy of the GNU General Public License \* along with this program. If not, see . \* or see http://www.gnu.org/ */ /** * \file htdocs/core/modules/propale/doc/pdf_azur.modules.php * \ingroup propale * \brief Fichier de la classe permettant de generer les propales au modele Azur */ require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; // wolftec require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; /** * Class to generate PDF proposal Azur */ class pdf_azur extends ModelePDFPropales { var $db; var $name; var $description; var $type; var $phpmin = array(4,3,0); // Minimum version of PHP required by module var $version = 'dolibarr'; var $page_largeur; var $page_hauteur; var $format; var $marge_gauche; var $marge_droite; var $marge_haute; var $marge_basse; var $emetteur; // Objet societe qui emet /** * Constructor * \* @param DoliDB $db Database handler */ function __construct($db) { global $conf,$langs,$mysoc; $langs-\>load("main"); $langs-\>load("bills"); $this-\>db = $db; $this-\>name = "azur"; $this-\>description = $langs-\>trans('DocModelAzurDescription'); // Dimension page pour format A4 $this-\>type = 'pdf'; $formatarray=pdf_getFormat(); $this-\>page_largeur = $formatarray['width']; $this-\>page_hauteur = $formatarray['height']; $this-\>format = array($this-\>page_largeur,$this-\>page_hauteur); $this-\>marge_gauche=isset($conf-\>global-\>MAIN_PDF_MARGIN_LEFT)?$conf-\>global-\>MAIN_PDF_MARGIN_LEFT:10; $this-\>marge_droite=isset($conf-\>global-\>MAIN_PDF_MARGIN_RIGHT)?$conf-\>global-\>MAIN_PDF_MARGIN_RIGHT:10; $this-\>marge_haute =isset($conf-\>global-\>MAIN_PDF_MARGIN_TOP)?$conf-\>global-\>MAIN_PDF_MARGIN_TOP:10; $this-\>marge_basse =isset($conf-\>global-\>MAIN_PDF_MARGIN_BOTTOM)?$conf-\>global-\>MAIN_PDF_MARGIN_BOTTOM:10; $this-\>option_logo = 1; // Affiche logo $this-\>option_tva = 1; // Gere option tva FACTURE_TVAOPTION $this-\>option_modereg = 1; // Affiche mode reglement $this-\>option_condreg = 1; // Affiche conditions reglement $this-\>option_codeproduitservice = 1; // Affiche code produit-service $this-\>option_multilang = 1; // Dispo en plusieurs langues $this-\>option_escompte = 1; // Affiche si il y a eu escompte $this-\>option_credit_note = 1; // Support credit notes $this-\>option_freetext = 1; // Support add of a personalised text $this-\>option_draft_watermark = 1; //Support add of a watermark on drafts $this-\>franchise=!$mysoc-\>tva_assuj; // Get source company $this-\>emetteur=$mysoc; if (empty($this-\>emetteur-\>country_code)) $this-\>emetteur-\>country_code=substr($langs-\>defaultlang,-2); // By default, if was not defined // Define position of columns $this-\>posxdesc=$this-\>marge_gauche+1; if($conf-\>global-\>PRODUCT_USE_UNITS) { $this-\>posxtva=99; $this-\>posxup=114; $this-\>posxqty=133; $this-\>posxunit=150; } else { $this-\>posxtva=112; $this-\>posxup=126; $this-\>posxqty=145; } $this-\>posxdiscount=162; $this-\>postotalht=174; if (! empty($conf-\>global-\>MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) $this-\>posxtva=$this-\>posxup; $this-\>posxpicture=$this-\>posxtva \- (empty($conf-\>global-\>MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf-\>global-\>MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images if ($this-\>page_largeur < 210) // To work with US executive format { $this-\>posxpicture-=20; $this-\>posxtva-=20; $this-\>posxup-=20; $this-\>posxqty-=20; $this-\>posxdiscount-=20; $this-\>postotalht-=20; } $this-\>tva=array(); $this-\>localtax1=array(); $this-\>localtax2=array(); $this-\>atleastoneratenotnull=0; $this-\>atleastonediscount=0; } /** \* Function to build pdf onto disk * \* @param Object $object Object to generate \* @param Translate $outputlangs Lang output object \* @param string $srctemplatepath Full path of source filename for generator using a template file \* @param int $hidedetails Do not show line details \* @param int $hidedesc Do not show desc \* @param int $hideref Do not show ref \* @return int 1=OK, 0=KO */ function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0) { global $user,$langs,$conf,$mysoc,$db,$hookmanager; if (! is_object($outputlangs)) $outputlangs=$langs; // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO if (! empty($conf-\>global-\>MAIN_USE_FPDF)) $outputlangs-\>charset_output='ISO-8859-1'; $outputlangs-\>load("main"); $outputlangs-\>load("dict"); $outputlangs-\>load("companies"); $outputlangs-\>load("bills"); $outputlangs-\>load("propal"); $outputlangs-\>load("products"); $nblignes = count($object-\>lines); // Loop on each lines to detect if there is at least one image to show $realpatharray=array(); if (! empty($conf-\>global-\>MAIN_GENERATE_PROPOSALS_WITH_PICTURE)) { $objphoto = new Product($this-\>db); for ($i = 0 ; $i < $nblignes ; $i++) { if (empty($object-\>lines[$i]-\>fk_product)) continue; $objphoto-\>fetch($object-\>lines[$i]-\>fk_product); if (! empty($conf-\>global-\>PRODUCT_USE_OLD_PATH_FOR_PHOTO)) { $pdir[0] = get_exdir($objphoto-\>id,2,0,0,$objphoto,'product') . $objphoto-\>id ."/photos/"; $pdir[1] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto-\>ref).'/'; } else { $pdir[0] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto-\>ref).'/'; // default $pdir[1] = get_exdir($objphoto-\>id,2,0,0,$objphoto,'product') . $objphoto-\>id ."/photos/"; // alternative } $arephoto = false; foreach ($pdir as $midir) { if (! $arephoto) { $dir = $conf-\>product-\>dir_output.'/'.$midir; foreach ($objphoto-\>liste_photos($dir,1) as $key =\> $obj) { if (empty($conf-\>global-\>CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo { if ($obj['photo_vignette']) { $filename= $obj['photo_vignette']; } else { $filename=$obj['photo']; } } else { $filename=$obj['photo']; } $realpath = $dir.$filename; $arephoto = true; } } } if ($realpath && $arephoto) $realpatharray[$i]=$realpath; } } if (count($realpatharray) == 0) $this-\>posxpicture=$this-\>posxtva; if ($conf-\>propal-\>dir_output) { $object-\>fetch_thirdparty(); // $deja_regle = 0; // Definition of $dir and $file if ($object-\>specimen) { $dir = $conf-\>propal-\>dir_output; $file = $dir . "/SPECIMEN.pdf"; } else { $objectref = dol_sanitizeFileName($object-\>ref); $dir = $conf-\>propal-\>dir_output . "/" . $objectref; $file = $dir . "/" . $objectref . ".pdf"; } if (! file_exists($dir)) { if (dol_mkdir($dir) < 0) { $this-\>error=$langs-\>transnoentities("ErrorCanNotCreateDir",$dir); return 0; } } if (file_exists($dir)) { // Add pdfgeneration hook if (! is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; $hookmanager=new HookManager($this-\>db); } $hookmanager-\>initHooks(array('pdfgeneration')); $parameters=array('file'=\>$file,'object'=\>$object,'outputlangs'=\>$outputlangs); global $action; $reshook=$hookmanager-\>executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks // Create pdf instance $pdf=pdf_getInstance($this-\>format); //wolftec Extrafields aus DB holen $extrafields = new ExtraFields($db); $extralabels=$extrafields-\>fetch_name_optionals_label($object-\>table_element); $object-\>fetch($rowid); $object-\>fetch_optionals($rowid,$extralabels); $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance $heightforinfotot = 50; // Height reserved to output the info and total part $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 $heightforfooter = $this-\>marge_basse \+ 8; // Height reserved to output the footer (value include bottom margin) $pdf-\>SetAutoPageBreak(1,0); if (class_exists('TCPDF')) { $pdf-\>setPrintHeader(false); $pdf-\>setPrintFooter(false); } $pdf-\>SetFont(pdf_getPDFFont($outputlangs)); // Set path to the background PDF File if (empty($conf-\>global-\>MAIN_DISABLE_FPDI) && ! empty($conf-\>global-\>MAIN_ADD_PDF_BACKGROUND)) { $pagecount = $pdf-\>setSourceFile($conf-\>mycompany-\>dir_output.'/'.$conf-\>global-\>MAIN_ADD_PDF_BACKGROUND); $tplidx = $pdf-\>importPage(1); } $pdf-\>Open(); $pagenb=0; $pdf-\>SetDrawColor(128,128,128); $pdf-\>SetTitle($outputlangs-\>convToOutputCharset($object-\>ref)); $pdf-\>SetSubject($outputlangs-\>transnoentities("CommercialProposal")); $pdf-\>SetCreator("Dolibarr ".DOL_VERSION); $pdf-\>SetAuthor($outputlangs-\>convToOutputCharset($user-\>getFullName($outputlangs))); $pdf-\>SetKeyWords($outputlangs-\>convToOutputCharset($object-\>ref)." ".$outputlangs-\>transnoentities("CommercialProposal")); if (! empty($conf-\>global-\>MAIN_DISABLE_PDF_COMPRESSION)) $pdf-\>SetCompression(false); $pdf-\>SetMargins($this-\>marge_gauche, $this-\>marge_haute, $this-\>marge_droite); // Left, Top, Right // Positionne $this-\>atleastonediscount si on a au moins une remise for ($i = 0 ; $i < $nblignes ; $i++) { if ($object-\>lines[$i]-\>remise_percent) { $this-\>atleastonediscount++; } } if (empty($this-\>atleastonediscount) && empty($conf-\>global-\>PRODUCT_USE_UNITS)) { $this-\>posxpicture+=($this-\>postotalht \- $this-\>posxdiscount); $this-\>posxtva+=($this-\>postotalht \- $this-\>posxdiscount); $this-\>posxup+=($this-\>postotalht \- $this-\>posxdiscount); $this-\>posxqty+=($this-\>postotalht \- $this-\>posxdiscount); $this-\>posxdiscount+=($this-\>postotalht \- $this-\>posxdiscount); //$this-\>postotalht; } // New page $pdf-\>AddPage(); if (! empty($tplidx)) $pdf-\>useTemplate($tplidx); $pagenb++; $this-\>_pagehead($pdf, $object, 1, $outputlangs); $pdf-\>SetFont('','', $default_font_size \- 1); $pdf-\>MultiCell(0, 3, ''); // Set interline to 3 $pdf-\>SetTextColor(0,0,0); $tab_top = 90; $tab_top_newpage = (empty($conf-\>global-\>MAIN_PDF_DONOTREPEAT_HEAD)?42:10); $tab_height = 130; $tab_height_newpage = 150; // Incoterm $height_incoterms = 0; if ($conf-\>incoterm-\>enabled) { $desc_incoterms = $object-\>getIncotermsForPDF(); if ($desc_incoterms) { $tab_top = 88; $pdf-\>SetFont('','', $default_font_size \- 1); $pdf-\>writeHTMLCell(190, 3, $this-\>posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1); $nexY = $pdf-\>GetY(); $height_incoterms=$nexY-$tab_top; // Rect prend une longueur en 3eme param $pdf-\>SetDrawColor(192,192,192); $pdf-\>Rect($this-\>marge_gauche, $tab_top-1, $this-\>page_largeur-$this-\>marge_gauche-$this-\>marge_droite, $height_incoterms+1); $tab_top = $nexY+6; $height_incoterms += 4; } } // Affiche notes $notetoshow=empty($object-\>note_public)?'':$object-\>note_public; if (! empty($conf-\>global-\>MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) { // Get first sale rep if (is_object($object-\>thirdparty)) { $salereparray=$object-\>thirdparty-\>getSalesRepresentatives($user); $salerepobj=new User($this-\>db); $salerepobj-\>fetch($salereparray[0]['id']); if (! empty($salerepobj-\>signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj-\>signature); } } if ($notetoshow) { $tab_top = 88 \+ $height_incoterms; $pdf-\>SetFont('','', $default_font_size \- 1); $pdf-\>writeHTMLCell(190, 3, $this-\>posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); $nexY = $pdf-\>GetY(); $height_note=$nexY-$tab_top; // Rect prend une longueur en 3eme param $pdf-\>SetDrawColor(192,192,192); $pdf-\>Rect($this-\>marge_gauche, $tab_top-1, $this-\>page_largeur-$this-\>marge_gauche-$this-\>marge_droite, $height_note+1); $tab_height = $tab_height \- $height_note; $tab_top = $nexY+6; } else { $height_note=0; } $iniY = $tab_top \+ 7; $curY = $tab_top \+ 7; $nexY = $tab_top \+ 7; // Loop on each lines for ($i = 0 ; $i < $nblignes ; $i++) { $curY = $nexY; $pdf-\>SetFont('','', $default_font_size \- 1); // Into loop to work with multipage $pdf-\>SetTextColor(0,0,0); // Define size of image if we need it $imglinesize=array(); if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]); $pdf-\>setTopMargin($tab_top_newpage); $pdf-\>setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot); // The only function to edit the bottom margin of current page to set it. $pageposbefore=$pdf-\>getPage(); $showpricebeforepagebreak=1; $posYAfterImage=0; $posYAfterDescription=0; // We start with Photo of product line if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY \+ $imglinesize['height']) \> ($this-\>page_hauteur-($heightforfooter+$heightforfreetext+$heightforinfotot))) // If photo too high, we moved completely on new page { $pdf-\>AddPage('','',true); if (! empty($tplidx)) $pdf-\>useTemplate($tplidx); if (empty($conf-\>global-\>MAIN_PDF_DONOTREPEAT_HEAD)) $this-\>_pagehead($pdf, $object, 0, $outputlangs); $pdf-\>setPage($pageposbefore+1); $curY = $tab_top_newpage; $showpricebeforepagebreak=0; } if (isset($imglinesize['width']) && isset($imglinesize['height'])) { $curX = $this-\>posxpicture-1; $pdf-\>Image($realpatharray[$i], $curX \+ (($this-\>posxtva-$this-\>posxpicture-$imglinesize['width'])/2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf-\>Image does not increase value return by getY, so we save it manually $posYAfterImage=$curY+$imglinesize['height']; } // Description of product line $curX = $this-\>posxdesc-1; $pdf-\>startTransaction(); pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this-\>posxpicture-$curX,3,$curX,$curY,$hideref,$hidedesc); $pageposafter=$pdf-\>getPage(); if ($pageposafter \> $pageposbefore) // There is a pagebreak { $pdf-\>rollbackTransaction(true); $pageposafter=$pageposbefore; //print $pageposafter.'-'.$pageposbefore;exit; $pdf-\>setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this-\>posxpicture-$curX,3,$curX,$curY,$hideref,$hidedesc); $pageposafter=$pdf-\>getPage(); $posyafter=$pdf-\>GetY(); //var_dump($posyafter); var_dump(($this-\>page_hauteur \- ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; if ($posyafter \> ($this-\>page_hauteur \- ($heightforfooter+$heightforfreetext+$heightforinfotot))) // There is no space left for total+free text { if ($i == ($nblignes-1)) // No more lines, and no space left to show total, so we create a new page { $pdf-\>AddPage('','',true); if (! empty($tplidx)) $pdf-\>useTemplate($tplidx); if (empty($conf-\>global-\>MAIN_PDF_DONOTREPEAT_HEAD)) $this-\>_pagehead($pdf, $object, 0, $outputlangs); $pdf-\>setPage($pageposafter+1); } } else { // We found a page break $showpricebeforepagebreak=0; } } else // No pagebreak { $pdf-\>commitTransaction(); } $posYAfterDescription=$pdf-\>GetY(); $nexY = $pdf-\>GetY(); $pageposafter=$pdf-\>getPage(); $pdf-\>setPage($pageposbefore); $pdf-\>setTopMargin($this-\>marge_haute); $pdf-\>setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. // We suppose that a too long description or photo were moved completely on next page if ($pageposafter \> $pageposbefore && empty($showpricebeforepagebreak)) { $pdf-\>setPage($pageposafter); $curY = $tab_top_newpage; } $pdf-\>SetFont('','', $default_font_size \- 1); // On repositionne la police par defaut // VAT Rate if (empty($conf-\>global-\>MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); $pdf-\>SetXY($this-\>posxtva, $curY); $pdf-\>MultiCell($this-\>posxup-$this-\>posxtva-0.8, 3, $vat_rate, 0, 'R'); } // Unit price before discount $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); $pdf-\>SetXY($this-\>posxup, $curY); $pdf-\>MultiCell($this-\>posxqty-$this-\>posxup-0.8, 3, $up_excl_tax, 0, 'R', 0); // Quantity $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $pdf-\>SetXY($this-\>posxqty, $curY); // Enough for 6 chars if($conf-\>global-\>PRODUCT_USE_UNITS) { $pdf-\>MultiCell($this-\>posxunit-$this-\>posxqty-0.8, 4, $qty, 0, 'R'); } else { $pdf-\>MultiCell($this-\>posxdiscount-$this-\>posxqty-0.8, 4, $qty, 0, 'R'); } // Unit if($conf-\>global-\>PRODUCT_USE_UNITS) { $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); $pdf-\>SetXY($this-\>posxunit, $curY); $pdf-\>MultiCell($this-\>posxdiscount-$this-\>posxunit-0.8, 4, $unit, 0, 'L'); } // Discount on line $pdf-\>SetXY($this-\>posxdiscount, $curY); if ($object-\>lines[$i]-\>remise_percent) { $pdf-\>SetXY($this-\>posxdiscount-2, $curY); $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); $pdf-\>MultiCell($this-\>postotalht-$this-\>posxdiscount+2, 3, $remise_percent, 0, 'R'); } // Total HT line $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails); $pdf-\>SetXY($this-\>postotalht, $curY); $pdf-\>MultiCell($this-\>page_largeur-$this-\>marge_droite-$this-\>postotalht, 3, $total_excl_tax, 0, 'R', 0); // Collecte des totaux par valeur de tva dans $this-\>tva["taux"]=total_tva $tvaligne=$object-\>lines[$i]-\>total_tva; $localtax1ligne=$object-\>lines[$i]-\>total_localtax1; $localtax2ligne=$object-\>lines[$i]-\>total_localtax2; $localtax1_rate=$object-\>lines[$i]-\>localtax1_tx; $localtax2_rate=$object-\>lines[$i]-\>localtax2_tx; $localtax1_type=$object-\>lines[$i]-\>localtax1_type; $localtax2_type=$object-\>lines[$i]-\>localtax2_type; if ($object-\>remise_percent) $tvaligne-=($tvaligne*$object-\>remise_percent)/100; if ($object-\>remise_percent) $localtax1ligne-=($localtax1ligne*$object-\>remise_percent)/100; if ($object-\>remise_percent) $localtax2ligne-=($localtax2ligne*$object-\>remise_percent)/100; $vatrate=(string) $object-\>lines[$i]-\>tva_tx; // Retrieve type from database for backward compatibility with old records if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax { $localtaxtmp_array=getLocalTaxesFromRate($vatrate,0,$object-\>thirdparty,$mysoc); $localtax1_type = $localtaxtmp_array[0]; $localtax2_type = $localtaxtmp_array[2]; } // retrieve global local tax if ($localtax1_type && $localtax1ligne != 0) $this-\>localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne; if ($localtax2_type && $localtax2ligne != 0) $this-\>localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne; if (($object-\>lines[$i]-\>info_bits & 0x01) == 0x01) $vatrate.='*'; if (! isset($this-\>tva[$vatrate])) $this-\>tva[$vatrate]=''; $this-\>tva[$vatrate] += $tvaligne; if ($posYAfterImage \> $posYAfterDescription) $nexY=$posYAfterImage; // Add line if (! empty($conf-\>global-\>MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes \- 1)) { $pdf-\>setPage($pageposafter); $pdf-\>SetLineStyle(array('dash'=\>'1,1','color'=\>array(210,210,210))); //$pdf-\>SetDrawColor(190,190,200); $pdf-\>line($this-\>marge_gauche, $nexY+1, $this-\>page_largeur \- $this-\>marge_droite, $nexY+1); $pdf-\>SetLineStyle(array('dash'=\>0)); } $nexY+=2; // Passe espace entre les lignes // Detect if some page were added automatically and output _tableau for past pages while ($pagenb < $pageposafter) { $pdf-\>setPage($pagenb); if ($pagenb == 1) { $this-\>_tableau($pdf, $tab_top, $this-\>page_hauteur \- $tab_top \- $heightforfooter, 0, $outputlangs, 0, 1); } else { $this-\>_tableau($pdf, $tab_top_newpage, $this-\>page_hauteur \- $tab_top_newpage \- $heightforfooter, 0, $outputlangs, 1, 1); } $this-\>_pagefoot($pdf,$object,$outputlangs,1); $pagenb++; $pdf-\>setPage($pagenb); $pdf-\>setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf-\>global-\>MAIN_PDF_DONOTREPEAT_HEAD)) $this-\>_pagehead($pdf, $object, 0, $outputlangs); } if (isset($object-\>lines[$i+1]-\>pagebreak) && $object-\>lines[$i+1]-\>pagebreak) { if ($pagenb == 1) { $this-\>_tableau($pdf, $tab_top, $this-\>page_hauteur \- $tab_top \- $heightforfooter, 0, $outputlangs, 0, 1); } else { $this-\>_tableau($pdf, $tab_top_newpage, $this-\>page_hauteur \- $tab_top_newpage \- $heightforfooter, 0, $outputlangs, 1, 1); } $this-\>_pagefoot($pdf,$object,$outputlangs,1); // New page $pdf-\>AddPage(); if (! empty($tplidx)) $pdf-\>useTemplate($tplidx); $pagenb++; if (empty($conf-\>global-\>MAIN_PDF_DONOTREPEAT_HEAD)) $this-\>_pagehead($pdf, $object, 0, $outputlangs); } } // Show square if ($pagenb == 1) { $this-\>_tableau($pdf, $tab_top, $this-\>page_hauteur \- $tab_top \- $heightforinfotot \- $heightforfreetext \- $heightforfooter, 0, $outputlangs, 0, 0); $bottomlasttab=$this-\>page_hauteur \- $heightforinfotot \- $heightforfreetext \- $heightforfooter \+ 1; } else { $this-\>_tableau($pdf, $tab_top_newpage, $this-\>page_hauteur \- $tab_top_newpage \- $heightforinfotot \- $heightforfreetext \- $heightforfooter, 0, $outputlangs, 1, 0); $bottomlasttab=$this-\>page_hauteur \- $heightforinfotot \- $heightforfreetext \- $heightforfooter \+ 1; } // Affiche zone infos $posy=$this-\>_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); // Affiche zone totaux $posy=$this-\>_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs); // Affiche zone versements /* if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) { $posy=$this-\>_tableau_versements($pdf, $object, $posy, $outputlangs); } */ // Customer signature area $posy=$this-\>_signature_area($pdf, $object, $posy, $outputlangs); // Pied de page $this-\>_pagefoot($pdf,$object,$outputlangs); if (method_exists($pdf,'AliasNbPages')) $pdf-\>AliasNbPages(); //If propal merge product PDF is active if (!empty($conf-\>global-\>PRODUIT_PDF_MERGE_PROPAL)) { require_once DOL_DOCUMENT_ROOT.'/product/class/propalmergepdfproduct.class.php'; $already_merged = array (); foreach ( $object-\>lines as $line ) { if (! empty($line-\>fk_product) && ! (in_array($line-\>fk_product, $already_merged))) { // Find the desire PDF $filetomerge = new Propalmergepdfproduct($this-\>db); if ($conf-\>global-\>MAIN_MULTILANGS) { $filetomerge-\>fetch_by_product($line-\>fk_product, $outputlangs-\>defaultlang); } else { $filetomerge-\>fetch_by_product($line-\>fk_product); } $already_merged[] = $line-\>fk_product; $product = new Product($this-\>db); $product-\>fetch($line-\>fk_product); if ($product-\>entity!=$conf-\>entity) { $entity_product_file=$product-\>entity; } else { $entity_product_file=$conf-\>entity; } // If PDF is selected and file is not empty if (count($filetomerge-\>lines) \> 0) { foreach ( $filetomerge-\>lines as $linefile ) { if (! empty($linefile-\>id) && ! empty($linefile-\>file_name)) { if (! empty($conf-\>product-\>enabled)) $filetomerge_dir = $conf-\>product-\>multidir_output[$entity_product_file] . '/' . dol_sanitizeFileName($line-\>product_ref); elseif (! empty($conf-\>service-\>enabled)) $filetomerge_dir = $conf-\>service-\>multidir_output[$entity_product_file] . '/' . dol_sanitizeFileName($line-\>product_ref); dol_syslog(get_class($this) . ':: upload_dir=' . $filetomerge_dir, LOG_DEBUG); $infile = $filetomerge_dir . '/' . $linefile-\>file_name; if (is_file($infile)) { $pagecount = $pdf-\>setSourceFile($infile); for($i = 1; $i <= $pagecount; $i ++) { $tplidx = $pdf-\>ImportPage($i); $s = $pdf-\>getTemplatesize($tplidx); $pdf-\>AddPage($s['h'] \> $s['w'] ? 'P' : 'L'); $pdf-\>useTemplate($tplidx); } } } } } } } } //exit; $pdf-\>Close(); $pdf-\>Output($file,'F'); //Add pdfgeneration hook $hookmanager-\>initHooks(array('pdfgeneration')); $parameters=array('file'=\>$file,'object'=\>$object,'outputlangs'=\>$outputlangs); global $action; $reshook=$hookmanager-\>executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks if (! empty($conf-\>global-\>MAIN_UMASK)) @chmod($file, octdec($conf-\>global-\>MAIN_UMASK)); return 1; // Pas d'erreur } else { $this-\>error=$langs-\>trans("ErrorCanNotCreateDir",$dir); return 0; } } else { $this-\>error=$langs-\>trans("ErrorConstantNotDefined","PROP_OUTPUTDIR"); return 0; } $this-\>error=$langs-\>trans("ErrorUnknown"); return 0; // Erreur par defaut } /** \* Show payments table * \* @param PDF $pdf Object PDF \* @param Object $object Object proposal \* @param int $posy Position y in PDF \* @param Translate $outputlangs Object langs for output \* @return int <0 if KO, \>0 if OK */ function _tableau_versements(&$pdf, $object, $posy, $outputlangs) { } /** \* Show miscellaneous information (payment mode, payment term, ...) * \* @param PDF $pdf Object PDF \* @param Object $object Object to show \* @param int $posy Y \* @param Translate $outputlangs Langs object \* @return void */ function _tableau_info(&$pdf, $object, $posy, $outputlangs) { global $conf; $default_font_size = pdf_getPDFFontSize($outputlangs); $pdf-\>SetFont('','', $default_font_size \- 1); // If France, show VAT mention if not applicable if ($this-\>emetteur-\>country_code == 'FR' && $this-\>franchise == 1) { $pdf-\>SetFont('','B', $default_font_size \- 2); $pdf-\>SetXY($this-\>marge_gauche, $posy); $pdf-\>MultiCell(100, 3, $outputlangs-\>transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); $posy=$pdf-\>GetY()+4; } $posxval=52; // Show shipping date if (! empty($object-\>date_livraison)) { $outputlangs-\>load("sendings"); $pdf-\>SetFont('','B', $default_font_size \- 2); $pdf-\>SetXY($this-\>marge_gauche, $posy); $titre = $outputlangs-\>transnoentities("DateDeliveryPlanned").':'; $pdf-\>MultiCell(80, 4, $titre, 0, 'L'); $pdf-\>SetFont('','', $default_font_size \- 2); $pdf-\>SetXY($posxval, $posy); $dlp=dol_print_date($object-\>date_livraison,"daytext",false,$outputlangs,true); $pdf-\>MultiCell(80, 4, $dlp, 0, 'L'); $posy=$pdf-\>GetY()+1; } elseif ($object-\>availability_code || $object-\>availability) // Show availability conditions { $pdf-\>SetFont('','B', $default_font_size \- 2); $pdf-\>SetXY($this-\>marge_gauche, $posy); $titre = $outputlangs-\>transnoentities("AvailabilityPeriod").':'; $pdf-\>MultiCell(80, 4, $titre, 0, 'L'); $pdf-\>SetTextColor(0,0,0); $pdf-\>SetFont('','', $default_font_size \- 2); $pdf-\>SetXY($posxval, $posy); $lib_availability=$outputlangs-\>transnoentities("AvailabilityType".$object-\>availability_code)!=('AvailabilityType'.$object-\>availability_code)?$outputlangs-\>transnoentities("AvailabilityType".$object-\>availability_code):$outputlangs-\>convToOutputCharset($object-\>availability); $lib_availability=str_replace('\n',"\n",$lib_availability); $pdf-\>MultiCell(80, 4, $lib_availability, 0, 'L'); $posy=$pdf-\>GetY()+1; } // Show payments conditions if (empty($conf-\>global-\>PROPALE_PDF_HIDE_PAYMENTTERMCOND) && ($object-\>cond_reglement_code || $object-\>cond_reglement)) { $pdf-\>SetFont('','B', $default_font_size \- 2); $pdf-\>SetXY($this-\>marge_gauche, $posy); $titre = $outputlangs-\>transnoentities("PaymentConditions").':'; $pdf-\>MultiCell(80, 4, $titre, 0, 'L'); $pdf-\>SetFont('','', $default_font_size \- 2); $pdf-\>SetXY($posxval, $posy); $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); $lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement); $pdf-\>MultiCell(80, 4, $lib_condition_paiement,0,'L'); $posy=$pdf-\>GetY()+3; } if (empty($conf-\>global-\>PROPALE_PDF_HIDE_PAYMENTTERMCOND)) { // Check a payment mode is defined /\* Not required on a proposal if (empty($object-\>mode_reglement_code) && ! $conf-\>global-\>FACTURE_CHQ_NUMBER && ! $conf-\>global-\>FACTURE_RIB_NUMBER) { $pdf-\>SetXY($this-\>marge_gauche, $posy); $pdf-\>SetTextColor(200,0,0); $pdf-\>SetFont('','B', $default_font_size \- 2); $pdf-\>MultiCell(90, 3, $outputlangs-\>transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0); $pdf-\>SetTextColor(0,0,0); $posy=$pdf-\>GetY()+1; } */ // Show payment mode if ($object-\>mode_reglement_code && $object-\>mode_reglement_code != 'CHQ' && $object-\>mode_reglement_code != 'VIR') { $pdf-\>SetFont('','B', $default_font_size \- 2); $pdf-\>SetXY($this-\>marge_gauche, $posy); $titre = $outputlangs-\>transnoentities("PaymentMode").':'; $pdf-\>MultiCell(80, 5, $titre, 0, 'L'); $pdf-\>SetFont('','', $default_font_size \- 2); $pdf-\>SetXY($posxval, $posy); $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); $pdf-\>MultiCell(80, 5, $lib_mode_reg,0,'L'); $posy=$pdf-\>GetY()+2; } // Show payment mode CHQ if (empty($object-\>mode_reglement_code) || $object-\>mode_reglement_code == 'CHQ') { // Si mode reglement non force ou si force a CHQ if (! empty($conf-\>global-\>FACTURE_CHQ_NUMBER)) { $diffsizetitle=(empty($conf-\>global-\>PDF_DIFFSIZE_TITLE)?3:$conf-\>global-\>PDF_DIFFSIZE_TITLE); if ($conf-\>global-\>FACTURE_CHQ_NUMBER \> 0) { $account = new Account($this-\>db); $account-\>fetch($conf-\>global-\>FACTURE_CHQ_NUMBER); $pdf-\>SetXY($this-\>marge_gauche, $posy); $pdf-\>SetFont('','B', $default_font_size \- $diffsizetitle); $pdf-\>MultiCell(100, 3, $outputlangs-\>transnoentities('PaymentByChequeOrderedTo',$account-\>proprio),0,'L',0); $posy=$pdf-\>GetY()+1; if (empty($conf-\>global-\>MAIN_PDF_HIDE_CHQ_ADDRESS)) { $pdf-\>SetXY($this-\>marge_gauche, $posy); $pdf-\>SetFont('','', $default_font_size \- $diffsizetitle); $pdf-\>MultiCell(100, 3, $outputlangs-\>convToOutputCharset($account-\>owner_address), 0, 'L', 0); $posy=$pdf-\>GetY()+2; } } if ($conf-\>global-\>FACTURE_CHQ_NUMBER == -1) { $pdf-\>SetXY($this-\>marge_gauche, $posy); $pdf-\>SetFont('','B', $default_font_size \- $diffsizetitle); $pdf-\>MultiCell(100, 3, $outputlangs-\>transnoentities('PaymentByChequeOrderedTo',$this-\>emetteur-\>name),0,'L',0); $posy=$pdf-\>GetY()+1; if (empty($conf-\>global-\>MAIN_PDF_HIDE_CHQ_ADDRESS)) { $pdf-\>SetXY($this-\>marge_gauche, $posy); $pdf-\>SetFont('','', $default_font_size \- $diffsizetitle); $pdf-\>MultiCell(100, 3, $outputlangs-\>convToOutputCharset($this-\>emetteur-\>getFullAddress()), 0, 'L', 0); $posy=$pdf-\>GetY()+2; } } } } // If payment mode not forced or forced to VIR, show payment with BAN if (empty($object-\>mode_reglement_code) || $object-\>mode_reglement_code == 'VIR') { if (! empty($object-\>fk_account) || ! empty($object-\>fk_bank) || ! empty($conf-\>global-\>FACTURE_RIB_NUMBER)) { $bankid=(empty($object-\>fk_account)?$conf-\>global-\>FACTURE_RIB_NUMBER:$object-\>fk_account); if (! empty($object-\>fk_bank)) $bankid=$object-\>fk_bank; // For backward compatibility when object-\>fk_account is forced with object-\>fk_bank $account = new Account($this-\>db); $account-\>fetch($bankid); $curx=$this-\>marge_gauche; $cury=$posy; $posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size); $posy+=2; } } } return $posy; } /** * Show total to pay * * @param PDF $pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Montant deja regle * @param int $posy Position depart * @param Translate $outputlangs Objet langs * @return int Position pour suite */ function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs) { global $conf,$mysoc; $default_font_size = pdf_getPDFFontSize($outputlangs); $tab2_top = $posy; $tab2_hl = 4; $pdf-\>SetFont('','', $default_font_size \- 1); // Tableau total $col1x = 120; $col2x = 170; if ($this-\>page_largeur < 210) // To work with US executive format { $col2x-=20; } $largcol2 = ($this-\>page_largeur \- $this-\>marge_droite \- $col2x); $useborder=0; $index = 0; // Total HT $pdf-\>SetFillColor(255,255,255); $pdf-\>SetXY($col1x, $tab2_top \+ 0); $pdf-\>MultiCell($col2x-$col1x, $tab2_hl, $outputlangs-\>transnoentities("TotalHT"), 0, 'L', 1); $pdf-\>SetXY($col2x, $tab2_top \+ 0); $pdf-\>MultiCell($largcol2, $tab2_hl, price($object-\>total_ht \+ (! empty($object-\>remise)?$object-\>remise:0), 0, $outputlangs), 0, 'R', 1); // Show VAT by rates and total $pdf-\>SetFillColor(248,248,248); $this-\>atleastoneratenotnull=0; if (empty($conf-\>global-\>MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) { $tvaisnull=((! empty($this-\>tva) && count($this-\>tva) == 1 && isset($this-\>tva['0.000']) && is_float($this-\>tva['0.000'])) ? true : false); if (! empty($conf-\>global-\>MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_ISNULL) && $tvaisnull) { // Nothing to do } else { //Local tax 1 before VAT //if (! empty($conf-\>global-\>FACTURE_LOCAL_TAX1_OPTION) && $conf-\>global-\>FACTURE_LOCAL_TAX1_OPTION=='localtax1on') //{ foreach( $this-\>localtax1 as $localtax_type =\> $localtax_rate ) { if (in_array((string) $localtax_type, array('1','3','5'))) continue; foreach( $localtax_rate as $tvakey =\> $tvaval ) { if ($tvakey!=0) // On affiche pas taux 0 { //$this-\>atleastoneratenotnull++; $index++; $pdf-\>SetXY($col1x, $tab2_top \+ $tab2_hl \* $index); $tvacompl=''; if (preg_match('/\*/',$tvakey)) { $tvakey=str_replace('*','',$tvakey); $tvacompl = " (".$outputlangs-\>transnoentities("NonPercuRecuperable").")"; } $totalvat = $outputlangs-\>transcountrynoentities("TotalLT1",$mysoc-\>country_code).' '; $totalvat.=vatrate(abs($tvakey),1).$tvacompl; $pdf-\>MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); $pdf-\>SetXY($col2x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); } } } //} //Local tax 2 before VAT //if (! empty($conf-\>global-\>FACTURE_LOCAL_TAX2_OPTION) && $conf-\>global-\>FACTURE_LOCAL_TAX2_OPTION=='localtax2on') //{ foreach( $this-\>localtax2 as $localtax_type =\> $localtax_rate ) { if (in_array((string) $localtax_type, array('1','3','5'))) continue; foreach( $localtax_rate as $tvakey =\> $tvaval ) { if ($tvakey!=0) // On affiche pas taux 0 { //$this-\>atleastoneratenotnull++; $index++; $pdf-\>SetXY($col1x, $tab2_top \+ $tab2_hl \* $index); $tvacompl=''; if (preg_match('/\*/',$tvakey)) { $tvakey=str_replace('*','',$tvakey); $tvacompl = " (".$outputlangs-\>transnoentities("NonPercuRecuperable").")"; } $totalvat = $outputlangs-\>transcountrynoentities("TotalLT2", $mysoc-\>country_code).' '; $totalvat.=vatrate(abs($tvakey),1).$tvacompl; $pdf-\>MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); $pdf-\>SetXY($col2x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); } } } //} // VAT foreach($this-\>tva as $tvakey =\> $tvaval) { if ($tvakey \> 0) // On affiche pas taux 0 { $this-\>atleastoneratenotnull++; $index++; $pdf-\>SetXY($col1x, $tab2_top \+ $tab2_hl \* $index); $tvacompl=''; if (preg_match('/\*/',$tvakey)) { $tvakey=str_replace('*','',$tvakey); $tvacompl = " (".$outputlangs-\>transnoentities("NonPercuRecuperable").")"; } $totalvat =$outputlangs-\>transnoentities("TotalVAT").' '; $totalvat.=vatrate($tvakey,1).$tvacompl; $pdf-\>MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); $pdf-\>SetXY($col2x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); } } //Local tax 1 after VAT //if (! empty($conf-\>global-\>FACTURE_LOCAL_TAX1_OPTION) && $conf-\>global-\>FACTURE_LOCAL_TAX1_OPTION=='localtax1on') //{ foreach( $this-\>localtax1 as $localtax_type =\> $localtax_rate ) { if (in_array((string) $localtax_type, array('2','4','6'))) continue; foreach( $localtax_rate as $tvakey =\> $tvaval ) { if ($tvakey != 0) // On affiche pas taux 0 { //$this-\>atleastoneratenotnull++; $index++; $pdf-\>SetXY($col1x, $tab2_top \+ $tab2_hl \* $index); $tvacompl=''; if (preg_match('/\*/',$tvakey)) { $tvakey=str_replace('*','',$tvakey); $tvacompl = " (".$outputlangs-\>transnoentities("NonPercuRecuperable").")"; } $totalvat = $outputlangs-\>transcountrynoentities("TotalLT1",$mysoc-\>country_code).' '; $totalvat.=vatrate(abs($tvakey),1).$tvacompl; $pdf-\>MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); $pdf-\>SetXY($col2x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); } } } //} //Local tax 2 after VAT //if (! empty($conf-\>global-\>FACTURE_LOCAL_TAX2_OPTION) && $conf-\>global-\>FACTURE_LOCAL_TAX2_OPTION=='localtax2on') //{ foreach( $this-\>localtax2 as $localtax_type =\> $localtax_rate ) { if (in_array((string) $localtax_type, array('2','4','6'))) continue; foreach( $localtax_rate as $tvakey =\> $tvaval ) { // retrieve global local tax if ($tvakey != 0) // On affiche pas taux 0 { //$this-\>atleastoneratenotnull++; $index++; $pdf-\>SetXY($col1x, $tab2_top \+ $tab2_hl \* $index); $tvacompl=''; if (preg_match('/\*/',$tvakey)) { $tvakey=str_replace('*','',$tvakey); $tvacompl = " (".$outputlangs-\>transnoentities("NonPercuRecuperable").")"; } $totalvat = $outputlangs-\>transcountrynoentities("TotalLT2",$mysoc-\>country_code).' '; $totalvat.=vatrate(abs($tvakey),1).$tvacompl; $pdf-\>MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); $pdf-\>SetXY($col2x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); } } } //} // Total TTC $index++; $pdf-\>SetXY($col1x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>SetTextColor(0,0,60); $pdf-\>SetFillColor(224,224,224); $pdf-\>MultiCell($col2x-$col1x, $tab2_hl, $outputlangs-\>transnoentities("TotalTTC"), $useborder, 'L', 1); $pdf-\>SetXY($col2x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol2, $tab2_hl, price($object-\>total_ttc, 0, $outputlangs), $useborder, 'R', 1); //wolftec Skonto-Bereich aus my_skonto als Extrafield bei Angebot if($object-\>array_options ['options_my_skonto'] \> 0){ $index++; $pdf-\>SetXY($this-\>marge_gauche, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol, $tab2_hl, 'Bei Zahlung innerhalb 7 Tagen erhalten Sie '.round($object-\>array_options ['options_my_skonto'] ,2). '% Skonto = '.price(round($object-\>total_ttc / 100 \* $object-\>array_options ['options_my_skonto'] ,2), 0, $outputlangs).'€.', $useborder, 'L', 1); }else{ $index++; $pdf-\>SetXY($this-\>marge_gauche, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol, $tab2_hl, 'Die Rechnung ist Zahlbar bei Lieferung.', $useborder, 'L', 1); } } } $pdf-\>SetTextColor(0,0,0); /* $resteapayer = $object-\>total_ttc \- $deja_regle; if (! empty($object-\>paye)) $resteapayer=0; */ if ($deja_regle \> 0) { $index++; $pdf-\>SetXY($col1x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($col2x-$col1x, $tab2_hl, $outputlangs-\>transnoentities("AlreadyPaid"), 0, 'L', 0); $pdf-\>SetXY($col2x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0); /* if ($object-\>close_code == 'discount_vat') { $index++; $pdf-\>SetFillColor(255,255,255); $pdf-\>SetXY($col1x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($col2x-$col1x, $tab2_hl, $outputlangs-\>transnoentities("EscompteOffered"), $useborder, 'L', 1); $pdf-\>SetXY($col2x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol2, $tab2_hl, price($object-\>total_ttc \- $deja_regle, 0, $outputlangs), $useborder, 'R', 1); $resteapayer=0; } */ $index++; $pdf-\>SetTextColor(0,0,60); $pdf-\>SetFillColor(224,224,224); $pdf-\>SetXY($col1x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($col2x-$col1x, $tab2_hl, $outputlangs-\>transnoentities("RemainderToPay"), $useborder, 'L', 1); $pdf-\>SetXY($col2x, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1); $pdf-\>SetFont('','', $default_font_size \- 1); $pdf-\>SetTextColor(0,0,0); } $index++; return ($tab2_top \+ ($tab2_hl \* $index)); } /** \* Show table for lines * \* @param PDF $pdf Object PDF \* @param string $tab_top Top position of table \* @param string $tab_height Height of table (rectangle) \* @param int $nexY Y (not used) \* @param Translate $outputlangs Langs object \* @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title \* @param int $hidebottom Hide bottom bar of array \* @return void */ function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0) { global $conf; // Force to disable hidetop and hidebottom $hidebottom=0; if ($hidetop) $hidetop=-1; $default_font_size = pdf_getPDFFontSize($outputlangs); // Amount in (at tab_top \- 1) $pdf-\>SetTextColor(0,0,0); $pdf-\>SetFont('','',$default_font_size \- 2); if (empty($hidetop)) { $titre = $outputlangs-\>transnoentities("AmountInCurrency",$outputlangs-\>transnoentitiesnoconv("Currency".$conf-\>currency)); $pdf-\>SetXY($this-\>page_largeur \- $this-\>marge_droite \- ($pdf-\>GetStringWidth($titre) \+ 3), $tab_top-4); $pdf-\>MultiCell(($pdf-\>GetStringWidth($titre) \+ 3), 2, $titre); //$conf-\>global-\>MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; 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)); } $pdf-\>SetDrawColor(128,128,128); $pdf-\>SetFont('','',$default_font_size \- 1); // Output Rect $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 if (empty($hidetop)) { $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 $pdf-\>SetXY($this-\>posxdesc-1, $tab_top+1); $pdf-\>MultiCell(108,2, $outputlangs-\>transnoentities("Designation"),'','L'); } if (! empty($conf-\>global-\>MAIN_GENERATE_PROPOSALS_WITH_PICTURE)) { $pdf-\>line($this-\>posxpicture-1, $tab_top, $this-\>posxpicture-1, $tab_top \+ $tab_height); if (empty($hidetop)) { //$pdf-\>SetXY($this-\>posxpicture-1, $tab_top+1); //$pdf-\>MultiCell($this-\>posxtva-$this-\>posxpicture-1,2, $outputlangs-\>transnoentities("Photo"),'','C'); } } if (empty($conf-\>global-\>MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) { $pdf-\>line($this-\>posxtva-1, $tab_top, $this-\>posxtva-1, $tab_top \+ $tab_height); if (empty($hidetop)) { $pdf-\>SetXY($this-\>posxtva-3, $tab_top+1); $pdf-\>MultiCell($this-\>posxup-$this-\>posxtva+3,2, $outputlangs-\>transnoentities("VAT"),'','C'); } } $pdf-\>line($this-\>posxup-1, $tab_top, $this-\>posxup-1, $tab_top \+ $tab_height); if (empty($hidetop)) { $pdf-\>SetXY($this-\>posxup-1, $tab_top+1); $pdf-\>MultiCell($this-\>posxqty-$this-\>posxup-1,2, $outputlangs-\>transnoentities("PriceUHT"),'','C'); } $pdf-\>line($this-\>posxqty-1, $tab_top, $this-\>posxqty-1, $tab_top \+ $tab_height); if (empty($hidetop)) { $pdf-\>SetXY($this-\>posxqty-1, $tab_top+1); if($conf-\>global-\>PRODUCT_USE_UNITS) { $pdf-\>MultiCell($this-\>posxunit-$this-\>posxqty-1,2, $outputlangs-\>transnoentities("Qty"),'','C'); } else { $pdf-\>MultiCell($this-\>posxdiscount-$this-\>posxqty-1,2, $outputlangs-\>transnoentities("Qty"),'','C'); } } if($conf-\>global-\>PRODUCT_USE_UNITS) { $pdf-\>line($this-\>posxunit \- 1, $tab_top, $this-\>posxunit \- 1, $tab_top \+ $tab_height); if (empty($hidetop)) { $pdf-\>SetXY($this-\>posxunit \- 1, $tab_top \+ 1); $pdf-\>MultiCell($this-\>posxdiscount \- $this-\>posxunit \- 1, 2, $outputlangs-\>transnoentities("Unit"), '', 'C'); } } $pdf-\>line($this-\>posxdiscount-1, $tab_top, $this-\>posxdiscount-1, $tab_top \+ $tab_height); if (empty($hidetop)) { if ($this-\>atleastonediscount) { $pdf-\>SetXY($this-\>posxdiscount-1, $tab_top+1); $pdf-\>MultiCell($this-\>postotalht-$this-\>posxdiscount+1,2, $outputlangs-\>transnoentities("ReductionShort"),'','C'); } } if ($this-\>atleastonediscount) { $pdf-\>line($this-\>postotalht, $tab_top, $this-\>postotalht, $tab_top \+ $tab_height); } if (empty($hidetop)) { $pdf-\>SetXY($this-\>postotalht-1, $tab_top+1); $pdf-\>MultiCell(30,2, $outputlangs-\>transnoentities("TotalHT"),'','C'); } } /** \* Show top header of page. * \* @param PDF $pdf Object PDF \* @param Object $object Object to show \* @param int $showaddress 0=no, 1=yes \* @param Translate $outputlangs Object lang for output \* @return void */ function _pagehead(&$pdf, $object, $showaddress, $outputlangs) { global $conf,$langs; $outputlangs-\>load("main"); $outputlangs-\>load("bills"); $outputlangs-\>load("propal"); $outputlangs-\>load("companies"); $default_font_size = pdf_getPDFFontSize($outputlangs); pdf_pagehead($pdf,$outputlangs,$this-\>page_hauteur); // Show Draft Watermark if($object-\>statut==0 && (! empty($conf-\>global-\>PROPALE_DRAFT_WATERMARK)) ) { pdf_watermark($pdf,$outputlangs,$this-\>page_hauteur,$this-\>page_largeur,'mm',$conf-\>global-\>PROPALE_DRAFT_WATERMARK); } $pdf-\>SetTextColor(0,0,60); $pdf-\>SetFont('','B', $default_font_size \+ 3); $posy=$this-\>marge_haute; $posx=$this-\>page_largeur-$this-\>marge_droite-100; $pdf-\>SetXY($this-\>marge_gauche,$posy); // Logo $logo=$conf-\>mycompany-\>dir_output.'/logos/'.$this-\>emetteur-\>logo; if ($this-\>emetteur-\>logo) { if (is_readable($logo)) { $height=pdf_getHeightForLogo($logo); $pdf-\>Image($logo, $this-\>marge_gauche, $posy, 0, $height); // width=0 (auto) } else { $pdf-\>SetTextColor(200,0,0); $pdf-\>SetFont('','B',$default_font_size \- 2); $pdf-\>MultiCell(100, 3, $outputlangs-\>transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); $pdf-\>MultiCell(100, 3, $outputlangs-\>transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); } } else { $text=$this-\>emetteur-\>name; $pdf-\>MultiCell(100, 4, $outputlangs-\>convToOutputCharset($text), 0, 'L'); } $pdf-\>SetFont('','B',$default_font_size \+ 3); $pdf-\>SetXY($posx,$posy); $pdf-\>SetTextColor(0,0,60); $title=$outputlangs-\>transnoentities("CommercialProposal"); $pdf-\>MultiCell(100, 4, $title, '', 'R'); $pdf-\>SetFont('','B',$default_font_size); $posy+=5; $pdf-\>SetXY($posx,$posy); $pdf-\>SetTextColor(0,0,60); $pdf-\>MultiCell(100, 4, $outputlangs-\>transnoentities("Ref")." : " . $outputlangs-\>convToOutputCharset($object-\>ref), '', 'R'); $posy+=1; $pdf-\>SetFont('','', $default_font_size \- 2); if ($object-\>ref_client) { $posy+=4; $pdf-\>SetXY($posx,$posy); $pdf-\>SetTextColor(0,0,60); $pdf-\>MultiCell(100, 3, $outputlangs-\>transnoentities("RefCustomer")." : " . $outputlangs-\>convToOutputCharset($object-\>ref_client), '', 'R'); } $posy+=4; $pdf-\>SetXY($posx,$posy); $pdf-\>SetTextColor(0,0,60); $pdf-\>MultiCell(100, 3, $outputlangs-\>transnoentities("Date")." : " . dol_print_date($object-\>date,"day",false,$outputlangs,true), '', 'R'); $posy+=4; $pdf-\>SetXY($posx,$posy); $pdf-\>SetTextColor(0,0,60); $pdf-\>MultiCell(100, 3, $outputlangs-\>transnoentities("DateEndPropal")." : " . dol_print_date($object-\>fin_validite,"day",false,$outputlangs,true), '', 'R'); if ($object-\>client-\>code_client) { $posy+=4; $pdf-\>SetXY($posx,$posy); $pdf-\>SetTextColor(0,0,60); $pdf-\>MultiCell(100, 3, $outputlangs-\>transnoentities("CustomerCode")." : " . $outputlangs-\>transnoentities($object-\>client-\>code_client), '', 'R'); } $posy+=2; // Show list of linked objects $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); if ($showaddress) { // Sender properties $carac_emetteur=''; // Add internal contact of proposal if defined $arrayidcontact=$object-\>getIdContact('internal','SALESREPFOLL'); if (count($arrayidcontact) \> 0) { $object-\>fetch_user($arrayidcontact[0]); $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs-\>transnoentities("Name").": ".$outputlangs-\>convToOutputCharset($object-\>user-\>getFullName($outputlangs))."\n"; } $carac_emetteur .= pdf_build_address($outputlangs, $this-\>emetteur, $object-\>client); // Show sender $posy=42; $posx=$this-\>marge_gauche; if (! empty($conf-\>global-\>MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this-\>page_largeur-$this-\>marge_droite-80; $hautcadre=40; // Show sender frame $pdf-\>SetTextColor(0,0,0); $pdf-\>SetFont('','', $default_font_size \- 2); $pdf-\>SetXY($posx,$posy-5); $pdf-\>MultiCell(66,5, $outputlangs-\>transnoentities("BillFrom").":", 0, 'L'); $pdf-\>SetXY($posx,$posy); $pdf-\>SetFillColor(230,230,230); $pdf-\>MultiCell(82, $hautcadre, "", 0, 'R', 1); $pdf-\>SetTextColor(0,0,60); // Show sender name $pdf-\>SetXY($posx+2,$posy+3); $pdf-\>SetFont('','B', $default_font_size); $pdf-\>MultiCell(80, 4, $outputlangs-\>convToOutputCharset($this-\>emetteur-\>name), 0, 'L'); $posy=$pdf-\>getY(); // Show sender information $pdf-\>SetXY($posx+2,$posy); $pdf-\>SetFont('','', $default_font_size \- 1); $pdf-\>MultiCell(80, 4, $carac_emetteur, 0, 'L'); // If CUSTOMER contact defined, we use it $usecontact=false; $arrayidcontact=$object-\>getIdContact('external','CUSTOMER'); if (count($arrayidcontact) \> 0) { $usecontact=true; $result=$object-\>fetch_contact($arrayidcontact[0]); } //Recipient name // On peut utiliser le nom de la societe du contact if ($usecontact && !empty($conf-\>global-\>MAIN_USE_COMPANY_NAME_OF_CONTACT)) { $thirdparty = $object-\>contact; } else { $thirdparty = $object-\>client; } $carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs); $carac_client=pdf_build_address($outputlangs,$this-\>emetteur,$object-\>client,($usecontact?$object-\>contact:''),$usecontact,'target'); // Show recipient $widthrecbox=100; if ($this-\>page_largeur < 210) $widthrecbox=84; // To work with US executive format $posy=42; $posx=$this-\>page_largeur-$this-\>marge_droite-$widthrecbox; if (! empty($conf-\>global-\>MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this-\>marge_gauche; // Show recipient frame $pdf-\>SetTextColor(0,0,0); $pdf-\>SetFont('','', $default_font_size \- 2); $pdf-\>SetXY($posx+2,$posy-5); $pdf-\>MultiCell($widthrecbox, 5, $outputlangs-\>transnoentities("BillTo").":", 0, 'L'); $pdf-\>Rect($posx, $posy, $widthrecbox, $hautcadre); // Show recipient name $pdf-\>SetXY($posx+2,$posy+3); $pdf-\>SetFont('','B', $default_font_size); $pdf-\>MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); $posy = $pdf-\>getY(); // Show recipient information $pdf-\>SetFont('','', $default_font_size \- 1); $pdf-\>SetXY($posx+2,$posy); $pdf-\>MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } $pdf-\>SetTextColor(0,0,0); } /** \* Show footer of page. Need this-\>emetteur object * \* @param PDF $pdf PDF \* @param Object $object Object to show \* @param Translate $outputlangs Object lang for output \* @param int $hidefreetext 1=Hide free text \* @return int Return height of bottom margin including footer text */ function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0) { // $showdetails=0; // return pdf_pagefoot($pdf,$outputlangs,'PROPALE_FREE_TEXT',$this-\>emetteur,$this-\>marge_basse,$this-\>marge_gauche,$this-\>page_hauteur,$object,$showdetails,$hidefreetext); //wolftec // _my_fusszeile(&$pdf, $object, $outputlangs); // $pdf-\>MultiCell($largcol, $tab2_hl, 'IBAN: DE70690916000000495905 , BIC: GENODE61PFD , Registergericht Freiburg HRB 706-379 , Steuernummer: 18145/30110 , UstId.: DE-217398681: ', $useborder, 'L', 1); // $index++; // $pdf-\>SetXY($this-\>marge_gauche, $tab2_top \+ $tab2_hl \* $index); // $pdf-\>MultiCell($largcol, $tab2_hl, 'IBAN: DE70690916000000495905 , BIC: GENODE61PFD , Registergericht Freiburg HRB 706-379 , Steuernummer: 18145/30110 , UstId.: DE-217398681: ', $useborder, 'L', 1); } /** * Show area for the customer to sign * * @param PDF $pdf Object PDF * @param Facture $object Object invoice * @param int $posy Position depart * @param Translate $outputlangs Objet langs * @return int Position pour suite */ function _signature_area(&$pdf, $object, $posy, $outputlangs) { $default_font_size = pdf_getPDFFontSize($outputlangs); $tab_top = $posy \+ 4; $tab_hl = 4; $pdf-\>SetFont('','', $default_font_size \- 1); $posx = 120; $largcol = ($this-\>page_largeur \- $this-\>marge_droite \- $posx); $useborder=0; $index = 0; // Total HT $pdf-\>SetFillColor(255,255,255); $pdf-\>SetXY($posx, $tab_top \+ 0); $pdf-\>MultiCell($largcol, $tab_hl, $outputlangs-\>transnoentities("ProposalCustomerSignature"), 0, 'L', 1); $pdf-\>SetXY($posx, $tab_top \+ $tab_hl); $pdf-\>MultiCell($largcol, $tab_hl*6, '', 1, 'R'); //wolftec //$pdf-\>SetXY($posx, $tab_top \+ $tab_hl+4); $nexY = $pdf-\>GetY(); $pdf-\>SetXY($this-\>marge_gauche, $nexY+4); $pdf-\>MultiCell(200, $tab2_hl, 'Volksbank Pfullendorf, IBAN: DE70690916000000495905 , BIC: GENODE61PFD', $useborder, 'L', 1); $pdf-\>SetXY($this-\>marge_gauche, $nexY+8); $pdf-\>MultiCell(200, $tab2_hl, 'Registergericht Freiburg HRB 706-379 , Steuernummer: 18145/30110 , UstId.: DE-217398681', $useborder, 'L', 1); return ($tab_hl*7); } //wolftec Seitenfuss function _my_fusszeile(&$pdf, $object, $outputlangs) { // $default_font_size = pdf_getPDFFontSize($outputlangs); //$tab_top = 4; // $tab2_hl = 4; // $pdf-\>SetFont('','', $default_font_size \- 1); // $pdf-\>SetFillColor(255,255,255); //$index++; // $pdf-\>SetXY($this-\>marge_gauche, $tab2_top \+ $tab2_hl \* $index); $pdf-\>MultiCell($largcol, $tab2_hl, 'IBAN: DE70690916000000495905 , BIC: GENODE61PFD , Registergericht Freiburg HRB 706-379 , Steuernummer: 18145/30110 , UstId.: DE-217398681: ', $useborder, 'L', 1); return 1; } }

Thank you wolfgang… how can i use any extrafiled in invoice php file for example fatcure.php

in the sample above i use the lines:
###############
if($object->array_options > 0){
$index++;
$pdf->SetXY($this->marge_gauche, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol, $tab2_hl, 'Bei Zahlung innerhalb 7 Tagen erhalten Sie '.round($object->array_options ,2).
'% Skonto = '.price(round($object->total_ttc / 100 * $object->array_options ,2), 0, $outputlangs).‘€.’, $useborder, ‘L’, 1);
}else{
$index++;
$pdf->SetXY($this->marge_gauche, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol, $tab2_hl, ‘Die Rechnung ist Zahlbar bei Lieferung.’, $useborder, ‘L’, 1);
}
###########
to print the field
$object->array_options
but bevore i do some code more, search for “wolftec”, it’s my comment to find my code-modifikations
then you have the position where to load include and initialise

but you have to know that it is different to use “EXTRAFIELDS” and “CUSTOMFIELDS”
if you want to use customfields you should have a look to it’s dokumentation and the name of the field is different
########
$lineid = $object->lines[$i]->rowid;
$object->customfields->lines->$lineid->cf_myfield
##################
there is a prefix “cf_” bevore every field you generate in module configuration !!!

in my sample i use extrafields because this is in the main-module of dolibarr and i have not to install the extrafield-module. the extrafield module seems to be the better solution, but first i want to play some time with it. there was a free version and a version to pay, but since some month the pay-verseion is free, too.

the better thing is that fields in invoice or so, can get values from adress or lines in invoice can get values from parts. to use them in pdf is nearly the same.

if you have problems with it, feel free to ask about, i need some training :slight_smile:
best regards
wolfgang :slight_smile: