diff --git a/htdocs/admin/supplier_payment.php b/htdocs/admin/supplier_payment.php index b5732d1f1c987bea482c5c1d08e7f5b88f39ff3a..933ee22a0622488feaf18e3445ce6095a67d5d8d 100644 --- a/htdocs/admin/supplier_payment.php +++ b/htdocs/admin/supplier_payment.php @@ -40,6 +40,7 @@ $action = GETPOST('action','alpha'); $value = GETPOST('value','alpha'); $label = GETPOST('label','alpha'); $scandir = GETPOST('scandir','alpha'); +$type='supplier_payment'; /* @@ -62,11 +63,112 @@ if ($action == 'updateMask') { setEventMessages($langs->trans("Error"), null, 'errors'); } +}else if ($action == 'setmod') +{ + dolibarr_set_const($db, "SUPPLIER_PAYMENT_ADDON",$value,'chaine',0,'',$conf->entity); } - if ($action == 'setmod') +// define constants for models generator that need parameters +else if ($action == 'setModuleOptions') { - dolibarr_set_const($db, "SUPPLIER_PAYMENT_ADDON",$value,'chaine',0,'',$conf->entity); + $post_size=count($_POST); + for($i=0;$i < $post_size;$i++) + { + if (array_key_exists('param'.$i,$_POST)) + { + $param=GETPOST("param".$i,'alpha'); + $value=GETPOST("value".$i,'alpha'); + if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); + } + } + if (! $res > 0) $error++; + + if (! $error) + { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} + +// Activate a model +else if ($action == 'set') +{ + $ret = addDocumentModel($value, $type, $label, $scandir); +} + +else if ($action == 'del') +{ + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + if ($conf->global->FACTURE_ADDON_PDF == "$value") dolibarr_del_const($db, 'SUPPLIER_PAYMENT_ADDON_PDF',$conf->entity); + } +} + +// Set default model +else if ($action == 'setdoc') +{ + if (dolibarr_set_const($db, "SUPPLIER_PAYMENT_ADDON_PDF",$value,'chaine',0,'',$conf->entity)) + { + // La constante qui a ete lue en avant du nouveau set + // on passe donc par une variable pour avoir un affichage coherent + $conf->global->FACTURE_ADDON_PDF = $value; + } + + // On active le modele + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $ret = addDocumentModel($value, $type, $label, $scandir); + } +} + +else if ($action == 'specimen') +{ + $modele=GETPOST('module','alpha'); + + $paiementFourn = new PaiementFourn($db); + $paiementFourn->initAsSpecimen(); + + // Search template files + $file=''; $classname=''; $filefound=0; + $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + foreach($dirmodels as $reldir) + { + $file=dol_buildpath($reldir."core/modules/supplier_payment/pdf/pdf_".$modele.".modules.php",0); + if (file_exists($file)) + { + $filefound=1; + $classname = "pdf_".$modele; + break; + } + } + + if ($filefound) + { + require_once $file; + + $module = new $classname($db); + + if ($module->write_file($paiementFourn,$langs) > 0) + { + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=supplier_payment&file=SPECIMEN.pdf"); + return; + } + else + { + setEventMessages($module->error, $module->errors, 'errors'); + dol_syslog($module->error, LOG_ERR); + } + } + else + { + setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); + dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); + } } /* @@ -96,6 +198,35 @@ if (empty($conf->global->SUPPLIER_PAYMENT_ADDON)) $conf->global->SUPPLIER_PAYMEN print load_fiche_titre($langs->trans("PaymentsNumberingModule"), '', ''); +/* + * Document templates generators + */ +print '<br>'; +print load_fiche_titre($langs->trans("BillsPDFModules"),'',''); + +// Load array def with activated templates +$def = array(); +$sql = "SELECT nom"; +$sql.= " FROM ".MAIN_DB_PREFIX."document_model"; +$sql.= " WHERE type = '".$type."'"; +$sql.= " AND entity = ".$conf->entity; +$resql=$db->query($sql); +if ($resql) +{ + $i = 0; + $num_rows=$db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } +} +else +{ + dol_print_error($db); +} + print '<table class="noborder" width="100%">'; print '<tr class="liste_titre">'; print '<td>'.$langs->trans("Name").'</td>'; @@ -140,7 +271,7 @@ foreach ($dirmodels as $reldir) require_once $dir.$filebis; $module = new $classname($db); - + // Show modules according to features level if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; @@ -217,6 +348,119 @@ foreach ($dirmodels as $reldir) print '</table>'; + +print '<table class="noborder" width="100%">'."\n"; +print '<tr class="liste_titre">'."\n"; +print '<td width="100">'.$langs->trans("Name").'</td>'."\n"; +print '<td>'.$langs->trans("Description").'</td>'."\n"; +print '<td align="center" width="60">'.$langs->trans("Status").'</td>'."\n"; +print '<td align="center" width="60">'.$langs->trans("Default").'</td>'."\n"; +print '<td align="center" width="40">'.$langs->trans("ShortInfo").'</td>'; +print '<td align="center" width="40">'.$langs->trans("Preview").'</td>'; +print '</tr>'."\n"; + +clearstatcache(); + +foreach ($dirmodels as $reldir) +{ + $dir = dol_buildpath($reldir."core/modules/supplier_payment/pdf/"); + + if (is_dir($dir)) + { + $var=true; + + $handle=opendir($dir); + + + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + { + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once $dir.'/'.$file; + $module = new $classname($db, new PaiementFourn($db)); + + $var=!$var; + print "<tr ".$bc[$var].">\n"; + print "<td>"; + print (empty($module->name)?$name:$module->name); + print "</td>\n"; + print "<td>\n"; + require_once $dir.$file; + $module = new $classname($db,$specimenthirdparty); + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + + print "</td>\n"; + + // Active + if (in_array($name, $def)) + { + print '<td align="center">'."\n"; + //if ($conf->global->SUPPLIER_PAYMENT_ADDON_PDF != "$name") + //{ + // Even if choice is the default value, we allow to disable it: For supplier invoice, we accept to have no doc generation at all + print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'&type=SUPPLIER_PAYMENT">'; + print img_picto($langs->trans("Enabled"),'switch_on'); + print '</a>'; + /*} + else + { + print img_picto($langs->trans("Enabled"),'switch_on'); + }*/ + print "</td>"; + } + else + { + print '<td align="center">'."\n"; + print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'&type=SUPPLIER_PAYMENT">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>'; + print "</td>"; + } + + // Default + print '<td align="center">'; + if ($conf->global->SUPPLIER_PAYMENT_ADDON_PDF == "$name") + { + //print img_picto($langs->trans("Default"),'on'); + // Even if choice is the default value, we allow to disable it: For supplier invoice, we accept to have no doc generation at all + print '<a href="'.$_SERVER["PHP_SELF"].'?action=unsetdoc&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'&type=SUPPLIER_PAYMENT"" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"),'on').'</a>'; + } + else + { + print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'&type=SUPPLIER_PAYMENT"" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; + } + print '</td>'; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='<br>'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + $htmltooltip.='<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + $htmltooltip.='<br><br><u>'.$langs->trans("FeaturesSupported").':</u>'; + $htmltooltip.='<br>'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + $htmltooltip.='<br>'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='<br>'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + print '<td align="center">'; + print $form->textwithpicto('',$htmltooltip,1,0); + print '</td>'; + print '<td align="center">'; + print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"),'order').'</a>'; + print '</td>'; + + print "</tr>\n"; + } + } + + closedir($handle); + } + } +} + +print '</table><br>'; + dol_fiche_end(); diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index bb63e4c3560149a2281a7a5ec0de39959c946fea..5f80dbcd6c1971278ed419cafd1b1c26a204973c 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -345,6 +345,9 @@ class Conf $this->fournisseur->facture=new stdClass(); $this->fournisseur->facture->dir_output =$rootfordata."/fournisseur/facture"; $this->fournisseur->facture->dir_temp =$rootfordata."/fournisseur/facture/temp"; + $this->fournisseur->payment=new stdClass(); + $this->fournisseur->payment->dir_output =$rootfordata."/fournisseur/payment"; + $this->fournisseur->payment->dir_temp =$rootfordata."/fournisseur/payment/temp"; // To prepare split of module fournisseur into fournisseur + supplier_order + supplier_invoice if (! empty($this->fournisseur->enabled) && empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // By default, if module supplier is on, we set new properties diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index 0b5e9ebb3587dff40238fd90595164c181730395..b44f854087cad5705896df1b116cec12fc35e455 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -172,6 +172,7 @@ class FormActions if ($typeelement == 'invoice') $title=$langs->trans('ActionsOnBill'); elseif ($typeelement == 'invoice_supplier' || $typeelement == 'supplier_invoice') $title=$langs->trans('ActionsOnBill'); elseif ($typeelement == 'propal') $title=$langs->trans('ActionsOnPropal'); + elseif ($typeelement == 'supplier_payment') $title=$langs->trans('ActionsOnSupplierPayment'); elseif ($typeelement == 'supplier_proposal') $title=$langs->trans('ActionsOnSupplierProposal'); elseif ($typeelement == 'order') $title=$langs->trans('ActionsOnOrder'); elseif ($typeelement == 'order_supplier' || $typeelement == 'supplier_order') $title=$langs->trans('ActionsOnOrder'); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 6c8a1170a90e7c140ede85855fa950aaf932c8d2..e80ff8008dfc7909b45eea04e8fb5dd3fb4adb22 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -466,6 +466,15 @@ class FormFile $modellist=ModelePDFSuppliersInvoices::liste_modeles($this->db); } } + else if ($modulepart == 'supplier_payment') + { + if (is_array($genallowed)) $modellist=$genallowed; + else + { + include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_payment/modules_supplier_payment.php'; + $modellist=ModelePDFSuppliersPayments::liste_modeles($this->db); + } + } else if ($modulepart == 'remisecheque') { if (is_array($genallowed)) $modellist=$genallowed; diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 6bce1a443c53225cf5a4ca81c1900733146d965a..2b1cfa8870960520acd677a9d53a614a42315a9e 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1885,6 +1885,16 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->fournisseur->facture->dir_output.'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture_fourn WHERE facnumber='".$db->escape($refname)."' AND entity=".$conf->entity; } + // Wrapping pour les rapport de paiements + else if ($modulepart == 'supplier_payment') + { + if ($fuser->rights->fournisseur->facture->lire || preg_match('/^specimen/i',$original_file)) + { + $accessallowed=1; + } + $original_file=$conf->fournisseur->payment->dir_output.'/'.$original_file; + $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."paiementfournisseur WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; + } // Wrapping pour les rapport de paiements else if ($modulepart == 'facture_paiement') diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 540228bcd42ba9ced6cbce89fb60b92f563d09b2..88ad26ac9da2d3e2da1d8cd442ba7caea8d9e09b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4322,7 +4322,7 @@ function get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart) $path = ''; - $arrayforoldpath=array('cheque','user','category','holiday','shipment','supplier_invoice','invoice_supplier','mailing'); + $arrayforoldpath=array('cheque','user','category','holiday','shipment','supplier_invoice','invoice_supplier','mailing','supplier_payment'); if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) $arrayforoldpath[]='product'; if (! empty($level) && in_array($modulepart, $arrayforoldpath)) { diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 0eff5075594098062ddf4a5d36ac06a1bd3d769a..7df62774ca63ae1b1b5cedccc7f58b66598f524e 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -21,9 +21,123 @@ * \brief A set of functions for Dolibarr * This file contains all frequently used functions. */ + + +/** + * Function to return number in text. + * + * + * @param float $num Number to convert + * @param Lang $langs Language + * @param boolean $currency 0=number to translate | 1=currency to translate + * @param boolean $centimes 0=no centimes | 1=centimes to translate + * @return string Text of the number + */ +function dol_convertToWord($num, $langs, $currency=false, $centimes=false) +{ + global $conf; + + $num = str_replace(array(',', ' '), '', trim($num)); + if(! $num) { + return false; + } + if($centimes && strlen($num) == 1) { + $num = $num*10; + } + $TNum = explode('.',$num); + $num = (int) $TNum[0]; + $words = array(); + $list1 = array( + '', + $langs->transnoentitiesnoconv('one'), + $langs->transnoentitiesnoconv('two'), + $langs->transnoentitiesnoconv('three'), + $langs->transnoentitiesnoconv('four'), + $langs->transnoentitiesnoconv('five'), + $langs->transnoentitiesnoconv('six'), + $langs->transnoentitiesnoconv('seven'), + $langs->transnoentitiesnoconv('eight'), + $langs->transnoentitiesnoconv('nine'), + $langs->transnoentitiesnoconv('ten'), + $langs->transnoentitiesnoconv('eleven'), + $langs->transnoentitiesnoconv('twelve'), + $langs->transnoentitiesnoconv('thirteen'), + $langs->transnoentitiesnoconv('fourteen'), + $langs->transnoentitiesnoconv('fifteen'), + $langs->transnoentitiesnoconv('sixteen'), + $langs->transnoentitiesnoconv('seventeen'), + $langs->transnoentitiesnoconv('eighteen'), + $langs->transnoentitiesnoconv('nineteen') + ); + $list2 = array( + '', + $langs->transnoentitiesnoconv('ten'), + $langs->transnoentitiesnoconv('twenty'), + $langs->transnoentitiesnoconv('thirty'), + $langs->transnoentitiesnoconv('forty'), + $langs->transnoentitiesnoconv('fifty'), + $langs->transnoentitiesnoconv('sixty'), + $langs->transnoentitiesnoconv('seventy'), + $langs->transnoentitiesnoconv('eighty'), + $langs->transnoentitiesnoconv('ninety'), + $langs->transnoentitiesnoconv('hundred') + ); + $list3 = array( + '', + $langs->transnoentitiesnoconv('thousand'), + $langs->transnoentitiesnoconv('million'), + $langs->transnoentitiesnoconv('billion'), + $langs->transnoentitiesnoconv('trillion'), + $langs->transnoentitiesnoconv('quadrillion') + ); + + $num_length = strlen($num); + $levels = (int) (($num_length + 2) / 3); + $max_length = $levels * 3; + $num = substr('00' . $num, -$max_length); + $num_levels = str_split($num, 3); + for ($i = 0; $i < count($num_levels); $i++) { + $levels--; + $hundreds = (int) ($num_levels[$i] / 100); + $hundreds = ($hundreds ? ' ' . $list1[$hundreds] . ' '.$langs->transnoentities('hundred') . ( $hundreds == 1 ? '' : 's' ) . ' ': ''); + $tens = (int) ($num_levels[$i] % 100); + $singles = ''; + if ( $tens < 20 ) { + $tens = ($tens ? ' ' . $list1[$tens] . ' ' : '' ); + } else { + $tens = (int) ($tens / 10); + $tens = ' ' . $list2[$tens] . ' '; + $singles = (int) ($num_levels[$i] % 10); + $singles = ' ' . $list1[$singles] . ' '; + } + $words[] = $hundreds . $tens . $singles . ( ( $levels && ( int ) ( $num_levels[$i] ) ) ? ' ' . $list3[$levels] . ' ' : '' ); + } //end for loop + $commas = count($words); + if ($commas > 1) { + $commas = $commas - 1; + } + $concatWords = implode(' ', $words); + // Delete multi whitespaces + $concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords)); + + if(!empty($currency)) { + $concatWords .= ' '.$currency; + } + + // If we need to write cents call again this function for cents + if(!empty($TNum[1])) { + if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and'); + $concatWords .= ' '.dol_convertToWord($TNum[1], $langs, $currency, true); + if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes'); + } + return $concatWords; +} + + /** * Function to return number or amount in text. - * + * + * @deprecated * @param float $numero Number to convert * @param Lang $langs Language * @param string $numorcurrency 'number' or 'amount' @@ -45,6 +159,7 @@ function dolNumberToWord($numero, $langs, $numorcurrency='number') break; } } + var_dump($langs); /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and in case exist why ask $lang like a parameter?*/ if (((is_object($langs) && $langs->default == 'es_MX') || (! is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') diff --git a/htdocs/core/modules/supplier_payment/modules_supplier_payment.php b/htdocs/core/modules/supplier_payment/modules_supplier_payment.php index c9023a9fc651c8aad171474e983b273f374bbddb..d8586777d304245d2b5093d4640eccf169d7e09c 100644 --- a/htdocs/core/modules/supplier_payment/modules_supplier_payment.php +++ b/htdocs/core/modules/supplier_payment/modules_supplier_payment.php @@ -16,6 +16,37 @@ * or see http://www.gnu.org/ */ +require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; +/** + * Parent class for supplier invoices models + */ +abstract class ModelePDFSuppliersPayments extends CommonDocGenerator +{ + var $error=''; + + + /** + * Return list of active generation models + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of numbers + */ + static function liste_modeles($db,$maxfilenamelength=0) + { + global $conf; + + $type='supplier_payment'; + $liste=array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $liste=getListOfModels($db,$type,$maxfilenamelength); + + return $liste; + } + +} + /** * \class ModeleNumRefPayments * \brief Payment numbering references mother class diff --git a/htdocs/core/modules/supplier_payment/pdf/index.html b/htdocs/core/modules/supplier_payment/pdf/index.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/htdocs/core/modules/supplier_payment/pdf/pdf_cow.modules.php b/htdocs/core/modules/supplier_payment/pdf/pdf_cow.modules.php new file mode 100644 index 0000000000000000000000000000000000000000..83c0d38b0ce34fb636cdefe53d5d8c3a221de60d --- /dev/null +++ b/htdocs/core/modules/supplier_payment/pdf/pdf_cow.modules.php @@ -0,0 +1,780 @@ +<?php +/* Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es> + * Copyright (C) 2010-2014 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com> + * + * 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 <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php + * \ingroup fournisseur + * \brief Class file to generate the supplier invoices with the canelle model + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_payment/modules_supplier_payment.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.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/pdf.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functionsnumtoword.lib.php'; + + +/** + * Class to generate the supplier invoices with the canelle model + */ +class pdf_cow extends ModelePDFSuppliersPayments +{ + 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 = "cow"; + $this->description = $langs->trans('SuppliersPaymentModel'); + + // 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->franchise=!$mysoc->tva_assuj; + + // Defini position des colonnes + $this->posxdate=$this->marge_gauche+1; + $this->posxreffacturefourn=30; + $this->posxreffacture=65; + $this->posxtype=100; + $this->posxtotalht=80; + $this->posxtva=90; + $this->posxtotalttc=180; + + //if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) $this->posxtva=$this->posxup; + if ($this->page_largeur < 210) // To work with US executive format + { + $this->posxreffacturefourn-=20; + $this->posxreffacture-=20; + $this->posxtype-=20; + $this->posxtotalht-=20; + $this->posxtva-=20; + $this->posxtotalttc-=20; + } + + $this->tva=array(); + $this->localtax1=array(); + $this->localtax2=array(); + $this->atleastoneratenotnull=0; + $this->atleastonediscount=0; + } + + + /** + * Function to build pdf onto disk + * + * @param PaiementFourn $object Id of 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,$hookmanager; + + // Get source company + if (! is_object($object->thirdparty)) $object->fetch_thirdparty(); + if (! is_object($object->thirdparty)) $object->thirdparty=$mysoc; // If fetch_thirdparty fails, object has no socid (specimen) + $this->emetteur=$object->thirdparty; + if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined + + 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("products"); + $outputlangs->load("suppliers"); + $object->factures = array(); + + if ($conf->fournisseur->payment->dir_output) + { + $object->fetch_thirdparty(); + /** + * Supplier invoice list + */ + $sql = 'SELECT f.rowid, f.ref, f.datef, f.ref_supplier, f.total_ht, f.total_tva, f.total_ttc, pf.amount, f.rowid as facid, f.paye'; + $sql .= ', f.fk_statut, s.nom as name, s.rowid as socid'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf,'.MAIN_DB_PREFIX.'facture_fourn as f,'.MAIN_DB_PREFIX.'societe as s'; + $sql .= ' WHERE pf.fk_facturefourn = f.rowid AND f.fk_soc = s.rowid'; + $sql .= ' AND pf.fk_paiementfourn = '.$object->id; + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql) > 0) + { + while($objp = $this->db->fetch_object($resql)) { + $objp->type = $outputlangs->trans('SupplierInvoice'); + $object->lines[] = $objp; + } + } + } + + $total = $object->montant; + + // Definition of $dir and $file + if ($object->specimen) + { + $dir = $conf->fournisseur->payment->dir_output; + $file = $dir . "/SPECIMEN.pdf"; + } + else + { + $objectref = dol_sanitizeFileName($object->ref); + $objectrefsupplier = dol_sanitizeFileName($object->ref_supplier); + $dir = $conf->fournisseur->payment->dir_output.'/'.$objectref; + $file = $dir . "/" . $objectref . ".pdf"; + if (! empty($conf->global->SUPPLIER_REF_IN_NAME)) $file = $dir . "/" . $objectref . ($objectrefsupplier?"_".$objectrefsupplier:"").".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 + + $nblignes = count($object->lines); + + $pdf=pdf_getInstance($this->format); + $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("Invoice")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Order")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); + 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 + + + // 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; + + $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); + + $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(); + + // Description of product line + $curX = $this->posxdate-1; + $showpricebeforepagebreak=1; + + $pdf->startTransaction(); + //pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxtva-$curX,3,$curX,$curY,$hideref,$hidedesc,1); + $pdf->writeHTMLCell($this->posxtva-$curX, 4, $curX, $curY, $object->lines[$i]->datef, 0, 1, false, true, 'J',true); + $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->posxtva-$curX,4,$curX,$curY,$hideref,$hidedesc,1); + $pdf->writeHTMLCell($this->posxtva-$curX, 4, $curX, $curY, $object->lines[$i]->datef, 0, 1, false, true, 'J',true); + $posyafter=$pdf->GetY(); + 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(); + } + + $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 is 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 + + // ref fourn + $pdf->SetXY($this->posxreffacturefourn, $curY); + $pdf->MultiCell($this->posxreffacturefourn-$this->posxup-0.8, 3, $object->lines[$i]->ref_supplier, 0, 'L', 0); + + // ref facture fourn + $pdf->SetXY($this->posxreffacture, $curY); + $pdf->MultiCell($this->posxreffacture-$this->posxup-0.8, 3, $object->lines[$i]->ref, 0, 'L', 0); + + // type + $pdf->SetXY($this->posxtype, $curY); + $pdf->MultiCell($this->posxtype-$this->posxup-0.8, 3, $object->lines[$i]->type, 0, 'L', 0); + + // Total ht + $pdf->SetXY($this->posxtotalht, $curY); + $pdf->MultiCell($this->posxtotalht-$this->posxup-0.8, 3, price($object->lines[$i]->total_ht), 0, 'R', 0); + + // Total tva + $pdf->SetXY($this->posxtva, $curY); + $pdf->MultiCell($this->posxtva-$this->posxup-0.8, 3, price($object->lines[$i]->total_tva), 0, 'R', 0); + + // Total TTC line + $pdf->SetXY($this->posxtotalttc, $curY); + $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->posxtotalttc, 3, price($object->lines[$i]->total_ttc), 0, 'R', 0); + + + // 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(80,80,80))); + //$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 cheèque + $posy=$this->_tableau_cheque($pdf, $object, $bottomlasttab, $outputlangs); + + // Affiche zone totaux + //$posy=$this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); + + // Pied de page + $this->_pagefoot($pdf, $object, $outputlangs); + if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages(); + + $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","SUPPLIER_OUTPUTDIR"); + return 0; + } + } + + /** + * Show total to pay + * + * @param PDF $pdf Object PDF + * @param PaiementFourn $object Object PaiementFourn + * @param int $posy Position depart + * @param Translate $outputlangs Objet langs + * @return int Position pour suite + */ + function _tableau_cheque(&$pdf, $object, $posy, $outputlangs) + { + global $conf,$mysoc; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetFillColor(255,255,255); + + // N° payment + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->MultiCell(30, 4, 'N° '.$outputlangs->transnoentities("Payment"), 0, 'L', 1); + + // Ref payment + $pdf->SetXY($this->marge_gauche + 30, $posy); + $pdf->MultiCell(50, 4, $object->ref, 0, 'L', 1); + + // Total payments + $pdf->SetXY($this->page_largeur - $this->marge_droite - 50, $posy); + $pdf->MultiCell(50, 4, price($object->montant), 0, 'R', 1); + $posy += 20; + + // translate amount + $currency = $conf->currency; + $translateinletter = strtoupper(dol_convertToWord($object->montant,$outputlangs,$currency)); + $pdf->SetXY($this->marge_gauche + 50, $posy); + $pdf->MultiCell(90, 8, $translateinletter, 0, 'L', 1); + $posy += 8; + + // To + $pdf->SetXY($this->marge_gauche + 50, $posy); + $pdf->MultiCell(150, 4, $object->thirdparty->nom, 0, 'L', 1); + + $pdf->SetXY($this->page_largeur - $this->marge_droite - 30, $posy); + $pdf->MultiCell(35, 4, str_pad(price($object->montant). ' '.$currency,18,'*',STR_PAD_LEFT), 0, 'R', 1); + $posy += 10; + + + // City + $pdf->SetXY($this->page_largeur - $this->marge_droite - 30, $posy); + $pdf->MultiCell(150, 4, $mysoc->town, 0, 'L', 1); + $posy += 4; + + // Date + $pdf->SetXY($this->page_largeur - $this->marge_droite - 30, $posy); + $pdf->MultiCell(150, 4, date("d").' '.$outputlangs->transnoentitiesnoconv(date("F")).' '.date("Y"), 0, 'L', 1); + + } + + + /** + * 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 Hide top bar of array + * @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,$mysoc; + + // 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); + + $titre = strtoupper($mysoc->town).', le '.date("d").' '.$outputlangs->transnoentitiesnoconv(date("F")).' '.date("Y"); + $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3) - 60, $tab_top-6); + $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); + + $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$conf->currency)); + $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top); + $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); + + + $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 + + } + + + /** + * Show top header of page. + * + * @param PDF $pdf Object PDF + * @param FactureFournisseur $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 $langs,$conf,$mysoc; + + $outputlangs->load("main"); + $outputlangs->load("bills"); + $outputlangs->load("orders"); + $outputlangs->load("companies"); + $default_font_size = pdf_getPDFFontSize($outputlangs); + + // Do not add the BACKGROUND as this is for suppliers + //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); + + $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/'.$mysoc->logo; + if ($mysoc->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("ErrorGoToModuleSetup"), 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); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("SupplierInvoice")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R'); + $posy+=1; + + if ($object->ref_supplier) + { + $posy+=4; + $pdf->SetFont('','B', $default_font_size); + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("RefSupplier")." : " . $object->ref_supplier, '', 'R'); + $posy+=1; + } + + $pdf->SetFont('','', $default_font_size - 1); + + if (! empty($conf->global->PDF_SHOW_PROJECT)) + { + $object->fetch_projet(); + if (! empty($object->project->ref)) + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $langs->load("projects"); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Project")." : " . (empty($object->project->ref)?'':$object->projet->ref), '', 'R'); + } + } + + if ($object->date) + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Date")." : " . dol_print_date($object->date,"day",false,$outputlangs,true), '', 'R'); + } + else + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(255,0,0); + $pdf->MultiCell(100, 4, strtolower($outputlangs->transnoentities("OrderToProcess")), '', 'R'); + } + + if ($object->thirdparty->code_fournisseur) + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("SupplierCode")." : " . $outputlangs->transnoentities($object->thirdparty->code_fournisseur), '', 'R'); + } + + $posy+=1; + $pdf->SetTextColor(0,0,60); + + // 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 = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty); + + // 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 BILLING contact defined on invoice, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('internal','BILLING'); + 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 = $mysoc; + } + + $carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs); + + $carac_client=pdf_build_address($outputlangs,$this->emetteur,$mysoc,((!empty($object->contact))?$object->contact:null),$usecontact,'target',$object); + + // Show recipient + $widthrecbox=90; + 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, "",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'); + } + } + + /** + * Show footer of page. Need this->emetteur object + * + * @param PDF $pdf PDF + * @param FactureFournisseur $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) + { + global $conf; + $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; + return pdf_pagefoot($pdf,$outputlangs,'SUPPLIER_INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext); + } + +} + diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php index 738c0eb716fe04fb63b12f468eb5a0fb7576cafa..5d8279b1c5492f531c6e9e563f51f6dd5897f01f 100644 --- a/htdocs/fourn/class/paiementfourn.class.php +++ b/htdocs/fourn/class/paiementfourn.class.php @@ -660,6 +660,49 @@ class PaiementFourn extends Paiement } } + /** + * Create a document onto disk according to template model. + * + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs Object lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @return int <0 if KO, 0 if nothing done, >0 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0) + { + global $conf, $user, $langs; + + $langs->load("suppliers"); + + // Set the model on the model name to use + if (empty($modele)) + { + if (! empty($conf->global->SUPPLIER_PAYMENT_ADDON_PDF)) + { + $modele = $conf->global->SUPPLIER_PAYMENT_ADDON_PDF; + } + else + { + $modele = ''; // No default value. For supplier invoice, we allow to disable all PDF generation + } + } + + if (empty($modele)) + { + return 0; + } + else + { + $modelpath = "core/modules/supplier_payment/pdf/"; + + return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + + + /** * get the right way of payment * diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index 3b93eb85cc9aed55794ebcea2c6bbd919d4c524e..9cb44a92bb87dcdd6752b6239e96c56ab08eb25d 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -26,6 +26,7 @@ */ require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; require DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php'; require DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; @@ -42,6 +43,11 @@ $confirm = GETPOST('confirm','alpha'); $object = new PaiementFourn($db); +// PDF +$hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); +$hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0)); +$hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0)); + /* * Actions */ @@ -133,6 +139,32 @@ if ($action == 'setdatep' && ! empty($_POST['datepday'])) } } +// Build document +if ($action == 'builddoc') +{ + // Save modele used + $object->fetch($id); + $object->fetch_thirdparty(); + + // Save last template used to generate document + if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); + + $outputlangs = $langs; + $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->thirdparty->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $action=''; + } +} + /* * View @@ -143,6 +175,7 @@ llxHeader(); $result=$object->fetch($id); $form = new Form($db); +$formfile = new FormFile($db); $head = payment_supplier_prepare_head($object); @@ -344,6 +377,33 @@ if ($result > 0) } } print '</div>'; + + print '<div class="fichecenter"><div class="fichehalfleft">'; + + /* + * Documents generes + */ + $ref=dol_sanitizeFileName($object->ref); + $filedir = $conf->fournisseur->payment->dir_output.'/'.dol_sanitizeFileName($object->ref); + $urlsource=$_SERVER['PHP_SELF'].'?id='.$object->id; + $genallowed=$user->rights->fournisseur->facture->creer; + $delallowed=$user->rights->fournisseur->facture->supprimer; + $modelpdf=(! empty($object->modelpdf)?$object->modelpdf:(empty($conf->global->SUPPLIER_PAYMENT_ADDON_PDF)?'':$conf->global->SUPPLIER_PAYMENT_ADDON_PDF)); + + print $formfile->showdocuments('supplier_payment',$ref,$filedir,$urlsource,$genallowed,$delallowed,$modelpdf,1,0,0,40,0,'','','',$societe->default_lang); + $somethingshown=$formfile->numoffiles; + + print '</div><div class="fichehalfright"><div class="ficheaddleft">'; + //print '</td><td valign="top" width="50%">'; + //print '<br>'; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + $formactions=new FormActions($db); + $somethingshown=$formactions->showactions($object,'supplier_payment',$socid,0,'listaction'.($genallowed?'largetitle':'')); + + print '</div></div></div>'; + //print '</td></tr></table>'; } else diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index aa755daa09a875e1ad53cd86c0c16dc5188dabe9..e7803281e67bd633e810ca04044757a983aec4c9 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -98,3 +98,5 @@ CREATE TABLE llx_product_attribute_combination entity INT DEFAULT 1 NOT NULL ); +ALTER TABLE llx_paiementfourn ADD COLUMN model_pdf varchar(255); + diff --git a/htdocs/install/mysql/tables/llx_paiementfourn.sql b/htdocs/install/mysql/tables/llx_paiementfourn.sql index aba54627a09b511fbad235f6c74ae00735f9b623..0e9b1885c975663aa02345cdd71728be66c0db43 100644 --- a/htdocs/install/mysql/tables/llx_paiementfourn.sql +++ b/htdocs/install/mysql/tables/llx_paiementfourn.sql @@ -32,5 +32,6 @@ create table llx_paiementfourn num_paiement varchar(50), -- numero de paiement (cheque) note text, fk_bank integer NOT NULL, - statut smallint NOT NULL DEFAULT 0 + statut smallint NOT NULL DEFAULT 0, + model_pdf varchar(255) )ENGINE=innodb; diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index 08a88d923c0e344c3b5e8123124e01d9af802a65..0c6db69fed349c5aebf9166a5a019ab8425dc3b1 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -816,5 +816,40 @@ SearchIntoContracts=Contrats SearchIntoCustomerShipments=Expéditions clients SearchIntoExpenseReports=Notes de frais SearchIntoLeaves=Congés - BulkActions=Bulk actions +#Numbers translate +centimes=centimes +one=un +two=deux +three=trois +four=quatre +five=cinq +six=six +seven=sept +eight=huit +nine=neuf +ten=dix +eleven=onze +twelve=douze +thirteen=treize +fourteen=quatorze +fifteen=quinze +sixteen=seize +seventeen=dix-sept +eighteen=dix-huit +nineteen=dix-neuf +twenty=vingt +thirty=trente +forty=quarante +fifty=cinquante +sixty=soixante +seventy=soixante-dix +eighty=quatre-vingt +ninety=quatre-vingt-dix +hundred=cent +hundreds=cents +thousand=mille +million=million +billion=milliard +trillion=billion +quadrillion=quadrillion diff --git a/htdocs/langs/fr_FR/suppliers.lang b/htdocs/langs/fr_FR/suppliers.lang index 7c2d064aea4ad79d47bb24b66e7c02abb974f18e..b5593fab2ccaecb7ace80af652212eb9596b3cc2 100644 --- a/htdocs/langs/fr_FR/suppliers.lang +++ b/htdocs/langs/fr_FR/suppliers.lang @@ -41,4 +41,5 @@ DoNotOrderThisProductToThisSupplier=Ne pas commander NotTheGoodQualitySupplier=Mauvaise qualité ReputationForThisProduct=Réputation BuyerName=Nom de l'acheteur -AllProductServicePrices=All product / service prices +SuppliersPaymentModel=Model liste des factures réglées par ce paiement +AllProductServicePrices=All product / service prices \ No newline at end of file