From 07a4709b4510e7e868457cbec458d73f99ced115 Mon Sep 17 00:00:00 2001 From: fhenry Date: Wed, 17 Apr 2013 21:14:46 +0200 Subject: [PATCH 01/97] fix [ bug #825 ] User first name not visible into users->perms --- htdocs/user/perms.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php index e6836a9b1d4..bca0ba9ee6a 100644 --- a/htdocs/user/perms.php +++ b/htdocs/user/perms.php @@ -260,7 +260,7 @@ print ''."\n"; // Lastname print ''.$langs->trans("Lastname").''; -print ''.$fuser->lastName.''; +print ''.$fuser->lastname.''; print ''."\n"; // Firstname From c0c1de79920764293452f4198bf6ddc6b0575be1 Mon Sep 17 00:00:00 2001 From: fhenry Date: Thu, 18 Apr 2013 08:40:29 +0200 Subject: [PATCH 02/97] [ task #826 ] Increasing stock when deleting an invoice --- ChangeLog | 1 + htdocs/admin/stock.php | 19 +- htdocs/compta/facture.php | 35 +- htdocs/compta/facture/class/facture.class.php | 6433 +++++++++-------- htdocs/langs/en_US/agenda.lang | 1 + htdocs/langs/en_US/stocks.lang | 1 + htdocs/langs/es_ES/agenda.lang | 1 + htdocs/langs/es_ES/stocks.lang | 1 + htdocs/langs/fr_FR/agenda.lang | 1 + htdocs/langs/fr_FR/stocks.lang | 1 + 10 files changed, 3296 insertions(+), 3198 deletions(-) diff --git a/ChangeLog b/ChangeLog index da6bd6b1bfd..1de66c954a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -49,6 +49,7 @@ For users: - New: [ task #814 ] Add extrafield feature into Project/project tasks module - New: [ task #770 ] Add ODT document generation for Projects module - New: [ task #741 ] Add intervention box +- New: [ task #826 ] Optionnal increase stock when deleting an invoice already validated For translators: - Update language files. diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index bbdbf3276db..96502bbdb10 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2013 Philippe Grand + * Copyright (C) 2013 Florian Henry * * 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 @@ -61,15 +62,18 @@ if ($action == 'STOCK_CALCULATE_ON_BILL' // Mode of stock increase if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL' || $action == 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER' -|| $action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') +|| $action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER' +|| $action == 'STOCK_CALCULATE_ON_DELETE_INVOICE') { $db->begin(); $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_BILL", '','chaine',0,'',$conf->entity); $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", '','chaine',0,'',$conf->entity); $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", '','chaine',0,'',$conf->entity); + $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_DELETE_INVOICE", '','chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_BILL", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_BILL','alpha'),'chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER','alpha'),'chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER','alpha'),'chaine',0,'',$conf->entity); + if ($action == 'STOCK_CALCULATE_ON_DELETE_INVOICE') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_DELETE_INVOICE", GETPOST('STOCK_CALCULATE_ON_DELETE_INVOICE','alpha'),'chaine',0,'',$conf->entity); } if($action) @@ -239,6 +243,19 @@ if (! empty($conf->fournisseur->enabled)) print ''; print "\n\n\n"; } +if (! empty($conf->facture->enabled)) +{ + $var=!$var; + print ""; + print ''.$langs->trans("ReStockOnDeleteInvoice").''; + print ''; + print "
"; + print ''; + print ""; + print $form->selectyesno("STOCK_CALCULATE_ON_DELETE_INVOICE",$conf->global->STOCK_CALCULATE_ON_DELETE_INVOICE,1); + print ''; + print "
\n\n\n"; +} print ''; diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 53e839e0241..6ba029d63b4 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -156,7 +156,21 @@ else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->fact { $result = $object->fetch($id); $object->fetch_thirdparty(); - $result = $object->delete(); + + $idwarehouse=GETPOST('idwarehouse'); + + //Check for warehouse + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_DELETE_INVOICE) && $object->hasProductsOrServices(1) && $object->statut>=1) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors'); + $action=''; + } + } + + $result = $object->delete(0,0,$idwarehouse); if ($result > 0) { header('Location: '.DOL_URL_ROOT.'/compta/facture/list.php'); @@ -2334,8 +2348,23 @@ else if ($id > 0 || ! empty($ref)) // Confirmation to delete invoice if ($action == 'delete') { - $text=$langs->trans('ConfirmDeleteBill'); - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','',0,1); + $text=$langs->trans('ConfirmDeleteBill',$object->ref); + $formquestion=array(); + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_DELETE_INVOICE) && $object->hasProductsOrServices(1) && $object->statut>=1) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete',$formquestion,"yes",1); + }else { + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','','',1); + } } // Confirmation de la validation diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index f36ddc88a1d..fa03d8527b0 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1,37 +1,37 @@ * Copyright (C) 2004-2012 Laurent Destailleur - * Copyright (C) 2004 Sebastien Di Cintio - * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2013 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2007 Franky Van Liedekerke - * Copyright (C) 2010-2012 Juanjo Menent - * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2012 Marcos García - * Copyright (C) 2013 Cedric Gross - * Copyright (C) 2013 Florian Henry - * - * 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 . - */ +* Copyright (C) 2004 Sebastien Di Cintio +* Copyright (C) 2004 Benoit Mortier +* Copyright (C) 2005 Marc Barilley / Ocebo +* Copyright (C) 2005-2013 Regis Houssin +* Copyright (C) 2006 Andre Cianfarani +* Copyright (C) 2007 Franky Van Liedekerke +* Copyright (C) 2010-2012 Juanjo Menent +* Copyright (C) 2012 Christophe Battarel +* Copyright (C) 2012 Marcos García +* Copyright (C) 2013 Cedric Gross +* Copyright (C) 2013 Florian Henry +* +* 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 . +*/ /** * \file htdocs/compta/facture/class/facture.class.php - * \ingroup facture - * \brief File of class to manage invoices - */ +* \ingroup facture +* \brief File of class to manage invoices +*/ include_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php'; require_once DOL_DOCUMENT_ROOT .'/product/class/product.class.php'; @@ -44,1831 +44,1870 @@ require_once DOL_DOCUMENT_ROOT .'/margin/lib/margins.lib.php'; */ class Facture extends CommonInvoice { - public $element='facture'; - public $table_element='facture'; - public $table_element_line = 'facturedet'; - public $fk_element = 'fk_facture'; - protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + public $element='facture'; + public $table_element='facture'; + public $table_element_line = 'facturedet'; + public $fk_element = 'fk_facture'; + protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - var $id; - //! Id client - var $socid; - //! Objet societe client (to load with fetch_client method) - var $client; - var $author; - var $fk_user_author; - var $fk_user_valid; - //! Invoice date - var $date; // Invoice date - var $date_creation; // Creation date - var $date_validation; // Validation date - var $datem; - var $ref; - var $ref_client; - var $ref_ext; - var $ref_int; - //! 0=Standard invoice, 1=Replacement invoice, 2=Credit note invoice, 3=Deposit invoice, 4=Proforma invoice - var $type=0; + var $id; + //! Id client + var $socid; + //! Objet societe client (to load with fetch_client method) + var $client; + var $author; + var $fk_user_author; + var $fk_user_valid; + //! Invoice date + var $date; // Invoice date + var $date_creation; // Creation date + var $date_validation; // Validation date + var $datem; + var $ref; + var $ref_client; + var $ref_ext; + var $ref_int; + //! 0=Standard invoice, 1=Replacement invoice, 2=Credit note invoice, 3=Deposit invoice, 4=Proforma invoice + var $type=0; - //var $amount; - var $remise_absolue; - var $remise_percent; - var $total_ht=0; - var $total_tva=0; - var $total_ttc=0; - var $revenuestamp; - var $note; // deprecated - var $note_private; - var $note_public; - //! 0=draft, - //! 1=validated (need to be paid), - //! 2=classified paid partially (close_code='discount_vat','badcustomer') or completely (close_code=null), - //! 3=classified abandoned and no payment done (close_code='badcustomer','abandon' or 'replaced') - var $statut; - //! Fermeture apres paiement partiel: discount_vat, badcustomer, abandon - //! Fermeture alors que aucun paiement: replaced (si remplace), abandon - var $close_code; - //! Commentaire si mis a paye sans paiement complet - var $close_note; - //! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code - var $paye; - //! id of source invoice if replacement invoice or credit note - var $fk_facture_source; - var $origin; - var $origin_id; - var $linked_objects=array(); - var $fk_project; - var $date_lim_reglement; - var $cond_reglement_id; // Id in llx_c_paiement - var $cond_reglement_code; // Code in llx_c_paiement - var $mode_reglement_id; // Id in llx_c_paiement - var $mode_reglement_code; // Code in llx_c_paiement - var $fk_bank; // Field to store bank id to use when payment mode is withdraw - var $modelpdf; - var $products=array(); // deprecated - var $lines=array(); - var $line; - var $extraparams=array(); - //! Pour board - var $nbtodo; - var $nbtodolate; - var $specimen; + //var $amount; + var $remise_absolue; + var $remise_percent; + var $total_ht=0; + var $total_tva=0; + var $total_ttc=0; + var $revenuestamp; + var $note; // deprecated + var $note_private; + var $note_public; + //! 0=draft, + //! 1=validated (need to be paid), + //! 2=classified paid partially (close_code='discount_vat','badcustomer') or completely (close_code=null), + //! 3=classified abandoned and no payment done (close_code='badcustomer','abandon' or 'replaced') + var $statut; + //! Fermeture apres paiement partiel: discount_vat, badcustomer, abandon + //! Fermeture alors que aucun paiement: replaced (si remplace), abandon + var $close_code; + //! Commentaire si mis a paye sans paiement complet + var $close_note; + //! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code + var $paye; + //! id of source invoice if replacement invoice or credit note + var $fk_facture_source; + var $origin; + var $origin_id; + var $linked_objects=array(); + var $fk_project; + var $date_lim_reglement; + var $cond_reglement_id; // Id in llx_c_paiement + var $cond_reglement_code; // Code in llx_c_paiement + var $mode_reglement_id; // Id in llx_c_paiement + var $mode_reglement_code; // Code in llx_c_paiement + var $fk_bank; // Field to store bank id to use when payment mode is withdraw + var $modelpdf; + var $products=array(); // deprecated + var $lines=array(); + var $line; + var $extraparams=array(); + //! Pour board + var $nbtodo; + var $nbtodolate; + var $specimen; - var $fac_rec; + var $fac_rec; - /** - * Constructor - * + /** + * Constructor + * * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - } + */ + function __construct($db) + { + $this->db = $db; + } - /** - * Create invoice in database - * Note: this->ref can be set or empty. If empty, we will use "(PROV)" - * - * @param User $user Object user that create - * @param int $notrigger 1=Does not execute triggers, 0 otherwise - * @param int $forceduedate 1=Do not recalculate due date from payment condition but force it with value - * @return int <0 if KO, >0 if OK - */ - function create($user,$notrigger=0,$forceduedate=0) - { - global $langs,$conf,$mysoc,$hookmanager; - $error=0; + /** + * Create invoice in database + * Note: this->ref can be set or empty. If empty, we will use "(PROV)" + * + * @param User $user Object user that create + * @param int $notrigger 1=Does not execute triggers, 0 otherwise + * @param int $forceduedate 1=Do not recalculate due date from payment condition but force it with value + * @return int <0 if KO, >0 if OK + */ + function create($user,$notrigger=0,$forceduedate=0) + { + global $langs,$conf,$mysoc,$hookmanager; + $error=0; - // Clean parameters - if (empty($this->type)) $this->type = 0; - $this->ref_client=trim($this->ref_client); - $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated - $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note_private)); - $this->note_public=trim($this->note_public); - if (! $this->cond_reglement_id) $this->cond_reglement_id = 0; - if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; - $this->brouillon = 1; + // Clean parameters + if (empty($this->type)) $this->type = 0; + $this->ref_client=trim($this->ref_client); + $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated + $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note_private)); + $this->note_public=trim($this->note_public); + if (! $this->cond_reglement_id) $this->cond_reglement_id = 0; + if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; + $this->brouillon = 1; - dol_syslog(get_class($this)."::create user=".$user->id); + dol_syslog(get_class($this)."::create user=".$user->id); - // Check parameters - if (empty($this->date) || empty($user->id)) - { - $this->error="ErrorBadParameter"; - dol_syslog(get_class($this)."::create Try to create an invoice with an empty parameter (user, date, ...)", LOG_ERR); - return -3; - } - $soc = new Societe($this->db); - $result=$soc->fetch($this->socid); - if ($result < 0) - { - $this->error="Failed to fetch company"; - dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); - return -2; - } + // Check parameters + if (empty($this->date) || empty($user->id)) + { + $this->error="ErrorBadParameter"; + dol_syslog(get_class($this)."::create Try to create an invoice with an empty parameter (user, date, ...)", LOG_ERR); + return -3; + } + $soc = new Societe($this->db); + $result=$soc->fetch($this->socid); + if ($result < 0) + { + $this->error="Failed to fetch company"; + dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); + return -2; + } - $now=dol_now(); + $now=dol_now(); - $this->db->begin(); + $this->db->begin(); - // Create invoice from a predefined invoice - if ($this->fac_rec > 0) - { - require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; - $_facrec = new FactureRec($this->db); - $result=$_facrec->fetch($this->fac_rec); + // Create invoice from a predefined invoice + if ($this->fac_rec > 0) + { + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; + $_facrec = new FactureRec($this->db); + $result=$_facrec->fetch($this->fac_rec); - $this->fk_project = $_facrec->fk_project; - $this->cond_reglement = $_facrec->cond_reglement_id; - $this->cond_reglement_id = $_facrec->cond_reglement_id; - $this->mode_reglement = $_facrec->mode_reglement_id; - $this->mode_reglement_id = $_facrec->mode_reglement_id; - $this->remise_absolue = $_facrec->remise_absolue; - $this->remise_percent = $_facrec->remise_percent; + $this->fk_project = $_facrec->fk_project; + $this->cond_reglement = $_facrec->cond_reglement_id; + $this->cond_reglement_id = $_facrec->cond_reglement_id; + $this->mode_reglement = $_facrec->mode_reglement_id; + $this->mode_reglement_id = $_facrec->mode_reglement_id; + $this->remise_absolue = $_facrec->remise_absolue; + $this->remise_percent = $_facrec->remise_percent; - // Clean parametres - if (! $this->type) $this->type = 0; - $this->ref_client=trim($this->ref_client); - $this->note_private=trim($this->note_private); - $this->note_public=trim($this->note_public); - //if (! $this->remise) $this->remise = 0; - if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; - $this->brouillon = 1; - } + // Clean parametres + if (! $this->type) $this->type = 0; + $this->ref_client=trim($this->ref_client); + $this->note_private=trim($this->note_private); + $this->note_public=trim($this->note_public); + //if (! $this->remise) $this->remise = 0; + if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; + $this->brouillon = 1; + } - // Define due date if not already defined - $datelim=(empty($forceduedate)?$this->calculate_date_lim_reglement():$forceduedate); + // Define due date if not already defined + $datelim=(empty($forceduedate)?$this->calculate_date_lim_reglement():$forceduedate); - // Insert into database - $socid = $this->socid; + // Insert into database + $socid = $this->socid; - $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture ("; - $sql.= " facnumber"; - $sql.= ", entity"; - $sql.= ", ref_ext"; - $sql.= ", type"; - $sql.= ", fk_soc"; - $sql.= ", datec"; - $sql.= ", remise_absolue"; - $sql.= ", remise_percent"; - $sql.= ", datef"; - $sql.= ", note_private"; - $sql.= ", note_public"; - $sql.= ", ref_client, ref_int"; - $sql.= ", fk_facture_source, fk_user_author, fk_projet"; - $sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf"; - $sql.= ")"; - $sql.= " VALUES ("; - $sql.= "'(PROV)'"; - $sql.= ", ".$conf->entity; - $sql.= ", ".($this->ref_ext?"'".$this->db->escape($this->ref_ext)."'":"null"); - $sql.= ", '".$this->type."'"; - $sql.= ", '".$socid."'"; - $sql.= ", '".$this->db->idate($now)."'"; - $sql.= ",".($this->remise_absolue>0?$this->remise_absolue:'NULL'); - $sql.= ",".($this->remise_percent>0?$this->remise_percent:'NULL'); - $sql.= ", '".$this->db->idate($this->date)."'"; - $sql.= ",".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); - $sql.= ",".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); - $sql.= ",".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null"); - $sql.= ",".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); - $sql.= ",".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null"); - $sql.= ",".($user->id > 0 ? "'".$user->id."'":"null"); - $sql.= ",".($this->fk_project?$this->fk_project:"null"); - $sql.= ','.$this->cond_reglement_id; - $sql.= ",".$this->mode_reglement_id; - $sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."')"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture ("; + $sql.= " facnumber"; + $sql.= ", entity"; + $sql.= ", ref_ext"; + $sql.= ", type"; + $sql.= ", fk_soc"; + $sql.= ", datec"; + $sql.= ", remise_absolue"; + $sql.= ", remise_percent"; + $sql.= ", datef"; + $sql.= ", note_private"; + $sql.= ", note_public"; + $sql.= ", ref_client, ref_int"; + $sql.= ", fk_facture_source, fk_user_author, fk_projet"; + $sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf"; + $sql.= ")"; + $sql.= " VALUES ("; + $sql.= "'(PROV)'"; + $sql.= ", ".$conf->entity; + $sql.= ", ".($this->ref_ext?"'".$this->db->escape($this->ref_ext)."'":"null"); + $sql.= ", '".$this->type."'"; + $sql.= ", '".$socid."'"; + $sql.= ", '".$this->db->idate($now)."'"; + $sql.= ",".($this->remise_absolue>0?$this->remise_absolue:'NULL'); + $sql.= ",".($this->remise_percent>0?$this->remise_percent:'NULL'); + $sql.= ", '".$this->db->idate($this->date)."'"; + $sql.= ",".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); + $sql.= ",".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); + $sql.= ",".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null"); + $sql.= ",".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); + $sql.= ",".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null"); + $sql.= ",".($user->id > 0 ? "'".$user->id."'":"null"); + $sql.= ",".($this->fk_project?$this->fk_project:"null"); + $sql.= ','.$this->cond_reglement_id; + $sql.= ",".$this->mode_reglement_id; + $sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."')"; - dol_syslog(get_class($this)."::create sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture'); + dol_syslog(get_class($this)."::create sql=".$sql); + $resql=$this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture'); - // Update ref with new one - $this->ref='(PROV'.$this->id.')'; - $sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET facnumber='".$this->ref."' WHERE rowid=".$this->id; + // Update ref with new one + $this->ref='(PROV'.$this->id.')'; + $sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET facnumber='".$this->ref."' WHERE rowid=".$this->id; - dol_syslog(get_class($this)."::create sql=".$sql); - $resql=$this->db->query($sql); - if (! $resql) $error++; + dol_syslog(get_class($this)."::create sql=".$sql); + $resql=$this->db->query($sql); + if (! $resql) $error++; - // Add object linked - if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects)) - { - foreach($this->linked_objects as $origin => $origin_id) - { - $ret = $this->add_object_linked($origin, $origin_id); - if (! $ret) - { - dol_print_error($this->db); - $error++; - } + // Add object linked + if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects)) + { + foreach($this->linked_objects as $origin => $origin_id) + { + $ret = $this->add_object_linked($origin, $origin_id); + if (! $ret) + { + dol_print_error($this->db); + $error++; + } - // TODO mutualiser - if ($origin == 'commande') - { - // On recupere les differents contact interne et externe - $order = new Commande($this->db); - $order->id = $origin_id; + // TODO mutualiser + if ($origin == 'commande') + { + // On recupere les differents contact interne et externe + $order = new Commande($this->db); + $order->id = $origin_id; - // On recupere le commercial suivi propale - $this->userid = $order->getIdcontact('internal', 'SALESREPFOLL'); + // On recupere le commercial suivi propale + $this->userid = $order->getIdcontact('internal', 'SALESREPFOLL'); - if ($this->userid) - { - //On passe le commercial suivi commande en commercial suivi paiement - $this->add_contact($this->userid[0], 'SALESREPFOLL', 'internal'); - } + if ($this->userid) + { + //On passe le commercial suivi commande en commercial suivi paiement + $this->add_contact($this->userid[0], 'SALESREPFOLL', 'internal'); + } - // On recupere le contact client facturation commande - $this->contactid = $order->getIdcontact('external', 'BILLING'); + // On recupere le contact client facturation commande + $this->contactid = $order->getIdcontact('external', 'BILLING'); - if ($this->contactid) - { - //On passe le contact client facturation commande en contact client facturation - $this->add_contact($this->contactid[0], 'BILLING', 'external'); - } - } - } - } + if ($this->contactid) + { + //On passe le contact client facturation commande en contact client facturation + $this->add_contact($this->contactid[0], 'BILLING', 'external'); + } + } + } + } - /* - * Insert lines of invoices into database - */ - if (count($this->lines) && is_object($this->lines[0])) - { - $fk_parent_line = 0; + /* + * Insert lines of invoices into database + */ + if (count($this->lines) && is_object($this->lines[0])) + { + $fk_parent_line = 0; - dol_syslog("There is ".count($this->lines)." lines that are invoice lines objects"); - foreach ($this->lines as $i => $val) - { - $newinvoiceline=new FactureLigne($this->db); - $newinvoiceline=$this->lines[$i]; - $newinvoiceline->fk_facture=$this->id; - if ($result >= 0 && ($newinvoiceline->info_bits & 0x01) == 0) // We keep only lines with first bit = 0 - { - // Reset fk_parent_line for no child products and special product + dol_syslog("There is ".count($this->lines)." lines that are invoice lines objects"); + foreach ($this->lines as $i => $val) + { + $newinvoiceline=new FactureLigne($this->db); + $newinvoiceline=$this->lines[$i]; + $newinvoiceline->fk_facture=$this->id; + if ($result >= 0 && ($newinvoiceline->info_bits & 0x01) == 0) // We keep only lines with first bit = 0 + { + // Reset fk_parent_line for no child products and special product if (($newinvoiceline->product_type != 9 && empty($newinvoiceline->fk_parent_line)) || $newinvoiceline->product_type == 9) { $fk_parent_line = 0; } - $newinvoiceline->fk_parent_line=$fk_parent_line; + $newinvoiceline->fk_parent_line=$fk_parent_line; $result=$newinvoiceline->insert(); - // Defined the new fk_parent_line + // Defined the new fk_parent_line if ($result > 0 && $newinvoiceline->product_type == 9) { $fk_parent_line = $result; } - } - if ($result < 0) - { - $this->error=$newinvoiceline->error; - $error++; - break; - } - } - } - else - { - $fk_parent_line = 0; + } + if ($result < 0) + { + $this->error=$newinvoiceline->error; + $error++; + break; + } + } + } + else + { + $fk_parent_line = 0; - dol_syslog("There is ".count($this->lines)." lines that are array lines"); - foreach ($this->lines as $i => $val) - { - if (($this->lines[$i]->info_bits & 0x01) == 0) // We keep only lines with first bit = 0 - { - // Reset fk_parent_line for no child products and special product + dol_syslog("There is ".count($this->lines)." lines that are array lines"); + foreach ($this->lines as $i => $val) + { + if (($this->lines[$i]->info_bits & 0x01) == 0) // We keep only lines with first bit = 0 + { + // Reset fk_parent_line for no child products and special product if (($this->lines[$i]->product_type != 9 && empty($this->lines[$i]->fk_parent_line)) || $this->lines[$i]->product_type == 9) { $fk_parent_line = 0; } - $result = $this->addline( - $this->id, - $this->lines[$i]->desc, - $this->lines[$i]->subprice, - $this->lines[$i]->qty, - $this->lines[$i]->tva_tx, - $this->lines[$i]->localtax1_tx, - $this->lines[$i]->localtax2_tx, - $this->lines[$i]->fk_product, - $this->lines[$i]->remise_percent, - $this->lines[$i]->date_start, - $this->lines[$i]->date_end, - $this->lines[$i]->fk_code_ventilation, - $this->lines[$i]->info_bits, - $this->lines[$i]->fk_remise_except, - 'HT', - 0, - $this->lines[$i]->product_type, - $this->lines[$i]->rang, - $this->lines[$i]->special_code, - '', - 0, - $fk_parent_line, - $this->lines[$i]->fk_fournprice, - $this->lines[$i]->pa_ht, - $this->lines[$i]->label - ); - if ($result < 0) - { - $this->error=$this->db->lasterror(); - dol_print_error($this->db); - $this->db->rollback(); - return -1; - } + $result = $this->addline( + $this->id, + $this->lines[$i]->desc, + $this->lines[$i]->subprice, + $this->lines[$i]->qty, + $this->lines[$i]->tva_tx, + $this->lines[$i]->localtax1_tx, + $this->lines[$i]->localtax2_tx, + $this->lines[$i]->fk_product, + $this->lines[$i]->remise_percent, + $this->lines[$i]->date_start, + $this->lines[$i]->date_end, + $this->lines[$i]->fk_code_ventilation, + $this->lines[$i]->info_bits, + $this->lines[$i]->fk_remise_except, + 'HT', + 0, + $this->lines[$i]->product_type, + $this->lines[$i]->rang, + $this->lines[$i]->special_code, + '', + 0, + $fk_parent_line, + $this->lines[$i]->fk_fournprice, + $this->lines[$i]->pa_ht, + $this->lines[$i]->label + ); + if ($result < 0) + { + $this->error=$this->db->lasterror(); + dol_print_error($this->db); + $this->db->rollback(); + return -1; + } - // Defined the new fk_parent_line + // Defined the new fk_parent_line if ($result > 0 && $this->lines[$i]->product_type == 9) { $fk_parent_line = $result; } - } - } - } + } + } + } - /* - * Insert lines of predefined invoices - */ - if (! $error && $this->fac_rec > 0) - { - foreach ($_facrec->lines as $i => $val) - { - if ($_facrec->lines[$i]->fk_product) - { - $prod = new Product($this->db); - $res=$prod->fetch($_facrec->lines[$i]->fk_product); - } - $tva_tx = get_default_tva($mysoc,$soc,$prod->id); - $localtax1_tx=get_localtax($tva_tx,1,$soc); - $localtax2_tx=get_localtax($tva_tx,2,$soc); + /* + * Insert lines of predefined invoices + */ + if (! $error && $this->fac_rec > 0) + { + foreach ($_facrec->lines as $i => $val) + { + if ($_facrec->lines[$i]->fk_product) + { + $prod = new Product($this->db); + $res=$prod->fetch($_facrec->lines[$i]->fk_product); + } + $tva_tx = get_default_tva($mysoc,$soc,$prod->id); + $localtax1_tx=get_localtax($tva_tx,1,$soc); + $localtax2_tx=get_localtax($tva_tx,2,$soc); - $result_insert = $this->addline( - $this->id, - $_facrec->lines[$i]->desc, - $_facrec->lines[$i]->subprice, - $_facrec->lines[$i]->qty, - $tva_tx, - $localtax1_tx, - $localtax2_tx, - $_facrec->lines[$i]->fk_product, - $_facrec->lines[$i]->remise_percent, - '','',0,0,'','HT',0, - $_facrec->lines[$i]->product_type, - $_facrec->lines[$i]->rang, - $_facrec->lines[$i]->special_code, - '', - 0, - 0, - null, - 0, - $_facrec->lines[$i]->label - ); + $result_insert = $this->addline( + $this->id, + $_facrec->lines[$i]->desc, + $_facrec->lines[$i]->subprice, + $_facrec->lines[$i]->qty, + $tva_tx, + $localtax1_tx, + $localtax2_tx, + $_facrec->lines[$i]->fk_product, + $_facrec->lines[$i]->remise_percent, + '','',0,0,'','HT',0, + $_facrec->lines[$i]->product_type, + $_facrec->lines[$i]->rang, + $_facrec->lines[$i]->special_code, + '', + 0, + 0, + null, + 0, + $_facrec->lines[$i]->label + ); - if ( $result_insert < 0) - { - $error++; - $this->error=$this->db->error(); - break; - } - } - } + if ( $result_insert < 0) + { + $error++; + $this->error=$this->db->error(); + break; + } + } + } - if (! $error) - { - $result=$this->update_price(1); - if ($result > 0) - { - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('invoicedao')); - $parameters=array('invoiceid'=>$this->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - else if ($reshook < 0) $error++; + if (! $error) + { + $result=$this->update_price(1); + if ($result > 0) + { + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('invoicedao')); + $parameters=array('invoiceid'=>$this->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_CREATE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_CREATE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers - if (! $error) - { - $this->db->commit(); - return $this->id; - } - else - { - $this->db->rollback(); - return -4; - } - } - else - { - $this->error=$langs->trans('FailedToUpdatePrice'); - $this->db->rollback(); - return -3; - } - } - else - { - dol_syslog(get_class($this)."::create error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::create error ".$this->error." sql=".$sql, LOG_ERR); - $this->db->rollback(); - return -1; - } - } + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -4; + } + } + else + { + $this->error=$langs->trans('FailedToUpdatePrice'); + $this->db->rollback(); + return -3; + } + } + else + { + dol_syslog(get_class($this)."::create error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::create error ".$this->error." sql=".$sql, LOG_ERR); + $this->db->rollback(); + return -1; + } + } - /** - * Create a new invoice in database from current invoice - * - * @param User $user Object user that ask creation - * @param int $invertdetail Reverse sign of amounts for lines - * @return int <0 if KO, >0 if OK - */ - function createFromCurrent($user,$invertdetail=0) - { - // Charge facture source - $facture=new Facture($this->db); + /** + * Create a new invoice in database from current invoice + * + * @param User $user Object user that ask creation + * @param int $invertdetail Reverse sign of amounts for lines + * @return int <0 if KO, >0 if OK + */ + function createFromCurrent($user,$invertdetail=0) + { + // Charge facture source + $facture=new Facture($this->db); - $facture->fk_facture_source = $this->fk_facture_source; - $facture->type = $this->type; - $facture->socid = $this->socid; - $facture->date = $this->date; - $facture->note_public = $this->note_public; - $facture->note_private = $this->note_private; - $facture->ref_client = $this->ref_client; - $facture->modelpdf = $this->modelpdf; - $facture->fk_project = $this->fk_project; - $facture->cond_reglement_id = $this->cond_reglement_id; - $facture->mode_reglement_id = $this->mode_reglement_id; - $facture->remise_absolue = $this->remise_absolue; - $facture->remise_percent = $this->remise_percent; + $facture->fk_facture_source = $this->fk_facture_source; + $facture->type = $this->type; + $facture->socid = $this->socid; + $facture->date = $this->date; + $facture->note_public = $this->note_public; + $facture->note_private = $this->note_private; + $facture->ref_client = $this->ref_client; + $facture->modelpdf = $this->modelpdf; + $facture->fk_project = $this->fk_project; + $facture->cond_reglement_id = $this->cond_reglement_id; + $facture->mode_reglement_id = $this->mode_reglement_id; + $facture->remise_absolue = $this->remise_absolue; + $facture->remise_percent = $this->remise_percent; - $facture->lines = $this->lines; // Tableau des lignes de factures - $facture->products = $this->lines; // Tant que products encore utilise + $facture->lines = $this->lines; // Tableau des lignes de factures + $facture->products = $this->lines; // Tant que products encore utilise - // Loop on each line of new invoice - foreach($facture->lines as $i => $line) - { - if ($invertdetail) - { - $facture->lines[$i]->subprice = -$facture->lines[$i]->subprice; - $facture->lines[$i]->total_ht = -$facture->lines[$i]->total_ht; - $facture->lines[$i]->total_tva = -$facture->lines[$i]->total_tva; - $facture->lines[$i]->total_localtax1 = -$facture->lines[$i]->total_localtax1; - $facture->lines[$i]->total_localtax2 = -$facture->lines[$i]->total_localtax2; - $facture->lines[$i]->total_ttc = -$facture->lines[$i]->total_ttc; - } - } + // Loop on each line of new invoice + foreach($facture->lines as $i => $line) + { + if ($invertdetail) + { + $facture->lines[$i]->subprice = -$facture->lines[$i]->subprice; + $facture->lines[$i]->total_ht = -$facture->lines[$i]->total_ht; + $facture->lines[$i]->total_tva = -$facture->lines[$i]->total_tva; + $facture->lines[$i]->total_localtax1 = -$facture->lines[$i]->total_localtax1; + $facture->lines[$i]->total_localtax2 = -$facture->lines[$i]->total_localtax2; + $facture->lines[$i]->total_ttc = -$facture->lines[$i]->total_ttc; + } + } - dol_syslog(get_class($this)."::createFromCurrent invertdetail=".$invertdetail." socid=".$this->socid." nboflines=".count($facture->lines)); + dol_syslog(get_class($this)."::createFromCurrent invertdetail=".$invertdetail." socid=".$this->socid." nboflines=".count($facture->lines)); - $facid = $facture->create($user); - if ($facid <= 0) - { - $this->error=$facture->error; - $this->errors=$facture->errors; - } + $facid = $facture->create($user); + if ($facid <= 0) + { + $this->error=$facture->error; + $this->errors=$facture->errors; + } - return $facid; - } + return $facid; + } - /** - * Load an object from its id and create a new one in database - * - * @param int $socid Id of thirdparty - * @return int New id of clone - */ - function createFromClone($socid=0) - { - global $conf,$user,$langs; + /** + * Load an object from its id and create a new one in database + * + * @param int $socid Id of thirdparty + * @return int New id of clone + */ + function createFromClone($socid=0) + { + global $conf,$user,$langs; - $error=0; + $error=0; - $this->db->begin(); + $this->db->begin(); - // Load source object - $objFrom = dol_clone($this); + // Load source object + $objFrom = dol_clone($this); - // Change socid if needed - if (! empty($socid) && $socid != $this->socid) - { - $objsoc = new Societe($this->db); + // Change socid if needed + if (! empty($socid) && $socid != $this->socid) + { + $objsoc = new Societe($this->db); - if ($objsoc->fetch($socid)>0) - { - $this->socid = $objsoc->id; - $this->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); - $this->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); - $this->fk_project = ''; - $this->fk_delivery_address = ''; - } + if ($objsoc->fetch($socid)>0) + { + $this->socid = $objsoc->id; + $this->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); + $this->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); + $this->fk_project = ''; + $this->fk_delivery_address = ''; + } - // TODO Change product price if multi-prices - } + // TODO Change product price if multi-prices + } - $this->id=0; - $this->statut=0; + $this->id=0; + $this->statut=0; - // Clear fields - $this->user_author = $user->id; - $this->user_valid = ''; - $this->fk_facture_source = 0; - $this->date_creation = ''; - $this->date_validation = ''; - $this->ref_client = ''; - $this->close_code = ''; - $this->close_note = ''; - $this->products = $this->lines; // Tant que products encore utilise + // Clear fields + $this->user_author = $user->id; + $this->user_valid = ''; + $this->fk_facture_source = 0; + $this->date_creation = ''; + $this->date_validation = ''; + $this->ref_client = ''; + $this->close_code = ''; + $this->close_note = ''; + $this->products = $this->lines; // Tant que products encore utilise - // Loop on each line of new invoice - foreach($this->lines as $i => $line) - { - if (($this->lines[$i]->info_bits & 0x02) == 0x02) // We do not clone line of discounts - { - unset($this->lines[$i]); - unset($this->products[$i]); // Tant que products encore utilise - } - } + // Loop on each line of new invoice + foreach($this->lines as $i => $line) + { + if (($this->lines[$i]->info_bits & 0x02) == 0x02) // We do not clone line of discounts + { + unset($this->lines[$i]); + unset($this->products[$i]); // Tant que products encore utilise + } + } - // Create clone - $result=$this->create($user); - if ($result < 0) $error++; + // Create clone + $result=$this->create($user); + if ($result < 0) $error++; - if (! $error) - { - // Hook of thirdparty module + if (! $error) + { + // Hook of thirdparty module if (is_object($hookmanager)) { - $parameters=array('objFrom'=>$objFrom); - $action=''; + $parameters=array('objFrom'=>$objFrom); + $action=''; $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) $error++; } - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_CLONE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - - // End - if (! $error) - { - $this->db->commit(); - return $this->id; - } - else - { - $this->db->rollback(); - return -1; - } - } - - /** - * Load an object from an order and create a new invoice into database - * - * @param Object $object Object source - * @return int <0 if KO, 0 if nothing done, 1 if OK - */ - function createFromOrder($object) - { - global $conf,$user,$langs,$hookmanager; - - $error=0; - - // Closed order - $this->date = dol_now(); - $this->source = 0; - - $num=count($object->lines); - for ($i = 0; $i < $num; $i++) - { - $line = new FactureLigne($this->db); - - $line->libelle = $object->lines[$i]->libelle; - $line->label = $object->lines[$i]->label; - $line->desc = $object->lines[$i]->desc; - $line->subprice = $object->lines[$i]->subprice; - $line->total_ht = $object->lines[$i]->total_ht; - $line->total_tva = $object->lines[$i]->total_tva; - $line->total_ttc = $object->lines[$i]->total_ttc; - $line->tva_tx = $object->lines[$i]->tva_tx; - $line->localtax1_tx = $object->lines[$i]->localtax1_tx; - $line->localtax2_tx = $object->lines[$i]->localtax2_tx; - $line->qty = $object->lines[$i]->qty; - $line->fk_remise_except = $object->lines[$i]->fk_remise_except; - $line->remise_percent = $object->lines[$i]->remise_percent; - $line->fk_product = $object->lines[$i]->fk_product; - $line->info_bits = $object->lines[$i]->info_bits; - $line->product_type = $object->lines[$i]->product_type; - $line->rang = $object->lines[$i]->rang; - $line->special_code = $object->lines[$i]->special_code; - $line->fk_parent_line = $object->lines[$i]->fk_parent_line; - - $this->lines[$i] = $line; - } - - $this->socid = $object->socid; - $this->fk_project = $object->fk_project; - $this->cond_reglement_id = $object->cond_reglement_id; - $this->mode_reglement_id = $object->mode_reglement_id; - $this->availability_id = $object->availability_id; - $this->demand_reason_id = $object->demand_reason_id; - $this->date_livraison = $object->date_livraison; - $this->fk_delivery_address = $object->fk_delivery_address; - $this->contact_id = $object->contactid; - $this->ref_client = $object->ref_client; - $this->note_private = $object->note_private; - $this->note_public = $object->note_public; - - $this->origin = $object->element; - $this->origin_id = $object->id; - - // Possibility to add external linked objects with hooks - $this->linked_objects[$this->origin] = $this->origin_id; - if (! empty($object->other_linked_objects) && is_array($object->other_linked_objects)) - { - $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects); - } - - $ret = $this->create($user); - - if ($ret > 0) - { - // Actions hooked (by external module) - $hookmanager->initHooks(array('invoicedao')); - - $parameters=array('objFrom'=>$object); - $action=''; - $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) $error++; - - if (! $error) - { - return 1; - } - else return -1; - } - else return -1; - } - - /** - * Return clicable link of object (with eventually picto) - * - * @param int $withpicto Add picto into link - * @param string $option Where point the link - * @param int $max Maxlength of ref - * @param int $short 1=Return just URL - * @param string $moretitle Add more text to title tooltip - * @return string String with URL - */ - function getNomUrl($withpicto=0,$option='',$max=0,$short=0,$moretitle='') - { - global $langs; - - $result=''; - - if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id; - else $url = DOL_URL_ROOT.'/compta/facture.php?facid='.$this->id; - - if ($short) return $url; - - $picto='bill'; - if ($this->type == 1) $picto.='r'; // Replacement invoice - if ($this->type == 2) $picto.='a'; // Credit note - if ($this->type == 3) $picto.='d'; // Deposit invoice - - $label=$langs->trans("ShowInvoice").': '.$this->ref; - if ($this->type == 1) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref; - if ($this->type == 2) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref; - if ($this->type == 3) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref; - if ($moretitle) $label.=' - '.$moretitle; - - //$linkstart=''; - $linkstart=''; - $linkend=''; - - if ($withpicto) $result.=($linkstart.img_object(($max?dol_trunc($label,$max):$label),$picto).$linkend); - if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$linkstart.($max?dol_trunc($this->ref,$max):$this->ref).$linkend; - return $result; - } - - - /** - * Get object and lines from database - * - * @param int $rowid Id of object to load - * @param string $ref Reference of invoice - * @param string $ref_ext External reference of invoice - * @param int $ref_int Internal reference of other object - * @return int >0 if OK, <0 if KO, 0 if not found - */ - function fetch($rowid, $ref='', $ref_ext='', $ref_int='') - { - global $conf; - - if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1; - - $sql = 'SELECT f.rowid,f.facnumber,f.ref_client,f.ref_ext,f.ref_int,f.type,f.fk_soc,f.amount,f.tva, f.localtax1, f.localtax2, f.total, f.total_ttc, f.revenuestamp'; - $sql.= ', f.remise_percent, f.remise_absolue, f.remise'; - $sql.= ', f.datef as df'; - $sql.= ', f.date_lim_reglement as dlr'; - $sql.= ', f.datec as datec'; - $sql.= ', f.date_valid as datev'; - $sql.= ', f.tms as datem'; - $sql.= ', f.note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.model_pdf'; - $sql.= ', f.fk_facture_source'; - $sql.= ', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet, f.extraparams'; - $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; - $sql.= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id'; - $sql.= ' WHERE f.entity = '.$conf->entity; - if ($rowid) $sql.= " AND f.rowid=".$rowid; - if ($ref) $sql.= " AND f.facnumber='".$this->db->escape($ref)."'"; - if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'"; - if ($ref_int) $sql.= " AND f.ref_int='".$this->db->escape($ref_int)."'"; - - dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - if ($this->db->num_rows($result)) - { - $obj = $this->db->fetch_object($result); - - $this->id = $obj->rowid; - $this->ref = $obj->facnumber; - $this->ref_client = $obj->ref_client; - $this->ref_ext = $obj->ref_ext; - $this->ref_int = $obj->ref_int; - $this->type = $obj->type; - $this->date = $this->db->jdate($obj->df); - $this->date_creation = $this->db->jdate($obj->datec); - $this->date_validation = $this->db->jdate($obj->datev); - $this->datem = $this->db->jdate($obj->datem); - $this->remise_percent = $obj->remise_percent; - $this->remise_absolue = $obj->remise_absolue; - //$this->remise = $obj->remise; - $this->total_ht = $obj->total; - $this->total_tva = $obj->tva; - $this->total_localtax1 = $obj->localtax1; - $this->total_localtax2 = $obj->localtax2; - $this->total_ttc = $obj->total_ttc; - $this->revenuestamp = $obj->revenuestamp; - $this->paye = $obj->paye; - $this->close_code = $obj->close_code; - $this->close_note = $obj->close_note; - $this->socid = $obj->fk_soc; - $this->statut = $obj->fk_statut; - $this->date_lim_reglement = $this->db->jdate($obj->dlr); - $this->mode_reglement_id = $obj->fk_mode_reglement; - $this->mode_reglement_code = $obj->mode_reglement_code; - $this->mode_reglement = $obj->mode_reglement_libelle; - $this->cond_reglement_id = $obj->fk_cond_reglement; - $this->cond_reglement_code = $obj->cond_reglement_code; - $this->cond_reglement = $obj->cond_reglement_libelle; - $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; - $this->fk_project = $obj->fk_projet; - $this->fk_facture_source = $obj->fk_facture_source; - $this->note = $obj->note_private; // deprecated - $this->note_private = $obj->note_private; - $this->note_public = $obj->note_public; - $this->user_author = $obj->fk_user_author; - $this->user_valid = $obj->fk_user_valid; - $this->modelpdf = $obj->model_pdf; - - $this->extraparams = (array) json_decode($obj->extraparams, true); - - if ($this->statut == 0) $this->brouillon = 1; - - // Retreive all extrafield for invoice - // fetch optionals attributes and labels - if(!class_exists('Extrafields')) - require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); - $extrafields=new ExtraFields($this->db); - $extralabels=$extrafields->fetch_name_optionals_label('facture',true); - if (count($extralabels)>0) { - $this->array_options = array(); - } - foreach($extrafields->attribute_label as $key=>$label) - { - $this->array_options['options_'.$key]=$label; - } - - /* - * Lines - */ - - $this->lines = array(); - - $result=$this->fetch_lines(); - if ($result < 0) - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); - return -3; - } - return 1; - } - else - { - $this->error='Bill with id '.$rowid.' or ref '.$ref.' not found sql='.$sql; - dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); - return 0; - } - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); - return -1; - } - } - - - /** - * Load all detailed lines into this->lines - * - * @return int 1 if OK, < 0 if KO - */ - function fetch_lines() - { - $this->lines=array(); - - $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.tva_tx, '; - $sql.= ' l.localtax1_tx, l.localtax2_tx, l.remise, l.remise_percent, l.fk_remise_except, l.subprice,'; - $sql.= ' l.rang, l.special_code,'; - $sql.= ' l.date_start as date_start, l.date_end as date_end,'; - $sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,'; - $sql.= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; - $sql.= ' WHERE l.fk_facture = '.$this->id; - $sql.= ' ORDER BY l.rang'; - - dol_syslog(get_class($this).'::fetch_lines sql='.$sql, LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; - while ($i < $num) - { - $objp = $this->db->fetch_object($result); - $line = new FactureLigne($this->db); - - $line->rowid = $objp->rowid; - $line->label = $objp->custom_label; - $line->desc = $objp->description; // Description line - $line->product_type = $objp->product_type; // Type of line - $line->product_ref = $objp->product_ref; // Ref product - $line->libelle = $objp->product_label; // TODO deprecated - $line->product_label = $objp->product_label; // Label product - $line->product_desc = $objp->product_desc; // Description product - $line->fk_product_type = $objp->fk_product_type; // Type of product - $line->qty = $objp->qty; - $line->subprice = $objp->subprice; - $line->tva_tx = $objp->tva_tx; - $line->localtax1_tx = $objp->localtax1_tx; - $line->localtax2_tx = $objp->localtax2_tx; - $line->remise_percent = $objp->remise_percent; - $line->fk_remise_except = $objp->fk_remise_except; - $line->fk_product = $objp->fk_product; - $line->date_start = $this->db->jdate($objp->date_start); - $line->date_end = $this->db->jdate($objp->date_end); - $line->date_start = $this->db->jdate($objp->date_start); - $line->date_end = $this->db->jdate($objp->date_end); - $line->info_bits = $objp->info_bits; - $line->total_ht = $objp->total_ht; - $line->total_tva = $objp->total_tva; - $line->total_localtax1 = $objp->total_localtax1; - $line->total_localtax2 = $objp->total_localtax2; - $line->total_ttc = $objp->total_ttc; - $line->code_ventilation = $objp->fk_code_ventilation; - $line->fk_fournprice = $objp->fk_fournprice; - $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht); - $line->pa_ht = $marginInfos[0]; - $line->marge_tx = $marginInfos[1]; - $line->marque_tx = $marginInfos[2]; - $line->rang = $objp->rang; - $line->special_code = $objp->special_code; - $line->fk_parent_line = $objp->fk_parent_line; - - // Ne plus utiliser - //$line->price = $objp->price; - //$line->remise = $objp->remise; - - $this->lines[$i] = $line; - - $i++; - } - $this->db->free($result); - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this).'::fetch_lines '.$this->error,LOG_ERR); - return -3; - } - } - - - /** - * Update database - * - * @param User $user User that modify - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <0 if KO, >0 if OK - */ - function update($user=0, $notrigger=0) - { - global $conf, $langs; - $error=0; - - // Clean parameters - if (empty($this->type)) $this->type=0; - if (isset($this->facnumber)) $this->facnumber=trim($this->ref); - if (isset($this->ref_client)) $this->ref_client=trim($this->ref_client); - if (isset($this->increment)) $this->increment=trim($this->increment); - if (isset($this->close_code)) $this->close_code=trim($this->close_code); - if (isset($this->close_note)) $this->close_note=trim($this->close_note); - if (isset($this->note) || isset($this->note_private)) $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated - if (isset($this->note) || isset($this->note_private)) $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note)); - if (isset($this->note_public)) $this->note_public=trim($this->note_public); - if (isset($this->modelpdf)) $this->modelpdf=trim($this->modelpdf); - if (isset($this->import_key)) $this->import_key=trim($this->import_key); - - // Check parameters - // Put here code to add control on parameters values - - // Update request - $sql = "UPDATE ".MAIN_DB_PREFIX."facture SET"; - - $sql.= " facnumber=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").","; - $sql.= " type=".(isset($this->type)?$this->type:"null").","; - $sql.= " ref_client=".(isset($this->ref_client)?"'".$this->db->escape($this->ref_client)."'":"null").","; - $sql.= " increment=".(isset($this->increment)?"'".$this->db->escape($this->increment)."'":"null").","; - $sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").","; - $sql.= " datec=".(strval($this->date_creation)!='' ? "'".$this->db->idate($this->date_creation)."'" : 'null').","; - $sql.= " datef=".(strval($this->date)!='' ? "'".$this->db->idate($this->date)."'" : 'null').","; - $sql.= " date_valid=".(strval($this->date_validation)!='' ? "'".$this->db->idate($this->date_validation)."'" : 'null').","; - $sql.= " paye=".(isset($this->paye)?$this->paye:"null").","; - $sql.= " remise_percent=".(isset($this->remise_percent)?$this->remise_percent:"null").","; - $sql.= " remise_absolue=".(isset($this->remise_absolue)?$this->remise_absolue:"null").","; - //$sql.= " remise=".(isset($this->remise)?$this->remise:"null").","; - $sql.= " close_code=".(isset($this->close_code)?"'".$this->db->escape($this->close_code)."'":"null").","; - $sql.= " close_note=".(isset($this->close_note)?"'".$this->db->escape($this->close_note)."'":"null").","; - $sql.= " tva=".(isset($this->total_tva)?$this->total_tva:"null").","; - $sql.= " localtax1=".(isset($this->total_localtax1)?$this->total_localtax1:"null").","; - $sql.= " localtax2=".(isset($this->total_localtax2)?$this->total_localtax2:"null").","; - $sql.= " total=".(isset($this->total_ht)?$this->total_ht:"null").","; - $sql.= " total_ttc=".(isset($this->total_ttc)?$this->total_ttc:"null").","; - $sql.= " revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp != '')?$this->revenuestamp:"null").","; - $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").","; - $sql.= " fk_user_author=".(isset($this->user_author)?$this->user_author:"null").","; - $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").","; - $sql.= " fk_facture_source=".(isset($this->fk_facture_source)?$this->fk_facture_source:"null").","; - $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").","; - $sql.= " fk_cond_reglement=".(isset($this->cond_reglement_id)?$this->cond_reglement_id:"null").","; - $sql.= " fk_mode_reglement=".(isset($this->mode_reglement_id)?$this->mode_reglement_id:"null").","; - $sql.= " date_lim_reglement=".(strval($this->date_lim_reglement)!='' ? "'".$this->db->idate($this->date_lim_reglement)."'" : 'null').","; - $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; - $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").","; - $sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").","; - $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null").""; - - $sql.= " WHERE rowid=".$this->id; - - $this->db->begin(); - - dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } - - if (! $error) - { - if (! $notrigger) - { - // Call triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_MODIFY',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // End call triggers - } - } - - // Commit or rollback - if ($error) - { - foreach($this->errors as $errmsg) - { - dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); - $this->error.=($this->error?', '.$errmsg:$errmsg); - } - $this->db->rollback(); - return -1*$error; - } - else - { - $this->db->commit(); - return 1; - } - } - - - /** - * Add a discount line into invoice using an existing absolute discount - * - * @param int $idremise Id of absolute discount - * @return int >0 if OK, <0 if KO - */ - function insert_discount($idremise) - { - global $langs; - - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - - $this->db->begin(); - - $remise=new DiscountAbsolute($this->db); - $result=$remise->fetch($idremise); - - if ($result > 0) - { - if ($remise->fk_facture) // Protection against multiple submission - { - $this->error=$langs->trans("ErrorDiscountAlreadyUsed"); - $this->db->rollback(); - return -5; - } - - $facligne=new FactureLigne($this->db); - $facligne->fk_facture=$this->id; - $facligne->fk_remise_except=$remise->id; - $facligne->desc=$remise->description; // Description ligne - $facligne->tva_tx=$remise->tva_tx; - $facligne->subprice=-$remise->amount_ht; - $facligne->fk_product=0; // Id produit predefini - $facligne->qty=1; - $facligne->remise_percent=0; - $facligne->rang=-1; - $facligne->info_bits=2; - - $facligne->total_ht = -$remise->amount_ht; - $facligne->total_tva = -$remise->amount_tva; - $facligne->total_ttc = -$remise->amount_ttc; - - $lineid=$facligne->insert(); - if ($lineid > 0) - { - $result=$this->update_price(1); - if ($result > 0) - { - // Create linke between discount and invoice line - $result=$remise->link_to_invoice($lineid,0); - if ($result < 0) - { - $this->error=$remise->error; - $this->db->rollback(); - return -4; - } - - $this->db->commit(); - return 1; - } - else - { - $this->error=$facligne->error; - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$facligne->error; - $this->db->rollback(); - return -2; - } - } - else - { - $this->db->rollback(); - return -3; - } - } - - /** - * Set customer ref - * - * @param string $ref_client Customer ref - * @return int <0 if KO, >0 if OK - */ - function set_ref_client($ref_client) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; - if (empty($ref_client)) - $sql .= ' SET ref_client = NULL'; - else - $sql .= ' SET ref_client = \''.$this->db->escape($ref_client).'\''; - $sql .= ' WHERE rowid = '.$this->id; - if ($this->db->query($sql)) - { - $this->ref_client = $ref_client; - return 1; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - /** - * Delete invoice - * - * @param int $rowid Id of invoice to delete. If empty, we delete current instance of invoice - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function delete($rowid=0, $notrigger=0) - { - global $user,$langs,$conf; - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - if (! $rowid) $rowid=$this->id; - - dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG); - - // TODO Test if there is at least on payment. If yes, refuse to delete. - - $error=0; - $this->db->begin(); - - if (! $error && ! $notrigger) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_DELETE',$this,$user,$langs,$conf); - if ($result < 0) { - $error++; $this->errors=$interface->errors; - } - // Fin appel triggers - } - - if (! $error) - { - // Delete linked object - $res = $this->deleteObjectLinked(); - if ($res < 0) $error++; - } - - if (! $error) - { - // If invoice was converted into a discount not yet consumed, we remove discount - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql.= ' WHERE fk_facture_source = '.$rowid; - $sql.= ' AND fk_facture_line IS NULL'; - $resql=$this->db->query($sql); - - // If invoice has consumned discounts - $this->fetch_lines(); - $list_rowid_det=array(); - foreach($this->lines as $key => $invoiceline) - { - $list_rowid_det[]=$invoiceline->rowid; - } - - // Consumned discounts are freed - if (count($list_rowid_det)) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql.= ' SET fk_facture = NULL, fk_facture_line = NULL'; - $sql.= ' WHERE fk_facture_line IN ('.join(',',$list_rowid_det).')'; - - dol_syslog(get_class($this)."::delete sql=".$sql); - if (! $this->db->query($sql)) - { - $this->error=$this->db->error()." sql=".$sql; - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - $this->db->rollback(); - return -5; - } - } - - // Delete invoice line - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid; - if ($this->db->query($sql) && $this->delete_linked_contact()) - { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid; - $resql=$this->db->query($sql); - if ($resql) - { - // On efface le repertoire de pdf provisoire - $ref = dol_sanitizeFileName($this->ref); - if ($conf->facture->dir_output) - { - $dir = $conf->facture->dir_output . "/" . $ref; - $file = $conf->facture->dir_output . "/" . $ref . "/" . $ref . ".pdf"; - if (file_exists($file)) // We must delete all files before deleting directory - { - $ret=dol_delete_preview($this); - - if (! dol_delete_file($file,0,0,0,$this)) // For triggers - { - $this->error=$langs->trans("ErrorCanNotDeleteFile",$file); - $this->db->rollback(); - return 0; - } - } - if (file_exists($dir)) - { - if (! dol_delete_dir_recursive($dir)) // For remove dir and meta - { - $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir); - $this->db->rollback(); - return 0; - } - } - } - - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->lasterror()." sql=".$sql; - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - $this->db->rollback(); - return -6; - } - } - else - { - $this->error=$this->db->lasterror()." sql=".$sql; - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - $this->db->rollback(); - return -4; - } - } - else - { - $this->error=$this->db->lasterror(); - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } - - - /** - * Renvoi une date limite de reglement de facture en fonction des - * conditions de reglements de la facture et date de facturation - * - * @param string $cond_reglement Condition of payment (code or id) to use. If 0, we use current condition. - * @return date Date limite de reglement si ok, <0 si ko - */ - function calculate_date_lim_reglement($cond_reglement=0) - { - if (! $cond_reglement) $cond_reglement=$this->cond_reglement_code; - if (! $cond_reglement) $cond_reglement=$this->cond_reglement_id; - - $cdr_nbjour=0; $cdr_fdm=0; $cdr_decalage=0; - - $sqltemp = 'SELECT c.fdm,c.nbjour,c.decalage'; - $sqltemp.= ' FROM '.MAIN_DB_PREFIX.'c_payment_term as c'; - if (is_numeric($cond_reglement)) $sqltemp.= " WHERE c.rowid=".$cond_reglement; - else $sqltemp.= " WHERE c.code='".$this->db->escape($cond_reglement)."'"; - - dol_syslog(get_class($this).'::calculate_date_lim_reglement sql='.$sqltemp); - $resqltemp=$this->db->query($sqltemp); - if ($resqltemp) - { - if ($this->db->num_rows($resqltemp)) - { - $obj = $this->db->fetch_object($resqltemp); - $cdr_nbjour = $obj->nbjour; - $cdr_fdm = $obj->fdm; - $cdr_decalage = $obj->decalage; - } - } - else - { - $this->error=$this->db->error(); - return -1; - } - $this->db->free($resqltemp); - - /* Definition de la date limite */ - - // 1 : ajout du nombre de jours - $datelim = $this->date + ($cdr_nbjour * 3600 * 24); - - // 2 : application de la regle "fin de mois" - if ($cdr_fdm) - { - $mois=date('m', $datelim); - $annee=date('Y', $datelim); - if ($mois == 12) - { - $mois = 1; - $annee += 1; - } - else - { - $mois += 1; - } - // On se deplace au debut du mois suivant, et on retire un jour - $datelim=dol_mktime(12,0,0,$mois,1,$annee); - $datelim -= (3600 * 24); - } - - // 3 : application du decalage - $datelim += ($cdr_decalage * 3600 * 24); - - return $datelim; - } - - /** - * Tag la facture comme paye completement (close_code non renseigne) ou partiellement (close_code renseigne) + appel trigger BILL_PAYED - * - * @param User $user Objet utilisateur qui modifie - * @param string $close_code Code renseigne si on classe a payee completement alors que paiement incomplet (cas escompte par exemple) - * @param string $close_note Commentaire renseigne si on classe a payee alors que paiement incomplet (cas escompte par exemple) - * @return int <0 if KO, >0 if OK - */ - function set_paid($user,$close_code='',$close_note='') - { - global $conf,$langs; - $error=0; - - if ($this->paye != 1) - { - $this->db->begin(); - - dol_syslog(get_class($this)."::set_paid rowid=".$this->id, LOG_DEBUG); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET'; - $sql.= ' fk_statut=2'; - if (! $close_code) $sql.= ', paye=1'; - if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'"; - if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'"; - $sql.= ' WHERE rowid = '.$this->id; - - $resql = $this->db->query($sql); - if ($resql) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_PAYED',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - else - { - $error++; - $this->error=$this->db->error(); - dol_print_error($this->db); - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - return 0; - } - } - - - /** - * Tag la facture comme non payee completement + appel trigger BILL_UNPAYED - * Fonction utilisee quand un paiement prelevement est refuse, - * ou quand une facture annulee et reouverte. - * - * @param User $user Object user that change status - * @return int <0 if KO, >0 if OK - */ - function set_unpaid($user) - { - global $conf,$langs; - $error=0; - - $this->db->begin(); - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; - $sql.= ' SET paye=0, fk_statut=1, close_code=null, close_note=null'; - $sql.= ' WHERE rowid = '.$this->id; - - dol_syslog(get_class($this)."::set_unpaid sql=".$sql); - $resql = $this->db->query($sql); - if ($resql) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_UNPAYED',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - else - { - $error++; - $this->error=$this->db->error(); - dol_print_error($this->db); - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - - - /** - * Tag invoice as canceled, with no payment on it (example for replacement invoice or payment never received) + call trigger BILL_CANCEL - * Warning, if option to decrease stock on invoice was set, this function does not change stock (it might be a cancel because - * of no payment even if merchandises were sent). - * - * @param User $user Object user making change - * @param string $close_code Code de fermeture - * @param string $close_note Comment - * @return int <0 if KO, >0 if OK - */ - function set_canceled($user,$close_code='',$close_note='') - { - global $conf,$langs; + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_CLONE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + + // End + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Load an object from an order and create a new invoice into database + * + * @param Object $object Object source + * @return int <0 if KO, 0 if nothing done, 1 if OK + */ + function createFromOrder($object) + { + global $conf,$user,$langs,$hookmanager; $error=0; - dol_syslog(get_class($this)."::set_canceled rowid=".$this->id, LOG_DEBUG); + // Closed order + $this->date = dol_now(); + $this->source = 0; - $this->db->begin(); + $num=count($object->lines); + for ($i = 0; $i < $num; $i++) + { + $line = new FactureLigne($this->db); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET'; - $sql.= ' fk_statut=3'; - if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'"; - if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'"; - $sql.= ' WHERE rowid = '.$this->id; + $line->libelle = $object->lines[$i]->libelle; + $line->label = $object->lines[$i]->label; + $line->desc = $object->lines[$i]->desc; + $line->subprice = $object->lines[$i]->subprice; + $line->total_ht = $object->lines[$i]->total_ht; + $line->total_tva = $object->lines[$i]->total_tva; + $line->total_ttc = $object->lines[$i]->total_ttc; + $line->tva_tx = $object->lines[$i]->tva_tx; + $line->localtax1_tx = $object->lines[$i]->localtax1_tx; + $line->localtax2_tx = $object->lines[$i]->localtax2_tx; + $line->qty = $object->lines[$i]->qty; + $line->fk_remise_except = $object->lines[$i]->fk_remise_except; + $line->remise_percent = $object->lines[$i]->remise_percent; + $line->fk_product = $object->lines[$i]->fk_product; + $line->info_bits = $object->lines[$i]->info_bits; + $line->product_type = $object->lines[$i]->product_type; + $line->rang = $object->lines[$i]->rang; + $line->special_code = $object->lines[$i]->special_code; + $line->fk_parent_line = $object->lines[$i]->fk_parent_line; - $resql = $this->db->query($sql); - if ($resql) - { - // On desaffecte de la facture les remises liees - // car elles n'ont pas ete utilisees vu que la facture est abandonnee. - $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql.= ' SET fk_facture = NULL'; - $sql.= ' WHERE fk_facture = '.$this->id; + $this->lines[$i] = $line; + } - $resql=$this->db->query($sql); - if ($resql) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_CANCEL',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers + $this->socid = $object->socid; + $this->fk_project = $object->fk_project; + $this->cond_reglement_id = $object->cond_reglement_id; + $this->mode_reglement_id = $object->mode_reglement_id; + $this->availability_id = $object->availability_id; + $this->demand_reason_id = $object->demand_reason_id; + $this->date_livraison = $object->date_livraison; + $this->fk_delivery_address = $object->fk_delivery_address; + $this->contact_id = $object->contactid; + $this->ref_client = $object->ref_client; + $this->note_private = $object->note_private; + $this->note_public = $object->note_public; - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error()." sql=".$sql; - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->db->error()." sql=".$sql; - $this->db->rollback(); - return -2; - } - } + $this->origin = $object->element; + $this->origin_id = $object->id; - /** - * Tag invoice as validated + call trigger BILL_VALIDATE - * Object must have lines loaded with fetch_lines - * - * @param User $user Object user that validate - * @param string $force_number Reference to force on invoice - * @param int $idwarehouse Id of warehouse to use for stock decrease - * @return int <0 if KO, >0 if OK - */ - function validate($user, $force_number='', $idwarehouse=0) - { - global $conf,$langs; - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + // Possibility to add external linked objects with hooks + $this->linked_objects[$this->origin] = $this->origin_id; + if (! empty($object->other_linked_objects) && is_array($object->other_linked_objects)) + { + $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects); + } - $now=dol_now(); + $ret = $this->create($user); - $error=0; - dol_syslog(get_class($this).'::validate user='.$user->id.', force_number='.$force_number.', idwarehouse='.$idwarehouse); + if ($ret > 0) + { + // Actions hooked (by external module) + $hookmanager->initHooks(array('invoicedao')); - // Check parameters - if (! $this->brouillon) - { - dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING); - return 0; - } + $parameters=array('objFrom'=>$object); + $action=''; + $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) $error++; - if (! $user->rights->facture->valider) - { - $this->error='Permission denied'; - dol_syslog(get_class($this)."::validate ".$this->error, LOG_ERR); - return -1; - } + if (! $error) + { + return 1; + } + else return -1; + } + else return -1; + } - $this->db->begin(); + /** + * Return clicable link of object (with eventually picto) + * + * @param int $withpicto Add picto into link + * @param string $option Where point the link + * @param int $max Maxlength of ref + * @param int $short 1=Return just URL + * @param string $moretitle Add more text to title tooltip + * @return string String with URL + */ + function getNomUrl($withpicto=0,$option='',$max=0,$short=0,$moretitle='') + { + global $langs; - $this->fetch_thirdparty(); - $this->fetch_lines(); + $result=''; - // Check parameters - if ($this->type == 1) // si facture de remplacement - { - // Controle que facture source connue - if ($this->fk_facture_source <= 0) - { - $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("InvoiceReplacement")); - $this->db->rollback(); - return -10; - } + if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id; + else $url = DOL_URL_ROOT.'/compta/facture.php?facid='.$this->id; - // Charge la facture source a remplacer - $facreplaced=new Facture($this->db); - $result=$facreplaced->fetch($this->fk_facture_source); - if ($result <= 0) - { - $this->error=$langs->trans("ErrorBadInvoice"); - $this->db->rollback(); - return -11; - } + if ($short) return $url; - // Controle que facture source non deja remplacee par une autre - $idreplacement=$facreplaced->getIdReplacingInvoice('validated'); - if ($idreplacement && $idreplacement != $this->id) - { - $facreplacement=new Facture($this->db); - $facreplacement->fetch($idreplacement); - $this->error=$langs->trans("ErrorInvoiceAlreadyReplaced",$facreplaced->ref,$facreplacement->ref); - $this->db->rollback(); - return -12; - } + $picto='bill'; + if ($this->type == 1) $picto.='r'; // Replacement invoice + if ($this->type == 2) $picto.='a'; // Credit note + if ($this->type == 3) $picto.='d'; // Deposit invoice - $result=$facreplaced->set_canceled($user,'replaced',''); - if ($result < 0) - { - $this->error=$facreplaced->error; - $this->db->rollback(); - return -13; - } - } + $label=$langs->trans("ShowInvoice").': '.$this->ref; + if ($this->type == 1) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref; + if ($this->type == 2) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref; + if ($this->type == 3) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref; + if ($moretitle) $label.=' - '.$moretitle; - // Define new ref - if ($force_number) - { - $num = $force_number; - } - else if (preg_match('/^[\(]?PROV/i', $this->ref)) - { - if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date - { - $this->date=dol_now(); - $this->date_lim_reglement=$this->calculate_date_lim_reglement(); - } - $num = $this->getNextNumRef($this->client); - } - else - { - $num = $this->ref; - } + //$linkstart=''; + $linkstart=''; + $linkend=''; - if ($num) - { - $this->update_price(1); + if ($withpicto) $result.=($linkstart.img_object(($max?dol_trunc($label,$max):$label),$picto).$linkend); + if ($withpicto && $withpicto != 2) $result.=' '; + if ($withpicto != 2) $result.=$linkstart.($max?dol_trunc($this->ref,$max):$this->ref).$linkend; + return $result; + } - // Validate - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; - $sql.= " SET facnumber='".$num."', fk_statut = 1, fk_user_valid = ".$user->id.", date_valid = '".$this->db->idate($now)."'"; - if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date - { - $sql.= ', datef='.$this->db->idate($this->date); - $sql.= ', date_lim_reglement='.$this->db->idate($this->date_lim_reglement); - } - $sql.= ' WHERE rowid = '.$this->id; - dol_syslog(get_class($this)."::validate sql=".$sql); - $resql=$this->db->query($sql); - if (! $resql) - { - dol_syslog(get_class($this)."::validate Echec update - 10 - sql=".$sql, LOG_ERR); - dol_print_error($this->db); - $error++; - } + /** + * Get object and lines from database + * + * @param int $rowid Id of object to load + * @param string $ref Reference of invoice + * @param string $ref_ext External reference of invoice + * @param int $ref_int Internal reference of other object + * @return int >0 if OK, <0 if KO, 0 if not found + */ + function fetch($rowid, $ref='', $ref_ext='', $ref_int='') + { + global $conf; - // On verifie si la facture etait une provisoire - if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) - { - // La verif qu'une remise n'est pas utilisee 2 fois est faite au moment de l'insertion de ligne - } + if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1; - if (! $error) - { - // Define third party as a customer - $result=$this->client->set_as_client(); + $sql = 'SELECT f.rowid,f.facnumber,f.ref_client,f.ref_ext,f.ref_int,f.type,f.fk_soc,f.amount,f.tva, f.localtax1, f.localtax2, f.total, f.total_ttc, f.revenuestamp'; + $sql.= ', f.remise_percent, f.remise_absolue, f.remise'; + $sql.= ', f.datef as df'; + $sql.= ', f.date_lim_reglement as dlr'; + $sql.= ', f.datec as datec'; + $sql.= ', f.date_valid as datev'; + $sql.= ', f.tms as datem'; + $sql.= ', f.note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.model_pdf'; + $sql.= ', f.fk_facture_source'; + $sql.= ', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet, f.extraparams'; + $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; + $sql.= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id'; + $sql.= ' WHERE f.entity = '.$conf->entity; + if ($rowid) $sql.= " AND f.rowid=".$rowid; + if ($ref) $sql.= " AND f.facnumber='".$this->db->escape($ref)."'"; + if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'"; + if ($ref_int) $sql.= " AND f.ref_int='".$this->db->escape($ref_int)."'"; - // Si active on decremente le produit principal et ses composants a la validation de facture - if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL)) - { - require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; - $langs->load("agenda"); + dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); - // Loop on each line - $cpt=count($this->lines); - for ($i = 0; $i < $cpt; $i++) - { - if ($this->lines[$i]->fk_product > 0) - { - $mouvP = new MouvementStock($this->db); - // We decrease stock for product - if ($this->type == 2) $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num)); - else $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num)); - if ($result < 0) { $error++; } - } - } - } - } + $this->id = $obj->rowid; + $this->ref = $obj->facnumber; + $this->ref_client = $obj->ref_client; + $this->ref_ext = $obj->ref_ext; + $this->ref_int = $obj->ref_int; + $this->type = $obj->type; + $this->date = $this->db->jdate($obj->df); + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_validation = $this->db->jdate($obj->datev); + $this->datem = $this->db->jdate($obj->datem); + $this->remise_percent = $obj->remise_percent; + $this->remise_absolue = $obj->remise_absolue; + //$this->remise = $obj->remise; + $this->total_ht = $obj->total; + $this->total_tva = $obj->tva; + $this->total_localtax1 = $obj->localtax1; + $this->total_localtax2 = $obj->localtax2; + $this->total_ttc = $obj->total_ttc; + $this->revenuestamp = $obj->revenuestamp; + $this->paye = $obj->paye; + $this->close_code = $obj->close_code; + $this->close_note = $obj->close_note; + $this->socid = $obj->fk_soc; + $this->statut = $obj->fk_statut; + $this->date_lim_reglement = $this->db->jdate($obj->dlr); + $this->mode_reglement_id = $obj->fk_mode_reglement; + $this->mode_reglement_code = $obj->mode_reglement_code; + $this->mode_reglement = $obj->mode_reglement_libelle; + $this->cond_reglement_id = $obj->fk_cond_reglement; + $this->cond_reglement_code = $obj->cond_reglement_code; + $this->cond_reglement = $obj->cond_reglement_libelle; + $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; + $this->fk_project = $obj->fk_projet; + $this->fk_facture_source = $obj->fk_facture_source; + $this->note = $obj->note_private; // deprecated + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; + $this->user_author = $obj->fk_user_author; + $this->user_valid = $obj->fk_user_valid; + $this->modelpdf = $obj->model_pdf; - if (! $error) - { - $this->oldref = ''; + $this->extraparams = (array) json_decode($obj->extraparams, true); - // Rename directory if dir was a temporary ref - if (preg_match('/^[\(]?PROV/i', $this->ref)) - { - // On renomme repertoire facture ($this->ref = ancienne ref, $num = nouvelle ref) - // afin de ne pas perdre les fichiers attaches - $facref = dol_sanitizeFileName($this->ref); - $snumfa = dol_sanitizeFileName($num); - $dirsource = $conf->facture->dir_output.'/'.$facref; - $dirdest = $conf->facture->dir_output.'/'.$snumfa; - if (file_exists($dirsource)) - { - dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest); + if ($this->statut == 0) $this->brouillon = 1; - if (@rename($dirsource, $dirdest)) - { - $this->oldref = $facref; + // Retreive all extrafield for invoice + // fetch optionals attributes and labels + if(!class_exists('Extrafields')) + require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); + $extrafields=new ExtraFields($this->db); + $extralabels=$extrafields->fetch_name_optionals_label('facture',true); + if (count($extralabels)>0) { + $this->array_options = array(); + } + foreach($extrafields->attribute_label as $key=>$label) + { + $this->array_options['options_'.$key]=$label; + } - dol_syslog("Rename ok"); - // Suppression ancien fichier PDF dans nouveau rep - dol_delete_file($conf->facture->dir_output.'/'.$snumfa.'/'.$facref.'*.*'); - } - } - } - } + /* + * Lines + */ - // Set new ref and define current statut - if (! $error) - { - $this->ref = $num; - $this->facnumber=$num; - $this->statut=1; - $this->brouillon=0; - $this->date_validation=$now; - } + $this->lines = array(); - // Trigger calls - if (! $error) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_VALIDATE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - } - else - { - $error++; - } + $result=$this->fetch_lines(); + if ($result < 0) + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); + return -3; + } + return 1; + } + else + { + $this->error='Bill with id '.$rowid.' or ref '.$ref.' not found sql='.$sql; + dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); + return 0; + } + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); + return -1; + } + } - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - return -1; - } - } - /** - * Set draft status - * - * @param User $user Object user that modify - * @param int $idwarehouse Id warehouse to use for stock change. - * @return int <0 if KO, >0 if OK - */ - function set_draft($user,$idwarehouse=-1) - { - global $conf,$langs; + /** + * Load all detailed lines into this->lines + * + * @return int 1 if OK, < 0 if KO + */ + function fetch_lines() + { + $this->lines=array(); - $error=0; + $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.tva_tx, '; + $sql.= ' l.localtax1_tx, l.localtax2_tx, l.remise, l.remise_percent, l.fk_remise_except, l.subprice,'; + $sql.= ' l.rang, l.special_code,'; + $sql.= ' l.date_start as date_start, l.date_end as date_end,'; + $sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,'; + $sql.= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; + $sql.= ' WHERE l.fk_facture = '.$this->id; + $sql.= ' ORDER BY l.rang'; - if ($this->statut == 0) - { - dol_syslog(get_class($this)."::set_draft already draft status", LOG_WARNING); - return 0; - } + dol_syslog(get_class($this).'::fetch_lines sql='.$sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + while ($i < $num) + { + $objp = $this->db->fetch_object($result); + $line = new FactureLigne($this->db); - $this->db->begin(); + $line->rowid = $objp->rowid; + $line->label = $objp->custom_label; + $line->desc = $objp->description; // Description line + $line->product_type = $objp->product_type; // Type of line + $line->product_ref = $objp->product_ref; // Ref product + $line->libelle = $objp->product_label; // TODO deprecated + $line->product_label = $objp->product_label; // Label product + $line->product_desc = $objp->product_desc; // Description product + $line->fk_product_type = $objp->fk_product_type; // Type of product + $line->qty = $objp->qty; + $line->subprice = $objp->subprice; + $line->tva_tx = $objp->tva_tx; + $line->localtax1_tx = $objp->localtax1_tx; + $line->localtax2_tx = $objp->localtax2_tx; + $line->remise_percent = $objp->remise_percent; + $line->fk_remise_except = $objp->fk_remise_except; + $line->fk_product = $objp->fk_product; + $line->date_start = $this->db->jdate($objp->date_start); + $line->date_end = $this->db->jdate($objp->date_end); + $line->date_start = $this->db->jdate($objp->date_start); + $line->date_end = $this->db->jdate($objp->date_end); + $line->info_bits = $objp->info_bits; + $line->total_ht = $objp->total_ht; + $line->total_tva = $objp->total_tva; + $line->total_localtax1 = $objp->total_localtax1; + $line->total_localtax2 = $objp->total_localtax2; + $line->total_ttc = $objp->total_ttc; + $line->code_ventilation = $objp->fk_code_ventilation; + $line->fk_fournprice = $objp->fk_fournprice; + $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht); + $line->pa_ht = $marginInfos[0]; + $line->marge_tx = $marginInfos[1]; + $line->marque_tx = $marginInfos[2]; + $line->rang = $objp->rang; + $line->special_code = $objp->special_code; + $line->fk_parent_line = $objp->fk_parent_line; - $sql = "UPDATE ".MAIN_DB_PREFIX."facture"; - $sql.= " SET fk_statut = 0"; - $sql.= " WHERE rowid = ".$this->id; + // Ne plus utiliser + //$line->price = $objp->price; + //$line->remise = $objp->remise; - dol_syslog(get_class($this)."::set_draft sql=".$sql, LOG_DEBUG); - $result=$this->db->query($sql); - if ($result) - { - // Si on decremente le produit principal et ses composants a la validation de facture, on réincrement - if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL)) - { - require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; - $langs->load("agenda"); + $this->lines[$i] = $line; - $num=count($this->lines); - for ($i = 0; $i < $num; $i++) - { - if ($this->lines[$i]->fk_product > 0) - { - $mouvP = new MouvementStock($this->db); - // We decrease stock for product - if ($this->type == 2) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref)); - else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref)); // we use 0 for price, to not change the weighted average value - } - } - } + $i++; + } + $this->db->free($result); + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this).'::fetch_lines '.$this->error,LOG_ERR); + return -3; + } + } + + + /** + * Update database + * + * @param User $user User that modify + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function update($user=0, $notrigger=0) + { + global $conf, $langs; + $error=0; + + // Clean parameters + if (empty($this->type)) $this->type=0; + if (isset($this->facnumber)) $this->facnumber=trim($this->ref); + if (isset($this->ref_client)) $this->ref_client=trim($this->ref_client); + if (isset($this->increment)) $this->increment=trim($this->increment); + if (isset($this->close_code)) $this->close_code=trim($this->close_code); + if (isset($this->close_note)) $this->close_note=trim($this->close_note); + if (isset($this->note) || isset($this->note_private)) $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated + if (isset($this->note) || isset($this->note_private)) $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note)); + if (isset($this->note_public)) $this->note_public=trim($this->note_public); + if (isset($this->modelpdf)) $this->modelpdf=trim($this->modelpdf); + if (isset($this->import_key)) $this->import_key=trim($this->import_key); + + // Check parameters + // Put here code to add control on parameters values + + // Update request + $sql = "UPDATE ".MAIN_DB_PREFIX."facture SET"; + + $sql.= " facnumber=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").","; + $sql.= " type=".(isset($this->type)?$this->type:"null").","; + $sql.= " ref_client=".(isset($this->ref_client)?"'".$this->db->escape($this->ref_client)."'":"null").","; + $sql.= " increment=".(isset($this->increment)?"'".$this->db->escape($this->increment)."'":"null").","; + $sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").","; + $sql.= " datec=".(strval($this->date_creation)!='' ? "'".$this->db->idate($this->date_creation)."'" : 'null').","; + $sql.= " datef=".(strval($this->date)!='' ? "'".$this->db->idate($this->date)."'" : 'null').","; + $sql.= " date_valid=".(strval($this->date_validation)!='' ? "'".$this->db->idate($this->date_validation)."'" : 'null').","; + $sql.= " paye=".(isset($this->paye)?$this->paye:"null").","; + $sql.= " remise_percent=".(isset($this->remise_percent)?$this->remise_percent:"null").","; + $sql.= " remise_absolue=".(isset($this->remise_absolue)?$this->remise_absolue:"null").","; + //$sql.= " remise=".(isset($this->remise)?$this->remise:"null").","; + $sql.= " close_code=".(isset($this->close_code)?"'".$this->db->escape($this->close_code)."'":"null").","; + $sql.= " close_note=".(isset($this->close_note)?"'".$this->db->escape($this->close_note)."'":"null").","; + $sql.= " tva=".(isset($this->total_tva)?$this->total_tva:"null").","; + $sql.= " localtax1=".(isset($this->total_localtax1)?$this->total_localtax1:"null").","; + $sql.= " localtax2=".(isset($this->total_localtax2)?$this->total_localtax2:"null").","; + $sql.= " total=".(isset($this->total_ht)?$this->total_ht:"null").","; + $sql.= " total_ttc=".(isset($this->total_ttc)?$this->total_ttc:"null").","; + $sql.= " revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp != '')?$this->revenuestamp:"null").","; + $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").","; + $sql.= " fk_user_author=".(isset($this->user_author)?$this->user_author:"null").","; + $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").","; + $sql.= " fk_facture_source=".(isset($this->fk_facture_source)?$this->fk_facture_source:"null").","; + $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").","; + $sql.= " fk_cond_reglement=".(isset($this->cond_reglement_id)?$this->cond_reglement_id:"null").","; + $sql.= " fk_mode_reglement=".(isset($this->mode_reglement_id)?$this->mode_reglement_id:"null").","; + $sql.= " date_lim_reglement=".(strval($this->date_lim_reglement)!='' ? "'".$this->db->idate($this->date_lim_reglement)."'" : 'null').","; + $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; + $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").","; + $sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").","; + $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null").""; + + $sql.= " WHERE rowid=".$this->id; + + $this->db->begin(); + + dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { + $error++; $this->errors[]="Error ".$this->db->lasterror(); + } + + if (! $error) + { + if (! $notrigger) + { + // Call triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_MODIFY',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + + /** + * Add a discount line into invoice using an existing absolute discount + * + * @param int $idremise Id of absolute discount + * @return int >0 if OK, <0 if KO + */ + function insert_discount($idremise) + { + global $langs; + + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; + + $this->db->begin(); + + $remise=new DiscountAbsolute($this->db); + $result=$remise->fetch($idremise); + + if ($result > 0) + { + if ($remise->fk_facture) // Protection against multiple submission + { + $this->error=$langs->trans("ErrorDiscountAlreadyUsed"); + $this->db->rollback(); + return -5; + } + + $facligne=new FactureLigne($this->db); + $facligne->fk_facture=$this->id; + $facligne->fk_remise_except=$remise->id; + $facligne->desc=$remise->description; // Description ligne + $facligne->tva_tx=$remise->tva_tx; + $facligne->subprice=-$remise->amount_ht; + $facligne->fk_product=0; // Id produit predefini + $facligne->qty=1; + $facligne->remise_percent=0; + $facligne->rang=-1; + $facligne->info_bits=2; + + $facligne->total_ht = -$remise->amount_ht; + $facligne->total_tva = -$remise->amount_tva; + $facligne->total_ttc = -$remise->amount_ttc; + + $lineid=$facligne->insert(); + if ($lineid > 0) + { + $result=$this->update_price(1); + if ($result > 0) + { + // Create linke between discount and invoice line + $result=$remise->link_to_invoice($lineid,0); + if ($result < 0) + { + $this->error=$remise->error; + $this->db->rollback(); + return -4; + } + + $this->db->commit(); + return 1; + } + else + { + $this->error=$facligne->error; + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$facligne->error; + $this->db->rollback(); + return -2; + } + } + else + { + $this->db->rollback(); + return -3; + } + } + + /** + * Set customer ref + * + * @param string $ref_client Customer ref + * @return int <0 if KO, >0 if OK + */ + function set_ref_client($ref_client) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; + if (empty($ref_client)) + $sql .= ' SET ref_client = NULL'; + else + $sql .= ' SET ref_client = \''.$this->db->escape($ref_client).'\''; + $sql .= ' WHERE rowid = '.$this->id; + if ($this->db->query($sql)) + { + $this->ref_client = $ref_client; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Delete invoice + * + * @param int $rowid Id of invoice to delete. If empty, we delete current instance of invoice + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @param int $idwarehouse Id warehouse to use for stock change. + * @return int <0 if KO, >0 if OK + */ + function delete($rowid=0, $notrigger=0, $idwarehouse=-1) + { + global $user,$langs,$conf; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + if (empty($rowid)) $rowid=$this->id; + + dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG); + + // TODO Test if there is at least on payment. If yes, refuse to delete. + + $error=0; + $this->db->begin(); + + if (! $error && ! $notrigger) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_DELETE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + + if (! $error) + { + // Delete linked object + $res = $this->deleteObjectLinked(); + if ($res < 0) $error++; + } + + if (! $error) + { + // If invoice was converted into a discount not yet consumed, we remove discount + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'societe_remise_except'; + $sql.= ' WHERE fk_facture_source = '.$rowid; + $sql.= ' AND fk_facture_line IS NULL'; + $resql=$this->db->query($sql); + + // If invoice has consumned discounts + $this->fetch_lines(); + $list_rowid_det=array(); + foreach($this->lines as $key => $invoiceline) + { + $list_rowid_det[]=$invoiceline->rowid; + } + + // Consumned discounts are freed + if (count($list_rowid_det)) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; + $sql.= ' SET fk_facture = NULL, fk_facture_line = NULL'; + $sql.= ' WHERE fk_facture_line IN ('.join(',',$list_rowid_det).')'; + + dol_syslog(get_class($this)."::delete sql=".$sql); + if (! $this->db->query($sql)) + { + $this->error=$this->db->error()." sql=".$sql; + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -5; + } + } + + // If we decrament stock on invoice validation, we increment + if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_DELETE_INVOICE)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + $langs->load("agenda"); + + $num=count($this->lines); + for ($i = 0; $i < $num; $i++) + { + if ($this->lines[$i]->fk_product > 0) + { + $mouvP = new MouvementStock($this->db); + // We decrease stock for product + if ($this->type == 2) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceDeleteDolibarr",$this->ref)); + else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceDeleteDolibarr",$this->ref)); // we use 0 for price, to not change the weighted average value + } + } + } + + + // Delete invoice line + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid; + if ($this->db->query($sql) && $this->delete_linked_contact()) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid; + $resql=$this->db->query($sql); + if ($resql) + { + // On efface le repertoire de pdf provisoire + $ref = dol_sanitizeFileName($this->ref); + if ($conf->facture->dir_output) + { + $dir = $conf->facture->dir_output . "/" . $ref; + $file = $conf->facture->dir_output . "/" . $ref . "/" . $ref . ".pdf"; + if (file_exists($file)) // We must delete all files before deleting directory + { + $ret=dol_delete_preview($this); + + if (! dol_delete_file($file,0,0,0,$this)) // For triggers + { + $this->error=$langs->trans("ErrorCanNotDeleteFile",$file); + $this->db->rollback(); + return 0; + } + } + if (file_exists($dir)) + { + if (! dol_delete_dir_recursive($dir)) // For remove dir and meta + { + $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir); + $this->db->rollback(); + return 0; + } + } + } + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->lasterror()." sql=".$sql; + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -6; + } + } + else + { + $this->error=$this->db->lasterror()." sql=".$sql; + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -4; + } + } + else + { + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + + + /** + * Renvoi une date limite de reglement de facture en fonction des + * conditions de reglements de la facture et date de facturation + * + * @param string $cond_reglement Condition of payment (code or id) to use. If 0, we use current condition. + * @return date Date limite de reglement si ok, <0 si ko + */ + function calculate_date_lim_reglement($cond_reglement=0) + { + if (! $cond_reglement) $cond_reglement=$this->cond_reglement_code; + if (! $cond_reglement) $cond_reglement=$this->cond_reglement_id; + + $cdr_nbjour=0; $cdr_fdm=0; $cdr_decalage=0; + + $sqltemp = 'SELECT c.fdm,c.nbjour,c.decalage'; + $sqltemp.= ' FROM '.MAIN_DB_PREFIX.'c_payment_term as c'; + if (is_numeric($cond_reglement)) $sqltemp.= " WHERE c.rowid=".$cond_reglement; + else $sqltemp.= " WHERE c.code='".$this->db->escape($cond_reglement)."'"; + + dol_syslog(get_class($this).'::calculate_date_lim_reglement sql='.$sqltemp); + $resqltemp=$this->db->query($sqltemp); + if ($resqltemp) + { + if ($this->db->num_rows($resqltemp)) + { + $obj = $this->db->fetch_object($resqltemp); + $cdr_nbjour = $obj->nbjour; + $cdr_fdm = $obj->fdm; + $cdr_decalage = $obj->decalage; + } + } + else + { + $this->error=$this->db->error(); + return -1; + } + $this->db->free($resqltemp); + + /* Definition de la date limite */ + + // 1 : ajout du nombre de jours + $datelim = $this->date + ($cdr_nbjour * 3600 * 24); + + // 2 : application de la regle "fin de mois" + if ($cdr_fdm) + { + $mois=date('m', $datelim); + $annee=date('Y', $datelim); + if ($mois == 12) + { + $mois = 1; + $annee += 1; + } + else + { + $mois += 1; + } + // On se deplace au debut du mois suivant, et on retire un jour + $datelim=dol_mktime(12,0,0,$mois,1,$annee); + $datelim -= (3600 * 24); + } + + // 3 : application du decalage + $datelim += ($cdr_decalage * 3600 * 24); + + return $datelim; + } + + /** + * Tag la facture comme paye completement (close_code non renseigne) ou partiellement (close_code renseigne) + appel trigger BILL_PAYED + * + * @param User $user Objet utilisateur qui modifie + * @param string $close_code Code renseigne si on classe a payee completement alors que paiement incomplet (cas escompte par exemple) + * @param string $close_note Commentaire renseigne si on classe a payee alors que paiement incomplet (cas escompte par exemple) + * @return int <0 if KO, >0 if OK + */ + function set_paid($user,$close_code='',$close_note='') + { + global $conf,$langs; + $error=0; + + if ($this->paye != 1) + { + $this->db->begin(); + + dol_syslog(get_class($this)."::set_paid rowid=".$this->id, LOG_DEBUG); + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET'; + $sql.= ' fk_statut=2'; + if (! $close_code) $sql.= ', paye=1'; + if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'"; + if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'"; + $sql.= ' WHERE rowid = '.$this->id; + + $resql = $this->db->query($sql); + if ($resql) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_PAYED',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + else + { + $error++; + $this->error=$this->db->error(); + dol_print_error($this->db); + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + return 0; + } + } + + + /** + * Tag la facture comme non payee completement + appel trigger BILL_UNPAYED + * Fonction utilisee quand un paiement prelevement est refuse, + * ou quand une facture annulee et reouverte. + * + * @param User $user Object user that change status + * @return int <0 if KO, >0 if OK + */ + function set_unpaid($user) + { + global $conf,$langs; + $error=0; + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; + $sql.= ' SET paye=0, fk_statut=1, close_code=null, close_note=null'; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_unpaid sql=".$sql); + $resql = $this->db->query($sql); + if ($resql) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_UNPAYED',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + else + { + $error++; + $this->error=$this->db->error(); + dol_print_error($this->db); + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + + + /** + * Tag invoice as canceled, with no payment on it (example for replacement invoice or payment never received) + call trigger BILL_CANCEL + * Warning, if option to decrease stock on invoice was set, this function does not change stock (it might be a cancel because + * of no payment even if merchandises were sent). + * + * @param User $user Object user making change + * @param string $close_code Code de fermeture + * @param string $close_note Comment + * @return int <0 if KO, >0 if OK + */ + function set_canceled($user,$close_code='',$close_note='') + { + global $conf,$langs; + + $error=0; + + dol_syslog(get_class($this)."::set_canceled rowid=".$this->id, LOG_DEBUG); + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET'; + $sql.= ' fk_statut=3'; + if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'"; + if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'"; + $sql.= ' WHERE rowid = '.$this->id; + + $resql = $this->db->query($sql); + if ($resql) + { + // On desaffecte de la facture les remises liees + // car elles n'ont pas ete utilisees vu que la facture est abandonnee. + $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; + $sql.= ' SET fk_facture = NULL'; + $sql.= ' WHERE fk_facture = '.$this->id; + + $resql=$this->db->query($sql); + if ($resql) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_CANCEL',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -2; + } + } + + /** + * Tag invoice as validated + call trigger BILL_VALIDATE + * Object must have lines loaded with fetch_lines + * + * @param User $user Object user that validate + * @param string $force_number Reference to force on invoice + * @param int $idwarehouse Id of warehouse to use for stock decrease + * @return int <0 if KO, >0 if OK + */ + function validate($user, $force_number='', $idwarehouse=0) + { + global $conf,$langs; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $now=dol_now(); + + $error=0; + dol_syslog(get_class($this).'::validate user='.$user->id.', force_number='.$force_number.', idwarehouse='.$idwarehouse); + + // Check parameters + if (! $this->brouillon) + { + dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING); + return 0; + } + + if (! $user->rights->facture->valider) + { + $this->error='Permission denied'; + dol_syslog(get_class($this)."::validate ".$this->error, LOG_ERR); + return -1; + } + + $this->db->begin(); + + $this->fetch_thirdparty(); + $this->fetch_lines(); + + // Check parameters + if ($this->type == 1) // si facture de remplacement + { + // Controle que facture source connue + if ($this->fk_facture_source <= 0) + { + $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("InvoiceReplacement")); + $this->db->rollback(); + return -10; + } + + // Charge la facture source a remplacer + $facreplaced=new Facture($this->db); + $result=$facreplaced->fetch($this->fk_facture_source); + if ($result <= 0) + { + $this->error=$langs->trans("ErrorBadInvoice"); + $this->db->rollback(); + return -11; + } + + // Controle que facture source non deja remplacee par une autre + $idreplacement=$facreplaced->getIdReplacingInvoice('validated'); + if ($idreplacement && $idreplacement != $this->id) + { + $facreplacement=new Facture($this->db); + $facreplacement->fetch($idreplacement); + $this->error=$langs->trans("ErrorInvoiceAlreadyReplaced",$facreplaced->ref,$facreplacement->ref); + $this->db->rollback(); + return -12; + } + + $result=$facreplaced->set_canceled($user,'replaced',''); + if ($result < 0) + { + $this->error=$facreplaced->error; + $this->db->rollback(); + return -13; + } + } + + // Define new ref + if ($force_number) + { + $num = $force_number; + } + else if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date + { + $this->date=dol_now(); + $this->date_lim_reglement=$this->calculate_date_lim_reglement(); + } + $num = $this->getNextNumRef($this->client); + } + else + { + $num = $this->ref; + } + + if ($num) + { + $this->update_price(1); + + // Validate + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; + $sql.= " SET facnumber='".$num."', fk_statut = 1, fk_user_valid = ".$user->id.", date_valid = '".$this->db->idate($now)."'"; + if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date + { + $sql.= ', datef='.$this->db->idate($this->date); + $sql.= ', date_lim_reglement='.$this->db->idate($this->date_lim_reglement); + } + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::validate sql=".$sql); + $resql=$this->db->query($sql); + if (! $resql) + { + dol_syslog(get_class($this)."::validate Echec update - 10 - sql=".$sql, LOG_ERR); + dol_print_error($this->db); + $error++; + } + + // On verifie si la facture etait une provisoire + if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) + { + // La verif qu'une remise n'est pas utilisee 2 fois est faite au moment de l'insertion de ligne + } + + if (! $error) + { + // Define third party as a customer + $result=$this->client->set_as_client(); + + // Si active on decremente le produit principal et ses composants a la validation de facture + if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + $langs->load("agenda"); + + // Loop on each line + $cpt=count($this->lines); + for ($i = 0; $i < $cpt; $i++) + { + if ($this->lines[$i]->fk_product > 0) + { + $mouvP = new MouvementStock($this->db); + // We decrease stock for product + if ($this->type == 2) $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num)); + else $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num)); + if ($result < 0) { + $error++; + } + } + } + } + } + + if (! $error) + { + $this->oldref = ''; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // On renomme repertoire facture ($this->ref = ancienne ref, $num = nouvelle ref) + // afin de ne pas perdre les fichiers attaches + $facref = dol_sanitizeFileName($this->ref); + $snumfa = dol_sanitizeFileName($num); + $dirsource = $conf->facture->dir_output.'/'.$facref; + $dirdest = $conf->facture->dir_output.'/'.$snumfa; + if (file_exists($dirsource)) + { + dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) + { + $this->oldref = $facref; + + dol_syslog("Rename ok"); + // Suppression ancien fichier PDF dans nouveau rep + dol_delete_file($conf->facture->dir_output.'/'.$snumfa.'/'.$facref.'*.*'); + } + } + } + } + + // Set new ref and define current statut + if (! $error) + { + $this->ref = $num; + $this->facnumber=$num; + $this->statut=1; + $this->brouillon=0; + $this->date_validation=$now; + } + + // Trigger calls + if (! $error) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_VALIDATE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + } + else + { + $error++; + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -1; + } + } + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $idwarehouse Id warehouse to use for stock change. + * @return int <0 if KO, >0 if OK + */ + function set_draft($user,$idwarehouse=-1) + { + global $conf,$langs; + + $error=0; + + if ($this->statut == 0) + { + dol_syslog(get_class($this)."::set_draft already draft status", LOG_WARNING); + return 0; + } + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."facture"; + $sql.= " SET fk_statut = 0"; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::set_draft sql=".$sql, LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + // Si on decremente le produit principal et ses composants a la validation de facture, on réincrement + if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + $langs->load("agenda"); + + $num=count($this->lines); + for ($i = 0; $i < $num; $i++) + { + if ($this->lines[$i]->fk_product > 0) + { + $mouvP = new MouvementStock($this->db); + // We decrease stock for product + if ($this->type == 2) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref)); + else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref)); // we use 0 for price, to not change the weighted average value + } + } + } if ($error == 0) - { + { $old_statut=$this->statut; - $this->brouillon = 1; - $this->statut = 0; + $this->brouillon = 1; + $this->statut = 0; // Appel des triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; $interface=new Interfaces($this->db); @@ -1885,270 +1924,270 @@ class Facture extends CommonInvoice return -1; } - if ($error == 0) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -1; - } - } + if ($error == 0) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } - /** - * Add an invoice line into database (linked to product/service or not). - * Les parametres sont deja cense etre juste et avec valeurs finales a l'appel - * de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini - * par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit) - * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue) - * - * @param int $facid Id de la facture - * @param string $desc Description de la ligne - * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) - * @param double $qty Quantite - * @param double $txtva Taux de tva force, sinon -1 - * @param double $txlocaltax1 Local tax 1 rate - * @param double $txlocaltax2 Local tax 2 rate - * @param int $fk_product Id du produit/service predefini - * @param double $remise_percent Pourcentage de remise de la ligne - * @param timestamp $date_start Date de debut de validite du service - * @param timestamp $date_end Date de fin de validite du service - * @param int $ventil Code de ventilation comptable - * @param int $info_bits Bits de type de lignes - * @param int $fk_remise_except Id remise - * @param string $price_base_type HT or TTC - * @param double $pu_ttc Prix unitaire TTC (> 0 even for credit note) - * @param int $type Type of line (0=product, 1=service) - * @param int $rang Position of line - * @param int $special_code Special code (also used by externals modules!) - * @param string $origin 'order', ... - * @param int $origin_id Id of origin object - * @param int $fk_parent_line Id of parent line - * @param int $fk_fournprice To calculate margin - * @param int $pa_ht Buying price of line - * @param string $label Label of the line - * @return int <0 if KO, Id of line if OK - */ - function addline($facid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='') - { - dol_syslog(get_class($this)."::Addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product,remise_percent=$remise_percent,date_start=$date_start,date_end=$date_end,ventil=$ventil,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type", LOG_DEBUG); - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + /** + * Add an invoice line into database (linked to product/service or not). + * Les parametres sont deja cense etre juste et avec valeurs finales a l'appel + * de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini + * par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit) + * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue) + * + * @param int $facid Id de la facture + * @param string $desc Description de la ligne + * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) + * @param double $qty Quantite + * @param double $txtva Taux de tva force, sinon -1 + * @param double $txlocaltax1 Local tax 1 rate + * @param double $txlocaltax2 Local tax 2 rate + * @param int $fk_product Id du produit/service predefini + * @param double $remise_percent Pourcentage de remise de la ligne + * @param timestamp $date_start Date de debut de validite du service + * @param timestamp $date_end Date de fin de validite du service + * @param int $ventil Code de ventilation comptable + * @param int $info_bits Bits de type de lignes + * @param int $fk_remise_except Id remise + * @param string $price_base_type HT or TTC + * @param double $pu_ttc Prix unitaire TTC (> 0 even for credit note) + * @param int $type Type of line (0=product, 1=service) + * @param int $rang Position of line + * @param int $special_code Special code (also used by externals modules!) + * @param string $origin 'order', ... + * @param int $origin_id Id of origin object + * @param int $fk_parent_line Id of parent line + * @param int $fk_fournprice To calculate margin + * @param int $pa_ht Buying price of line + * @param string $label Label of the line + * @return int <0 if KO, Id of line if OK + */ + function addline($facid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='') + { + dol_syslog(get_class($this)."::Addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product,remise_percent=$remise_percent,date_start=$date_start,date_end=$date_end,ventil=$ventil,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type", LOG_DEBUG); + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - // Clean parameters - if (empty($remise_percent)) $remise_percent=0; - if (empty($qty)) $qty=0; - if (empty($info_bits)) $info_bits=0; - if (empty($rang)) $rang=0; - if (empty($ventil)) $ventil=0; - if (empty($txtva)) $txtva=0; - if (empty($txlocaltax1)) $txlocaltax1=0; - if (empty($txlocaltax2)) $txlocaltax2=0; - if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0; + // Clean parameters + if (empty($remise_percent)) $remise_percent=0; + if (empty($qty)) $qty=0; + if (empty($info_bits)) $info_bits=0; + if (empty($rang)) $rang=0; + if (empty($ventil)) $ventil=0; + if (empty($txtva)) $txtva=0; + if (empty($txlocaltax1)) $txlocaltax1=0; + if (empty($txlocaltax2)) $txlocaltax2=0; + if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0; - $remise_percent=price2num($remise_percent); - $qty=price2num($qty); - $pu_ht=price2num($pu_ht); - $pu_ttc=price2num($pu_ttc); - $pa_ht=price2num($pa_ht); - $txtva=price2num($txtva); - $txlocaltax1=price2num($txlocaltax1); - $txlocaltax2=price2num($txlocaltax2); + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + $pu_ht=price2num($pu_ht); + $pu_ttc=price2num($pu_ttc); + $pa_ht=price2num($pa_ht); + $txtva=price2num($txtva); + $txlocaltax1=price2num($txlocaltax1); + $txlocaltax2=price2num($txlocaltax2); - if ($price_base_type=='HT') - { - $pu=$pu_ht; - } - else - { - $pu=$pu_ttc; - } + if ($price_base_type=='HT') + { + $pu=$pu_ht; + } + else + { + $pu=$pu_ttc; + } - // Check parameters - if ($type < 0) return -1; + // Check parameters + if ($type < 0) return -1; - if (! empty($this->brouillon)) - { - $this->db->begin(); + if (! empty($this->brouillon)) + { + $this->db->begin(); - // Calcul du total TTC et de la TVA pour la ligne a partir de - // qty, pu, remise_percent et txtva - // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker - // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. - $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type); - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - $total_localtax1 = $tabprice[9]; - $total_localtax2 = $tabprice[10]; - $pu_ht = $tabprice[3]; + // Calcul du total TTC et de la TVA pour la ligne a partir de + // qty, pu, remise_percent et txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1 = $tabprice[9]; + $total_localtax2 = $tabprice[10]; + $pu_ht = $tabprice[3]; - // Rang to use - $rangtouse = $rang; - if ($rangtouse == -1) - { - $rangmax = $this->line_max($fk_parent_line); - $rangtouse = $rangmax + 1; - } + // Rang to use + $rangtouse = $rang; + if ($rangtouse == -1) + { + $rangmax = $this->line_max($fk_parent_line); + $rangtouse = $rangmax + 1; + } - $product_type=$type; - if ($fk_product) - { - $product=new Product($this->db); - $result=$product->fetch($fk_product); - $product_type=$product->type; - } + $product_type=$type; + if ($fk_product) + { + $product=new Product($this->db); + $result=$product->fetch($fk_product); + $product_type=$product->type; + } - // Insert line - $this->line=new FactureLigne($this->db); - $this->line->fk_facture=$facid; - $this->line->label=$label; - $this->line->desc=$desc; - $this->line->qty= ($this->type==2?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative - $this->line->tva_tx=$txtva; - $this->line->localtax1_tx=$txlocaltax1; - $this->line->localtax2_tx=$txlocaltax2; - $this->line->fk_product=$fk_product; - $this->line->product_type=$product_type; - $this->line->remise_percent=$remise_percent; - $this->line->subprice= ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise - $this->line->date_start=$date_start; - $this->line->date_end=$date_end; - $this->line->ventil=$ventil; - $this->line->rang=$rangtouse; - $this->line->info_bits=$info_bits; - $this->line->fk_remise_except=$fk_remise_except; - $this->line->total_ht= (($this->type==2||$qty<0)?-abs($total_ht):$total_ht); // For credit note and if qty is negative, total is negative - $this->line->total_tva= (($this->type==2||$qty<0)?-abs($total_tva):$total_tva); - $this->line->total_localtax1=(($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1); - $this->line->total_localtax2=(($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2); - $this->line->total_ttc= (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc); - $this->line->special_code=$special_code; - $this->line->fk_parent_line=$fk_parent_line; - $this->line->origin=$origin; - $this->line->origin_id=$origin_id; + // Insert line + $this->line=new FactureLigne($this->db); + $this->line->fk_facture=$facid; + $this->line->label=$label; + $this->line->desc=$desc; + $this->line->qty= ($this->type==2?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative + $this->line->tva_tx=$txtva; + $this->line->localtax1_tx=$txlocaltax1; + $this->line->localtax2_tx=$txlocaltax2; + $this->line->fk_product=$fk_product; + $this->line->product_type=$product_type; + $this->line->remise_percent=$remise_percent; + $this->line->subprice= ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise + $this->line->date_start=$date_start; + $this->line->date_end=$date_end; + $this->line->ventil=$ventil; + $this->line->rang=$rangtouse; + $this->line->info_bits=$info_bits; + $this->line->fk_remise_except=$fk_remise_except; + $this->line->total_ht= (($this->type==2||$qty<0)?-abs($total_ht):$total_ht); // For credit note and if qty is negative, total is negative + $this->line->total_tva= (($this->type==2||$qty<0)?-abs($total_tva):$total_tva); + $this->line->total_localtax1=(($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1); + $this->line->total_localtax2=(($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2); + $this->line->total_ttc= (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc); + $this->line->special_code=$special_code; + $this->line->fk_parent_line=$fk_parent_line; + $this->line->origin=$origin; + $this->line->origin_id=$origin_id; // infos marge $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; - $result=$this->line->insert(); - if ($result > 0) - { - // Reorder if child line + $result=$this->line->insert(); + if ($result > 0) + { + // Reorder if child line if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); - // Mise a jour informations denormalisees au niveau de la facture meme - $this->id=$facid; // TODO To move this we must remove parameter facid into this function declaration - $result=$this->update_price(1); - if ($result > 0) - { - $this->db->commit(); - return $this->line->rowid; - } - else - { - $this->error=$this->db->error(); - dol_syslog("Error sql=$sql, error=".$this->error,LOG_ERR); - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->line->error; - $this->db->rollback(); - return -2; - } - } - } + // Mise a jour informations denormalisees au niveau de la facture meme + $this->id=$facid; // TODO To move this we must remove parameter facid into this function declaration + $result=$this->update_price(1); + if ($result > 0) + { + $this->db->commit(); + return $this->line->rowid; + } + else + { + $this->error=$this->db->error(); + dol_syslog("Error sql=$sql, error=".$this->error,LOG_ERR); + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->line->error; + $this->db->rollback(); + return -2; + } + } + } - /** - * Update a detail line - * - * @param int $rowid Id of line to update - * @param string $desc Description of line - * @param double $pu Prix unitaire (HT ou TTC selon price_base_type) (> 0 even for credit note lines) - * @param double $qty Quantity - * @param double $remise_percent Pourcentage de remise de la ligne - * @param date $date_start Date de debut de validite du service - * @param date $date_end Date de fin de validite du service - * @param double $txtva VAT Rate - * @param double $txlocaltax1 Local tax 1 rate - * @param double $txlocaltax2 Local tax 2 rate - * @param string $price_base_type HT or TTC - * @param int $info_bits Miscellaneous informations - * @param int $type Type of line (0=product, 1=service) - * @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines). - * @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules) - * @param int $fk_fournprice Id of origin supplier price - * @param int $pa_ht Price (without tax) of product when it was bought - * @param string $label Label of the line - * @param int $special_code Special code (also used by externals modules!) - * @return int < 0 if KO, > 0 if OK - */ - function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0) - { - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + /** + * Update a detail line + * + * @param int $rowid Id of line to update + * @param string $desc Description of line + * @param double $pu Prix unitaire (HT ou TTC selon price_base_type) (> 0 even for credit note lines) + * @param double $qty Quantity + * @param double $remise_percent Pourcentage de remise de la ligne + * @param date $date_start Date de debut de validite du service + * @param date $date_end Date de fin de validite du service + * @param double $txtva VAT Rate + * @param double $txlocaltax1 Local tax 1 rate + * @param double $txlocaltax2 Local tax 2 rate + * @param string $price_base_type HT or TTC + * @param int $info_bits Miscellaneous informations + * @param int $type Type of line (0=product, 1=service) + * @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines). + * @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules) + * @param int $fk_fournprice Id of origin supplier price + * @param int $pa_ht Price (without tax) of product when it was bought + * @param string $label Label of the line + * @param int $special_code Special code (also used by externals modules!) + * @return int < 0 if KO, > 0 if OK + */ + function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - dol_syslog(get_class($this)."::updateline $rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1, $txlocaltax2, $price_base_type, $info_bits, $type, $fk_parent_line", LOG_DEBUG); + dol_syslog(get_class($this)."::updateline $rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1, $txlocaltax2, $price_base_type, $info_bits, $type, $fk_parent_line", LOG_DEBUG); - if ($this->brouillon) - { - $this->db->begin(); + if ($this->brouillon) + { + $this->db->begin(); - // Clean parameters - if (empty($qty)) $qty=0; - if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0; - if (empty($special_code) || $special_code == 3) $special_code=0; + // Clean parameters + if (empty($qty)) $qty=0; + if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0; + if (empty($special_code) || $special_code == 3) $special_code=0; - $remise_percent = price2num($remise_percent); - $qty = price2num($qty); - $pu = price2num($pu); - $pa_ht = price2num($pa_ht); - $txtva = price2num($txtva); - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); + $remise_percent = price2num($remise_percent); + $qty = price2num($qty); + $pu = price2num($pu); + $pa_ht = price2num($pa_ht); + $txtva = price2num($txtva); + $txlocaltax1 = price2num($txlocaltax1); + $txlocaltax2 = price2num($txlocaltax2); - // Check parameters - if ($type < 0) return -1; + // Check parameters + if ($type < 0) return -1; - // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva - // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker - // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. - $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type); - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - $total_localtax1=$tabprice[9]; - $total_localtax2=$tabprice[10]; - $pu_ht = $tabprice[3]; - $pu_tva = $tabprice[4]; - $pu_ttc = $tabprice[5]; + // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1=$tabprice[9]; + $total_localtax2=$tabprice[10]; + $pu_ht = $tabprice[3]; + $pu_tva = $tabprice[4]; + $pu_ttc = $tabprice[5]; - // Old properties: $price, $remise (deprecated) - $price = $pu; - $remise = 0; - if ($remise_percent > 0) - { - $remise = round(($pu * $remise_percent / 100),2); - $price = ($pu - $remise); - } - $price = price2num($price); + // Old properties: $price, $remise (deprecated) + $price = $pu; + $remise = 0; + if ($remise_percent > 0) + { + $remise = round(($pu * $remise_percent / 100),2); + $price = ($pu - $remise); + } + $price = price2num($price); - // Update line into database - $this->line=new FactureLigne($this->db); + // Update line into database + $this->line=new FactureLigne($this->db); - // Stock previous line records + // Stock previous line records $staticline=new FactureLigne($this->db); $staticline->fetch($rowid); $this->line->oldline = $staticline; @@ -2160,981 +2199,981 @@ class Facture extends CommonInvoice $this->line->rang = $rangmax + 1; } - $this->line->rowid = $rowid; - $this->line->label = $label; - $this->line->desc = $desc; - $this->line->qty = ($this->type==2?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative - $this->line->tva_tx = $txtva; - $this->line->localtax1_tx = $txlocaltax1; - $this->line->localtax2_tx = $txlocaltax2; - $this->line->remise_percent = $remise_percent; - $this->line->subprice = ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise - $this->line->date_start = $date_start; - $this->line->date_end = $date_end; - $this->line->total_ht = (($this->type==2||$qty<0)?-abs($total_ht):$total_ht); // For credit note and if qty is negative, total is negative - $this->line->total_tva = (($this->type==2||$qty<0)?-abs($total_tva):$total_tva); - $this->line->total_localtax1 = (($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1); - $this->line->total_localtax2 = (($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2); - $this->line->total_ttc = (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc); - $this->line->info_bits = $info_bits; - $this->line->special_code = $special_code; - $this->line->product_type = $type; - $this->line->fk_parent_line = $fk_parent_line; - $this->line->skip_update_total = $skip_update_total; + $this->line->rowid = $rowid; + $this->line->label = $label; + $this->line->desc = $desc; + $this->line->qty = ($this->type==2?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative + $this->line->tva_tx = $txtva; + $this->line->localtax1_tx = $txlocaltax1; + $this->line->localtax2_tx = $txlocaltax2; + $this->line->remise_percent = $remise_percent; + $this->line->subprice = ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise + $this->line->date_start = $date_start; + $this->line->date_end = $date_end; + $this->line->total_ht = (($this->type==2||$qty<0)?-abs($total_ht):$total_ht); // For credit note and if qty is negative, total is negative + $this->line->total_tva = (($this->type==2||$qty<0)?-abs($total_tva):$total_tva); + $this->line->total_localtax1 = (($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1); + $this->line->total_localtax2 = (($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2); + $this->line->total_ttc = (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc); + $this->line->info_bits = $info_bits; + $this->line->special_code = $special_code; + $this->line->product_type = $type; + $this->line->fk_parent_line = $fk_parent_line; + $this->line->skip_update_total = $skip_update_total; // infos marge $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; - // A ne plus utiliser - //$this->line->price=$price; - //$this->line->remise=$remise; + // A ne plus utiliser + //$this->line->price=$price; + //$this->line->remise=$remise; - $result=$this->line->update(); - if ($result > 0) - { - // Reorder if child line - if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); + $result=$this->line->update(); + if ($result > 0) + { + // Reorder if child line + if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); - // Mise a jour info denormalisees au niveau facture - $this->update_price(1); - $this->db->commit(); - return $result; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error="Invoice statut makes operation forbidden"; - return -2; - } - } + // Mise a jour info denormalisees au niveau facture + $this->update_price(1); + $this->db->commit(); + return $result; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error="Invoice statut makes operation forbidden"; + return -2; + } + } - /** - * Delete line in database - * - * @param int $rowid Id of line to delete - * @return int <0 if KO, >0 if OK - */ - function deleteline($rowid) - { - global $langs, $conf; + /** + * Delete line in database + * + * @param int $rowid Id of line to delete + * @return int <0 if KO, >0 if OK + */ + function deleteline($rowid) + { + global $langs, $conf; - dol_syslog(get_class($this)."::deleteline rowid=".$rowid, LOG_DEBUG); + dol_syslog(get_class($this)."::deleteline rowid=".$rowid, LOG_DEBUG); - if (! $this->brouillon) - { - $this->error='ErrorBadStatus'; - return -1; - } + if (! $this->brouillon) + { + $this->error='ErrorBadStatus'; + return -1; + } - $this->db->begin(); + $this->db->begin(); - // Libere remise liee a ligne de facture - $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql.= ' SET fk_facture_line = NULL'; - $sql.= ' WHERE fk_facture_line = '.$rowid; + // Libere remise liee a ligne de facture + $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; + $sql.= ' SET fk_facture_line = NULL'; + $sql.= ' WHERE fk_facture_line = '.$rowid; - dol_syslog(get_class($this)."::deleteline sql=".$sql); - $result = $this->db->query($sql); - if (! $result) - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::deleteline Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -1; - } + dol_syslog(get_class($this)."::deleteline sql=".$sql); + $result = $this->db->query($sql); + if (! $result) + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::deleteline Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -1; + } - $line=new FactureLigne($this->db); + $line=new FactureLigne($this->db); - // For triggers - $line->fetch($rowid); + // For triggers + $line->fetch($rowid); - if ($line->delete() > 0) - { - $result=$this->update_price(1); + if ($line->delete() > 0) + { + $result=$this->update_price(1); - if ($result > 0) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - return -1; - } - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - return -1; - } - } + if ($result > 0) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -1; + } + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -1; + } + } - /** - * Set percent discount - * - * @param User $user User that set discount - * @param double $remise Discount - * @return int <0 if ko, >0 if ok - */ - function set_remise($user, $remise) - { - // Clean parameters - if (empty($remise)) $remise=0; + /** + * Set percent discount + * + * @param User $user User that set discount + * @param double $remise Discount + * @return int <0 if ko, >0 if ok + */ + function set_remise($user, $remise) + { + // Clean parameters + if (empty($remise)) $remise=0; - if ($user->rights->facture->creer) - { - $remise=price2num($remise); + if ($user->rights->facture->creer) + { + $remise=price2num($remise); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; - $sql.= ' SET remise_percent = '.$remise; - $sql.= ' WHERE rowid = '.$this->id; - $sql.= ' AND fk_statut = 0 ;'; + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; + $sql.= ' SET remise_percent = '.$remise; + $sql.= ' WHERE rowid = '.$this->id; + $sql.= ' AND fk_statut = 0 ;'; - if ($this->db->query($sql)) - { - $this->remise_percent = $remise; - $this->update_price(1); - return 1; - } - else - { - $this->error=$this->db->error(); - return -1; - } - } - } + if ($this->db->query($sql)) + { + $this->remise_percent = $remise; + $this->update_price(1); + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + } - /** - * Set absolute discount - * - * @param User $user User that set discount - * @param double $remise Discount - * @return int <0 if KO, >0 if OK - */ - function set_remise_absolue($user, $remise) - { - if (empty($remise)) $remise=0; + /** + * Set absolute discount + * + * @param User $user User that set discount + * @param double $remise Discount + * @return int <0 if KO, >0 if OK + */ + function set_remise_absolue($user, $remise) + { + if (empty($remise)) $remise=0; - if ($user->rights->facture->creer) - { - $remise=price2num($remise); + if ($user->rights->facture->creer) + { + $remise=price2num($remise); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; - $sql.= ' SET remise_absolue = '.$remise; - $sql.= ' WHERE rowid = '.$this->id; - $sql.= ' AND fk_statut = 0 ;'; + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; + $sql.= ' SET remise_absolue = '.$remise; + $sql.= ' WHERE rowid = '.$this->id; + $sql.= ' AND fk_statut = 0 ;'; - dol_syslog(get_class($this)."::set_remise_absolue sql=$sql"); + dol_syslog(get_class($this)."::set_remise_absolue sql=$sql"); - if ($this->db->query($sql)) - { - $this->remise_absolue = $remise; - $this->update_price(1); - return 1; - } - else - { - $this->error=$this->db->error(); - return -1; - } - } - } + if ($this->db->query($sql)) + { + $this->remise_absolue = $remise; + $this->update_price(1); + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + } - /** - * Return list of payments - * - * @param string $filtertype 1 to filter on type of payment == 'PRE' - * @return array Array with list of payments - */ - function getListOfPayments($filtertype='') - { - $retarray=array(); + /** + * Return list of payments + * + * @param string $filtertype 1 to filter on type of payment == 'PRE' + * @return array Array with list of payments + */ + function getListOfPayments($filtertype='') + { + $retarray=array(); - $table='paiement_facture'; - $table2='paiement'; - $field='fk_facture'; - $field2='fk_paiement'; - if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') - { - $table='paiementfourn_facturefourn'; - $table2='paiementfourn'; - $field='fk_facturefourn'; - $field2='fk_paiementfourn'; - } + $table='paiement_facture'; + $table2='paiement'; + $field='fk_facture'; + $field2='fk_paiement'; + if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') + { + $table='paiementfourn_facturefourn'; + $table2='paiementfourn'; + $field='fk_facturefourn'; + $field2='fk_paiementfourn'; + } - $sql = 'SELECT pf.amount, p.fk_paiement, p.datep, t.code'; - $sql.= ' FROM '.MAIN_DB_PREFIX.$table.' as pf, '.MAIN_DB_PREFIX.$table2.' as p, '.MAIN_DB_PREFIX.'c_paiement as t'; - $sql.= ' WHERE pf.'.$field.' = '.$this->id; - $sql.= ' AND pf.'.$field2.' = p.rowid'; - $sql.= ' AND p.fk_paiement = t.id'; - if ($filtertype) $sql.=" AND t.code='PRE'"; + $sql = 'SELECT pf.amount, p.fk_paiement, p.datep, t.code'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$table.' as pf, '.MAIN_DB_PREFIX.$table2.' as p, '.MAIN_DB_PREFIX.'c_paiement as t'; + $sql.= ' WHERE pf.'.$field.' = '.$this->id; + $sql.= ' AND pf.'.$field2.' = p.rowid'; + $sql.= ' AND p.fk_paiement = t.id'; + if ($filtertype) $sql.=" AND t.code='PRE'"; - dol_syslog(get_class($this)."::getListOfPayments sql=".$sql, LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i=0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $retarray[]=array('amount'=>$obj->amount,'type'=>$obj->code, 'date'=>$obj->datep); - $i++; - } - $this->db->free($resql); - return $retarray; - } - else - { - $this->error=$this->db->lasterror(); - dol_print_error($this->db); - return array(); - } - } + dol_syslog(get_class($this)."::getListOfPayments sql=".$sql, LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $retarray[]=array('amount'=>$obj->amount,'type'=>$obj->code, 'date'=>$obj->datep); + $i++; + } + $this->db->free($resql); + return $retarray; + } + else + { + $this->error=$this->db->lasterror(); + dol_print_error($this->db); + return array(); + } + } - /** - * Return amount (with tax) of all credit notes and deposits invoices used by invoice - * - * @return int <0 if KO, Sum of credit notes and deposits amount otherwise - */ - function getSumCreditNotesUsed() - { - require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; + /** + * Return amount (with tax) of all credit notes and deposits invoices used by invoice + * + * @return int <0 if KO, Sum of credit notes and deposits amount otherwise + */ + function getSumCreditNotesUsed() + { + require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - $discountstatic=new DiscountAbsolute($this->db); - $result=$discountstatic->getSumCreditNotesUsed($this); - if ($result >= 0) - { - return $result; - } - else - { - $this->error=$discountstatic->error; - return -1; - } - } + $discountstatic=new DiscountAbsolute($this->db); + $result=$discountstatic->getSumCreditNotesUsed($this); + if ($result >= 0) + { + return $result; + } + else + { + $this->error=$discountstatic->error; + return -1; + } + } - /** - * Return amount (with tax) of all deposits invoices used by invoice - * - * @return int <0 if KO, Sum of deposits amount otherwise - */ - function getSumDepositsUsed() - { - require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; + /** + * Return amount (with tax) of all deposits invoices used by invoice + * + * @return int <0 if KO, Sum of deposits amount otherwise + */ + function getSumDepositsUsed() + { + require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - $discountstatic=new DiscountAbsolute($this->db); - $result=$discountstatic->getSumDepositsUsed($this); - if ($result >= 0) - { - return $result; - } - else - { - $this->error=$discountstatic->error; - return -1; - } - } + $discountstatic=new DiscountAbsolute($this->db); + $result=$discountstatic->getSumDepositsUsed($this); + if ($result >= 0) + { + return $result; + } + else + { + $this->error=$discountstatic->error; + return -1; + } + } - /** - * Return next reference of customer invoice not already used (or last reference) - * according to numbering module defined into constant FACTURE_ADDON - * - * @param Society $soc object company - * @param string $mode 'next' for next value or 'last' for last value - * @return string free ref or last ref - */ - function getNextNumRef($soc,$mode='next') - { - global $conf, $db, $langs; - $langs->load("bills"); + /** + * Return next reference of customer invoice not already used (or last reference) + * according to numbering module defined into constant FACTURE_ADDON + * + * @param Society $soc object company + * @param string $mode 'next' for next value or 'last' for last value + * @return string free ref or last ref + */ + function getNextNumRef($soc,$mode='next') + { + global $conf, $db, $langs; + $langs->load("bills"); - // Clean parameters (if not defined or using deprecated value) - if (empty($conf->global->FACTURE_ADDON)) $conf->global->FACTURE_ADDON='mod_facture_terre'; - else if ($conf->global->FACTURE_ADDON=='terre') $conf->global->FACTURE_ADDON='mod_facture_terre'; - else if ($conf->global->FACTURE_ADDON=='mercure') $conf->global->FACTURE_ADDON='mod_facture_mercure'; + // Clean parameters (if not defined or using deprecated value) + if (empty($conf->global->FACTURE_ADDON)) $conf->global->FACTURE_ADDON='mod_facture_terre'; + else if ($conf->global->FACTURE_ADDON=='terre') $conf->global->FACTURE_ADDON='mod_facture_terre'; + else if ($conf->global->FACTURE_ADDON=='mercure') $conf->global->FACTURE_ADDON='mod_facture_mercure'; - $mybool=false; + $mybool=false; - $file = $conf->global->FACTURE_ADDON.".php"; - $classname = $conf->global->FACTURE_ADDON; - // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot."/core/modules/facture/"; - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; - } + $file = $conf->global->FACTURE_ADDON.".php"; + $classname = $conf->global->FACTURE_ADDON; + // Include file with class + foreach ($conf->file->dol_document_root as $dirroot) + { + $dir = $dirroot."/core/modules/facture/"; + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } - // For compatibility - if (! $mybool) - { - $file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php"; - $classname = "mod_facture_".$conf->global->FACTURE_ADDON; - // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot."/core/modules/facture/"; - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; - } - } - //print "xx".$mybool.$dir.$file."-".$classname; + // For compatibility + if (! $mybool) + { + $file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php"; + $classname = "mod_facture_".$conf->global->FACTURE_ADDON; + // Include file with class + foreach ($conf->file->dol_document_root as $dirroot) + { + $dir = $dirroot."/core/modules/facture/"; + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + } + //print "xx".$mybool.$dir.$file."-".$classname; - if (! $mybool) - { - dol_print_error('',"Failed to include file ".$file); - return ''; - } + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } - $obj = new $classname(); + $obj = new $classname(); - $numref = ""; - $numref = $obj->getNumRef($soc,$this,$mode); + $numref = ""; + $numref = $obj->getNumRef($soc,$this,$mode); - if ( $numref != "") - { - return $numref; - } - else - { - //dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error); - return false; - } - } + if ( $numref != "") + { + return $numref; + } + else + { + //dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error); + return false; + } + } - /** - * Load miscellaneous information for tab "Info" - * - * @param int $id Id of object to load - * @return void - */ - function info($id) - { - $sql = 'SELECT c.rowid, datec, date_valid as datev, tms as datem,'; - $sql.= ' fk_user_author, fk_user_valid'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as c'; - $sql.= ' WHERE c.rowid = '.$id; + /** + * Load miscellaneous information for tab "Info" + * + * @param int $id Id of object to load + * @return void + */ + function info($id) + { + $sql = 'SELECT c.rowid, datec, date_valid as datev, tms as datem,'; + $sql.= ' fk_user_author, fk_user_valid'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as c'; + $sql.= ' WHERE c.rowid = '.$id; - $result=$this->db->query($sql); - if ($result) - { - if ($this->db->num_rows($result)) - { - $obj = $this->db->fetch_object($result); - $this->id = $obj->rowid; - if ($obj->fk_user_author) - { - $cuser = new User($this->db); - $cuser->fetch($obj->fk_user_author); - $this->user_creation = $cuser; - } - if ($obj->fk_user_valid) - { - $vuser = new User($this->db); - $vuser->fetch($obj->fk_user_valid); - $this->user_validation = $vuser; - } - $this->date_creation = $this->db->jdate($obj->datec); - $this->date_modification = $this->db->jdate($obj->datem); - $this->date_validation = $this->db->jdate($obj->datev); // Should be in log table - } - $this->db->free($result); - } - else - { - dol_print_error($this->db); - } - } + $result=$this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + $this->id = $obj->rowid; + if ($obj->fk_user_author) + { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + if ($obj->fk_user_valid) + { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = $this->db->jdate($obj->datem); + $this->date_validation = $this->db->jdate($obj->datev); // Should be in log table + } + $this->db->free($result); + } + else + { + dol_print_error($this->db); + } + } - /** - * Renvoi si les lignes de facture sont ventilees et/ou exportees en compta - * - * @return int <0 if KO, 0=no, 1=yes - */ - function getVentilExportCompta() - { - // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees - $ventilExportCompta = 0 ; - $num=count($this->lines); - for ($i = 0; $i < $num; $i++) - { - if ($this->lines[$i]->export_compta <> 0 && $this->lines[$i]->code_ventilation <> 0) - { - $ventilExportCompta++; - } - } + /** + * Renvoi si les lignes de facture sont ventilees et/ou exportees en compta + * + * @return int <0 if KO, 0=no, 1=yes + */ + function getVentilExportCompta() + { + // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees + $ventilExportCompta = 0 ; + $num=count($this->lines); + for ($i = 0; $i < $num; $i++) + { + if ($this->lines[$i]->export_compta <> 0 && $this->lines[$i]->code_ventilation <> 0) + { + $ventilExportCompta++; + } + } - if ($ventilExportCompta <> 0) - { - return 1; - } - else - { - return 0; - } - } + if ($ventilExportCompta <> 0) + { + return 1; + } + else + { + return 0; + } + } - /** - * Return if an invoice can be deleted - * Rule is: - * If hidden option INVOICE_CAN_ALWAYS_BE_REMOVED is on, we can - * If invoice has a definitive ref, is last, without payment and not dipatched into accountancy -> yes end of rule - * If invoice is draft and ha a temporary ref -> yes - * - * @return int <0 if KO, 0=no, 1=yes - */ - function is_erasable() - { - global $conf; + /** + * Return if an invoice can be deleted + * Rule is: + * If hidden option INVOICE_CAN_ALWAYS_BE_REMOVED is on, we can + * If invoice has a definitive ref, is last, without payment and not dipatched into accountancy -> yes end of rule + * If invoice is draft and ha a temporary ref -> yes + * + * @return int <0 if KO, 0=no, 1=yes + */ + function is_erasable() + { + global $conf; - if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED)) return 1; - if (! empty($conf->global->INVOICE_CAN_NEVER_BE_REMOVED)) return 0; + if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED)) return 1; + if (! empty($conf->global->INVOICE_CAN_NEVER_BE_REMOVED)) return 0; - // on verifie si la facture est en numerotation provisoire - $facref = substr($this->ref, 1, 4); + // on verifie si la facture est en numerotation provisoire + $facref = substr($this->ref, 1, 4); - // If not a draft invoice and not temporary invoice - if ($facref != 'PROV') - { - $maxfacnumber = $this->getNextNumRef($this->client,'last'); - $ventilExportCompta = $this->getVentilExportCompta(); - // If there is no invoice into the reset range and not already dispatched, we can delete - if ($maxfacnumber == '' && $ventilExportCompta == 0) return 1; - // If invoice to delete is last one and not already dispatched, we can delete - if ($maxfacnumber == $this->ref && $ventilExportCompta == 0) return 1; - } - else if ($this->statut == 0 && $facref == 'PROV') // Si facture brouillon et provisoire - { - return 1; - } + // If not a draft invoice and not temporary invoice + if ($facref != 'PROV') + { + $maxfacnumber = $this->getNextNumRef($this->client,'last'); + $ventilExportCompta = $this->getVentilExportCompta(); + // If there is no invoice into the reset range and not already dispatched, we can delete + if ($maxfacnumber == '' && $ventilExportCompta == 0) return 1; + // If invoice to delete is last one and not already dispatched, we can delete + if ($maxfacnumber == $this->ref && $ventilExportCompta == 0) return 1; + } + else if ($this->statut == 0 && $facref == 'PROV') // Si facture brouillon et provisoire + { + return 1; + } - return 0; - } + return 0; + } - /** - * Renvoi liste des factures remplacables - * Statut validee ou abandonnee pour raison autre + non payee + aucun paiement + pas deja remplacee - * - * @param int $socid Id societe - * @return array Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1) - */ - function list_replacable_invoices($socid=0) - { - global $conf; + /** + * Renvoi liste des factures remplacables + * Statut validee ou abandonnee pour raison autre + non payee + aucun paiement + pas deja remplacee + * + * @param int $socid Id societe + * @return array Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1) + */ + function list_replacable_invoices($socid=0) + { + global $conf; - $return = array(); + $return = array(); - $sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut,"; - $sql.= " ff.rowid as rowidnext"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON f.rowid = ff.fk_facture_source"; - $sql.= " WHERE (f.fk_statut = 1 OR (f.fk_statut = 3 AND f.close_code = 'abandon'))"; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND f.paye = 0"; // Pas classee payee completement - $sql.= " AND pf.fk_paiement IS NULL"; // Aucun paiement deja fait - $sql.= " AND ff.fk_statut IS NULL"; // Renvoi vrai si pas facture de remplacement - if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; - $sql.= " ORDER BY f.facnumber"; + $sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut,"; + $sql.= " ff.rowid as rowidnext"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON f.rowid = ff.fk_facture_source"; + $sql.= " WHERE (f.fk_statut = 1 OR (f.fk_statut = 3 AND f.close_code = 'abandon'))"; + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND f.paye = 0"; // Pas classee payee completement + $sql.= " AND pf.fk_paiement IS NULL"; // Aucun paiement deja fait + $sql.= " AND ff.fk_statut IS NULL"; // Renvoi vrai si pas facture de remplacement + if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; + $sql.= " ORDER BY f.facnumber"; - dol_syslog(get_class($this)."::list_replacable_invoices sql=$sql"); - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $return[$obj->rowid]=array( 'id' => $obj->rowid, + dol_syslog(get_class($this)."::list_replacable_invoices sql=$sql"); + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $return[$obj->rowid]=array( 'id' => $obj->rowid, 'ref' => $obj->facnumber, 'status' => $obj->fk_statut); - } - //print_r($return); - return $return; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::list_replacable_invoices ".$this->error, LOG_ERR); - return -1; - } - } + } + //print_r($return); + return $return; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::list_replacable_invoices ".$this->error, LOG_ERR); + return -1; + } + } - /** - * Renvoi liste des factures qualifiables pour correction par avoir - * Les factures qui respectent les regles suivantes sont retournees: - * (validee + paiement en cours) ou classee (payee completement ou payee partiellement) + pas deja remplacee + pas deja avoir - * - * @param int $socid Id societe - * @return array Tableau des factures ($id => array('ref'=>,'paymentornot'=>,'status'=>,'paye'=>) - */ - function list_qualified_avoir_invoices($socid=0) - { - global $conf; + /** + * Renvoi liste des factures qualifiables pour correction par avoir + * Les factures qui respectent les regles suivantes sont retournees: + * (validee + paiement en cours) ou classee (payee completement ou payee partiellement) + pas deja remplacee + pas deja avoir + * + * @param int $socid Id societe + * @return array Tableau des factures ($id => array('ref'=>,'paymentornot'=>,'status'=>,'paye'=>) + */ + function list_qualified_avoir_invoices($socid=0) + { + global $conf; - $return = array(); + $return = array(); - $sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut, f.type, f.paye, pf.fk_paiement"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=1)"; - $sql.= " WHERE f.entity = ".$conf->entity; - $sql.= " AND f.fk_statut in (1,2)"; - // $sql.= " WHERE f.fk_statut >= 1"; - // $sql.= " AND (f.paye = 1"; // Classee payee completement - // $sql.= " OR f.close_code IS NOT NULL)"; // Classee payee partiellement - $sql.= " AND ff.type IS NULL"; // Renvoi vrai si pas facture de remplacement - $sql.= " AND f.type != 2"; // Type non 2 si facture non avoir - if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; - $sql.= " ORDER BY f.facnumber"; + $sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut, f.type, f.paye, pf.fk_paiement"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=1)"; + $sql.= " WHERE f.entity = ".$conf->entity; + $sql.= " AND f.fk_statut in (1,2)"; + // $sql.= " WHERE f.fk_statut >= 1"; + // $sql.= " AND (f.paye = 1"; // Classee payee completement + // $sql.= " OR f.close_code IS NOT NULL)"; // Classee payee partiellement + $sql.= " AND ff.type IS NULL"; // Renvoi vrai si pas facture de remplacement + $sql.= " AND f.type != 2"; // Type non 2 si facture non avoir + if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; + $sql.= " ORDER BY f.facnumber"; - dol_syslog(get_class($this)."::list_qualified_avoir_invoices sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $qualified=0; - if ($obj->fk_statut == 1) $qualified=1; - if ($obj->fk_statut == 2) $qualified=1; - if ($qualified) - { - //$ref=$obj->facnumber; - $paymentornot=($obj->fk_paiement?1:0); - $return[$obj->rowid]=array('ref'=>$obj->facnumber,'status'=>$obj->fk_statut,'type'=>$obj->type,'paye'=>$obj->paye,'paymentornot'=>$paymentornot); - } - } + dol_syslog(get_class($this)."::list_qualified_avoir_invoices sql=".$sql); + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $qualified=0; + if ($obj->fk_statut == 1) $qualified=1; + if ($obj->fk_statut == 2) $qualified=1; + if ($qualified) + { + //$ref=$obj->facnumber; + $paymentornot=($obj->fk_paiement?1:0); + $return[$obj->rowid]=array('ref'=>$obj->facnumber,'status'=>$obj->fk_statut,'type'=>$obj->type,'paye'=>$obj->paye,'paymentornot'=>$paymentornot); + } + } - return $return; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::list_avoir_invoices ".$this->error, LOG_ERR); - return -1; - } - } + return $return; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::list_avoir_invoices ".$this->error, LOG_ERR); + return -1; + } + } - /** - * Create a withdrawal request for a standing order - * - * @param User $user User asking standing order - * @return int <0 if KO, >0 if OK - */ - function demande_prelevement($user) - { - dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); + /** + * Create a withdrawal request for a standing order + * + * @param User $user User asking standing order + * @return int <0 if KO, >0 if OK + */ + function demande_prelevement($user) + { + dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); - $soc = new Societe($this->db); - $soc->id = $this->socid; - $soc->load_ban(); + $soc = new Societe($this->db); + $soc->id = $this->socid; + $soc->load_ban(); - if ($this->statut > 0 && $this->paye == 0) - { - $sql = 'SELECT count(*)'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; - $sql.= ' WHERE fk_facture = '.$this->id; - $sql.= ' AND traite = 0'; + if ($this->statut > 0 && $this->paye == 0) + { + $sql = 'SELECT count(*)'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; + $sql.= ' WHERE fk_facture = '.$this->id; + $sql.= ' AND traite = 0'; - $resql=$this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - if ($row[0] == 0) - { - $now=dol_now(); + $resql=$this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + if ($row[0] == 0) + { + $now=dol_now(); - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande'; - $sql .= ' (fk_facture, amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib)'; - $sql .= ' VALUES ('.$this->id; - $sql .= ",'".price2num($this->total_ttc)."'"; - $sql .= ",".$this->db->idate($now).",".$user->id; - $sql .= ",'".$soc->bank_account->code_banque."'"; - $sql .= ",'".$soc->bank_account->code_guichet."'"; - $sql .= ",'".$soc->bank_account->number."'"; - $sql .= ",'".$soc->bank_account->cle_rib."')"; - if ( $this->db->query($sql)) - { - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this).'::demandeprelevement Erreur'); - return -1; - } - } - else - { - $this->error="A request already exists"; - dol_syslog(get_class($this).'::demandeprelevement Impossible de creer une demande, demande deja en cours'); - } - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this).'::demandeprelevement Erreur -2'); - return -2; - } - } - else - { - $this->error="Status of invoice does not allow this"; - dol_syslog(get_class($this)."::demandeprelevement ".$this->error." $this->statut, $this->paye, $this->mode_reglement_id"); - return -3; - } - } + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande'; + $sql .= ' (fk_facture, amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib)'; + $sql .= ' VALUES ('.$this->id; + $sql .= ",'".price2num($this->total_ttc)."'"; + $sql .= ",".$this->db->idate($now).",".$user->id; + $sql .= ",'".$soc->bank_account->code_banque."'"; + $sql .= ",'".$soc->bank_account->code_guichet."'"; + $sql .= ",'".$soc->bank_account->number."'"; + $sql .= ",'".$soc->bank_account->cle_rib."')"; + if ( $this->db->query($sql)) + { + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this).'::demandeprelevement Erreur'); + return -1; + } + } + else + { + $this->error="A request already exists"; + dol_syslog(get_class($this).'::demandeprelevement Impossible de creer une demande, demande deja en cours'); + } + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this).'::demandeprelevement Erreur -2'); + return -2; + } + } + else + { + $this->error="Status of invoice does not allow this"; + dol_syslog(get_class($this)."::demandeprelevement ".$this->error." $this->statut, $this->paye, $this->mode_reglement_id"); + return -3; + } + } - /** - * Supprime une demande de prelevement - * - * @param Use $user utilisateur creant la demande - * @param int $did id de la demande a supprimer - * @return int <0 if OK, >0 if KO - */ - function demande_prelevement_delete($user, $did) - { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; - $sql .= ' WHERE rowid = '.$did; - $sql .= ' AND traite = 0'; - if ( $this->db->query($sql) ) - { - return 0; - } - else - { - $this->error=$this->db->lasterror(); - dol_syslog(get_class($this).'::demande_prelevement_delete Error '.$this->error); - return -1; - } - } + /** + * Supprime une demande de prelevement + * + * @param Use $user utilisateur creant la demande + * @param int $did id de la demande a supprimer + * @return int <0 if OK, >0 if KO + */ + function demande_prelevement_delete($user, $did) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; + $sql .= ' WHERE rowid = '.$did; + $sql .= ' AND traite = 0'; + if ( $this->db->query($sql) ) + { + return 0; + } + else + { + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this).'::demande_prelevement_delete Error '.$this->error); + return -1; + } + } - /** - * Load indicators for dashboard (this->nbtodo and this->nbtodolate) - * - * @param User $user Object user - * @return int <0 if KO, >0 if OK - */ - function load_board($user) - { - global $conf, $user; + /** + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * + * @param User $user Object user + * @return int <0 if KO, >0 if OK + */ + function load_board($user) + { + global $conf, $user; - $now=dol_now(); + $now=dol_now(); - $this->nbtodo=$this->nbtodolate=0; - $clause = " WHERE"; + $this->nbtodo=$this->nbtodolate=0; + $clause = " WHERE"; - $sql = "SELECT f.rowid, f.date_lim_reglement as datefin"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; - if (!$user->rights->societe->client->voir && !$user->societe_id) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON f.fk_soc = sc.fk_soc"; - $sql.= " WHERE sc.fk_user = " .$user->id; - $clause = " AND"; - } - $sql.= $clause." f.paye=0"; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND f.fk_statut = 1"; - if ($user->societe_id) $sql.= " AND f.fk_soc = ".$user->societe_id; + $sql = "SELECT f.rowid, f.date_lim_reglement as datefin"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON f.fk_soc = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = " AND"; + } + $sql.= $clause." f.paye=0"; + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND f.fk_statut = 1"; + if ($user->societe_id) $sql.= " AND f.fk_soc = ".$user->societe_id; - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $this->nbtodo++; - if ($this->db->jdate($obj->datefin) < ($now - $conf->facture->client->warning_delay)) $this->nbtodolate++; - } - return 1; - } - else - { - dol_print_error($this->db); - $this->error=$this->db->error(); - return -1; - } - } + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nbtodo++; + if ($this->db->jdate($obj->datefin) < ($now - $conf->facture->client->warning_delay)) $this->nbtodolate++; + } + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } - /* gestion des contacts d'une facture */ + /* gestion des contacts d'une facture */ - /** - * Retourne id des contacts clients de facturation - * - * @return array Liste des id contacts facturation - */ - function getIdBillingContact() - { - return $this->getIdContact('external','BILLING'); - } + /** + * Retourne id des contacts clients de facturation + * + * @return array Liste des id contacts facturation + */ + function getIdBillingContact() + { + return $this->getIdContact('external','BILLING'); + } - /** - * Retourne id des contacts clients de livraison - * - * @return array Liste des id contacts livraison - */ - function getIdShippingContact() - { - return $this->getIdContact('external','SHIPPING'); - } + /** + * Retourne id des contacts clients de livraison + * + * @return array Liste des id contacts livraison + */ + function getIdShippingContact() + { + return $this->getIdContact('external','SHIPPING'); + } - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @param string $option ''=Create a specimen invoice with lines, 'nolines'=No lines - * @return void - */ - function initAsSpecimen($option='') - { - global $user,$langs,$conf; + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @param string $option ''=Create a specimen invoice with lines, 'nolines'=No lines + * @return void + */ + function initAsSpecimen($option='') + { + global $user,$langs,$conf; - $now=dol_now(); - $arraynow=dol_getdate($now); - $nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']); + $now=dol_now(); + $arraynow=dol_getdate($now); + $nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']); - $prodids = array(); - $sql = "SELECT rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."product"; - $sql.= " WHERE entity IN (".getEntity('product', 1).")"; - $resql = $this->db->query($sql); - if ($resql) - { - $num_prods = $this->db->num_rows($resql); - $i = 0; - while ($i < $num_prods) - { - $i++; - $row = $this->db->fetch_row($resql); - $prodids[$i] = $row[0]; - } - } + $prodids = array(); + $sql = "SELECT rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."product"; + $sql.= " WHERE entity IN (".getEntity('product', 1).")"; + $resql = $this->db->query($sql); + if ($resql) + { + $num_prods = $this->db->num_rows($resql); + $i = 0; + while ($i < $num_prods) + { + $i++; + $row = $this->db->fetch_row($resql); + $prodids[$i] = $row[0]; + } + } - // Initialize parameters - $this->id=0; - $this->ref = 'SPECIMEN'; - $this->specimen=1; - $this->socid = 1; - $this->date = $nownotime; - $this->date_lim_reglement = $nownotime + 3600 * 24 *30; - $this->cond_reglement_id = 1; - $this->cond_reglement_code = 'RECEP'; - $this->date_lim_reglement=$this->calculate_date_lim_reglement(); - $this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR - $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR - $this->note_public='This is a comment (public)'; - $this->note_private='This is a comment (private)'; - $this->note='This is a comment (private)'; + // Initialize parameters + $this->id=0; + $this->ref = 'SPECIMEN'; + $this->specimen=1; + $this->socid = 1; + $this->date = $nownotime; + $this->date_lim_reglement = $nownotime + 3600 * 24 *30; + $this->cond_reglement_id = 1; + $this->cond_reglement_code = 'RECEP'; + $this->date_lim_reglement=$this->calculate_date_lim_reglement(); + $this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR + $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR + $this->note_public='This is a comment (public)'; + $this->note_private='This is a comment (private)'; + $this->note='This is a comment (private)'; - if (empty($option) || $option != 'nolines') - { - // Lines - $nbp = 5; - $xnbp = 0; - while ($xnbp < $nbp) - { - $line=new FactureLigne($this->db); - $line->desc=$langs->trans("Description")." ".$xnbp; - $line->qty=1; - $line->subprice=100; - $line->tva_tx=19.6; - $line->localtax1_tx=0; - $line->localtax2_tx=0; - $line->remise_percent=0; - if ($xnbp == 1) // Qty is negative (product line) - { - $prodid = rand(1, $num_prods); - $line->fk_product=$prodids[$prodid]; - $line->qty=-1; - $line->total_ht=-100; - $line->total_ttc=-119.6; - $line->total_tva=-19.6; - } - else if ($xnbp == 2) // UP is negative (free line) - { - $line->subprice=-100; - $line->total_ht=-100; - $line->total_ttc=-119.6; - $line->total_tva=-19.6; - $line->remise_percent=0; - } - else if ($xnbp == 3) // Discount is 50% (product line) - { - $prodid = rand(1, $num_prods); - $line->fk_product=$prodids[$prodid]; - $line->total_ht=50; - $line->total_ttc=59.8; - $line->total_tva=9.8; - $line->remise_percent=50; - } - else // (product line) - { - $prodid = rand(1, $num_prods); - $line->fk_product=$prodids[$prodid]; - $line->total_ht=100; - $line->total_ttc=119.6; - $line->total_tva=19.6; - $line->remise_percent=00; - } + if (empty($option) || $option != 'nolines') + { + // Lines + $nbp = 5; + $xnbp = 0; + while ($xnbp < $nbp) + { + $line=new FactureLigne($this->db); + $line->desc=$langs->trans("Description")." ".$xnbp; + $line->qty=1; + $line->subprice=100; + $line->tva_tx=19.6; + $line->localtax1_tx=0; + $line->localtax2_tx=0; + $line->remise_percent=0; + if ($xnbp == 1) // Qty is negative (product line) + { + $prodid = rand(1, $num_prods); + $line->fk_product=$prodids[$prodid]; + $line->qty=-1; + $line->total_ht=-100; + $line->total_ttc=-119.6; + $line->total_tva=-19.6; + } + else if ($xnbp == 2) // UP is negative (free line) + { + $line->subprice=-100; + $line->total_ht=-100; + $line->total_ttc=-119.6; + $line->total_tva=-19.6; + $line->remise_percent=0; + } + else if ($xnbp == 3) // Discount is 50% (product line) + { + $prodid = rand(1, $num_prods); + $line->fk_product=$prodids[$prodid]; + $line->total_ht=50; + $line->total_ttc=59.8; + $line->total_tva=9.8; + $line->remise_percent=50; + } + else // (product line) + { + $prodid = rand(1, $num_prods); + $line->fk_product=$prodids[$prodid]; + $line->total_ht=100; + $line->total_ttc=119.6; + $line->total_tva=19.6; + $line->remise_percent=00; + } - $this->lines[$xnbp]=$line; - $xnbp++; + $this->lines[$xnbp]=$line; + $xnbp++; - $this->total_ht += $line->total_ht; - $this->total_tva += $line->total_tva; - $this->total_ttc += $line->total_ttc; - } - $this->revenuestamp = 0; - - // Add a line "offered" - $line=new FactureLigne($this->db); - $line->desc=$langs->trans("Description")." (offered line)"; - $line->qty=1; - $line->subprice=100; - $line->tva_tx=19.6; - $line->localtax1_tx=0; - $line->localtax2_tx=0; - $line->remise_percent=100; - $line->total_ht=0; - $line->total_ttc=0; // 90 * 1.196 - $line->total_tva=0; - $prodid = rand(1, $num_prods); - $line->fk_product=$prodids[$prodid]; + $this->total_ht += $line->total_ht; + $this->total_tva += $line->total_tva; + $this->total_ttc += $line->total_ttc; + } + $this->revenuestamp = 0; - $this->lines[$xnbp]=$line; - $xnbp++; - } - } + // Add a line "offered" + $line=new FactureLigne($this->db); + $line->desc=$langs->trans("Description")." (offered line)"; + $line->qty=1; + $line->subprice=100; + $line->tva_tx=19.6; + $line->localtax1_tx=0; + $line->localtax2_tx=0; + $line->remise_percent=100; + $line->total_ht=0; + $line->total_ttc=0; // 90 * 1.196 + $line->total_tva=0; + $prodid = rand(1, $num_prods); + $line->fk_product=$prodids[$prodid]; - /** - * Load indicators for dashboard (this->nbtodo and this->nbtodolate) - * + $this->lines[$xnbp]=$line; + $xnbp++; + } + } + + /** + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * * @return int <0 if KO, >0 if OK - */ - function load_state_board() - { - global $conf, $user; + */ + function load_state_board() + { + global $conf, $user; - $this->nb=array(); + $this->nb=array(); - $clause = "WHERE"; + $clause = "WHERE"; - $sql = "SELECT count(f.rowid) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$user->societe_id) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; - $sql.= " WHERE sc.fk_user = " .$user->id; - $clause = "AND"; - } - $sql.= " ".$clause." f.entity = ".$conf->entity; + $sql = "SELECT count(f.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = "AND"; + } + $sql.= " ".$clause." f.entity = ".$conf->entity; - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $this->nb["invoices"]=$obj->nb; - } - return 1; - } - else - { - dol_print_error($this->db); - $this->error=$this->db->error(); - return -1; - } - } + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["invoices"]=$obj->nb; + } + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } - /** - * Create an array of invoice lines - * - * @return int >0 if OK, <0 if KO - */ - function getLinesArray() - { - $sql = 'SELECT l.rowid, l.label as custom_label, l.description, l.fk_product, l.product_type, l.qty, l.tva_tx,'; - $sql.= ' l.fk_remise_except, l.localtax1_tx, l.localtax2_tx,'; - $sql.= ' l.remise_percent, l.subprice, l.info_bits, l.rang, l.special_code, l.fk_parent_line,'; - $sql.= ' l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,'; - $sql.= ' l.date_start, l.date_end,'; - $sql.= ' p.ref as product_ref, p.fk_product_type, p.label as product_label,'; - $sql.= ' p.description as product_desc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product p ON l.fk_product=p.rowid'; - $sql.= ' WHERE l.fk_facture = '.$this->id; - $sql.= ' ORDER BY l.rang ASC, l.rowid'; + /** + * Create an array of invoice lines + * + * @return int >0 if OK, <0 if KO + */ + function getLinesArray() + { + $sql = 'SELECT l.rowid, l.label as custom_label, l.description, l.fk_product, l.product_type, l.qty, l.tva_tx,'; + $sql.= ' l.fk_remise_except, l.localtax1_tx, l.localtax2_tx,'; + $sql.= ' l.remise_percent, l.subprice, l.info_bits, l.rang, l.special_code, l.fk_parent_line,'; + $sql.= ' l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,'; + $sql.= ' l.date_start, l.date_end,'; + $sql.= ' p.ref as product_ref, p.fk_product_type, p.label as product_label,'; + $sql.= ' p.description as product_desc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product p ON l.fk_product=p.rowid'; + $sql.= ' WHERE l.fk_facture = '.$this->id; + $sql.= ' ORDER BY l.rang ASC, l.rowid'; - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); - $this->lines[$i]->id = $obj->rowid; - $this->lines[$i]->label = $obj->custom_label; - $this->lines[$i]->description = $obj->description; - $this->lines[$i]->fk_product = $obj->fk_product; - $this->lines[$i]->ref = $obj->product_ref; - $this->lines[$i]->product_label = $obj->product_label; - $this->lines[$i]->product_desc = $obj->product_desc; - $this->lines[$i]->fk_product_type = $obj->fk_product_type; - $this->lines[$i]->product_type = $obj->product_type; - $this->lines[$i]->qty = $obj->qty; - $this->lines[$i]->subprice = $obj->subprice; - $this->lines[$i]->fk_remise_except = $obj->fk_remise_except; - $this->lines[$i]->remise_percent = $obj->remise_percent; - $this->lines[$i]->tva_tx = $obj->tva_tx; - $this->lines[$i]->info_bits = $obj->info_bits; - $this->lines[$i]->total_ht = $obj->total_ht; - $this->lines[$i]->total_tva = $obj->total_tva; - $this->lines[$i]->total_ttc = $obj->total_ttc; - $this->lines[$i]->fk_parent_line = $obj->fk_parent_line; - $this->lines[$i]->special_code = $obj->special_code; - $this->lines[$i]->rang = $obj->rang; - $this->lines[$i]->date_start = $this->db->jdate($obj->date_start); - $this->lines[$i]->date_end = $this->db->jdate($obj->date_end); + $this->lines[$i]->id = $obj->rowid; + $this->lines[$i]->label = $obj->custom_label; + $this->lines[$i]->description = $obj->description; + $this->lines[$i]->fk_product = $obj->fk_product; + $this->lines[$i]->ref = $obj->product_ref; + $this->lines[$i]->product_label = $obj->product_label; + $this->lines[$i]->product_desc = $obj->product_desc; + $this->lines[$i]->fk_product_type = $obj->fk_product_type; + $this->lines[$i]->product_type = $obj->product_type; + $this->lines[$i]->qty = $obj->qty; + $this->lines[$i]->subprice = $obj->subprice; + $this->lines[$i]->fk_remise_except = $obj->fk_remise_except; + $this->lines[$i]->remise_percent = $obj->remise_percent; + $this->lines[$i]->tva_tx = $obj->tva_tx; + $this->lines[$i]->info_bits = $obj->info_bits; + $this->lines[$i]->total_ht = $obj->total_ht; + $this->lines[$i]->total_tva = $obj->total_tva; + $this->lines[$i]->total_ttc = $obj->total_ttc; + $this->lines[$i]->fk_parent_line = $obj->fk_parent_line; + $this->lines[$i]->special_code = $obj->special_code; + $this->lines[$i]->rang = $obj->rang; + $this->lines[$i]->date_start = $this->db->jdate($obj->date_start); + $this->lines[$i]->date_end = $this->db->jdate($obj->date_end); $this->lines[$i]->fk_fournprice = $obj->fk_fournprice; $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht); $this->lines[$i]->pa_ht = $marginInfos[0]; $this->lines[$i]->marge_tx = $marginInfos[1]; $this->lines[$i]->marque_tx = $marginInfos[2]; - $i++; - } - $this->db->free($resql); + $i++; + } + $this->db->free($resql); - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog("Error sql=".$sql.", error=".$this->error,LOG_ERR); - return -1; - } - } + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog("Error sql=".$sql.", error=".$this->error,LOG_ERR); + return -1; + } + } } @@ -3147,322 +3186,324 @@ class Facture extends CommonInvoice */ class FactureLigne { - var $db; - var $error; + var $db; + var $error; - var $oldline; + var $oldline; - //! From llx_facturedet - var $rowid; - //! Id facture - var $fk_facture; - //! Id parent line - var $fk_parent_line; - var $label; - //! Description ligne - var $desc; - var $fk_product; // Id of predefined product - var $product_type = 0; // Type 0 = product, 1 = Service + //! From llx_facturedet + var $rowid; + //! Id facture + var $fk_facture; + //! Id parent line + var $fk_parent_line; + var $label; + //! Description ligne + var $desc; + var $fk_product; // Id of predefined product + var $product_type = 0; // Type 0 = product, 1 = Service - var $qty; // Quantity (example 2) - var $tva_tx; // Taux tva produit/service (example 19.6) - var $localtax1_tx; // Local tax 1 - var $localtax2_tx; // Local tax 2 - var $subprice; // P.U. HT (example 100) - var $remise_percent; // % de la remise ligne (example 20%) - var $fk_remise_except; // Link to line into llx_remise_except - var $rang = 0; + var $qty; // Quantity (example 2) + var $tva_tx; // Taux tva produit/service (example 19.6) + var $localtax1_tx; // Local tax 1 + var $localtax2_tx; // Local tax 2 + var $subprice; // P.U. HT (example 100) + var $remise_percent; // % de la remise ligne (example 20%) + var $fk_remise_except; // Link to line into llx_remise_except + var $rang = 0; - var $fk_fournprice; - var $pa_ht; - var $marge_tx; - var $marque_tx; + var $fk_fournprice; + var $pa_ht; + var $marge_tx; + var $marque_tx; - var $info_bits = 0; // Liste d'options cumulables: - // Bit 0: 0 si TVA normal - 1 si TVA NPR - // Bit 1: 0 si ligne normal - 1 si bit discount (link to line into llx_remise_except) + var $info_bits = 0; // Liste d'options cumulables: + // Bit 0: 0 si TVA normal - 1 si TVA NPR + // Bit 1: 0 si ligne normal - 1 si bit discount (link to line into llx_remise_except) - var $special_code; // Liste d'options non cumulabels: - // 1: frais de port - // 2: ecotaxe - // 3: ?? + var $special_code; // Liste d'options non cumulabels: + // 1: frais de port + // 2: ecotaxe + // 3: ?? - var $origin; - var $origin_id; + var $origin; + var $origin_id; - //! Total HT de la ligne toute quantite et incluant la remise ligne - var $total_ht; - //! Total TVA de la ligne toute quantite et incluant la remise ligne - var $total_tva; - var $total_localtax1; //Total Local tax 1 de la ligne - var $total_localtax2; //Total Local tax 2 de la ligne - //! Total TTC de la ligne toute quantite et incluant la remise ligne - var $total_ttc; + //! Total HT de la ligne toute quantite et incluant la remise ligne + var $total_ht; + //! Total TVA de la ligne toute quantite et incluant la remise ligne + var $total_tva; + var $total_localtax1; //Total Local tax 1 de la ligne + var $total_localtax2; //Total Local tax 2 de la ligne + //! Total TTC de la ligne toute quantite et incluant la remise ligne + var $total_ttc; - var $fk_code_ventilation = 0; + var $fk_code_ventilation = 0; - var $date_start; - var $date_end; + var $date_start; + var $date_end; - // Ne plus utiliser - //var $price; // P.U. HT apres remise % de ligne (exemple 80) - //var $remise; // Montant calcule de la remise % sur PU HT (exemple 20) + // Ne plus utiliser + //var $price; // P.U. HT apres remise % de ligne (exemple 80) + //var $remise; // Montant calcule de la remise % sur PU HT (exemple 20) - // From llx_product - var $ref; // Product ref (deprecated) - var $product_ref; // Product ref - var $libelle; // Product label (deprecated) - var $product_label; // Product label - var $product_desc; // Description produit + // From llx_product + var $ref; // Product ref (deprecated) + var $product_ref; // Product ref + var $libelle; // Product label (deprecated) + var $product_label; // Product label + var $product_desc; // Description produit - var $skip_update_total; // Skip update price total for special lines + var $skip_update_total; // Skip update price total for special lines - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - } + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + } - /** - * Load invoice line from database - * - * @param int $rowid id of invoice line to get - * @return int <0 if KO, >0 if OK - */ - function fetch($rowid) - { - $sql = 'SELECT fd.rowid, fd.fk_facture, fd.fk_parent_line, fd.fk_product, fd.product_type, fd.label as custom_label, fd.description, fd.price, fd.qty, fd.tva_tx,'; - $sql.= ' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice,'; - $sql.= ' fd.date_start as date_start, fd.date_end as date_end, fd.fk_product_fournisseur_price as fk_fournprice, fd.buy_price_ht as pa_ht,'; - $sql.= ' fd.info_bits, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,'; - $sql.= ' fd.fk_code_ventilation,'; - $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid'; - $sql.= ' WHERE fd.rowid = '.$rowid; + /** + * Load invoice line from database + * + * @param int $rowid id of invoice line to get + * @return int <0 if KO, >0 if OK + */ + function fetch($rowid) + { + $sql = 'SELECT fd.rowid, fd.fk_facture, fd.fk_parent_line, fd.fk_product, fd.product_type, fd.label as custom_label, fd.description, fd.price, fd.qty, fd.tva_tx,'; + $sql.= ' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice,'; + $sql.= ' fd.date_start as date_start, fd.date_end as date_end, fd.fk_product_fournisseur_price as fk_fournprice, fd.buy_price_ht as pa_ht,'; + $sql.= ' fd.info_bits, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,'; + $sql.= ' fd.fk_code_ventilation,'; + $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid'; + $sql.= ' WHERE fd.rowid = '.$rowid; - $result = $this->db->query($sql); - if ($result) - { - $objp = $this->db->fetch_object($result); + $result = $this->db->query($sql); + if ($result) + { + $objp = $this->db->fetch_object($result); - $this->rowid = $objp->rowid; - $this->fk_facture = $objp->fk_facture; - $this->fk_parent_line = $objp->fk_parent_line; - $this->label = $objp->custom_label; - $this->desc = $objp->description; - $this->qty = $objp->qty; - $this->subprice = $objp->subprice; - $this->tva_tx = $objp->tva_tx; - $this->localtax1_tx = $objp->localtax1_tx; - $this->localtax2_tx = $objp->localtax2_tx; - $this->remise_percent = $objp->remise_percent; - $this->fk_remise_except = $objp->fk_remise_except; - $this->fk_product = $objp->fk_product; - $this->product_type = $objp->product_type; - $this->date_start = $this->db->jdate($objp->date_start); - $this->date_end = $this->db->jdate($objp->date_end); - $this->info_bits = $objp->info_bits; - $this->total_ht = $objp->total_ht; - $this->total_tva = $objp->total_tva; - $this->total_localtax1 = $objp->total_localtax1; - $this->total_localtax2 = $objp->total_localtax2; - $this->total_ttc = $objp->total_ttc; - $this->fk_code_ventilation = $objp->fk_code_ventilation; - $this->rang = $objp->rang; + $this->rowid = $objp->rowid; + $this->fk_facture = $objp->fk_facture; + $this->fk_parent_line = $objp->fk_parent_line; + $this->label = $objp->custom_label; + $this->desc = $objp->description; + $this->qty = $objp->qty; + $this->subprice = $objp->subprice; + $this->tva_tx = $objp->tva_tx; + $this->localtax1_tx = $objp->localtax1_tx; + $this->localtax2_tx = $objp->localtax2_tx; + $this->remise_percent = $objp->remise_percent; + $this->fk_remise_except = $objp->fk_remise_except; + $this->fk_product = $objp->fk_product; + $this->product_type = $objp->product_type; + $this->date_start = $this->db->jdate($objp->date_start); + $this->date_end = $this->db->jdate($objp->date_end); + $this->info_bits = $objp->info_bits; + $this->total_ht = $objp->total_ht; + $this->total_tva = $objp->total_tva; + $this->total_localtax1 = $objp->total_localtax1; + $this->total_localtax2 = $objp->total_localtax2; + $this->total_ttc = $objp->total_ttc; + $this->fk_code_ventilation = $objp->fk_code_ventilation; + $this->rang = $objp->rang; $this->fk_fournprice = $objp->fk_fournprice; $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht); $this->pa_ht = $marginInfos[0]; $this->marge_tx = $marginInfos[1]; $this->marque_tx = $marginInfos[2]; - $this->ref = $objp->product_ref; // deprecated - $this->product_ref = $objp->product_ref; - $this->libelle = $objp->product_libelle; // deprecated - $this->product_label = $objp->product_libelle; - $this->product_desc = $objp->product_desc; + $this->ref = $objp->product_ref; // deprecated + $this->product_ref = $objp->product_ref; + $this->libelle = $objp->product_libelle; // deprecated + $this->product_label = $objp->product_libelle; + $this->product_desc = $objp->product_desc; - $this->db->free($result); - } - else - { - dol_print_error($this->db); - } - } + $this->db->free($result); + } + else + { + dol_print_error($this->db); + } + } - /** - * Insert line in database - * - * @param int $notrigger 1 no triggers - * @return int <0 if KO, >0 if OK - */ - function insert($notrigger=0) - { - global $langs,$user,$conf; + /** + * Insert line in database + * + * @param int $notrigger 1 no triggers + * @return int <0 if KO, >0 if OK + */ + function insert($notrigger=0) + { + global $langs,$user,$conf; $error=0; - dol_syslog(get_class($this)."::insert rang=".$this->rang, LOG_DEBUG); + dol_syslog(get_class($this)."::insert rang=".$this->rang, LOG_DEBUG); - // Clean parameters - $this->desc=trim($this->desc); - if (empty($this->tva_tx)) $this->tva_tx=0; - if (empty($this->localtax1_tx)) $this->localtax1_tx=0; - if (empty($this->localtax2_tx)) $this->localtax2_tx=0; - if (empty($this->total_localtax1)) $this->total_localtax1=0; - if (empty($this->total_localtax2)) $this->total_localtax2=0; - if (empty($this->rang)) $this->rang=0; - if (empty($this->remise_percent)) $this->remise_percent=0; - if (empty($this->info_bits)) $this->info_bits=0; - if (empty($this->subprice)) $this->subprice=0; - if (empty($this->special_code)) $this->special_code=0; - if (empty($this->fk_parent_line)) $this->fk_parent_line=0; + // Clean parameters + $this->desc=trim($this->desc); + if (empty($this->tva_tx)) $this->tva_tx=0; + if (empty($this->localtax1_tx)) $this->localtax1_tx=0; + if (empty($this->localtax2_tx)) $this->localtax2_tx=0; + if (empty($this->total_localtax1)) $this->total_localtax1=0; + if (empty($this->total_localtax2)) $this->total_localtax2=0; + if (empty($this->rang)) $this->rang=0; + if (empty($this->remise_percent)) $this->remise_percent=0; + if (empty($this->info_bits)) $this->info_bits=0; + if (empty($this->subprice)) $this->subprice=0; + if (empty($this->special_code)) $this->special_code=0; + if (empty($this->fk_parent_line)) $this->fk_parent_line=0; - if (empty($this->pa_ht)) $this->pa_ht=0; + if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); - } + // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente + if ($this->pa_ht == 0) { + if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) + $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + } - // Check parameters - if ($this->product_type < 0) return -1; + // Check parameters + if ($this->product_type < 0) return -1; - $this->db->begin(); + $this->db->begin(); - // Insertion dans base de la ligne - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facturedet'; - $sql.= ' (fk_facture, fk_parent_line, label, description, qty, tva_tx, localtax1_tx, localtax2_tx,'; - $sql.= ' fk_product, product_type, remise_percent, subprice, fk_remise_except,'; - $sql.= ' date_start, date_end, fk_code_ventilation, '; - $sql.= ' rang, special_code, fk_product_fournisseur_price, buy_price_ht,'; - $sql.= ' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2)'; - $sql.= " VALUES (".$this->fk_facture.","; - $sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").","; - $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").","; - $sql.= " '".$this->db->escape($this->desc)."',"; - $sql.= " ".price2num($this->qty).","; - $sql.= " ".price2num($this->tva_tx).","; - $sql.= " ".price2num($this->localtax1_tx).","; - $sql.= " ".price2num($this->localtax2_tx).","; - $sql.= ' '.(! empty($this->fk_product)?$this->fk_product:"null").','; - $sql.= " ".$this->product_type.","; - $sql.= " ".price2num($this->remise_percent).","; - $sql.= " ".price2num($this->subprice).","; - $sql.= ' '.(! empty($this->fk_remise_except)?$this->fk_remise_except:"null").','; - $sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").","; - $sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null").","; - $sql.= ' '.$this->fk_code_ventilation.','; - $sql.= ' '.$this->rang.','; - $sql.= ' '.$this->special_code.','; - $sql.= ' '.(! empty($this->fk_fournprice)?$this->fk_fournprice:"null").','; - $sql.= ' '.price2num($this->pa_ht).','; - $sql.= " '".$this->info_bits."',"; - $sql.= " ".price2num($this->total_ht).","; + // Insertion dans base de la ligne + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facturedet'; + $sql.= ' (fk_facture, fk_parent_line, label, description, qty, tva_tx, localtax1_tx, localtax2_tx,'; + $sql.= ' fk_product, product_type, remise_percent, subprice, fk_remise_except,'; + $sql.= ' date_start, date_end, fk_code_ventilation, '; + $sql.= ' rang, special_code, fk_product_fournisseur_price, buy_price_ht,'; + $sql.= ' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2)'; + $sql.= " VALUES (".$this->fk_facture.","; + $sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").","; + $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").","; + $sql.= " '".$this->db->escape($this->desc)."',"; + $sql.= " ".price2num($this->qty).","; + $sql.= " ".price2num($this->tva_tx).","; + $sql.= " ".price2num($this->localtax1_tx).","; + $sql.= " ".price2num($this->localtax2_tx).","; + $sql.= ' '.(! empty($this->fk_product)?$this->fk_product:"null").','; + $sql.= " ".$this->product_type.","; + $sql.= " ".price2num($this->remise_percent).","; + $sql.= " ".price2num($this->subprice).","; + $sql.= ' '.(! empty($this->fk_remise_except)?$this->fk_remise_except:"null").','; + $sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").","; + $sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null").","; + $sql.= ' '.$this->fk_code_ventilation.','; + $sql.= ' '.$this->rang.','; + $sql.= ' '.$this->special_code.','; + $sql.= ' '.(! empty($this->fk_fournprice)?$this->fk_fournprice:"null").','; + $sql.= ' '.price2num($this->pa_ht).','; + $sql.= " '".$this->info_bits."',"; + $sql.= " ".price2num($this->total_ht).","; $sql.= " ".price2num($this->total_tva).","; $sql.= " ".price2num($this->total_ttc).","; - $sql.= " ".price2num($this->total_localtax1).","; - $sql.= " ".price2num($this->total_localtax2); - $sql.= ')'; + $sql.= " ".price2num($this->total_localtax1).","; + $sql.= " ".price2num($this->total_localtax2); + $sql.= ')'; - dol_syslog(get_class($this)."::insert sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'facturedet'); + dol_syslog(get_class($this)."::insert sql=".$sql); + $resql=$this->db->query($sql); + if ($resql) + { + $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'facturedet'); - // Si fk_remise_except defini, on lie la remise a la facture - // ce qui la flague comme "consommee". - if ($this->fk_remise_except) - { - $discount=new DiscountAbsolute($this->db); - $result=$discount->fetch($this->fk_remise_except); - if ($result >= 0) - { - // Check if discount was found - if ($result > 0) - { - // Check if discount not already affected to another invoice - if ($discount->fk_facture) - { - $this->error=$langs->trans("ErrorDiscountAlreadyUsed",$discount->id); - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -3; - } - else - { - $result=$discount->link_to_invoice($this->rowid,0); - if ($result < 0) - { - $this->error=$discount->error; - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -3; - } - } - } - else - { - $this->error=$langs->trans("ErrorADiscountThatHasBeenRemovedIsIncluded"); - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -3; - } - } - else - { - $this->error=$discount->error; - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -3; - } - } + // Si fk_remise_except defini, on lie la remise a la facture + // ce qui la flague comme "consommee". + if ($this->fk_remise_except) + { + $discount=new DiscountAbsolute($this->db); + $result=$discount->fetch($this->fk_remise_except); + if ($result >= 0) + { + // Check if discount was found + if ($result > 0) + { + // Check if discount not already affected to another invoice + if ($discount->fk_facture) + { + $this->error=$langs->trans("ErrorDiscountAlreadyUsed",$discount->id); + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -3; + } + else + { + $result=$discount->link_to_invoice($this->rowid,0); + if ($result < 0) + { + $this->error=$discount->error; + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -3; + } + } + } + else + { + $this->error=$langs->trans("ErrorADiscountThatHasBeenRemovedIsIncluded"); + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -3; + } + } + else + { + $this->error=$discount->error; + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -3; + } + } - if (! $notrigger) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result = $interface->run_triggers('LINEBILL_INSERT',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } + if (! $notrigger) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result = $interface->run_triggers('LINEBILL_INSERT',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } - $this->db->commit(); - return $this->rowid; + $this->db->commit(); + return $this->rowid; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } - /** - * Update line into database - * - * @param User $user User object - * @param int $notrigger Disable triggers - * @return int <0 if KO, >0 if OK - */ - function update($user='',$notrigger=0) - { - global $user,$langs,$conf; + /** + * Update line into database + * + * @param User $user User object + * @param int $notrigger Disable triggers + * @return int <0 if KO, >0 if OK + */ + function update($user='',$notrigger=0) + { + global $user,$langs,$conf; $error=0; - // Clean parameters - $this->desc=trim($this->desc); + // Clean parameters + $this->desc=trim($this->desc); if (empty($this->tva_tx)) $this->tva_tx=0; if (empty($this->localtax1_tx)) $this->localtax1_tx=0; if (empty($this->localtax2_tx)) $this->localtax2_tx=0; @@ -3474,74 +3515,76 @@ class FactureLigne if (empty($this->product_type)) $this->product_type=0; if (empty($this->fk_parent_line)) $this->fk_parent_line=0; - // Check parameters - if ($this->product_type < 0) return -1; + // Check parameters + if ($this->product_type < 0) return -1; - if (empty($this->pa_ht)) $this->pa_ht=0; + if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); - } + // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente + if ($this->pa_ht == 0) { + if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) + $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + } - $this->db->begin(); + $this->db->begin(); - // Mise a jour ligne en base - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; - $sql.= " description='".$this->db->escape($this->desc)."'"; - $sql.= ",label=".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null"); - $sql.= ",subprice=".price2num($this->subprice).""; - $sql.= ",remise_percent=".price2num($this->remise_percent).""; - if ($this->fk_remise_except) $sql.= ",fk_remise_except=".$this->fk_remise_except; - else $sql.= ",fk_remise_except=null"; - $sql.= ",tva_tx=".price2num($this->tva_tx).""; - $sql.= ",localtax1_tx=".price2num($this->localtax1_tx).""; - $sql.= ",localtax2_tx=".price2num($this->localtax2_tx).""; - $sql.= ",qty=".price2num($this->qty).""; - $sql.= ",date_start=".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null"); - $sql.= ",date_end=".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null"); - $sql.= ",product_type=".$this->product_type; - $sql.= ",info_bits='".$this->info_bits."'"; - $sql.= ",special_code='".$this->special_code."'"; - if (empty($this->skip_update_total)) - { - $sql.= ",total_ht=".price2num($this->total_ht).""; - $sql.= ",total_tva=".price2num($this->total_tva).""; - $sql.= ",total_ttc=".price2num($this->total_ttc).""; - $sql.= ",total_localtax1=".price2num($this->total_localtax1).""; - $sql.= ",total_localtax2=".price2num($this->total_localtax2).""; - } + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; + $sql.= " description='".$this->db->escape($this->desc)."'"; + $sql.= ",label=".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null"); + $sql.= ",subprice=".price2num($this->subprice).""; + $sql.= ",remise_percent=".price2num($this->remise_percent).""; + if ($this->fk_remise_except) $sql.= ",fk_remise_except=".$this->fk_remise_except; + else $sql.= ",fk_remise_except=null"; + $sql.= ",tva_tx=".price2num($this->tva_tx).""; + $sql.= ",localtax1_tx=".price2num($this->localtax1_tx).""; + $sql.= ",localtax2_tx=".price2num($this->localtax2_tx).""; + $sql.= ",qty=".price2num($this->qty).""; + $sql.= ",date_start=".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null"); + $sql.= ",date_end=".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null"); + $sql.= ",product_type=".$this->product_type; + $sql.= ",info_bits='".$this->info_bits."'"; + $sql.= ",special_code='".$this->special_code."'"; + if (empty($this->skip_update_total)) + { + $sql.= ",total_ht=".price2num($this->total_ht).""; + $sql.= ",total_tva=".price2num($this->total_tva).""; + $sql.= ",total_ttc=".price2num($this->total_ttc).""; + $sql.= ",total_localtax1=".price2num($this->total_localtax1).""; + $sql.= ",total_localtax2=".price2num($this->total_localtax2).""; + } $sql.= " , fk_product_fournisseur_price='".$this->fk_fournprice."'"; $sql.= " , buy_price_ht='".price2num($this->pa_ht)."'"; - $sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null"); - if (! empty($this->rang)) $sql.= ", rang=".$this->rang; - $sql.= " WHERE rowid = ".$this->rowid; + $sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null"); + if (! empty($this->rang)) $sql.= ", rang=".$this->rang; + $sql.= " WHERE rowid = ".$this->rowid; - dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if (! $notrigger) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result = $interface->run_triggers('LINEBILL_UPDATE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::update Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } + dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if (! $notrigger) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result = $interface->run_triggers('LINEBILL_UPDATE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::update Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } /** * Delete line in database @@ -3564,7 +3607,9 @@ class FactureLigne include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; $interface=new Interfaces($this->db); $result = $interface->run_triggers('LINEBILL_DELETE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } // Fin appel triggers $this->db->commit(); @@ -3580,45 +3625,45 @@ class FactureLigne } } - /** - * Mise a jour en base des champs total_xxx de ligne de facture - * - * @return int <0 if KO, >0 if OK - */ - function update_total() - { - $this->db->begin(); - dol_syslog(get_class($this)."::update_total", LOG_DEBUG); + /** + * Mise a jour en base des champs total_xxx de ligne de facture + * + * @return int <0 if KO, >0 if OK + */ + function update_total() + { + $this->db->begin(); + dol_syslog(get_class($this)."::update_total", LOG_DEBUG); - // Clean parameters + // Clean parameters if (empty($this->total_localtax1)) $this->total_localtax1=0; if (empty($this->total_localtax2)) $this->total_localtax2=0; - // Mise a jour ligne en base - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; - $sql.= " total_ht=".price2num($this->total_ht).""; - $sql.= ",total_tva=".price2num($this->total_tva).""; - $sql.= ",total_localtax1=".price2num($this->total_localtax1).""; - $sql.= ",total_localtax2=".price2num($this->total_localtax2).""; - $sql.= ",total_ttc=".price2num($this->total_ttc).""; - $sql.= " WHERE rowid = ".$this->rowid; + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; + $sql.= " total_ht=".price2num($this->total_ht).""; + $sql.= ",total_tva=".price2num($this->total_tva).""; + $sql.= ",total_localtax1=".price2num($this->total_localtax1).""; + $sql.= ",total_localtax2=".price2num($this->total_localtax2).""; + $sql.= ",total_ttc=".price2num($this->total_ttc).""; + $sql.= " WHERE rowid = ".$this->rowid; - dol_syslog(get_class($this)."::update_total sql=".$sql, LOG_DEBUG); + dol_syslog(get_class($this)."::update_total sql=".$sql, LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::update_total Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } + $resql=$this->db->query($sql); + if ($resql) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::update_total Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } } ?> diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 2355c112194..7bd84be4cd1 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -40,6 +40,7 @@ ActionsEvents= Events for which Dolibarr will create an action in agenda automat PropalValidatedInDolibarr= Proposal %s validated InvoiceValidatedInDolibarr= Invoice %s validated InvoiceBackToDraftInDolibarr=Invoice %s go back to draft status +InvoiceDeleteDolibarr=Invoice %s deleted OrderValidatedInDolibarr= Order %s validated OrderApprovedInDolibarr=Order %s approved OrderBackToDraftInDolibarr=Order %s go back to draft status diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 35aa3ca537a..918665fcc4b 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -55,6 +55,7 @@ DeStockOnShipment=Decrease real stocks on shipment validation ReStockOnBill=Increase real stocks on suppliers invoices/credit notes validation ReStockOnValidateOrder=Increase real stocks on suppliers orders approbation ReStockOnDispatchOrder=Increase real stocks on manual dispatching into warehouses, after supplier order receiving +ReStockOnDispatchOrder=Increase real stocks on invocie deletion OrderStatusNotReadyToDispatch=Order has not yet or no more a status that allows dispatching of products in stock warehouses. StockDiffPhysicTeoric=Reason for difference stock physical and theoretical NoPredefinedProductToDispatch=No predefined products for this object. So no dispatching in stock is required. diff --git a/htdocs/langs/es_ES/agenda.lang b/htdocs/langs/es_ES/agenda.lang index e0131db59fe..f254bf1b453 100644 --- a/htdocs/langs/es_ES/agenda.lang +++ b/htdocs/langs/es_ES/agenda.lang @@ -41,6 +41,7 @@ ActionsEvents=Eventos para que Dolibarr cree una acción de forma automática PropalValidatedInDolibarr=Presupuesto %s validado InvoiceValidatedInDolibarr=Factura %s validada InvoiceBackToDraftInDolibarr=Factura %s devuelta a borrador +InvoiceDeleteDolibarr=Factura %s elimina OrderValidatedInDolibarr=Pedido %s validado OrderApprovedInDolibarr=Pedido %s aprobado OrderBackToDraftInDolibarr=Pedido %s devuelto a borrador diff --git a/htdocs/langs/es_ES/stocks.lang b/htdocs/langs/es_ES/stocks.lang index fe51937ac65..8bbc06c59c1 100644 --- a/htdocs/langs/es_ES/stocks.lang +++ b/htdocs/langs/es_ES/stocks.lang @@ -54,6 +54,7 @@ DeStockOnShipment=Decrementar los stocks físicos sobre los envíos ReStockOnBill=Incrementar los stocks físicos sobre las facturas/abonos de proveedores ReStockOnValidateOrder=Incrementar los stocks físicos sobre los pedidos a proveedores ReStockOnDispatchOrder=Incrementa los stocks físicos en el desglose manual de la recepción de los pedidos a proveedores en los almacenes +ReStockOnDeleteInvoice=Incrementa los stocks físicos a la suppresion de las facturas OrderStatusNotReadyToDispatch=El pedido aún no está o no tiene un estado que permita un desglose de stock. StockDiffPhysicTeoric=Motivo de la diferencia entre valores físicos y teóricos NoPredefinedProductToDispatch=No hay productos predefinidos en este objeto. Por lo tanto no se puede realizar un desglose de stock. diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index 33555be6951..cf8216b617b 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -40,6 +40,7 @@ ActionsEvents=Événements pour lesquels Dolibarr doit créer une action dans l' PropalValidatedInDolibarr=Proposition %s validée InvoiceValidatedInDolibarr=Facture %s validée InvoiceBackToDraftInDolibarr=Facture %s repassée en brouillon +InvoiceDeleteDolibarr=Facture %s supprimée OrderValidatedInDolibarr=Commande %s validée OrderApprovedInDolibarr=Commande %s approuvée OrderBackToDraftInDolibarr=Commande %s repassée en brouillon diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index fb016e23ef3..e8219f5faf8 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -55,6 +55,7 @@ DeStockOnShipment=Décrémente les stocks physiques sur validation des expéditi ReStockOnBill=Incrémente les stocks physiques sur validation des factures/avoirs fournisseurs ReStockOnValidateOrder=Incrémente les stocks physiques sur approbation des commandes fournisseurs ReStockOnDispatchOrder=Incrémente les stocks physiques sur ventilation manuelle de la réception des commandes fournisseurs dans les entrepôts +ReStockOnDeleteInvoice=Incrémente les stocks physiques sur la suppression des factures OrderStatusNotReadyToDispatch=La commande n'a pas encore ou n'a plus un statut permettant une ventilation en stock. StockDiffPhysicTeoric=Raison écart stock physique-théorique NoPredefinedProductToDispatch=Pas de produits prédéfinis dans cet objet. Aucune ventilation en stock n'est donc à faire. From 1381373c95250e161ff569c6469490b544572b13 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Thu, 18 Apr 2013 09:24:29 +0200 Subject: [PATCH 03/97] Fix : set emetteur to MYCOMPANY when payment is a customer --- htdocs/compta/paiement.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index 4a8f93a52f6..232126d68e2 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -286,7 +286,8 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie $(\'.fieldrequireddyn\').addClass(\'fieldrequired\'); if ($(\'#fieldchqemetteur\').val() == \'\') { - $(\'#fieldchqemetteur\').val(jQuery(\'#thirdpartylabel\').val()); + var emetteur = ('.$facture->type.' == 2) ? \''.dol_escape_htmltag(MAIN_INFO_SOCIETE_NOM).'\' : jQuery(\'#thirdpartylabel\').val(); + $(\'#fieldchqemetteur\').val(emetteur); } } else From dcdbdd42fbe52a1c9bb74ae814a66f3ce70cb7b6 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Thu, 18 Apr 2013 09:25:19 +0200 Subject: [PATCH 04/97] Fix : action list couldn't be sorted by label, action type was kept in filter --- htdocs/comm/action/listactions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php index b603792b957..7a5dbfdaff9 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/listactions.php @@ -182,7 +182,7 @@ if ($filtera > 0 || $filtert > 0 || $filterd > 0) } $sql.= $db->order($sortfield,$sortorder); $sql.= $db->plimit($limit + 1, $offset); -//print $sql; +print $sql; dol_syslog("comm/action/listactions.php sql=".$sql); $resql=$db->query($sql); @@ -238,7 +238,7 @@ if ($resql) $i = 0; print ''; print ''; - print_liste_field_titre($langs->trans("Action"),$_SERVER["PHP_SELF"],"acode",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Action"),$_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); //print_liste_field_titre($langs->trans("Title"),$_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); print_liste_field_titre($langs->trans("DateStart"),$_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("DateEnd"),$_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder); From 2538a9e20e0888832d3300b71801c9ff5cc537a7 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 18 Apr 2013 09:39:43 +0200 Subject: [PATCH 05/97] Fix: duplicate sql request --- htdocs/install/mysql/migration/3.3.0-3.4.0.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql index e8c1da2aa4f..4bc303e932d 100755 --- a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql +++ b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql @@ -266,7 +266,6 @@ ALTER TABLE llx_commande_extrafields ADD INDEX idx_commande_extrafields (fk_obje ALTER TABLE llx_socpeople ADD COLUMN note_public text after note; ALTER TABLE llx_societe ADD COLUMN note_public text after note; -ALTER TABLE llx_facture_fourn_det ADD COLUMN info_bits integer NOT NULL DEFAULT 0 after date_end; ALTER TABLE llx_actioncomm ADD COLUMN transparency integer after fk_user_action; INSERT INTO llx_c_action_trigger (rowid,code,label,description,elementtype,rang) VALUES (29,'FICHINTER_SENTBYMAIL','Intervention sent by mail','Executed when a intervention is sent by mail','ficheinter',29); From b6bcffa4d9487a90997575bc6e405a671f2de1e1 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 18 Apr 2013 09:44:33 +0200 Subject: [PATCH 06/97] Fix: missing field --- .../install/mysql/migration/3.3.0-3.4.0.sql | 1 + .../tables/llx_product_fournisseur_price.sql | 26 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql index 4bc303e932d..b8542349f5f 100755 --- a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql +++ b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql @@ -180,6 +180,7 @@ UPDATE llx_c_tva set localtax1=0, localtax1_type='0' where localtax1_type = '7'; UPDATE llx_c_tva set localtax2=0, localtax2_type='0' where localtax2_type = '7'; ALTER TABLE llx_facture_fourn_det ADD COLUMN info_bits integer NOT NULL DEFAULT 0 after date_end; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN info_bits integer NOT NULL DEFAULT 0 after tva_tx; ALTER TABLE llx_actioncomm ADD COLUMN code varchar(32) NULL after fk_action; diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql index 2a26034c130..e48c3ce6f82 100644 --- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql +++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql @@ -1,7 +1,7 @@ -- ============================================================================ -- Copyright (C) 2003 Rodolphe Quiedeville -- Copyright (C) 2009-2011 Laurent Destailleur --- Copyright (C) 2009-2012 Regis Houssin +-- Copyright (C) 2009-2013 Regis Houssin -- Copyright (C) 2012 Juanjo Menent -- -- This program is free software; you can redistribute it and/or modify @@ -21,23 +21,23 @@ create table llx_product_fournisseur_price ( - rowid integer AUTO_INCREMENT PRIMARY KEY, - entity integer DEFAULT 1 NOT NULL, -- multi company id - datec datetime, - tms timestamp, + rowid integer AUTO_INCREMENT PRIMARY KEY, + entity integer DEFAULT 1 NOT NULL, -- multi company id + datec datetime, + tms timestamp, fk_product integer, - fk_soc integer, + fk_soc integer, ref_fourn varchar(30), - fk_availability integer, - price double(24,8) DEFAULT 0, + fk_availability integer, + price double(24,8) DEFAULT 0, quantity double, - remise_percent double NOT NULL DEFAULT 0, + remise_percent double NOT NULL DEFAULT 0, remise double NOT NULL DEFAULT 0, unitprice double(24,8) DEFAULT 0, - charges double(24,8) DEFAULT 0, + charges double(24,8) DEFAULT 0, unitcharges double(24,8) DEFAULT 0, - tva_tx double(6,3) NOT NULL, + tva_tx double(6,3) NOT NULL, info_bits integer NOT NULL DEFAULT 0, - fk_user integer, - import_key varchar(14) -- Import key + fk_user integer, + import_key varchar(14) -- Import key )ENGINE=innodb; From 6c62d0cd283fffcb819346217046682b75faae80 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Thu, 18 Apr 2013 10:12:16 +0200 Subject: [PATCH 07/97] Print forgotten --- htdocs/comm/action/listactions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php index 7a5dbfdaff9..9e7a7a959bb 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/listactions.php @@ -182,7 +182,7 @@ if ($filtera > 0 || $filtert > 0 || $filterd > 0) } $sql.= $db->order($sortfield,$sortorder); $sql.= $db->plimit($limit + 1, $offset); -print $sql; +//print $sql; dol_syslog("comm/action/listactions.php sql=".$sql); $resql=$db->query($sql); From ebb09db710ba7b4d6f4f4fefa376d30e95d3bcd6 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 18 Apr 2013 11:05:31 +0200 Subject: [PATCH 08/97] Fix: for avoid errors --- htdocs/core/lib/functions.lib.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 7ea8087613e..46f65283a3e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3105,12 +3105,16 @@ function get_default_npr($thirdparty_seller, $thirdparty_buyer, $idprod=0, $idpr if ($idprodfournprice > 0) { + if (! class_exists('ProductFournisseur')) + require DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.product.class.php'; $prodprice = new ProductFournisseur($db); $prodprice->fetch_product_fournisseur_price($idprodfournprice); return $prodprice->fourn_tva_npr; } elseif ($idprod > 0) { + if (! class_exists('Product')) + require DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $prod = new Product($db); $prod->fetch($idprod); return $prod->tva_npr; From ce60e503bca0a90b35e37c688cc5f1dfb11ecda8 Mon Sep 17 00:00:00 2001 From: fhenry Date: Thu, 18 Apr 2013 18:10:56 +0200 Subject: [PATCH 09/97] Fix trans for [ task #826 ] Increasing stock when deleting an invoice --- htdocs/langs/en_US/stocks.lang | 2 +- htdocs/langs/es_ES/agenda.lang | 2 +- htdocs/langs/es_ES/stocks.lang | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 918665fcc4b..9f4923c82ce 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -55,7 +55,7 @@ DeStockOnShipment=Decrease real stocks on shipment validation ReStockOnBill=Increase real stocks on suppliers invoices/credit notes validation ReStockOnValidateOrder=Increase real stocks on suppliers orders approbation ReStockOnDispatchOrder=Increase real stocks on manual dispatching into warehouses, after supplier order receiving -ReStockOnDispatchOrder=Increase real stocks on invocie deletion +ReStockOnDeleteInvoice=Increase real stocks on invoice deletion OrderStatusNotReadyToDispatch=Order has not yet or no more a status that allows dispatching of products in stock warehouses. StockDiffPhysicTeoric=Reason for difference stock physical and theoretical NoPredefinedProductToDispatch=No predefined products for this object. So no dispatching in stock is required. diff --git a/htdocs/langs/es_ES/agenda.lang b/htdocs/langs/es_ES/agenda.lang index f254bf1b453..70a768bec15 100644 --- a/htdocs/langs/es_ES/agenda.lang +++ b/htdocs/langs/es_ES/agenda.lang @@ -41,7 +41,7 @@ ActionsEvents=Eventos para que Dolibarr cree una acción de forma automática PropalValidatedInDolibarr=Presupuesto %s validado InvoiceValidatedInDolibarr=Factura %s validada InvoiceBackToDraftInDolibarr=Factura %s devuelta a borrador -InvoiceDeleteDolibarr=Factura %s elimina +InvoiceDeleteDolibarr=Factura %s eliminada OrderValidatedInDolibarr=Pedido %s validado OrderApprovedInDolibarr=Pedido %s aprobado OrderBackToDraftInDolibarr=Pedido %s devuelto a borrador diff --git a/htdocs/langs/es_ES/stocks.lang b/htdocs/langs/es_ES/stocks.lang index 8bbc06c59c1..d8ee6854a1d 100644 --- a/htdocs/langs/es_ES/stocks.lang +++ b/htdocs/langs/es_ES/stocks.lang @@ -54,7 +54,7 @@ DeStockOnShipment=Decrementar los stocks físicos sobre los envíos ReStockOnBill=Incrementar los stocks físicos sobre las facturas/abonos de proveedores ReStockOnValidateOrder=Incrementar los stocks físicos sobre los pedidos a proveedores ReStockOnDispatchOrder=Incrementa los stocks físicos en el desglose manual de la recepción de los pedidos a proveedores en los almacenes -ReStockOnDeleteInvoice=Incrementa los stocks físicos a la suppresion de las facturas +ReStockOnDeleteInvoice=Incrementa los stocks físicos en la eliminación de facturas OrderStatusNotReadyToDispatch=El pedido aún no está o no tiene un estado que permita un desglose de stock. StockDiffPhysicTeoric=Motivo de la diferencia entre valores físicos y teóricos NoPredefinedProductToDispatch=No hay productos predefinidos en este objeto. Por lo tanto no se puede realizar un desglose de stock. From a880a8c51e0e124c37e821fe03133e73df7819fc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Apr 2013 19:37:50 +0200 Subject: [PATCH 10/97] Qual: Work to prepare usage of jquery data plugins. --- htdocs/core/class/html.form.class.php | 10 +++++----- htdocs/core/datepicker.php | 6 +++--- htdocs/langs/ar_SA/main.lang | 5 ++++- htdocs/langs/bg_BG/main.lang | 3 +++ htdocs/langs/ca_ES/main.lang | 3 +++ htdocs/langs/da_DK/main.lang | 5 ++++- htdocs/langs/de_AT/main.lang | 2 ++ htdocs/langs/de_DE/main.lang | 3 +++ htdocs/langs/el_GR/main.lang | 5 ++++- htdocs/langs/en_AU/main.lang | 4 ++++ htdocs/langs/en_GB/main.lang | 4 ++++ htdocs/langs/en_IN/main.lang | 4 ++++ htdocs/langs/en_NZ/main.lang | 4 ++++ htdocs/langs/en_SA/main.lang | 3 +++ htdocs/langs/en_US/main.lang | 3 +++ htdocs/langs/es_ES/main.lang | 3 +++ htdocs/langs/es_HN/main.lang | 9 --------- htdocs/langs/es_PR/main.lang | 9 --------- htdocs/langs/et_EE/main.lang | 3 +++ htdocs/langs/fa_IR/main.lang | 4 ++++ htdocs/langs/fi_FI/main.lang | 5 ++++- htdocs/langs/fr_BE/main.lang | 4 ++++ htdocs/langs/fr_CA/main.lang | 4 ++++ htdocs/langs/fr_CH/main.lang | 4 ++++ htdocs/langs/fr_FR/main.lang | 7 +++++-- htdocs/langs/he_IL/main.lang | 5 ++++- htdocs/langs/hu_HU/main.lang | 5 ++++- htdocs/langs/is_IS/main.lang | 5 ++++- htdocs/langs/it_IT/main.lang | 13 ++++++++----- htdocs/langs/ja_JP/main.lang | 9 ++++++--- htdocs/langs/nb_NO/main.lang | 5 ++++- htdocs/langs/nl_BE/main.lang | 4 ++++ htdocs/langs/nl_NL/main.lang | 5 ++++- htdocs/langs/pl_PL/main.lang | 5 ++++- htdocs/langs/pt_PT/main.lang | 5 ++++- htdocs/langs/ro_RO/main.lang | 5 ++++- htdocs/langs/ru_RU/main.lang | 5 ++++- htdocs/langs/ru_UA/main.lang | 4 ++++ htdocs/langs/sl_SI/main.lang | 3 +++ htdocs/langs/sv_SE/main.lang | 5 ++++- htdocs/langs/tr_TR/main.lang | 3 +++ htdocs/langs/zh_CN/main.lang | 5 ++++- htdocs/langs/zh_TW/main.lang | 5 ++++- 43 files changed, 160 insertions(+), 52 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index ae60706f523..944f364ee4b 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3333,7 +3333,7 @@ class Form if (strval($set_time) != '' && $set_time != -1) { //$formated_date=dol_print_date($set_time,$conf->format_date_short); - $formated_date=dol_print_date($set_time,$langs->trans("FormatDateShort")); // FormatDateShort for dol_print_date/FormatDateShortJava that is same for javascript + $formated_date=dol_print_date($set_time,$langs->trans("FormatDateShortInput")); // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript } // Calendrier popup version eldy @@ -3342,7 +3342,7 @@ class Form // Zone de saisie manuelle de la date $retstring.='trans("FormatDateShortJava").'\'); "'; // FormatDateShort for dol_print_date/FormatDateShortJava that is same for javascript + $retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript $retstring.='>'; // Icone calendrier @@ -3350,7 +3350,7 @@ class Form { $retstring.=''; + $retstring.=' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');">'.img_object($langs->trans("SelectDate"),'calendarday','class="datecallink"').''; } else $retstring.=''; @@ -3359,7 +3359,7 @@ class Form $retstring.=''."\n"; } else - { + { print "Bad value of MAIN_POPUP_CALENDAR"; } } @@ -3453,7 +3453,7 @@ class Form if ($usecalendar == "eldy") { $base=DOL_URL_ROOT.'/core/'; - $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJava").'\',\''.$langs->defaultlang.'\');'; + $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');'; } else { diff --git a/htdocs/core/datepicker.php b/htdocs/core/datepicker.php index 76b8dbb4b79..a976eb83f01 100644 --- a/htdocs/core/datepicker.php +++ b/htdocs/core/datepicker.php @@ -224,16 +224,16 @@ function displayBox($selectedDate,$month,$year) if($thedate==$selDate) $dayclass="dpSelected"; elseif($thedate==$today) $dayclass="dpToday"; - if ($langs->trans("FormatDateShortJava")=="FormatDateShortJava") + if ($langs->trans("FormatDateShortJavaInput")=="FormatDateShortJavaInput") { - print "ERROR FormatDateShortJava not defined for language ".$langs->defaultlang; + print "ERROR FormatDateShortJavaInput not defined for language ".$langs->defaultlang; exit; } // Sur click dans calendrier, appelle fonction dpClickDay echo ""; $cols++; diff --git a/htdocs/langs/ar_SA/main.lang b/htdocs/langs/ar_SA/main.lang index f273f913d04..93e44d0cf43 100644 --- a/htdocs/langs/ar_SA/main.lang +++ b/htdocs/langs/ar_SA/main.lang @@ -15,7 +15,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=. SeparatorThousand=None FormatDateShort=%d/%m/%Y +FormatDateShortInpu=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -600,7 +604,6 @@ Prefix=بادئة // START - Lines generated via autotranslator.php tool (2012-02-29 15:55:27). // Reference language: en_US -> ar_SA -FormatDateShortJQuery=dd/mm/yy AddLink=إضافة وصلة Of=من SearchOf=البحث diff --git a/htdocs/langs/bg_BG/main.lang b/htdocs/langs/bg_BG/main.lang index 51df97caecb..9356eeac9a0 100644 --- a/htdocs/langs/bg_BG/main.lang +++ b/htdocs/langs/bg_BG/main.lang @@ -10,8 +10,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/ca_ES/main.lang b/htdocs/langs/ca_ES/main.lang index 35b4d437e4e..b4689f1537d 100644 --- a/htdocs/langs/ca_ES/main.lang +++ b/htdocs/langs/ca_ES/main.lang @@ -4,8 +4,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/da_DK/main.lang b/htdocs/langs/da_DK/main.lang index 7dd615bfa86..128bf629fc7 100644 --- a/htdocs/langs/da_DK/main.lang +++ b/htdocs/langs/da_DK/main.lang @@ -14,7 +14,11 @@ CHARSET=UTF-8 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -624,7 +628,6 @@ Prefix=Præfiks // START - Lines generated via autotranslator.php tool (2012-02-29 15:59:19). // Reference language: en_US -> da_DK -FormatDateShortJQuery=dd/mm/yy AddLink=Tilføj link Of=af SearchOf=Søg diff --git a/htdocs/langs/de_AT/main.lang b/htdocs/langs/de_AT/main.lang index ed9d7b27ec2..095cf44e5e2 100644 --- a/htdocs/langs/de_AT/main.lang +++ b/htdocs/langs/de_AT/main.lang @@ -10,7 +10,9 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand=. FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/de_DE/main.lang b/htdocs/langs/de_DE/main.lang index bac265965cc..88e22f914d8 100644 --- a/htdocs/langs/de_DE/main.lang +++ b/htdocs/langs/de_DE/main.lang @@ -11,8 +11,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand=. FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/MM/yy +FormatDateShortJQueryInput=dd/MM/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/el_GR/main.lang b/htdocs/langs/el_GR/main.lang index d37b716a9ba..b38a1417ea8 100644 --- a/htdocs/langs/el_GR/main.lang +++ b/htdocs/langs/el_GR/main.lang @@ -7,7 +7,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y @@ -592,7 +596,6 @@ ShortSunday=Κ // START - Lines generated via autotranslator.php tool (2011-06-26 15:35:22). // Reference language: en_US -> el_GR -FormatDateShortJQuery=dd/mm/yy AddLink=Προσθήκη συνδέσμου Of=του AmountByMonth=Ποσό ανά μήνα diff --git a/htdocs/langs/en_AU/main.lang b/htdocs/langs/en_AU/main.lang index 02b689c7c47..e1c3f95b5ea 100644 --- a/htdocs/langs/en_AU/main.lang +++ b/htdocs/langs/en_AU/main.lang @@ -4,7 +4,11 @@ CHARSET=UTF-8 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/en_GB/main.lang b/htdocs/langs/en_GB/main.lang index 8bd3243e226..6ec5c920232 100644 --- a/htdocs/langs/en_GB/main.lang +++ b/htdocs/langs/en_GB/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/en_IN/main.lang b/htdocs/langs/en_IN/main.lang index 795d89bce4e..8bf5df955b5 100644 --- a/htdocs/langs/en_IN/main.lang +++ b/htdocs/langs/en_IN/main.lang @@ -4,7 +4,11 @@ DIRECTION=ltr SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatDateTextShort=%b %d, %Y FormatDateText=%B %d, %Y diff --git a/htdocs/langs/en_NZ/main.lang b/htdocs/langs/en_NZ/main.lang index 1e6ca9a9ddc..d3f11199968 100644 --- a/htdocs/langs/en_NZ/main.lang +++ b/htdocs/langs/en_NZ/main.lang @@ -4,7 +4,11 @@ CHARSET=UTF-8 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/en_SA/main.lang b/htdocs/langs/en_SA/main.lang index 146ae3fd85e..cb8e3ba6e6d 100644 --- a/htdocs/langs/en_SA/main.lang +++ b/htdocs/langs/en_SA/main.lang @@ -6,8 +6,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 28de6467cbb..3e313654b94 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -4,8 +4,11 @@ DIRECTION=ltr SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%m/%d/%Y +FormatDateShortInput=%m/%d/%Y FormatDateShortJava=MM/dd/yyyy +FormatDateShortJavaInput=MM/dd/yyyy FormatDateShortJQuery=mm/dd/yy +FormatDateShortJQueryInput=mm/dd/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y diff --git a/htdocs/langs/es_ES/main.lang b/htdocs/langs/es_ES/main.lang index b1c231a4a67..aece1ad9d15 100644 --- a/htdocs/langs/es_ES/main.lang +++ b/htdocs/langs/es_ES/main.lang @@ -4,8 +4,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/es_HN/main.lang b/htdocs/langs/es_HN/main.lang index 390b2055e2f..421e7598de5 100644 --- a/htdocs/langs/es_HN/main.lang +++ b/htdocs/langs/es_HN/main.lang @@ -3,15 +3,6 @@ CHARSET=UTF-8 DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= -FormatDateShort=%d/%m/%Y -FormatDateShortJava=dd/MM/yyyy -FormatHourShort=%H:%M -FormatHourShortDuration=%H:%M -FormatDateTextShort=%d %b %Y -FormatDateText=%d %B %Y -FormatDateHourShort=%d/%m/%Y %H:%M -FormatDateHourTextShort=%d %b %Y %H:%M -FormatDateHourText=%d %B %Y %H:%M AmountVAT=Importe ISV TotalVAT=Total ISV IncludedVAT=ISV incluido diff --git a/htdocs/langs/es_PR/main.lang b/htdocs/langs/es_PR/main.lang index 401b367ff52..5cb39740ada 100644 --- a/htdocs/langs/es_PR/main.lang +++ b/htdocs/langs/es_PR/main.lang @@ -3,15 +3,6 @@ CHARSET=UTF-8 DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= -FormatDateShort=%d/%m/%Y -FormatDateShortJava=dd/MM/yyyy -FormatHourShort=%H:%M -FormatHourShortDuration=%H:%M -FormatDateTextShort=%d %b %Y -FormatDateText=%d %B %Y -FormatDateHourShort=%d/%m/%Y %H:%M -FormatDateHourTextShort=%d %b %Y %H:%M -FormatDateHourText=%d %B %Y %H:%M AmountVAT=Importe IVU TotalVAT=Total IVU IncludedVAT=IVU incluido diff --git a/htdocs/langs/et_EE/main.lang b/htdocs/langs/et_EE/main.lang index f02122fad5b..086bfe8b5b0 100644 --- a/htdocs/langs/et_EE/main.lang +++ b/htdocs/langs/et_EE/main.lang @@ -12,8 +12,11 @@ DIRECTION=ltr SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%m/%d/%Y +FormatDateShortInput=%m/%d/%Y FormatDateShortJava=MM/dd/yyyy +FormatDateShortJavaInput=MM/dd/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y diff --git a/htdocs/langs/fa_IR/main.lang b/htdocs/langs/fa_IR/main.lang index 4cb4fc7d9f7..6645152d1d2 100644 --- a/htdocs/langs/fa_IR/main.lang +++ b/htdocs/langs/fa_IR/main.lang @@ -15,7 +15,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=/ SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/fi_FI/main.lang b/htdocs/langs/fi_FI/main.lang index 734a3356dd9..b451e91e115 100644 --- a/htdocs/langs/fi_FI/main.lang +++ b/htdocs/langs/fi_FI/main.lang @@ -11,7 +11,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H.%M FormatDateTextShort=%d. %b %Y FormatDateText=%d. %B %Y @@ -616,7 +620,6 @@ Prefix=Etuliite // START - Lines generated via autotranslator.php tool (2012-02-29 16:10:23). // Reference language: en_US -> fi_FI -FormatDateShortJQuery=dd/mm/yy AddLink=Lisää linkki Of=ja SearchOf=Etsi diff --git a/htdocs/langs/fr_BE/main.lang b/htdocs/langs/fr_BE/main.lang index 3a222bdd6b9..664e394aeba 100644 --- a/htdocs/langs/fr_BE/main.lang +++ b/htdocs/langs/fr_BE/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/fr_CA/main.lang b/htdocs/langs/fr_CA/main.lang index 3cd76162e3d..ca4b13b8480 100644 --- a/htdocs/langs/fr_CA/main.lang +++ b/htdocs/langs/fr_CA/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/fr_CH/main.lang b/htdocs/langs/fr_CH/main.lang index dbe4956c684..83cc40057ea 100644 --- a/htdocs/langs/fr_CH/main.lang +++ b/htdocs/langs/fr_CH/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d-%m-%Y +FormatDateShortInput=%d-%m-%Y FormatDateShortJava=dd-MM-yyyy +FormatDateShortJavaInput=dd-MM-yyyy +FormatDateShortJQuery=dd-mm-yy +FormatDateShortJQueryInput=dd-mm-yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index b31b711f3a3..ad25de082f4 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -3,9 +3,12 @@ CHARSET=UTF-8 DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= -FormatDateShort=%d/%m/%Y -FormatDateShortJava=dd/MM/yyyy +FormatDateShort=%d/%m/%y +FormatDateShortInput=%d/%m/%Y +FormatDateShortJava=dd/MM/yy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/he_IL/main.lang b/htdocs/langs/he_IL/main.lang index 1561f468861..03c0061acf1 100644 --- a/htdocs/langs/he_IL/main.lang +++ b/htdocs/langs/he_IL/main.lang @@ -15,8 +15,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%m/%d/%Y +FormatDateShortInput=%m/%d/%Y FormatDateShortJava=MM/dd/yyyy -FormatDateShortJQuery=dd/mm/yy +FormatDateShortJavaInput=MM/dd/yyyy +FormatDateShortJQuery=mm/dd/yy +FormatDateShortJQueryInput=mm/dd/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y diff --git a/htdocs/langs/hu_HU/main.lang b/htdocs/langs/hu_HU/main.lang index 8ee7c826648..9fb2cf4f61d 100644 --- a/htdocs/langs/hu_HU/main.lang +++ b/htdocs/langs/hu_HU/main.lang @@ -5,7 +5,11 @@ FONTFORPDF=dejavusans SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y @@ -587,7 +591,6 @@ ShortSunday=V // START - Lines generated via autotranslator.php tool (2012-02-29 16:13:31). // Reference language: en_US -> hu_HU -FormatDateShortJQuery=dd/mm/yy AddLink=Link hozzáadása Of=A SearchOf=Keresés diff --git a/htdocs/langs/is_IS/main.lang b/htdocs/langs/is_IS/main.lang index 619f60994d9..c89746ed401 100644 --- a/htdocs/langs/is_IS/main.lang +++ b/htdocs/langs/is_IS/main.lang @@ -12,7 +12,11 @@ DIRECTION=ltr SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -604,7 +608,6 @@ Reason=Ástæða // START - Lines generated via autotranslator.php tool (2012-02-29 16:26:19). // Reference language: en_US -> is_IS -FormatDateShortJQuery=dd/mm/yy AddLink=Bæta við tengli Of=á SearchOf=Leita diff --git a/htdocs/langs/it_IT/main.lang b/htdocs/langs/it_IT/main.lang index 43e9b108b78..78664cd01f8 100644 --- a/htdocs/langs/it_IT/main.lang +++ b/htdocs/langs/it_IT/main.lang @@ -270,15 +270,18 @@ FollowingConstantsWillBeSubstituted =Le seguenti costanti saranno sostitute ForCustomer =Per i clienti FormatDateHourShort =%d/%m/%Y %H.%M FormatDateHourText =%d %B %Y %H:%M -FormatDateHourTextShort =%d %b %Y %H.%M +FormatDateHourTextShort =%d %b %Y %H.%M FormatDateShort =%d/%m/%Y +FormatDateShortInput =%d/%m/%Y FormatDateShortJava =dd/MM/yyyy -FormatDateShortJQuery =dd/mm/yy +FormatDateShortJavaInput =dd/MM/yyyy +FormatDateShortJQuery =dd/mm/yy +FormatDateShortJQueryInput =dd/mm/yy FormatDateText =%d %B %Y FormatDateTextShort =%d %b %Y -FormatHourShortDuration =%H:%M -FormatHourShort =%H.%M -For =Per +FormatHourShortDuration =%H:%M +FormatHourShort =%H.%M +For =Per FreeZone =Testo libero Frequency =Frequenza FridayMin =Ven diff --git a/htdocs/langs/ja_JP/main.lang b/htdocs/langs/ja_JP/main.lang index 6f6201cb7ec..d4c93c068e5 100644 --- a/htdocs/langs/ja_JP/main.lang +++ b/htdocs/langs/ja_JP/main.lang @@ -9,9 +9,12 @@ FONTSIZEFORPDF=9 // Reference language: en_US -> ja_JP SeparatorDecimal=. SeparatorThousand=、 -FormatDateShort=%m/%d/%Y -FormatDateShortJava=MM/dd/yyyy -FormatDateShortJQuery=dd/mm/yy +FormatDateShort=%m/%d/%Y +FormatDateShortInput=%m/%d/%Y +FormatDateShortJava=MM/dd/yyyy +FormatDateShortJavaInput=MM/dd/yyyy +FormatDateShortJQuery=mm/dd/yy +FormatDateShortJQueryInput=mm/dd/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y diff --git a/htdocs/langs/nb_NO/main.lang b/htdocs/langs/nb_NO/main.lang index 203896ba362..123ed5a86ed 100644 --- a/htdocs/langs/nb_NO/main.lang +++ b/htdocs/langs/nb_NO/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H.%M FormatDateTextShort=%d. %b %Y FormatDateText=%d. %B %Y @@ -606,7 +610,6 @@ Day0=Søndag // START - Lines generated via autotranslator.php tool (2012-02-29 17:06:43). // Reference language: en_US -> nb_NO -FormatDateShortJQuery=dd/mm/yy AddLink=Legg til link Of=av SearchOf=Søk diff --git a/htdocs/langs/nl_BE/main.lang b/htdocs/langs/nl_BE/main.lang index 3d16e786aed..d4aff86e9c3 100644 --- a/htdocs/langs/nl_BE/main.lang +++ b/htdocs/langs/nl_BE/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/nl_NL/main.lang b/htdocs/langs/nl_NL/main.lang index 40947ca565f..100bd776c3a 100644 --- a/htdocs/langs/nl_NL/main.lang +++ b/htdocs/langs/nl_NL/main.lang @@ -4,7 +4,11 @@ DIRECTION = ltr SeparatorDecimal = , SeparatorThousand = . FormatDateShort = %d-%m-%Y +FormatDateShortInput = %d-%m-%Y FormatDateShortJava = dd-MM-yyyy +FormatDateShortJavaInput = dd-MM-yyyy +FormatDateShortJQuery=dd-mm-yy +FormatDateShortJQueryInput=dd-mm-yy FormatHourShort = %H:%M FormatHourShortDuration = %H:%M FormatDateTextShort = %d %b %Y @@ -590,7 +594,6 @@ ShortSunday = Zo // START - Lines generated via autotranslator.php tool (2011-10-10 01:46:39). // Reference language: en_US -> nl_NL -FormatDateShortJQuery=dd/mm/yy JanuaryMin=Jan FebruaryMin=Februari MarchMin=Mar diff --git a/htdocs/langs/pl_PL/main.lang b/htdocs/langs/pl_PL/main.lang index 5f725587178..41236b3456a 100644 --- a/htdocs/langs/pl_PL/main.lang +++ b/htdocs/langs/pl_PL/main.lang @@ -15,7 +15,11 @@ FONTSIZEFORPDF=8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d-%m-%Y +FormatDateShortInput=%d-%m-%Y FormatDateShortJava=dd-MM-yyyy +FormatDateShortJavaInput=dd-MM-yyyy +FormatDateShortJQuery=dd-mm-yy +FormatDateShortJQueryInput=dd-mm-yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -620,7 +624,6 @@ Prefix=Przedrostek // START - Lines generated via autotranslator.php tool (2012-02-29 17:18:29). // Reference language: en_US -> pl_PL -FormatDateShortJQuery=dd/mm/yy AddLink=Dodaj link Of=z SearchOf=Szukaj diff --git a/htdocs/langs/pt_PT/main.lang b/htdocs/langs/pt_PT/main.lang index 86d60b9b037..4df4d1ea5ec 100644 --- a/htdocs/langs/pt_PT/main.lang +++ b/htdocs/langs/pt_PT/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -601,7 +605,6 @@ Prefix=Prefixo // START - Lines generated via autotranslator.php tool (2012-02-29 15:45:52). // Reference language: en_US -> pt_PT -FormatDateShortJQuery=dd/mm/yy AddLink=Adicionar link Of=de SearchOf=Pesquisar diff --git a/htdocs/langs/ro_RO/main.lang b/htdocs/langs/ro_RO/main.lang index df4536746d8..8b7530a1702 100644 --- a/htdocs/langs/ro_RO/main.lang +++ b/htdocs/langs/ro_RO/main.lang @@ -13,7 +13,11 @@ FONTSIZEFORPDF=8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -618,7 +622,6 @@ Prefix=Prefix // START - Lines generated via autotranslator.php tool (2012-02-29 17:23:15). // Reference language: en_US -> ro_RO -FormatDateShortJQuery=dd/mm/yy AddLink=Adauga link-ul Of=de SearchOf=Căutare diff --git a/htdocs/langs/ru_RU/main.lang b/htdocs/langs/ru_RU/main.lang index 1d203fb98f0..30be774c29f 100644 --- a/htdocs/langs/ru_RU/main.lang +++ b/htdocs/langs/ru_RU/main.lang @@ -15,7 +15,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -628,7 +632,6 @@ Person=Персона // START - Lines generated via autotranslator.php tool (2011-08-18 23:26:41). // Reference language: en_US -> ru_RU -FormatDateShortJQuery=dd/mm/yy AddLink=Добавить ссылку Of=из AmountByMonth=Сумма за месяц diff --git a/htdocs/langs/ru_UA/main.lang b/htdocs/langs/ru_UA/main.lang index cef3a719ae0..cac36234fbf 100644 --- a/htdocs/langs/ru_UA/main.lang +++ b/htdocs/langs/ru_UA/main.lang @@ -10,7 +10,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/sl_SI/main.lang b/htdocs/langs/sl_SI/main.lang index 793d9498587..c79ca0d5dc5 100644 --- a/htdocs/langs/sl_SI/main.lang +++ b/htdocs/langs/sl_SI/main.lang @@ -6,8 +6,11 @@ FONTSIZEFORPDF=8 SeparatorDecimal = , SeparatorThousand = . FormatDateShort = %d/%m/%Y +FormatDateShortInput = %d/%m/%Y FormatDateShortJava = dd/MM/yyyy +FormatDateShortJavaInput = dd/MM/yyyy FormatDateShortJQuery = dd/mm/yy +FormatDateShortJQueryInput = dd/mm/yy FormatHourShort = %I:%M %p FormatHourShortDuration = %H:%M FormatDateTextShort = %d. %b, %Y diff --git a/htdocs/langs/sv_SE/main.lang b/htdocs/langs/sv_SE/main.lang index 55287b657a0..dde9641a208 100644 --- a/htdocs/langs/sv_SE/main.lang +++ b/htdocs/langs/sv_SE/main.lang @@ -12,7 +12,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%Y-%m-%d +FormatDateShortInput=%Y-%m-%d FormatDateShortJava=yyyy-MM-dd +FormatDateShortJavaInput=yyyy-MM-dd +FormatDateShortJQuery=yy-mm-dd +FormatDateShortJQueryInput=yy-mm-dd FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d %Y @@ -594,7 +598,6 @@ ShortSunday=S // START - Lines generated via autotranslator.php tool (2012-02-29 17:32:03). // Reference language: en_US -> sv_SE -FormatDateShortJQuery=dd/mm/yy AddLink=Tillsätt länk Of=av SearchOf=Sök diff --git a/htdocs/langs/tr_TR/main.lang b/htdocs/langs/tr_TR/main.lang index 7f372bf7dd5..8862e8b7635 100644 --- a/htdocs/langs/tr_TR/main.lang +++ b/htdocs/langs/tr_TR/main.lang @@ -14,8 +14,11 @@ FONTSIZEFORPDF=8 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/zh_CN/main.lang b/htdocs/langs/zh_CN/main.lang index 04235a1bd69..04c6ee545bd 100644 --- a/htdocs/langs/zh_CN/main.lang +++ b/htdocs/langs/zh_CN/main.lang @@ -17,7 +17,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=. SeparatorThousand=None FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatDateTextShort=%b %d, %Y FormatDateText=%B %d, %Y @@ -604,7 +608,6 @@ Prefix=字首 // START - Lines generated via autotranslator.php tool (2012-02-29 17:37:09). // Reference language: en_US -> zh_CN -FormatDateShortJQuery=dd/mm/yy AddLink=添加链接 Of=的 SearchOf=搜索 diff --git a/htdocs/langs/zh_TW/main.lang b/htdocs/langs/zh_TW/main.lang index b853fbb6073..aff84edf1ef 100644 --- a/htdocs/langs/zh_TW/main.lang +++ b/htdocs/langs/zh_TW/main.lang @@ -13,7 +13,11 @@ FONTFORPDF=msungstdlight SeparatorDecimal=. SeparatorThousand=None FormatDateShort=%Y/%m/%d +FormatDateShortInput=%Y/%m/%d FormatDateShortJava=yyyy/MM/dd +FormatDateShortJavaInput=yyyy/MM/dd +FormatDateShortJQuery=yy/mm/dd +FormatDateShortJQueryInput=yy/mm/dd FormatHourShort=%I:%M %p FormatDateTextShort=%Y %b %d FormatDateText=%Y %B %d @@ -600,7 +604,6 @@ Prefix=字首 // START - Lines generated via autotranslator.php tool (2012-02-29 17:37:09). // Reference language: en_US -> zh_CN -FormatDateShortJQuery=dd/mm/yy AddLink=添加鏈接 Of=的 SearchOf=搜尋 From ac8868e2d2b7bc4624ee8f062f51defed28bc0ab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Apr 2013 19:56:14 +0200 Subject: [PATCH 11/97] Fix: Use correct format for js --- htdocs/core/get_menudiv.php | 5 ----- htdocs/core/search_page.php | 5 ----- htdocs/langs/de_AT/main.lang | 2 ++ htdocs/projet/ganttview.php | 4 ++-- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/htdocs/core/get_menudiv.php b/htdocs/core/get_menudiv.php index 0d9e3c0a54b..51bda89ffd0 100644 --- a/htdocs/core/get_menudiv.php +++ b/htdocs/core/get_menudiv.php @@ -40,11 +40,6 @@ $langs->load("main"); $right=($langs->trans("DIRECTION")=='rtl'?'left':'right'); $left=($langs->trans("DIRECTION")=='rtl'?'right':'left'); -//var_dump($langs->defaultlang); -//var_dump($conf->format_date_short_java); -//var_dump($langs->trans("FormatDateShortJava")); - - /* * View diff --git a/htdocs/core/search_page.php b/htdocs/core/search_page.php index 3cab48155ae..fe21a82c56f 100644 --- a/htdocs/core/search_page.php +++ b/htdocs/core/search_page.php @@ -40,11 +40,6 @@ $langs->load("main"); $right=($langs->trans("DIRECTION")=='rtl'?'left':'right'); $left=($langs->trans("DIRECTION")=='rtl'?'right':'left'); -//var_dump($langs->defaultlang); -//var_dump($conf->format_date_short_java); -//var_dump($langs->trans("FormatDateShortJava")); - - /* * View diff --git a/htdocs/langs/de_AT/main.lang b/htdocs/langs/de_AT/main.lang index 095cf44e5e2..6a44f3dbfee 100644 --- a/htdocs/langs/de_AT/main.lang +++ b/htdocs/langs/de_AT/main.lang @@ -13,6 +13,8 @@ FormatDateShort=%d/%m/%Y FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/MM/yy +FormatDateShortJQueryInput=dd/MM/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index 3a36fd1f591..e19571f9518 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -184,8 +184,8 @@ if (count($tasksarray)>0) // Show Gant diagram from $taskarray using JSGantt - $dateformat=$langs->trans("FormatDateShort"); - $dateformat=strtolower($langs->trans("FormatDateShortJava")); + $dateformat=$langs->trans("FormatDateShort"); // Used by include ganttchart.php later + $dateformat=$langs->trans("FormatDateShortJQuery"); // Used by include ganttchart.php later $array_contacts=array(); $tasks=array(); $project_dependencies=array(); From 6860aa05c7027152496bb3b304309f1764932320 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Apr 2013 00:20:21 +0200 Subject: [PATCH 12/97] Fix: Missing test --- htdocs/societe/societe.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/societe/societe.php b/htdocs/societe/societe.php index 26583442b2c..93401eaebf0 100644 --- a/htdocs/societe/societe.php +++ b/htdocs/societe/societe.php @@ -122,7 +122,7 @@ if ($mode == 'search') if ($search_type > 0 && in_array($search_type,array('1,3','2,3'))) $sql .= " AND s.client IN (".$db->escape($search_type).")"; if ($search_type > 0 && in_array($search_type,array('4'))) $sql .= " AND s.fournisseur = 1"; if ($search_type == '0') $sql .= " AND s.client = 0 AND s.fournisseur = 0"; - + $result=$db->query($sql); if ($result) { @@ -365,13 +365,13 @@ if ($resql) print ''; - // Status + // Status print ' - + margin->enabled)) { @@ -373,6 +376,11 @@ $(document).ready(function() { $('#price_ttc').attr('disabled','disabled'); } + $('#remise_percent').bind('change', function() { + if ($(this).val() < $('#origin_remise_percent').val()) + $('#remise_percent').val($('#origin_remise_percent').val()); + }); + $('#tva_tx').change(function() { if ($(this).val() == 0) { if ($('#idprod').val() == 0) { From 5d7b94f6610a94f8204965bfe6ac78ca8a3f7a2a Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 19 Apr 2013 13:30:08 +0200 Subject: [PATCH 23/97] Fix: the purchase price, manually entered is not taken recovered --- htdocs/core/class/commonobject.class.php | 285 ++++++++++++----------- 1 file changed, 148 insertions(+), 137 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9f8a2aabf7d..6d8dfff5934 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2946,11 +2946,11 @@ abstract class CommonObject global $conf,$langs,$bc; //var_dump($line); - if (!empty($line->date_start)) - { + if (!empty($line->date_start)) + { $date_start=$line->date_start; } - else + else { $date_start=$line->date_debut_prevue; if ($line->date_debut_reel) $date_start=$line->date_debut_reel; @@ -2959,7 +2959,7 @@ abstract class CommonObject { $date_end=$line->date_end; } - else + else { $date_end=$line->date_fin_prevue; if ($line->date_fin_reel) $date_end=$line->date_fin_reel; @@ -2995,7 +2995,7 @@ abstract class CommonObject $this->tpl['label'].=$line->desc; }else { $this->tpl['label'].= ($line->label ? ' '.$line->label : ''); - } + } // Dates if ($line->product_type == 1 && ($date_start || $date_end)) { @@ -3048,149 +3048,160 @@ abstract class CommonObject } + /** + * + * @param string $force_price + * @return multitype:number string NULL + */ + function getMarginInfos($force_price=false) { + global $conf; + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - function getMarginInfos($force_price=false) { - global $conf; - require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - $marginInfos = array( - 'pa_products' => 0, - 'pv_products' => 0, - 'margin_on_products' => 0, - 'margin_rate_products' => '', - 'mark_rate_products' => '', - 'pa_services' => 0, - 'pv_services' => 0, - 'margin_on_services' => 0, - 'margin_rate_services' => '', - 'mark_rate_services' => '', - 'pa_total' => 0, - 'pv_total' => 0, - 'total_margin' => 0, - 'total_margin_rate' => '', - 'total_mark_rate' => '' - ); - foreach($this->lines as $line) { - if (isset($line->fk_fournprice) && !$force_price) { - $product = new ProductFournisseur($this->db); - if ($product->fetch_product_fournisseur_price($line->fk_fournprice)) - $line->pa_ht = $product->fourn_unitprice; - if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == "2" && $product->fourn_unitcharges > 0) - $line->pa_ht += $product->fourn_unitcharges; - } - // si prix d'achat non renseigné et devrait l'être, alors prix achat = prix vente - if ((!isset($line->pa_ht) || $line->pa_ht == 0) && $line->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) { - $line->pa_ht = $line->subprice * (1 - ($line->remise_percent / 100)); - } + $marginInfos = array( + 'pa_products' => 0, + 'pv_products' => 0, + 'margin_on_products' => 0, + 'margin_rate_products' => '', + 'mark_rate_products' => '', + 'pa_services' => 0, + 'pv_services' => 0, + 'margin_on_services' => 0, + 'margin_rate_services' => '', + 'mark_rate_services' => '', + 'pa_total' => 0, + 'pv_total' => 0, + 'total_margin' => 0, + 'total_margin_rate' => '', + 'total_mark_rate' => '' + ); - // calcul des marges - if (isset($line->fk_remise_except) && isset($conf->global->MARGIN_METHODE_FOR_DISCOUNT)) { // remise - if ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '1') { // remise globale considérée comme produit - $marginInfos['pa_products'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_products'] += $line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100); + foreach($this->lines as $line) { + if (empty($line->pa_ht) && isset($line->fk_fournprice) && !$force_price) { + $product = new ProductFournisseur($this->db); + if ($product->fetch_product_fournisseur_price($line->fk_fournprice)) + $line->pa_ht = $product->fourn_unitprice; + if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == "2" && $product->fourn_unitcharges > 0) + $line->pa_ht += $product->fourn_unitcharges; + } + // si prix d'achat non renseigné et devrait l'être, alors prix achat = prix vente + if ((!isset($line->pa_ht) || $line->pa_ht == 0) && $line->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) { + $line->pa_ht = $line->subprice * (1 - ($line->remise_percent / 100)); + } + + // calcul des marges + if (isset($line->fk_remise_except) && isset($conf->global->MARGIN_METHODE_FOR_DISCOUNT)) { // remise + if ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '1') { // remise globale considérée comme produit + $marginInfos['pa_products'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pv_products'] += $line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100); } - elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '2') { // remise globale considérée comme service - $marginInfos['pa_services'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_services'] += $line->subprice * (1 - ($line->remise_percent / 100)); - $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100); + elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '2') { // remise globale considérée comme service + $marginInfos['pa_services'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pv_services'] += $line->subprice * (1 - ($line->remise_percent / 100)); + $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100); } - elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '3') { // remise globale prise en compte uniqt sur total - $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_total'] += $line->subprice * (1 - ($line->remise_percent / 100)); + elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '3') { // remise globale prise en compte uniqt sur total + $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pv_total'] += $line->subprice * (1 - ($line->remise_percent / 100)); } } - else { - $type=$line->product_type?$line->product_type:$line->fk_product_type; - if ($type == 0) { // product - $marginInfos['pa_products'] += $line->qty * $line->pa_ht; - $marginInfos['pv_products'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pa_total'] += $line->qty * $line->pa_ht; - $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); - } - elseif ($type == 1) { // service - $marginInfos['pa_services'] += $line->qty * $line->pa_ht; - $marginInfos['pv_services'] += $line->qty * $line->subprice * (1 - ($line->remise_percent / 100)); - $marginInfos['pa_total'] += $line->qty * $line->pa_ht; - $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); - } - } - } + else { + $type=$line->product_type?$line->product_type:$line->fk_product_type; + if ($type == 0) { // product + $marginInfos['pa_products'] += $line->qty * $line->pa_ht; + $marginInfos['pv_products'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pa_total'] += $line->qty * $line->pa_ht; + $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + } + elseif ($type == 1) { // service + $marginInfos['pa_services'] += $line->qty * $line->pa_ht; + $marginInfos['pv_services'] += $line->qty * $line->subprice * (1 - ($line->remise_percent / 100)); + $marginInfos['pa_total'] += $line->qty * $line->pa_ht; + $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + } + } + } - $marginInfos['margin_on_products'] = $marginInfos['pv_products'] - $marginInfos['pa_products']; - if ($marginInfos['pa_products'] > 0) - $marginInfos['margin_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pa_products'],5); - if ($marginInfos['pv_products'] > 0) - $marginInfos['mark_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pv_products'],5); + $marginInfos['margin_on_products'] = $marginInfos['pv_products'] - $marginInfos['pa_products']; + if ($marginInfos['pa_products'] > 0) + $marginInfos['margin_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pa_products'],5); + if ($marginInfos['pv_products'] > 0) + $marginInfos['mark_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pv_products'],5); - $marginInfos['margin_on_services'] = $marginInfos['pv_services'] - $marginInfos['pa_services']; - if ($marginInfos['pa_services'] > 0) - $marginInfos['margin_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pa_services'],5); - if ($marginInfos['pv_services'] > 0) - $marginInfos['mark_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pv_services'],5); + $marginInfos['margin_on_services'] = $marginInfos['pv_services'] - $marginInfos['pa_services']; + if ($marginInfos['pa_services'] > 0) + $marginInfos['margin_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pa_services'],5); + if ($marginInfos['pv_services'] > 0) + $marginInfos['mark_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pv_services'],5); + $marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total']; + if ($marginInfos['pa_total'] > 0) + $marginInfos['total_margin_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pa_total'],5); + if ($marginInfos['pv_total'] > 0) + $marginInfos['total_mark_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pv_total'],5); - $marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total']; - if ($marginInfos['pa_total'] > 0) - $marginInfos['total_margin_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pa_total'],5); - if ($marginInfos['pv_total'] > 0) - $marginInfos['total_mark_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pv_total'],5); + return $marginInfos; + } - return $marginInfos; - } + /** + * + * @param string $force_price + */ + function displayMarginInfos($force_price=false) { + global $langs, $conf; + + $marginInfo = $this->getMarginInfos($force_price); + + print '
trans("FormatDateShortJava")."')\""; + echo " onClick=\"dpClickDay(".$mydate["year"].",parseInt('".dol_print_date($thedate,"%m")."',10),".$mydate["mday"].",'".$langs->trans("FormatDateShortJavaInput")."')\""; echo ">".sprintf("%02s",$mydate["mday"])."'; print ''; print ''; print '  '; From 738ed467b37641eb62b55602d0289265e72ec6b6 Mon Sep 17 00:00:00 2001 From: fhenry Date: Fri, 19 Apr 2013 07:54:55 +0200 Subject: [PATCH 13/97] Fix bug on update invoice line in PgSQL --- htdocs/compta/facture/class/facture.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index fa03d8527b0..a8f80335496 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3553,7 +3553,7 @@ class FactureLigne $sql.= ",total_localtax1=".price2num($this->total_localtax1).""; $sql.= ",total_localtax2=".price2num($this->total_localtax2).""; } - $sql.= " , fk_product_fournisseur_price='".$this->fk_fournprice."'"; + $sql.= " , fk_product_fournisseur_price=".(! empty($this->fk_fournprice)?"'".$this->db->escape($this->fk_fournprice)."'":"null"); $sql.= " , buy_price_ht='".price2num($this->pa_ht)."'"; $sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null"); if (! empty($this->rang)) $sql.= ", rang=".$this->rang; From d5a4f73501c459bdee3070d96c327f744f4adfb8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Apr 2013 09:10:56 +0200 Subject: [PATCH 14/97] Add fill/reset --- htdocs/langs/en_US/main.lang | 2 ++ htdocs/langs/fr_FR/main.lang | 2 ++ 2 files changed, 4 insertions(+) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 28de6467cbb..e7e8b880297 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -472,6 +472,8 @@ Report=Report Keyword=Mot clé Legend=Legend FillTownFromZip=Fill city from zip +Fill=Fill +Reset=Reset ShowLog=Show log File=File Files=Files diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index b31b711f3a3..5880a20f284 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -475,6 +475,8 @@ Report=Rapport Keyword=Mot clé Legend=Légende FillTownFromZip=Renseigner ville +Fill=Remplir +Reset=Vider ShowLog=Afficher historique File=Fichier Files=Fichiers From 5c1b3d86c36a71bc6457c14673f564c3fec4b635 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Apr 2013 09:44:37 +0200 Subject: [PATCH 15/97] Fix: Uniformize pdf code for typhon. This should also solve problem of overlapped text into delivery receipts. --- .../livraison/pdf/pdf_typhon.modules.php | 383 +++++++++++------- 1 file changed, 232 insertions(+), 151 deletions(-) diff --git a/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php b/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php index c4a1150d505..adf1b8689b1 100644 --- a/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php +++ b/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php @@ -38,6 +38,22 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; */ class pdf_typhon extends ModelePDFDeliveryOrder { + 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 /** @@ -75,26 +91,26 @@ class pdf_typhon extends ModelePDFDeliveryOrder $this->franchise=!$mysoc->tva_assuj; - // Recupere emmetteur + // Get source company $this->emetteur=$mysoc; - if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default if not defined + if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined - // Defini position des colonnes + // Define position of columns $this->posxdesc=$this->marge_gauche+1; - $this->posxcomm=120; + $this->posxcomm=111; //$this->posxtva=111; - $this->posxup=132; - $this->posxqty=168; - $this->posxdiscount=162; - $this->postotalht=177; + //$this->posxup=126; + $this->posxqty=174; + //$this->posxdiscount=162; + //$this->postotalht=174; if ($this->page_largeur < 210) // To work with US executive format { $this->posxcomm-=20; //$this->posxtva-=20; - $this->posxup-=20; + //$this->posxup-=20; $this->posxqty-=20; - $this->posxdiscount-=20; - $this->postotalht-=20; + //$this->posxdiscount-=20; + //$this->postotalht-=20; } $this->tva=array(); @@ -104,15 +120,19 @@ class pdf_typhon extends ModelePDFDeliveryOrder /** - * Fonction generant le bon de livraison sur le disque - * - * @param Object $object Object livraison a generer - * @param Translate $outputlangs Lang output object - * @return int 1 if OK, <=0 if KO + * 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) + function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0) { - global $user,$langs,$conf; + global $user,$langs,$conf,$mysoc,$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 @@ -126,17 +146,23 @@ class pdf_typhon extends ModelePDFDeliveryOrder $outputlangs->load("deliveries"); $outputlangs->load("sendings"); - if ($conf->expedition->dir_output."/receipt") + if ($conf->expedition->dir_output) { $object->fetch_thirdparty(); - $nblines = count($object->lines); - - $objectref = dol_sanitizeFileName($object->ref); - $dir = $conf->expedition->dir_output."/receipt"; - if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; - $file = $dir . "/" . $objectref . ".pdf"; - + // Definition of $dir and $file + if ($object->specimen) + { + $dir = $conf->expedition->dir_output."/receipt"; + $file = $dir . "/SPECIMEN.pdf"; + } + else + { + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->expedition->dir_output."/receipt/" . $objectref; + $file = $dir . "/" . $objectref . ".pdf"; + } + if (! file_exists($dir)) { if (dol_mkdir($dir) < 0) @@ -148,9 +174,12 @@ class pdf_typhon extends ModelePDFDeliveryOrder if (file_exists($dir)) { - $pdf=pdf_getInstance($this->format); + $nblines = count($object->lines); + + // Create pdf instance + $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 + $heightforinfotot = 30; // 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); @@ -195,7 +224,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder /* // Positionne $this->atleastonediscount si on a au moins une remise - for ($i = 0 ; $i < $nblignes ; $i++) + for ($i = 0 ; $i < $nblines ; $i++) { if ($object->lines[$i]->remise_percent) { @@ -214,7 +243,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetTextColor(0,0,0); $tab_top = 90; - $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?22:10); + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42:10); $tab_height = 130; $tab_height_newpage = 150; @@ -223,7 +252,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder { $tab_top = 88; - $pdf->SetFont('','', $default_font_size - 1); // Dans boucle pour gerer multi-page + $pdf->SetFont('','', $default_font_size - 1); $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($object->note_public), 0, 1); $nexY = $pdf->GetY(); $height_note=$nexY-$tab_top; @@ -252,13 +281,46 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetTextColor(0,0,0); $pdf->setTopMargin($tab_top_newpage); - $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext); // The only function to edit the bottom margin of current page to set it. + $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->posxdesc-1; - pdf_writelinedesc($pdf,$object,$i,$outputlangs,108,3,$curX,$curY); + $showpricebeforepagebreak=1; + + $pdf->startTransaction(); + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxcomm-$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->posxcomm-$curX,4,$curX,$curY,$hideref,$hidedesc); + $posyafter=$pdf->GetY(); + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblines-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($pagenb+1); + } + } + else + { + // We found a page break + $showpricebeforepagebreak=0; + } + } + else // No pagebreak + { + $pdf->commitTransaction(); + } + $nexY = $pdf->GetY(); $pageposafter=$pdf->getPage(); $pdf->setPage($pageposbefore); @@ -266,17 +328,15 @@ class pdf_typhon extends ModelePDFDeliveryOrder $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) { + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { $pdf->setPage($pageposafter); $curY = $tab_top_newpage; } $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut - $nexY = $pdf->GetY()+4; - /* // TVA - $pdf->SetXY($this->posxtva, $curY); + $pdf->SetXY($this->posxcomm, $curY); $pdf->MultiCell(10, 4, ($object->lines[$i]->tva_tx < 0 ? '*':'').abs($object->lines[$i]->tva_tx), 0, 'R'); // Prix unitaire HT avant remise @@ -284,8 +344,9 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->MultiCell(20, 4, price($object->lines[$i]->subprice), 0, 'R', 0); */ // Quantity + //$qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxqty, $curY); - $pdf->MultiCell(30, 3, $object->lines[$i]->qty_shipped, 0, 'R'); + $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->posxqty, 3, $object->lines[$i]->qty_shipped, 0, 'R'); /* // Remise sur ligne $pdf->SetXY($this->posxdiscount, $curY); @@ -307,7 +368,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder */ // Add line - if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1)) + if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(210,210,210))); //$pdf->SetDrawColor(190,190,200); @@ -333,6 +394,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $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) { @@ -349,34 +411,38 @@ class pdf_typhon extends ModelePDFDeliveryOrder $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); - $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfooter + 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); - $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfooter + 1; + $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; } - /* - * Pied de page - */ + // Affiche zone infos + $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); + + // Pied de page $this->_pagefoot($pdf,$object,$outputlangs); - + $pdf->AliasNbPages(); + // Check product remaining to be delivered // TODO doit etre modifie //$waitingDelivery = $object->getRemainingDelivered(); + /* $waitingDelivery=''; if (is_array($waitingDelivery) & !empty($waitingDelivery)) { - $pdf->AddPage('P', 'A4'); + $pdf->AddPage(); $this->_pagehead($pdf, $object, 1, $outputlangs); $pdf-> SetY(90); @@ -426,17 +492,28 @@ class pdf_typhon extends ModelePDFDeliveryOrder $this->_pagefoot($pdf,$object,$outputlangs); - } - - $pdf->AliasNbPages(); + $pdf->AliasNbPages(); + }*/ $pdf->Close(); $pdf->Output($file,'F'); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($file, octdec($conf->global->MAIN_UMASK)); - return 1; + // 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('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 { @@ -449,66 +526,90 @@ class pdf_typhon extends ModelePDFDeliveryOrder return 0; } - + /** + * 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); + $pdf->SetXY($this->marge_gauche, $posy); + + $larg_sign = ($this->page_largeur-$this->marge_gauche-$this->marge_droite)/3; + $pdf->Rect($this->marge_gauche, $posy + 1, $larg_sign, 25); + $pdf->SetXY($this->marge_gauche + 2, $posy + 2); + $pdf->MultiCell($larg_sign,2, $outputlangs->trans("For").' '.$outputlangs->convToOutputCharset($mysoc->name).":",'','L'); + + $pdf->Rect(2*$larg_sign+$this->marge_gauche, $posy + 1, $larg_sign, 25); + $pdf->SetXY(2*$larg_sign+$this->marge_gauche + 2, $posy + 2); + $pdf->MultiCell($larg_sign,2, $outputlangs->trans("ForCustomer").':','','L'); + } + /** * 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 + * @param int $nexY Y (not used) * @param Translate $outputlangs Langs object - * @param int $hidetop Hide top bar of array + * @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,$mysoc; + + // Force to disable hidetop and hidebottom + $hidebottom=0; + if ($hidetop) $hidetop=-1; + $default_font_size = pdf_getPDFFontSize($outputlangs); - - $pdf->SetDrawColor(128,128,128); - - // Rect prend une longueur en 3eme param - $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height); - // line prend une position y en 3eme param - if (empty($hidetop)) - $pdf->line($this->marge_gauche, $tab_top+6, $this->page_largeur-$this->marge_droite, $tab_top+6); - + + // Amount in (at tab_top - 1) $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + + // Output Rec + $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+6, $this->page_largeur-$this->marge_droite, $tab_top+6); + } + + $pdf->SetDrawColor(128,128,128); $pdf->SetFont('','', $default_font_size - 1); - if (empty($hidetop)) { + if (empty($hidetop)) + { $pdf->SetXY($this->posxdesc-1, $tab_top+1); - $pdf->MultiCell(80,2, $outputlangs->transnoentities("Designation"),'','L'); + $pdf->MultiCell($this->posxcomm - $this->posxdesc,2, $outputlangs->transnoentities("Designation"),'','L'); } // Modif SEB pour avoir une col en plus pour les commentaires clients $pdf->line($this->posxcomm, $tab_top, $this->posxcomm, $tab_top + $tab_height); if (empty($hidetop)) { $pdf->SetXY($this->posxcomm, $tab_top+1); - $pdf->MultiCell(80,2, $outputlangs->transnoentities("Comments"),'','L'); + $pdf->MultiCell($this->posxqty - $this->posxcomm,2, $outputlangs->transnoentities("Comments"),'','L'); } // Qty $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); - $pdf->MultiCell(30, 2, $outputlangs->transnoentities("QtyShipped"),'','R'); + $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->posxqty, 2, $outputlangs->transnoentities("QtyShipped"),'','R'); } - if (empty($hidebottom)) { - // Modif Seb cadres signatures - $pdf->SetFont('','', $default_font_size); - $larg_sign = ($this->page_largeur-$this->marge_gauche-$this->marge_droite)/3; - $pdf->Rect($this->marge_gauche, ($tab_top + $tab_height + 3), $larg_sign, 25); - $pdf->SetXY($this->marge_gauche + 2, $tab_top + $tab_height + 5); - $pdf->MultiCell($larg_sign,2, $outputlangs->trans("For").' '.$outputlangs->convToOutputCharset($mysoc->name).":",'','L'); - - $pdf->Rect(2*$larg_sign+$this->marge_gauche, ($tab_top + $tab_height + 3), $larg_sign, 25); - $pdf->SetXY(2*$larg_sign+$this->marge_gauche + 2, $tab_top + $tab_height + 5); - $pdf->MultiCell($larg_sign,2, $outputlangs->trans("ForCustomer").':','','L'); - } } /** @@ -522,22 +623,29 @@ class pdf_typhon extends ModelePDFDeliveryOrder */ function _pagehead(&$pdf, $object, $showaddress, $outputlangs) { - global $langs,$conf,$mysoc; + global $conf,$langs,$hookmanager; + $default_font_size = pdf_getPDFFontSize($outputlangs); pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); - $pdf->SetTextColor(0,0,60); - $pdf->SetFont('','B', $default_font_size + 3); - - $posx=$this->page_largeur-$this->marge_droite-100; - $posy=$this->marge_haute; - - $pdf->SetXY($this->marge_gauche,$posy); - + // Show Draft Watermark + if($object->statut==0 && (! empty($conf->global->COMMANDE_DRAFT_WATERMARK)) ) + { + pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->COMMANDE_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/'.$mysoc->logo; - if ($mysoc->logo) + $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; + if ($this->emetteur->logo) { if (is_readable($logo)) { @@ -548,8 +656,8 @@ class pdf_typhon extends ModelePDFDeliveryOrder { $pdf->SetTextColor(200,0,0); $pdf->SetFont('','B', $default_font_size - 2); - $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); - $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorGoToModuleSetup"), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); } } else $pdf->MultiCell(100, 4, $this->emetteur->name, 0, 'L'); @@ -557,7 +665,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetFont('','B', $default_font_size + 2); $pdf->SetXY($posx,$posy); $pdf->SetTextColor(0,0,60); - $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DeliveryOrder")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DeliveryOrder")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R'); $pdf->SetFont('','',$default_font_size + 2); @@ -585,69 +693,42 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetTextColor(0,0,60); - // Add origin linked objects - // TODO extend to other objects - $object->fetchObjectLinked('','',$object->id,'delivery'); - - if (! empty($object->linkedObjects)) - { - $outputlangs->load('orders'); - - foreach($object->linkedObjects as $elementtype => $objects) - { - $object->fetchObjectLinked('','',$objects[0]->id,$objects[0]->element); - - foreach($object->linkedObjects as $elementtype => $objects) - { - $num=count($objects); - for ($i=0;$i<$num;$i++) - { - $order=new Commande($this->db); - $result=$order->fetch($objects[$i]->id); - if ($result >= 0) - { - $posy+=5; - $pdf->SetXY($posx,$posy); - $pdf->SetFont('','', $default_font_size - 1); - $text=$order->ref; - if ($order->ref_client) $text.=' ('.$order->ref_client.')'; - $pdf->MultiCell(100, 4, $outputlangs->transnoentities("RefOrder")." : ".$outputlangs->transnoentities($text), '', 'R'); - } - } - } - } - } - + $posy+=2; + + // Show list of linked objects + $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); + if ($showaddress) { - // Emetteur + // Sender properties + $carac_emetteur = pdf_build_address($outputlangs,$this->emetteur); + + // 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($this->marge_gauche,$posy-5); - $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":"); - - - $pdf->SetXY($this->marge_gauche,$posy); + $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->SetXY($this->marge_gauche+2,$posy+3); - - // Nom emetteur $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'); - // Sender properties - $carac_emetteur = pdf_build_address($outputlangs,$this->emetteur); - - $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($this->marge_gauche+2,$posy+9); - $pdf->MultiCell(80, 3, $carac_emetteur, 0, 'L'); - + // Show sender information + $pdf->SetXY($posx+2,$posy+8); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); + // Client destinataire $posy=42; $pdf->SetTextColor(0,0,0); @@ -655,7 +736,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetXY(102,$posy-5); $pdf->MultiCell(80,5, $outputlangs->transnoentities("DeliveryAddress").":", 0, 'L'); - // If SHIPPING contact defined on invoice, we use it + // If SHIPPING contact defined on order, we use it $usecontact=false; $arrayidcontact=$object->commande->getIdContact('external','SHIPPING'); if (count($arrayidcontact) > 0) @@ -677,7 +758,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $carac_client_name=$outputlangs->convToOutputCharset($object->client->nom); } - $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->client,$object->contact,$usecontact,'target'); + $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->client,($usecontact?$object->contact:''),$usecontact,'target'); // Show recipient $widthrecbox=100; @@ -700,7 +781,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+8); + $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } @@ -713,7 +794,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text - * @return void + * @return int Return height of bottom margin including footer text */ function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0) { From 3e9a8677c6f26826b43fee1a0e535946099f0143 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 19 Apr 2013 09:48:55 +0200 Subject: [PATCH 16/97] Fix: no result with a number with a comma --- htdocs/compta/facture/list.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index a27041c82a5..1222a5bdb4a 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -3,7 +3,7 @@ * Copyright (C) 2004 Eric Seigne * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2010-2012 Juanjo Menent * Copyright (C) 2012 Christophe Battarel @@ -184,11 +184,11 @@ if ($search_societe) } if ($search_montant_ht) { - $sql.= ' AND f.total = \''.$db->escape(trim($search_montant_ht)).'\''; + $sql.= ' AND f.total = \''.$db->escape(price2num(trim($search_montant_ht))).'\''; } if ($search_montant_ttc) { - $sql.= ' AND f.total_ttc = \''.$db->escape(trim($search_montant_ttc)).'\''; + $sql.= ' AND f.total_ttc = \''.$db->escape(price2num(trim($search_montant_ttc))).'\''; } if ($month > 0) { From df0b0ebf51d6289cc3269afc9573702d03483ccd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Apr 2013 09:52:25 +0200 Subject: [PATCH 17/97] Fix: Uniformize pdf code for typhon. This should also solve problem of overlapped text into delivery receipts. Conflicts: htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php --- .../livraison/pdf/pdf_typhon.modules.php | 383 +++++++++++------- 1 file changed, 232 insertions(+), 151 deletions(-) diff --git a/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php b/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php index 0e65800698a..adf1b8689b1 100644 --- a/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php +++ b/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php @@ -38,6 +38,22 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; */ class pdf_typhon extends ModelePDFDeliveryOrder { + 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 /** @@ -75,26 +91,26 @@ class pdf_typhon extends ModelePDFDeliveryOrder $this->franchise=!$mysoc->tva_assuj; - // Recupere emmetteur + // Get source company $this->emetteur=$mysoc; - if (! $this->emetteur->pays_code) $this->emetteur->pays_code=substr($langs->defaultlang,-2); // Par defaut, si n'�tait pas d�fini + if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined - // Defini position des colonnes + // Define position of columns $this->posxdesc=$this->marge_gauche+1; - $this->posxcomm=120; + $this->posxcomm=111; //$this->posxtva=111; - $this->posxup=132; - $this->posxqty=168; - $this->posxdiscount=162; - $this->postotalht=177; + //$this->posxup=126; + $this->posxqty=174; + //$this->posxdiscount=162; + //$this->postotalht=174; if ($this->page_largeur < 210) // To work with US executive format { $this->posxcomm-=20; //$this->posxtva-=20; - $this->posxup-=20; + //$this->posxup-=20; $this->posxqty-=20; - $this->posxdiscount-=20; - $this->postotalht-=20; + //$this->posxdiscount-=20; + //$this->postotalht-=20; } $this->tva=array(); @@ -104,15 +120,19 @@ class pdf_typhon extends ModelePDFDeliveryOrder /** - * Fonction generant le bon de livraison sur le disque - * - * @param Object $object Object livraison a generer - * @param Translate $outputlangs Lang output object - * @return int 1 if OK, <=0 if KO + * 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) + function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0) { - global $user,$langs,$conf; + global $user,$langs,$conf,$mysoc,$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 @@ -126,17 +146,23 @@ class pdf_typhon extends ModelePDFDeliveryOrder $outputlangs->load("deliveries"); $outputlangs->load("sendings"); - if ($conf->expedition->dir_output."/receipt") + if ($conf->expedition->dir_output) { $object->fetch_thirdparty(); - $nblines = count($object->lines); - - $objectref = dol_sanitizeFileName($object->ref); - $dir = $conf->expedition->dir_output."/receipt"; - if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; - $file = $dir . "/" . $objectref . ".pdf"; - + // Definition of $dir and $file + if ($object->specimen) + { + $dir = $conf->expedition->dir_output."/receipt"; + $file = $dir . "/SPECIMEN.pdf"; + } + else + { + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->expedition->dir_output."/receipt/" . $objectref; + $file = $dir . "/" . $objectref . ".pdf"; + } + if (! file_exists($dir)) { if (dol_mkdir($dir) < 0) @@ -148,9 +174,12 @@ class pdf_typhon extends ModelePDFDeliveryOrder if (file_exists($dir)) { - $pdf=pdf_getInstance($this->format); + $nblines = count($object->lines); + + // Create pdf instance + $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 + $heightforinfotot = 30; // 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); @@ -195,7 +224,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder /* // Positionne $this->atleastonediscount si on a au moins une remise - for ($i = 0 ; $i < $nblignes ; $i++) + for ($i = 0 ; $i < $nblines ; $i++) { if ($object->lines[$i]->remise_percent) { @@ -214,7 +243,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetTextColor(0,0,0); $tab_top = 90; - $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?22:10); + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42:10); $tab_height = 130; $tab_height_newpage = 150; @@ -223,7 +252,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder { $tab_top = 88; - $pdf->SetFont('','', $default_font_size - 1); // Dans boucle pour gerer multi-page + $pdf->SetFont('','', $default_font_size - 1); $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($object->note_public), 0, 1); $nexY = $pdf->GetY(); $height_note=$nexY-$tab_top; @@ -252,13 +281,46 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetTextColor(0,0,0); $pdf->setTopMargin($tab_top_newpage); - $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext); // The only function to edit the bottom margin of current page to set it. + $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->posxdesc-1; - pdf_writelinedesc($pdf,$object,$i,$outputlangs,108,3,$curX,$curY); + $showpricebeforepagebreak=1; + + $pdf->startTransaction(); + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxcomm-$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->posxcomm-$curX,4,$curX,$curY,$hideref,$hidedesc); + $posyafter=$pdf->GetY(); + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblines-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($pagenb+1); + } + } + else + { + // We found a page break + $showpricebeforepagebreak=0; + } + } + else // No pagebreak + { + $pdf->commitTransaction(); + } + $nexY = $pdf->GetY(); $pageposafter=$pdf->getPage(); $pdf->setPage($pageposbefore); @@ -266,17 +328,15 @@ class pdf_typhon extends ModelePDFDeliveryOrder $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) { + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { $pdf->setPage($pageposafter); $curY = $tab_top_newpage; } $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut - $nexY = $pdf->GetY()+4; - /* // TVA - $pdf->SetXY($this->posxtva, $curY); + $pdf->SetXY($this->posxcomm, $curY); $pdf->MultiCell(10, 4, ($object->lines[$i]->tva_tx < 0 ? '*':'').abs($object->lines[$i]->tva_tx), 0, 'R'); // Prix unitaire HT avant remise @@ -284,8 +344,9 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->MultiCell(20, 4, price($object->lines[$i]->subprice), 0, 'R', 0); */ // Quantity + //$qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxqty, $curY); - $pdf->MultiCell(30, 3, $object->lines[$i]->qty_shipped, 0, 'R'); + $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->posxqty, 3, $object->lines[$i]->qty_shipped, 0, 'R'); /* // Remise sur ligne $pdf->SetXY($this->posxdiscount, $curY); @@ -307,7 +368,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder */ // Add line - if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1)) + if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(210,210,210))); //$pdf->SetDrawColor(190,190,200); @@ -333,6 +394,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $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) { @@ -349,34 +411,38 @@ class pdf_typhon extends ModelePDFDeliveryOrder $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); - $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfooter + 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); - $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfooter + 1; + $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; } - /* - * Pied de page - */ + // Affiche zone infos + $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); + + // Pied de page $this->_pagefoot($pdf,$object,$outputlangs); - + $pdf->AliasNbPages(); + // Check product remaining to be delivered // TODO doit etre modifie //$waitingDelivery = $object->getRemainingDelivered(); + /* $waitingDelivery=''; if (is_array($waitingDelivery) & !empty($waitingDelivery)) { - $pdf->AddPage('P', 'A4'); + $pdf->AddPage(); $this->_pagehead($pdf, $object, 1, $outputlangs); $pdf-> SetY(90); @@ -426,17 +492,28 @@ class pdf_typhon extends ModelePDFDeliveryOrder $this->_pagefoot($pdf,$object,$outputlangs); - } - - $pdf->AliasNbPages(); + $pdf->AliasNbPages(); + }*/ $pdf->Close(); $pdf->Output($file,'F'); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($file, octdec($conf->global->MAIN_UMASK)); - return 1; + // 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('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 { @@ -449,66 +526,90 @@ class pdf_typhon extends ModelePDFDeliveryOrder return 0; } - + /** + * 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); + $pdf->SetXY($this->marge_gauche, $posy); + + $larg_sign = ($this->page_largeur-$this->marge_gauche-$this->marge_droite)/3; + $pdf->Rect($this->marge_gauche, $posy + 1, $larg_sign, 25); + $pdf->SetXY($this->marge_gauche + 2, $posy + 2); + $pdf->MultiCell($larg_sign,2, $outputlangs->trans("For").' '.$outputlangs->convToOutputCharset($mysoc->name).":",'','L'); + + $pdf->Rect(2*$larg_sign+$this->marge_gauche, $posy + 1, $larg_sign, 25); + $pdf->SetXY(2*$larg_sign+$this->marge_gauche + 2, $posy + 2); + $pdf->MultiCell($larg_sign,2, $outputlangs->trans("ForCustomer").':','','L'); + } + /** * 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 + * @param int $nexY Y (not used) * @param Translate $outputlangs Langs object - * @param int $hidetop Hide top bar of array + * @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,$mysoc; + + // Force to disable hidetop and hidebottom + $hidebottom=0; + if ($hidetop) $hidetop=-1; + $default_font_size = pdf_getPDFFontSize($outputlangs); - - $pdf->SetDrawColor(128,128,128); - - // Rect prend une longueur en 3eme param - $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height); - // line prend une position y en 3eme param - if (empty($hidetop)) - $pdf->line($this->marge_gauche, $tab_top+6, $this->page_largeur-$this->marge_droite, $tab_top+6); - + + // Amount in (at tab_top - 1) $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + + // Output Rec + $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+6, $this->page_largeur-$this->marge_droite, $tab_top+6); + } + + $pdf->SetDrawColor(128,128,128); $pdf->SetFont('','', $default_font_size - 1); - if (empty($hidetop)) { + if (empty($hidetop)) + { $pdf->SetXY($this->posxdesc-1, $tab_top+1); - $pdf->MultiCell(80,2, $outputlangs->transnoentities("Designation"),'','L'); + $pdf->MultiCell($this->posxcomm - $this->posxdesc,2, $outputlangs->transnoentities("Designation"),'','L'); } // Modif SEB pour avoir une col en plus pour les commentaires clients $pdf->line($this->posxcomm, $tab_top, $this->posxcomm, $tab_top + $tab_height); if (empty($hidetop)) { $pdf->SetXY($this->posxcomm, $tab_top+1); - $pdf->MultiCell(80,2, $outputlangs->transnoentities("Comments"),'','L'); + $pdf->MultiCell($this->posxqty - $this->posxcomm,2, $outputlangs->transnoentities("Comments"),'','L'); } // Qty $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); - $pdf->MultiCell(30, 2, $outputlangs->transnoentities("QtyShipped"),'','R'); + $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->posxqty, 2, $outputlangs->transnoentities("QtyShipped"),'','R'); } - if (empty($hidebottom)) { - // Modif Seb cadres signatures - $pdf->SetFont('','', $default_font_size); - $larg_sign = ($this->page_largeur-$this->marge_gauche-$this->marge_droite)/3; - $pdf->Rect($this->marge_gauche, ($tab_top + $tab_height + 3), $larg_sign, 25); - $pdf->SetXY($this->marge_gauche + 2, $tab_top + $tab_height + 5); - $pdf->MultiCell($larg_sign,2, $outputlangs->trans("For").' '.$outputlangs->convToOutputCharset($mysoc->name).":",'','L'); - - $pdf->Rect(2*$larg_sign+$this->marge_gauche, ($tab_top + $tab_height + 3), $larg_sign, 25); - $pdf->SetXY(2*$larg_sign+$this->marge_gauche + 2, $tab_top + $tab_height + 5); - $pdf->MultiCell($larg_sign,2, $outputlangs->trans("ForCustomer").':','','L'); - } } /** @@ -522,22 +623,29 @@ class pdf_typhon extends ModelePDFDeliveryOrder */ function _pagehead(&$pdf, $object, $showaddress, $outputlangs) { - global $langs,$conf,$mysoc; + global $conf,$langs,$hookmanager; + $default_font_size = pdf_getPDFFontSize($outputlangs); pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); - $pdf->SetTextColor(0,0,60); - $pdf->SetFont('','B', $default_font_size + 3); - - $posx=$this->page_largeur-$this->marge_droite-100; - $posy=$this->marge_haute; - - $pdf->SetXY($this->marge_gauche,$posy); - + // Show Draft Watermark + if($object->statut==0 && (! empty($conf->global->COMMANDE_DRAFT_WATERMARK)) ) + { + pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->COMMANDE_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/'.$mysoc->logo; - if ($mysoc->logo) + $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; + if ($this->emetteur->logo) { if (is_readable($logo)) { @@ -548,8 +656,8 @@ class pdf_typhon extends ModelePDFDeliveryOrder { $pdf->SetTextColor(200,0,0); $pdf->SetFont('','B', $default_font_size - 2); - $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); - $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorGoToModuleSetup"), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); } } else $pdf->MultiCell(100, 4, $this->emetteur->name, 0, 'L'); @@ -557,7 +665,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetFont('','B', $default_font_size + 2); $pdf->SetXY($posx,$posy); $pdf->SetTextColor(0,0,60); - $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DeliveryOrder")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DeliveryOrder")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R'); $pdf->SetFont('','',$default_font_size + 2); @@ -585,69 +693,42 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetTextColor(0,0,60); - // Add origin linked objects - // TODO extend to other objects - $object->fetchObjectLinked('','',$object->id,'delivery'); - - if (! empty($object->linkedObjects)) - { - $outputlangs->load('orders'); - - foreach($object->linkedObjects as $elementtype => $objects) - { - $object->fetchObjectLinked('','',$objects[0]->id,$objects[0]->element); - - foreach($object->linkedObjects as $elementtype => $objects) - { - $num=count($objects); - for ($i=0;$i<$num;$i++) - { - $order=new Commande($this->db); - $result=$order->fetch($objects[$i]->id); - if ($result >= 0) - { - $posy+=5; - $pdf->SetXY($posx,$posy); - $pdf->SetFont('','', $default_font_size - 1); - $text=$order->ref; - if ($order->ref_client) $text.=' ('.$order->ref_client.')'; - $pdf->MultiCell(100, 4, $outputlangs->transnoentities("RefOrder")." : ".$outputlangs->transnoentities($text), '', 'R'); - } - } - } - } - } - + $posy+=2; + + // Show list of linked objects + $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); + if ($showaddress) { - // Emetteur + // Sender properties + $carac_emetteur = pdf_build_address($outputlangs,$this->emetteur); + + // 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($this->marge_gauche,$posy-5); - $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":"); - - - $pdf->SetXY($this->marge_gauche,$posy); + $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->SetXY($this->marge_gauche+2,$posy+3); - - // Nom emetteur $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'); - // Sender properties - $carac_emetteur = pdf_build_address($outputlangs,$this->emetteur); - - $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($this->marge_gauche+2,$posy+9); - $pdf->MultiCell(80, 3, $carac_emetteur, 0, 'L'); - + // Show sender information + $pdf->SetXY($posx+2,$posy+8); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); + // Client destinataire $posy=42; $pdf->SetTextColor(0,0,0); @@ -655,7 +736,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetXY(102,$posy-5); $pdf->MultiCell(80,5, $outputlangs->transnoentities("DeliveryAddress").":", 0, 'L'); - // If SHIPPING contact defined on invoice, we use it + // If SHIPPING contact defined on order, we use it $usecontact=false; $arrayidcontact=$object->commande->getIdContact('external','SHIPPING'); if (count($arrayidcontact) > 0) @@ -677,7 +758,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $carac_client_name=$outputlangs->convToOutputCharset($object->client->nom); } - $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->client,$object->contact,$usecontact,'target'); + $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->client,($usecontact?$object->contact:''),$usecontact,'target'); // Show recipient $widthrecbox=100; @@ -700,7 +781,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+8); + $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } @@ -713,7 +794,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text - * @return void + * @return int Return height of bottom margin including footer text */ function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0) { From 45300ccdd876e724b92961b0a4ffcd8395794781 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 19 Apr 2013 09:48:55 +0200 Subject: [PATCH 18/97] Fix: no result with a number with a comma --- htdocs/comm/propal/list.php | 4 ++-- htdocs/compta/facture/list.php | 6 +++--- htdocs/fourn/facture/index.php | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 4063802ffa4..1d4d5b82c24 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2010-2011 Juanjo Menent * Copyright (C) 2010-2011 Philippe Grand @@ -165,7 +165,7 @@ if ($search_societe) } if ($search_montant_ht) { - $sql.= " AND p.total_ht='".$db->escape(trim($search_montant_ht))."'"; + $sql.= " AND p.total_ht='".$db->escape(price2num(trim($search_montant_ht)))."'"; } if ($sall) $sql.= " AND (s.nom LIKE '%".$db->escape($sall)."%' OR p.note LIKE '%".$db->escape($sall)."%' OR pd.description LIKE '%".$db->escape($sall)."%')"; if ($socid) $sql.= ' AND s.rowid = '.$socid; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 1003dd23700..952fc760af5 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -3,7 +3,7 @@ * Copyright (C) 2004 Eric Seigne * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2010-2012 Juanjo Menent * Copyright (C) 2012 Christophe Battarel @@ -183,11 +183,11 @@ if ($search_societe) } if ($search_montant_ht) { - $sql.= ' AND f.total = \''.$db->escape(trim($search_montant_ht)).'\''; + $sql.= ' AND f.total = \''.$db->escape(price2num(trim($search_montant_ht))).'\''; } if ($search_montant_ttc) { - $sql.= ' AND f.total_ttc = \''.$db->escape(trim($search_montant_ttc)).'\''; + $sql.= ' AND f.total_ttc = \''.$db->escape(price2num(trim($search_montant_ttc))).'\''; } if ($month > 0) { diff --git a/htdocs/fourn/facture/index.php b/htdocs/fourn/facture/index.php index 3d55e528daf..5934029aef3 100644 --- a/htdocs/fourn/facture/index.php +++ b/htdocs/fourn/facture/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2004-2013 Laurent Destailleur - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2013 Philippe Grand * * This program is free software; you can redistribute it and/or modify @@ -156,12 +156,12 @@ if (GETPOST("search_societe")) if (GETPOST("search_montant_ht")) { - $sql .= " AND fac.total_ht = '".$db->escape(GETPOST("search_montant_ht"))."'"; + $sql .= " AND fac.total_ht = '".$db->escape(price2num(GETPOST("search_montant_ht")))."'"; } if (GETPOST("search_montant_ttc")) { - $sql .= " AND fac.total_ttc = '".$db->escape(GETPOST("search_montant_ttc"))."'"; + $sql .= " AND fac.total_ttc = '".$db->escape(price2num(GETPOST("search_montant_ttc")))."'"; } $sql.= $db->order($sortfield,$sortorder); From 17d5ab97744865c2fee376285d6183d8034d71b7 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 19 Apr 2013 09:57:13 +0200 Subject: [PATCH 19/97] Fix: no result with a number with a comma Conflicts: htdocs/fourn/facture/index.php Change-Id: I6c67e3d2936673ea0993adfa1597bd11caf125fe --- htdocs/comm/propal/list.php | 4 ++-- htdocs/fourn/facture/index.php | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 95e549c0b1d..81306b47033 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2010-2011 Juanjo Menent * Copyright (C) 2010-2011 Philippe Grand @@ -167,7 +167,7 @@ if ($search_societe) } if ($search_montant_ht) { - $sql.= " AND p.total_ht='".$db->escape(trim($search_montant_ht))."'"; + $sql.= " AND p.total_ht='".$db->escape(price2num(trim($search_montant_ht)))."'"; } if ($sall) $sql.= " AND (s.nom LIKE '%".$db->escape($sall)."%' OR p.note LIKE '%".$db->escape($sall)."%' OR pd.description LIKE '%".$db->escape($sall)."%')"; if ($socid) $sql.= ' AND s.rowid = '.$socid; diff --git a/htdocs/fourn/facture/index.php b/htdocs/fourn/facture/index.php index 6181ec15b24..5d1f9795380 100644 --- a/htdocs/fourn/facture/index.php +++ b/htdocs/fourn/facture/index.php @@ -1,7 +1,8 @@ - * Copyright (C) 2004-2011 Laurent Destailleur - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2004-2013 Laurent Destailleur + * Copyright (C) 2005-2013 Regis Houssin + * Copyright (C) 2013 Philippe Grand * * 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 @@ -155,12 +156,12 @@ if (GETPOST("search_societe")) if (GETPOST("search_montant_ht")) { - $sql .= " AND fac.total_ht = '".$db->escape(GETPOST("search_montant_ht"))."'"; + $sql .= " AND fac.total_ht = '".$db->escape(price2num(GETPOST("search_montant_ht")))."'"; } if (GETPOST("search_montant_ttc")) { - $sql .= " AND fac.total_ttc = '".$db->escape(GETPOST("search_montant_ttc"))."'"; + $sql .= " AND fac.total_ttc = '".$db->escape(price2num(GETPOST("search_montant_ttc")))."'"; } $sql.= $db->order($sortfield,$sortorder); From 8a69cdd43318cd9f8a12152f1c5bb1e9ae80baf1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Apr 2013 10:08:30 +0200 Subject: [PATCH 20/97] Fix: delete of survey --- .../opensurvey/class/opensurveysondage.class.php | 8 +++++--- htdocs/opensurvey/list.php | 15 +++++---------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php index 0a3f2c571df..188e830be63 100644 --- a/htdocs/opensurvey/class/opensurveysondage.class.php +++ b/htdocs/opensurvey/class/opensurveysondage.class.php @@ -337,7 +337,7 @@ class Opensurveysondage extends CommonObject * * @param User $user User that deletes * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @param string $numsondageadmin Num sondage to delete + * @param string $numsondageadmin Num sondage admin to delete * @return int <0 if KO, >0 if OK */ function delete($user, $notrigger, $numsondageadmin) @@ -345,6 +345,8 @@ class Opensurveysondage extends CommonObject global $conf, $langs; $error=0; + $numsondage=substr($numsondageadmin, 0, 16); + $this->db->begin(); if (! $error) @@ -366,10 +368,10 @@ class Opensurveysondage extends CommonObject if (! $error) { - $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage_admin = '".$numsondageadmin."'"; + $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage = '".$numsondage."'"; dol_syslog(get_class($this)."::delete sql=".$sql, LOG_DEBUG); $resql=$this->db->query($sql); - $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage_admin = '".$numsondageadmin."'"; + $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage = '".$numsondage."'"; dol_syslog(get_class($this)."::delete sql=".$sql, LOG_DEBUG); $resql=$this->db->query($sql); diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php index 506ffecc99e..c87526ce5ca 100755 --- a/htdocs/opensurvey/list.php +++ b/htdocs/opensurvey/list.php @@ -27,6 +27,7 @@ require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); $action=GETPOST('action'); $id=GETPOST('id'); +$numsondage=substr($id, 0, 16); if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="p.titre"; @@ -45,16 +46,10 @@ if ($action == 'delete_confirm') { $db->begin(); - $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage_admin = '".$id."'"; - dol_syslog("Delete poll sql=".$sql, LOG_DEBUG); - $resql=$db->query($sql); - $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage_admin = '".$id."'"; - dol_syslog("Delete poll sql=".$sql, LOG_DEBUG); - $resql=$db->query($sql); - $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_sondage WHERE id_sondage_admin = '".$id."'"; - dol_syslog("Delete poll sql=".$sql, LOG_DEBUG); - $resql=$db->query($sql); - + $object=new Opensurveysondage($db); + + $result=$object->delete($user,'',$numsondageadmin); + $db->commit(); } From 56a0f70ad3c8f0607f6d47888863d790b509f0f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Apr 2013 10:33:25 +0200 Subject: [PATCH 21/97] Fix: margin disabled into demo for foundation --- htdocs/public/demo/index.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/public/demo/index.php b/htdocs/public/demo/index.php index c0e47ea955d..1c03c17c5b5 100644 --- a/htdocs/public/demo/index.php +++ b/htdocs/public/demo/index.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006-2012 Laurent Destailleur + * Copyright (C) 2006-2013 Laurent Destailleur * Copyright (C) 2010 Regis Houssin * * This program is free software; you can redistribute it and/or modify @@ -42,7 +42,7 @@ $hookmanager->initHooks(array('demo')); $demoprofiles=array( array('default'=>'1', 'key'=>'profdemoservonly','label'=>'DemoCompanyServiceOnly', - 'disablemodules'=>'adherent,barcode,boutique,cashdesk,categorie,don,expedition,externalsite,mailmanspip,prelevement,product,stock', + 'disablemodules'=>'adherent,barcode,boutique,cashdesk,categorie,don,expedition,externalsite,mailmanspip,margin,prelevement,product,stock', 'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot8.png'), array('default'=>'-1','key'=>'profdemoshopwithdesk','label'=>'DemoCompanyShopWithCashDesk', 'disablemodules'=>'adherent,boutique,categorie,don,externalsite,ficheinter,mailmanspip,prelevement,product,stock', @@ -54,10 +54,10 @@ $demoprofiles=array( 'disablemodules'=>'adherent,boutique,don,externalsite,mailmanspip', 'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot9.png'), array('default'=>'-1', 'key'=>'profdemofun','label'=>'DemoFundation', - 'disablemodules'=>'banque,barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,prelevement,product,projet,propal,propale,service,societe,stock,tax', + 'disablemodules'=>'banque,barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,margin,prelevement,product,projet,propal,propale,service,societe,stock,tax', 'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot6.png'), array('default'=>'0', 'key'=>'profdemofun2','label'=>'DemoFundation2', - 'disablemodules'=>'barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,prelevement,product,projet,propal,propale,service,societe,stock,tax', + 'disablemodules'=>'barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,margin,prelevement,product,projet,propal,propale,service,societe,stock,tax', 'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot6.png') ); From 077698d78989f7d8c3836fb0fd8c08110315e887 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 19 Apr 2013 12:47:53 +0200 Subject: [PATCH 22/97] Fix: for avoid missing the customer discount --- htdocs/core/tpl/objectline_add.tpl.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/htdocs/core/tpl/objectline_add.tpl.php b/htdocs/core/tpl/objectline_add.tpl.php index 497d4a294ba..6a7cffcb3fc 100644 --- a/htdocs/core/tpl/objectline_add.tpl.php +++ b/htdocs/core/tpl/objectline_add.tpl.php @@ -80,8 +80,8 @@ if (! empty($conf->margin->enabled)) { 'origin_price_ht_cache' => 'price_ht', 'origin_tva_tx_cache' => 'tva_tx', 'origin_price_ttc_cache' => 'price_ttc', - 'qty' => 'qty' - ,'remise_percent' => 'discount' + 'qty' => 'qty', + 'remise_percent' => 'discount' ), 'update_textarea' => array( 'product_desc' => 'desc' @@ -160,7 +160,10 @@ if (! empty($conf->margin->enabled)) { % + % + +
'; + print ''; + print ''; + print ''; + if ($conf->global->MARGIN_TYPE == "1") + print ''; + else + print ''; + print ''; + if (! empty($conf->global->DISPLAY_MARGIN_RATES)) + print ''; + if (! empty($conf->global->DISPLAY_MARK_RATES)) + print ''; + print ''; + //if ($marginInfo['margin_on_products'] != 0 && $marginInfo['margin_on_services'] != 0) { + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->global->DISPLAY_MARGIN_RATES)) + print ''; + if (! empty($conf->global->DISPLAY_MARK_RATES)) + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->global->DISPLAY_MARGIN_RATES)) + print ''; + if (! empty($conf->global->DISPLAY_MARK_RATES)) + print ''; + print ''; + //} + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->global->DISPLAY_MARGIN_RATES)) + print ''; + if (! empty($conf->global->DISPLAY_MARK_RATES)) + print ''; + print ''; + print '
'.$langs->trans('Margins').''.$langs->trans('SellingPrice').''.$langs->trans('BuyingPrice').''.$langs->trans('CostPrice').''.$langs->trans('Margin').''.$langs->trans('MarginRate').''.$langs->trans('MarkRate').'
'.$langs->trans('MarginOnProducts').''.price($marginInfo['pv_products']).''.price($marginInfo['pa_products']).''.price($marginInfo['margin_on_products']).''.(($marginInfo['margin_rate_products'] == '')?'n/a':price($marginInfo['margin_rate_products']).'%').''.(($marginInfo['mark_rate_products'] == '')?'n/a':price($marginInfo['mark_rate_products']).'%').'
'.$langs->trans('MarginOnServices').''.price($marginInfo['pv_services']).''.price($marginInfo['pa_services']).''.price($marginInfo['margin_on_services']).''.(($marginInfo['margin_rate_services'] == '')?'n/a':price($marginInfo['margin_rate_services']).'%').''.(($marginInfo['mark_rate_services'] == '')?'n/a':price($marginInfo['mark_rate_services']).'%').'
'.$langs->trans('TotalMargin').''.price($marginInfo['pv_total']).''.price($marginInfo['pa_total']).''.price($marginInfo['total_margin']).''.(($marginInfo['total_margin_rate'] == '')?'n/a':price($marginInfo['total_margin_rate']).'%').''.(($marginInfo['total_mark_rate'] == '')?'n/a':price($marginInfo['total_mark_rate']).'%').'
'; + } - function displayMarginInfos($force_price=false) { - global $langs, $conf; - $marginInfo = $this->getMarginInfos($force_price); - print ''; - print ''; - print ''; - print ''; - if ($conf->global->MARGIN_TYPE == "1") - print ''; - else - print ''; - print ''; - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) - print ''; - if (! empty($conf->global->DISPLAY_MARK_RATES)) - print ''; - print ''; - //if ($marginInfo['margin_on_products'] != 0 && $marginInfo['margin_on_services'] != 0) { - print ''; - print ''; - print ''; - print ''; - print ''; - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) - print ''; - if (! empty($conf->global->DISPLAY_MARK_RATES)) - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) - print ''; - if (! empty($conf->global->DISPLAY_MARK_RATES)) - print ''; - print ''; - //} - print ''; - print ''; - print ''; - print ''; - print ''; - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) - print ''; - if (! empty($conf->global->DISPLAY_MARK_RATES)) - print ''; - print ''; - print '
'.$langs->trans('Margins').''.$langs->trans('SellingPrice').''.$langs->trans('BuyingPrice').''.$langs->trans('CostPrice').''.$langs->trans('Margin').''.$langs->trans('MarginRate').''.$langs->trans('MarkRate').'
'.$langs->trans('MarginOnProducts').''.price($marginInfo['pv_products']).''.price($marginInfo['pa_products']).''.price($marginInfo['margin_on_products']).''.(($marginInfo['margin_rate_products'] == '')?'n/a':price($marginInfo['margin_rate_products']).'%').''.(($marginInfo['mark_rate_products'] == '')?'n/a':price($marginInfo['mark_rate_products']).'%').'
'.$langs->trans('MarginOnServices').''.price($marginInfo['pv_services']).''.price($marginInfo['pa_services']).''.price($marginInfo['margin_on_services']).''.(($marginInfo['margin_rate_services'] == '')?'n/a':price($marginInfo['margin_rate_services']).'%').''.(($marginInfo['mark_rate_services'] == '')?'n/a':price($marginInfo['mark_rate_services']).'%').'
'.$langs->trans('TotalMargin').''.price($marginInfo['pv_total']).''.price($marginInfo['pa_total']).''.price($marginInfo['total_margin']).''.(($marginInfo['total_margin_rate'] == '')?'n/a':price($marginInfo['total_margin_rate']).'%').''.(($marginInfo['total_mark_rate'] == '')?'n/a':price($marginInfo['total_mark_rate']).'%').'
'; - } } - ?> From 556574cbc96b17149ceec49627143e33ebcde76c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 19 Apr 2013 13:47:30 +0200 Subject: [PATCH 24/97] FIXME: this field not exist in llx_product_fournisseur_price --- htdocs/fourn/class/fournisseur.product.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 9a86f0e9ee3..8d5a3474bf8 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -296,7 +296,7 @@ class ProductFournisseur extends Product function fetch_product_fournisseur_price($rowid) { $sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.fk_availability,"; - $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product, pfp.charges, pfp.unitcharges, pfp.recuperableonly as fourn_tva_npr"; + $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product, pfp.charges, pfp.unitcharges"; // , pfp.recuperableonly as fourn_tva_npr"; FIXME this field not exist in llx_product_fournisseur_price $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql.= " WHERE pfp.rowid = ".$rowid; @@ -320,7 +320,7 @@ class ProductFournisseur extends Product $this->product_id = $obj->fk_product; // deprecated $this->fk_product = $obj->fk_product; $this->fk_availability = $obj->fk_availability; - $this->fourn_tva_npr = $obj->fourn_tva_npr; + //$this->fourn_tva_npr = $obj->fourn_tva_npr; // FIXME this field not exist in llx_product_fournisseur_price return 1; } else From 570e4391a578e6df9a263daff144977fec28b057 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Apr 2013 14:51:39 +0200 Subject: [PATCH 25/97] Fix: Box with product out of stocks for pgsql --- .../core/boxes/box_produits_alerte_stock.php | 16 ++- htdocs/core/class/html.formother.class.php | 107 ++++++++---------- .../install/mysql/tables/llx_product.key.sql | 3 +- 3 files changed, 62 insertions(+), 64 deletions(-) diff --git a/htdocs/core/boxes/box_produits_alerte_stock.php b/htdocs/core/boxes/box_produits_alerte_stock.php index 41070298cac..57c2cc4de4c 100644 --- a/htdocs/core/boxes/box_produits_alerte_stock.php +++ b/htdocs/core/boxes/box_produits_alerte_stock.php @@ -64,20 +64,23 @@ class box_produits_alerte_stock extends ModeleBoxes if ($user->rights->produit->lire || $user->rights->service->lire) { - $sql = "SELECT p.rowid, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.seuil_stock_alerte, s.reel"; + $sql = "SELECT p.rowid, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.seuil_stock_alerte,"; + $sql.= " SUM(".$db->ifsql("s.reel IS NULL","0","s.reel").") as total_stock"; $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as s on p.rowid = s.fk_product"; $sql.= ' WHERE p.entity IN ('.getEntity($productstatic->element, 1).')'; - $sql.= " AND p.tosell = 1"; + $sql.= " AND p.tosell = 1 AND p.seuil_stock_alerte > 0"; if (empty($user->rights->produit->lire)) $sql.=' AND p.fk_product_type != 0'; if (empty($user->rights->service->lire)) $sql.=' AND p.fk_product_type != 1'; - $sql.= " HAVING s.reel < p.seuil_stock_alerte"; - $sql.= $db->order('s.reel', 'DESC'); + $sql.= " GROUP BY p.rowid, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.seuil_stock_alerte"; + $sql.= " HAVING SUM(".$db->ifsql("s.reel IS NULL","0","s.reel").") < p.seuil_stock_alerte"; + $sql.= $db->order('p.seuil_stock_alerte', 'DESC'); $sql.= $db->plimit($max, 0); $result = $db->query($sql); if ($result) { + $langs->load("stocks"); $num = $db->num_rows($result); $i = 0; while ($i < $num) @@ -128,7 +131,8 @@ class box_produits_alerte_stock extends ModeleBoxes 'text' => $price_base_type); $this->info_box_contents[$i][4] = array('td' => 'align="center"', - 'text' => $objp->reel . ' / '.$objp->seuil_stock_alerte); + 'text' => $objp->total_stock . ' / '.$objp->seuil_stock_alerte, + 'text2'=>img_warning($langs->transnoentitiesnoconv("StockLowerThanLimit"))); $this->info_box_contents[$i][5] = array('td' => 'align="right" width="18"', 'text' => $productstatic->LibStatut($objp->tosell,3,0)); @@ -138,7 +142,7 @@ class box_produits_alerte_stock extends ModeleBoxes $i++; } - if ($num==0) $this->info_box_contents[$i][0] = array('td' => 'align="center"','text'=>$langs->trans("NoRecordedProducts")); + if ($num==0) $this->info_box_contents[$i][0] = array('td' => 'align="center"','text'=>$langs->trans("NoTooLowStockProducts")); } else { diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 3de291bbe76..8a964c9d846 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -893,9 +893,34 @@ class FormOther $selectboxlist=$form->selectarray('boxcombo', $arrayboxtoactivatelabel,'',1); } + // Javascript code for dynamic actions if (! empty($conf->use_javascript_ajax)) { print ''; + if (! count($arrayboxtoactivatelabel)) print 'jQuery("#boxcombo").hide();'; + print ' + + jQuery("#left, #right").sortable({ + /* placeholder: \'ui-state-highlight\', */ + handle: \'.boxhandle\', + revert: \'invalid\', + items: \'.box\', + containment: \'.fiche\', + connectWith: \'.connectedSortable\', + stop: function(event, ui) { + updateBoxOrder(0); + } + }); + + jQuery(".boxclose").click(function() { + var self = this; // because JQuery can modify this + var boxid=self.id.substring(8); + jQuery(\'#boxto_\'+boxid).remove(); + updateBoxOrder(1); + }); + + });'."\n"; + + print ''."\n"; } $nbboxactivated=count($boxidactivatedforuser); @@ -996,59 +1042,6 @@ class FormOther print ""; print ""; - - if ($conf->use_javascript_ajax) - { - print "\n"; - print ''."\n"; - } } return count($boxactivated); diff --git a/htdocs/install/mysql/tables/llx_product.key.sql b/htdocs/install/mysql/tables/llx_product.key.sql index 06ad7ce2f0a..1500cfba762 100644 --- a/htdocs/install/mysql/tables/llx_product.key.sql +++ b/htdocs/install/mysql/tables/llx_product.key.sql @@ -1,6 +1,6 @@ -- ============================================================================ -- Copyright (C) 2002-2004 Rodolphe Quiedeville --- Copyright (C) 2004-2005 Laurent Destailleur +-- Copyright (C) 2004-2013 Laurent Destailleur -- Copyright (C) 2005-2009 Regis Houssin -- -- This program is free software; you can redistribute it and/or modify @@ -24,3 +24,4 @@ ALTER TABLE llx_product ADD UNIQUE INDEX uk_product_ref (ref, entity); ALTER TABLE llx_product ADD INDEX idx_product_label (label); ALTER TABLE llx_product ADD INDEX idx_product_barcode (barcode); ALTER TABLE llx_product ADD INDEX idx_product_import_key (import_key); +ALTER TABLE llx_product ADD INDEX idx_product_seuil_stock_alerte (seuil_stock_alerte); From 08ae1d289b7829894d96448b607efe22666dde13 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Apr 2013 15:02:53 +0200 Subject: [PATCH 26/97] Pgsql compatibility --- htdocs/core/modules/modOpenSurvey.class.php | 34 ++++++++------- .../install/mysql/migration/3.3.0-3.4.0.sql | 41 +++++++++++++++++++ .../sql/llx_opensurvey_comments.key.sql | 22 ---------- .../sql/llx_opensurvey_comments.sql | 25 ----------- .../sql/llx_opensurvey_sondage.key.sql | 19 --------- .../opensurvey/sql/llx_opensurvey_sondage.sql | 33 --------------- .../sql/llx_opensurvey_user_studs.key.sql | 20 --------- .../sql/llx_opensurvey_user_studs.sql | 24 ----------- 8 files changed, 57 insertions(+), 161 deletions(-) delete mode 100755 htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql delete mode 100755 htdocs/opensurvey/sql/llx_opensurvey_comments.sql delete mode 100755 htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql delete mode 100755 htdocs/opensurvey/sql/llx_opensurvey_sondage.sql delete mode 100755 htdocs/opensurvey/sql/llx_opensurvey_user_studs.key.sql delete mode 100755 htdocs/opensurvey/sql/llx_opensurvey_user_studs.sql diff --git a/htdocs/core/modules/modOpenSurvey.class.php b/htdocs/core/modules/modOpenSurvey.class.php index 0930f7dfa94..6c49a1c2143 100755 --- a/htdocs/core/modules/modOpenSurvey.class.php +++ b/htdocs/core/modules/modOpenSurvey.class.php @@ -1,7 +1,18 @@ +/* Copyright (C) 2013 Laurent Destailleur * - * Licensed under the GNU GPL v3 or higher (See file gpl-3.0.html) + * 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 . */ /** @@ -184,10 +195,11 @@ class modOpenSurvey extends DolibarrModules */ function init($options='') { + // Permissions + $this->remove($options); + $sql = array(); - $result=$this->load_tables(); - return $this->_init($sql,$options); } @@ -205,20 +217,6 @@ class modOpenSurvey extends DolibarrModules return $this->_remove($sql,$options); } - - - /** - * Create tables and keys required by module - * Files mymodule.sql and mymodule.key.sql with create table and create keys - * commands must be stored in directory /mymodule/sql/ - * This function is called by this->init. - * - * @return int <=0 if KO, >0 if OK - */ - function load_tables() - { - return $this->_load_tables('/opensurvey/sql/'); - } } ?> diff --git a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql index b8542349f5f..957dadf2845 100755 --- a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql +++ b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql @@ -306,3 +306,44 @@ create table llx_projet_task_extrafields import_key varchar(14) -- import key ) ENGINE=innodb; ALTER TABLE llx_projet_task_extrafields ADD INDEX idx_projet_task_extrafields (fk_object); + + +CREATE TABLE llx_opensurvey_comments ( + id_comment INTEGER unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_sondage CHAR(16) NOT NULL, + comment text NOT NULL, + tms timestamp, + usercomment text +) ENGINE=InnoDB; + +CREATE TABLE llx_opensurvey_sondage ( + id_sondage VARCHAR(16) PRIMARY KEY, + id_sondage_admin CHAR(24), + commentaires text, + mail_admin VARCHAR(128), + nom_admin VARCHAR(64), + titre text, + date_fin datetime, + format VARCHAR(2), + mailsonde varchar(2) DEFAULT '0', + survey_link_visible integer DEFAULT 1, + canedit integer DEFAULT 0, + origin varchar(64), + tms timestamp, + sujet TEXT +) ENGINE=InnoDB; +CREATE TABLE llx_opensurvey_user_studs ( + id_users INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, + nom VARCHAR(64) NOT NULL, + id_sondage VARCHAR(16) NOT NULL, + reponses VARCHAR(100) NOT NULL, + tms timestamp +) ENGINE=InnoDB; + +ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_comment (id_comment); +ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_sondage (id_sondage); +ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_id_sondage_admin (id_sondage_admin); +ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_date_fin (date_fin); +ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_id_users (id_users); +ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_nom (nom); +ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_id_sondage (id_sondage); diff --git a/htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql b/htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql deleted file mode 100755 index 3f7460f3e8a..00000000000 --- a/htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql +++ /dev/null @@ -1,22 +0,0 @@ --- ============================================================================ --- Copyright (C) 2013 Laurent Destailleur --- --- 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 . --- ============================================================================ - -ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_comment id_comment; -ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_sondage id_sondage; - - - diff --git a/htdocs/opensurvey/sql/llx_opensurvey_comments.sql b/htdocs/opensurvey/sql/llx_opensurvey_comments.sql deleted file mode 100755 index 613627c46aa..00000000000 --- a/htdocs/opensurvey/sql/llx_opensurvey_comments.sql +++ /dev/null @@ -1,25 +0,0 @@ --- ============================================================================ --- Copyright (C) 2013 Laurent Destailleur --- --- 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 . --- ============================================================================ - -CREATE TABLE llx_opensurvey_comments ( - id_comment INTEGER unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, - id_sondage CHAR(16) NOT NULL, - comment text NOT NULL, - tms timestamp, - usercomment text -) ENGINE=InnoDB; - diff --git a/htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql b/htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql deleted file mode 100755 index 377f8abc45e..00000000000 --- a/htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql +++ /dev/null @@ -1,19 +0,0 @@ --- ============================================================================ --- Copyright (C) 2013 Laurent Destailleur --- --- 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 . --- ============================================================================ - -ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_id_sondage_admin id_sondage_admin; -ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_date_fin date_fin; diff --git a/htdocs/opensurvey/sql/llx_opensurvey_sondage.sql b/htdocs/opensurvey/sql/llx_opensurvey_sondage.sql deleted file mode 100755 index 1704938a6f7..00000000000 --- a/htdocs/opensurvey/sql/llx_opensurvey_sondage.sql +++ /dev/null @@ -1,33 +0,0 @@ --- ============================================================================ --- Copyright (C) 2013 Laurent Destailleur --- --- 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 . --- ============================================================================ - -CREATE TABLE llx_opensurvey_sondage ( - id_sondage VARCHAR(16) PRIMARY KEY, - id_sondage_admin CHAR(24), - commentaires text, - mail_admin VARCHAR(128), - nom_admin VARCHAR(64), - titre text, - date_fin datetime, - format VARCHAR(2), - mailsonde varchar(2) DEFAULT '0', - survey_link_visible integer DEFAULT 1, - canedit integer DEFAULT 0, - origin varchar(64), - tms timestamp, - sujet TEXT -) ENGINE=InnoDB; diff --git a/htdocs/opensurvey/sql/llx_opensurvey_user_studs.key.sql b/htdocs/opensurvey/sql/llx_opensurvey_user_studs.key.sql deleted file mode 100755 index 041b2d0593d..00000000000 --- a/htdocs/opensurvey/sql/llx_opensurvey_user_studs.key.sql +++ /dev/null @@ -1,20 +0,0 @@ --- ============================================================================ --- Copyright (C) 2013 Laurent Destailleur --- --- 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 . --- ============================================================================ - -ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_id_users (id_users); -ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_nom (nom); -ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_id_sondage (id_sondage); diff --git a/htdocs/opensurvey/sql/llx_opensurvey_user_studs.sql b/htdocs/opensurvey/sql/llx_opensurvey_user_studs.sql deleted file mode 100755 index 78d7fa69c4d..00000000000 --- a/htdocs/opensurvey/sql/llx_opensurvey_user_studs.sql +++ /dev/null @@ -1,24 +0,0 @@ --- ============================================================================ --- Copyright (C) 2013 Laurent Destailleur --- --- 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 . --- ============================================================================ - -CREATE TABLE llx_opensurvey_user_studs ( - id_users INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, - nom VARCHAR(64) NOT NULL, - id_sondage VARCHAR(16) NOT NULL, - reponses VARCHAR(100) NOT NULL, - tms timestamp -) ENGINE=InnoDB; From a3c5bef38150deb60d7b4d122016dd03329bf396 Mon Sep 17 00:00:00 2001 From: fhenry Date: Fri, 19 Apr 2013 15:12:02 +0200 Subject: [PATCH 27/97] Fix bug FactureLine update for PgSQL http://www.dolibarr.fr/forum/527-bugs-sur-la-version-stable-courante/41317-impossible-de-modifier-une-ligne-de-facture#41422 --- htdocs/compta/facture/class/facture.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 2333802cc40..578049503c4 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3457,7 +3457,7 @@ class FactureLigne $sql.= ",total_localtax1=".price2num($this->total_localtax1).""; $sql.= ",total_localtax2=".price2num($this->total_localtax2).""; } - $sql.= " , fk_product_fournisseur_price='".$this->fk_fournprice."'"; + $sql.= " , fk_product_fournisseur_price=".(! empty($this->fk_fournprice)?"'".$this->db->escape($this->fk_fournprice)."'":"null"); $sql.= " , buy_price_ht='".price2num($this->pa_ht)."'"; $sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null"); if (! empty($this->rang)) $sql.= ", rang=".$this->rang; From bb3f40a1bfba126099660593ee8c950ac708b95b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Apr 2013 15:26:53 +0200 Subject: [PATCH 28/97] Qual: Clean code to be able to update combo box when removing a box. Qual: Opensurvey tables --- htdocs/core/boxes/modules_boxes.php | 3 +- htdocs/core/class/html.formother.class.php | 6 ++-- .../tables/llx_opensurvey_comments.key.sql | 22 +++++++++++++ .../mysql/tables/llx_opensurvey_comments.sql | 25 ++++++++++++++ .../tables/llx_opensurvey_sondage.key.sql | 19 +++++++++++ .../mysql/tables/llx_opensurvey_sondage.sql | 33 +++++++++++++++++++ .../tables/llx_opensurvey_user_studs.key.sql | 20 +++++++++++ .../tables/llx_opensurvey_user_studs.sql | 24 ++++++++++++++ 8 files changed, 149 insertions(+), 3 deletions(-) create mode 100755 htdocs/install/mysql/tables/llx_opensurvey_comments.key.sql create mode 100755 htdocs/install/mysql/tables/llx_opensurvey_comments.sql create mode 100755 htdocs/install/mysql/tables/llx_opensurvey_sondage.key.sql create mode 100755 htdocs/install/mysql/tables/llx_opensurvey_sondage.sql create mode 100755 htdocs/install/mysql/tables/llx_opensurvey_user_studs.key.sql create mode 100755 htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 2bd51b87f98..c681395f5af 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -165,7 +165,8 @@ class ModeleBoxes // Can't be abtract as it is instanciated to build "empty" print ''; // The image must have the class 'boxhandle' beause it's value used in DOM draggable objects to define the area used to catch the full object print img_picto($langs->trans("MoveBox",$this->box_id),'grip','class="boxhandle hideonsmartphone" style="cursor:move;"'); - print img_picto($langs->trans("Close",$this->box_id),'close','class="boxclose" style="cursor:pointer;" id="imgclose'.$this->box_id.'"'); + print img_picto($langs->trans("Close",$this->box_id),'close','class="boxclose" rel="x:y" style="cursor:pointer;" id="imgclose'.$this->box_id.'"'); + print ''; print ''; } print ''; diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 8a964c9d846..a0d63e42b4a 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -952,8 +952,10 @@ class FormOther jQuery(".boxclose").click(function() { var self = this; // because JQuery can modify this - var boxid=self.id.substring(8); - jQuery(\'#boxto_\'+boxid).remove(); + var boxid=self.id.substring(8); + var label=jQuery(\'#boxlabelentry\'+boxid).val(); + jQuery(\'#boxto_\'+boxid).remove(); + // TODO Add id, label into combo list updateBoxOrder(1); }); diff --git a/htdocs/install/mysql/tables/llx_opensurvey_comments.key.sql b/htdocs/install/mysql/tables/llx_opensurvey_comments.key.sql new file mode 100755 index 00000000000..33365f1ab20 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_opensurvey_comments.key.sql @@ -0,0 +1,22 @@ +-- ============================================================================ +-- Copyright (C) 2013 Laurent Destailleur +-- +-- 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 . +-- ============================================================================ + +ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_comment (id_comment); +ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_sondage (id_sondage); + + + diff --git a/htdocs/install/mysql/tables/llx_opensurvey_comments.sql b/htdocs/install/mysql/tables/llx_opensurvey_comments.sql new file mode 100755 index 00000000000..613627c46aa --- /dev/null +++ b/htdocs/install/mysql/tables/llx_opensurvey_comments.sql @@ -0,0 +1,25 @@ +-- ============================================================================ +-- Copyright (C) 2013 Laurent Destailleur +-- +-- 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 . +-- ============================================================================ + +CREATE TABLE llx_opensurvey_comments ( + id_comment INTEGER unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_sondage CHAR(16) NOT NULL, + comment text NOT NULL, + tms timestamp, + usercomment text +) ENGINE=InnoDB; + diff --git a/htdocs/install/mysql/tables/llx_opensurvey_sondage.key.sql b/htdocs/install/mysql/tables/llx_opensurvey_sondage.key.sql new file mode 100755 index 00000000000..3bf5771811e --- /dev/null +++ b/htdocs/install/mysql/tables/llx_opensurvey_sondage.key.sql @@ -0,0 +1,19 @@ +-- ============================================================================ +-- Copyright (C) 2013 Laurent Destailleur +-- +-- 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 . +-- ============================================================================ + +ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_id_sondage_admin (id_sondage_admin); +ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_date_fin (date_fin); diff --git a/htdocs/install/mysql/tables/llx_opensurvey_sondage.sql b/htdocs/install/mysql/tables/llx_opensurvey_sondage.sql new file mode 100755 index 00000000000..1704938a6f7 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_opensurvey_sondage.sql @@ -0,0 +1,33 @@ +-- ============================================================================ +-- Copyright (C) 2013 Laurent Destailleur +-- +-- 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 . +-- ============================================================================ + +CREATE TABLE llx_opensurvey_sondage ( + id_sondage VARCHAR(16) PRIMARY KEY, + id_sondage_admin CHAR(24), + commentaires text, + mail_admin VARCHAR(128), + nom_admin VARCHAR(64), + titre text, + date_fin datetime, + format VARCHAR(2), + mailsonde varchar(2) DEFAULT '0', + survey_link_visible integer DEFAULT 1, + canedit integer DEFAULT 0, + origin varchar(64), + tms timestamp, + sujet TEXT +) ENGINE=InnoDB; diff --git a/htdocs/install/mysql/tables/llx_opensurvey_user_studs.key.sql b/htdocs/install/mysql/tables/llx_opensurvey_user_studs.key.sql new file mode 100755 index 00000000000..041b2d0593d --- /dev/null +++ b/htdocs/install/mysql/tables/llx_opensurvey_user_studs.key.sql @@ -0,0 +1,20 @@ +-- ============================================================================ +-- Copyright (C) 2013 Laurent Destailleur +-- +-- 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 . +-- ============================================================================ + +ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_id_users (id_users); +ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_nom (nom); +ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_id_sondage (id_sondage); diff --git a/htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql b/htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql new file mode 100755 index 00000000000..78d7fa69c4d --- /dev/null +++ b/htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql @@ -0,0 +1,24 @@ +-- ============================================================================ +-- Copyright (C) 2013 Laurent Destailleur +-- +-- 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 . +-- ============================================================================ + +CREATE TABLE llx_opensurvey_user_studs ( + id_users INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, + nom VARCHAR(64) NOT NULL, + id_sondage VARCHAR(16) NOT NULL, + reponses VARCHAR(100) NOT NULL, + tms timestamp +) ENGINE=InnoDB; From becd40a8251436b51b21e93602c7b6165c1c97cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Fri, 19 Apr 2013 15:38:24 +0200 Subject: [PATCH 29/97] Fixed bug #828: Error when code_region is not a number in llx_c_regions (with postgres) --- ChangeLog | 3 ++- htdocs/admin/dict.php | 26 ++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 945bf875bfd..e605a1f3cfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,11 +19,12 @@ English Dolibarr ChangeLog - Fix: [ bug #806 ] Margins module with orders2invoice does not respect cost price - Fix: Orderstoinvoice didn't act as expected when no order was checked - Fix: Bad link to all proposals into Third party card if customer is prospect +- Fix: [ bug #774 ] Bug on creating event with box "all day" crossed - Fix: [ bug #789 ] VAT not being calculated in POS - Fix: [ bug #794 ] Lost filter on zipcode in prospect list -- Fix: [ bug #774 ] Bug on creating event with box "all day" crossed - Fix: [ bug #810 ] Cannot update ODT template path - Fix: [ bug #824 ] MAIN_DB_PREFIX not use into dictionnary +- Fix: [ bug #828 ] Error when code_region is not a number in llx_c_regions (with postgres) ***** ChangeLog for 3.3.1 compared to 3.3 ***** diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 2e49d0f2859..281ae05a65b 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -383,7 +383,7 @@ if ($id == 11) // Define localtax_typeList (used for dictionnary "c_tva") $localtax_typeList = array(); -if (GETPOST("id") == 10) +if ($id == 10) { $localtax_typeList = array( "0" => $langs->trans("No"), @@ -433,7 +433,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($fieldnamekey == 'position') $fieldnamekey = 'Position'; if ($fieldnamekey == 'unicode') $fieldnamekey = 'Unicode'; - $msg.=$langs->trans("ErrorFieldRequired",$langs->transnoentities($fieldnamekey)).'
'; + $msg.=$langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)).'
'; } } // Other checks @@ -441,14 +441,24 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) $ok=0; $msg.="Value 'system' and 'systemauto' for type is reserved. You can use 'user' as value to add your own record.
"; } - if (isset($_POST["code"]) && $_POST["code"]=='0') { - $ok=0; - $msg.="Code can't contains value 0
"; + if (isset($_POST["code"]) + { + if ($_POST["code"]=='0') + { + $ok=0; + $msg.="Code can't contains value 0
"; + } + if (!is_numeric($_POST['code'])) + { + $ok = 0; + $msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'
'; + } } if (isset($_POST["pays"]) && $_POST["pays"]=='0') { $ok=0; - $msg.=$langs->trans("ErrorFieldRequired",$langs->trans("Country")).'
'; + $msg.=$langs->transnoentities("ErrorFieldRequired",$langs->transnoentities("Country")).'
'; } + // Clean some parameters if (isset($_POST["localtax1"]) && empty($_POST["localtax1"])) $_POST["localtax1"]='0'; // If empty, we force to 0 if (isset($_POST["localtax2"]) && empty($_POST["localtax2"])) $_POST["localtax2"]='0'; // If empty, we force to 0 @@ -510,7 +520,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) else { if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - $msg=$langs->trans("ErrorRecordAlreadyExists").'
'; + $msg=$langs->transnoentities("ErrorRecordAlreadyExists").'
'; } else { dol_print_error($db); @@ -580,7 +590,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes') // delete { if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') { - $msg='
'.$langs->trans("ErrorRecordIsUsedByChild").'
'; + $msg='
'.$langs->transnoentities("ErrorRecordIsUsedByChild").'
'; } else { From 8030b395360fdc9006ef7a4eec8d4b13b6342a1c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Apr 2013 19:45:06 +0200 Subject: [PATCH 30/97] fix : undefined variable --- htdocs/core/class/hookmanager.class.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index efd7ad6932d..8e585f7e34a 100755 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -138,8 +138,6 @@ class HookManager { foreach($modules as $module => $actionclassinstance) { - //var_dump(get_class($actionclassinstance).'->'.$method); - // jump to next class if method does not exists if (! method_exists($actionclassinstance,$method)) continue; // test to avoid to run twice a hook, when a module implements several active contexts @@ -164,13 +162,13 @@ class HookManager } // Generic hooks that return a string (printSearchForm, printLeftBlock, printTopRightMenu, formAddObjectLine, formBuilddocOptions, ...) else - { + { // TODO. this should be done into the method by returning nothing if (is_array($parameters) && ! empty($parameters['special_code']) && $parameters['special_code'] > 3 && $parameters['special_code'] != $actionclassinstance->module_number) continue; $result = $actionclassinstance->$method($parameters, $object, $action, $this); - if (is_array($actionclassinstance->results)) $this->resArray =array_merge($this->resArray, $actionclassinstance->results); + if (! empty($actionclassinstance->results) && is_array($actionclassinstance->results)) $this->resArray =array_merge($this->resArray, $actionclassinstance->results); if (! empty($actionclassinstance->resprints)) $this->resPrint.=$actionclassinstance->resprints; // TODO. remove this. array result must be set into $actionclassinstance->results @@ -179,7 +177,7 @@ class HookManager if (! is_array($result) && ! is_numeric($result)) $this->resPrint.=$result; } - //print "method=".$method." results=".count($actionclassinstance->results)." resprints=".count($actionclassinstance->resprints)." result=".$result." resaction=".$resaction; + //print "method=".$method." results=".count($actionclassinstance->results)." resprints=".count($actionclassinstance->resprints)." result=".$result." resaction=".$resaction; } } } From 26aba2b609d237e282407ae9e6a9a612f72c8d94 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Fri, 19 Apr 2013 19:46:49 +0200 Subject: [PATCH 31/97] Add tracking url for carriers in dict --- htdocs/admin/dict.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index cf93f472019..3f1185890c4 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -147,7 +147,7 @@ $tabsql[14]= "SELECT e.rowid as rowid, e.code as code, e.libelle, e.price, e.org $tabsql[15]= "SELECT rowid as rowid, code, label as libelle, width, height, unit, active FROM ".MAIN_DB_PREFIX."c_paper_format"; $tabsql[16]= "SELECT code, label as libelle, active FROM ".MAIN_DB_PREFIX."c_prospectlevel"; $tabsql[17]= "SELECT id as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_type_fees"; -$tabsql[18]= "SELECT rowid as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_shipment_mode"; +$tabsql[18]= "SELECT rowid as rowid, code, libelle, tracking, active FROM ".MAIN_DB_PREFIX."c_shipment_mode"; $tabsql[19]= "SELECT id as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_effectif"; $tabsql[20]= "SELECT rowid as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_input_method"; $tabsql[21]= "SELECT c.rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_availability AS c"; @@ -203,7 +203,7 @@ $tabfield[14]= "code,libelle,price,organization,country_id,country"; $tabfield[15]= "code,libelle,width,height,unit"; $tabfield[16]= "code,libelle"; $tabfield[17]= "code,libelle"; -$tabfield[18]= "code,libelle"; +$tabfield[18]= "code,libelle,tracking"; $tabfield[19]= "code,libelle"; $tabfield[20]= "code,libelle"; $tabfield[21]= "code,label"; @@ -231,7 +231,7 @@ $tabfieldvalue[14]= "code,libelle,price,organization,country"; $tabfieldvalue[15]= "code,libelle,width,height,unit"; $tabfieldvalue[16]= "code,libelle"; $tabfieldvalue[17]= "code,libelle"; -$tabfieldvalue[18]= "code,libelle"; +$tabfieldvalue[18]= "code,libelle,tracking"; $tabfieldvalue[19]= "code,libelle"; $tabfieldvalue[20]= "code,libelle"; $tabfieldvalue[21]= "code,label"; @@ -259,7 +259,7 @@ $tabfieldinsert[14]= "code,libelle,price,organization,fk_pays"; $tabfieldinsert[15]= "code,label,width,height,unit"; $tabfieldinsert[16]= "code,label"; $tabfieldinsert[17]= "code,libelle"; -$tabfieldinsert[18]= "code,libelle"; +$tabfieldinsert[18]= "code,libelle,tracking"; $tabfieldinsert[19]= "code,libelle"; $tabfieldinsert[20]= "code,libelle"; $tabfieldinsert[21]= "code,label"; @@ -1299,6 +1299,7 @@ function fieldList($fieldlist,$obj='',$tabname='') print ''; $size=''; if ($fieldlist[$field]=='libelle') $size='size="32" '; + if ($fieldlist[$field]=='tracking') $size='size="92" '; if ($fieldlist[$field]=='accountancy_code') $size='size="15" '; if ($fieldlist[$field]=='accountancy_code_sell') $size='size="15" '; if ($fieldlist[$field]=='accountancy_code_buy') $size='size="15" '; From bfb05c78cd151d2f04d2f90f958f0ba42e8471bd Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Fri, 19 Apr 2013 20:20:10 +0200 Subject: [PATCH 32/97] Change carrier config into dict instead of dedicated conf page --- htdocs/admin/carrier.php | 222 ------------------ htdocs/admin/confexped.php | 4 - htdocs/admin/expedition.php | 4 - htdocs/admin/livraison.php | 4 - .../expedition/methode_expedition.modules.php | 68 ------ .../methode_expedition_colsui.modules.php | 56 ----- .../methode_expedition_enl.modules.php | 57 ----- .../methode_expedition_lettremax.modules.php | 57 ----- .../methode_expedition_trans.modules.php | 59 ----- htdocs/expedition/class/expedition.class.php | 49 +--- 10 files changed, 11 insertions(+), 569 deletions(-) delete mode 100644 htdocs/admin/carrier.php delete mode 100644 htdocs/core/modules/expedition/methode_expedition.modules.php delete mode 100644 htdocs/core/modules/expedition/methode_expedition_colsui.modules.php delete mode 100644 htdocs/core/modules/expedition/methode_expedition_enl.modules.php delete mode 100644 htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php delete mode 100644 htdocs/core/modules/expedition/methode_expedition_trans.modules.php diff --git a/htdocs/admin/carrier.php b/htdocs/admin/carrier.php deleted file mode 100644 index edb995d3fe7..00000000000 --- a/htdocs/admin/carrier.php +++ /dev/null @@ -1,222 +0,0 @@ - - * - * 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 . - */ - -/** - * \file htdocs/admin/carrier.php - * \ingroup expedition - * \brief Page to setup carriers. TODO Delete this page. We mut use dictionnary instead. - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; - -$langs->load("admin"); -$langs->load("sendings"); -$langs->load("deliveries"); -$langs->load('other'); - -if (! $user->admin) - accessforbidden(); - -$action=GETPOST('action','alpha'); -$carrier=GETPOST('carrier','int'); - -$object = new Expedition($db); - - -/* - * Actions - */ -//if ($action==setvalue AND $carrier) -if ($action=='setvalue') -{ - // need to add check on values - $object->update['code']=GETPOST('code','alpha'); - $object->update['libelle']=GETPOST('libelle','alpha'); - $object->update['description']=GETPOST('description','alpha'); - $object->update['tracking']=GETPOST('tracking','alpha'); - $object->update_delivery_method($carrier); - header("Location: carrier.php"); - exit; -} - -if ($action=='activate_carrier' && $carrier!='') -{ - $object->activ_delivery_method($carrier); -} - -if ($action=='disable_carrier' && $carrier!='') -{ - $object->disable_delivery_method($carrier); -} - -/* - * View - */ - -$form=new Form($db); - -llxHeader("",""); - -$linkback=''.$langs->trans("BackToModuleList").''; -print_fiche_titre($langs->trans("SendingsSetup"),$linkback,'setup'); -print '
'; - - -//if ($mesg) print $mesg.'
'; - - -$h = 0; - -$head[$h][0] = DOL_URL_ROOT."/admin/confexped.php"; -$head[$h][1] = $langs->trans("Setup"); -$h++; - -$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php"; -$head[$h][1] = $langs->trans("Carriers"); -$hselected=$h; -$h++; - -if (! empty($conf->global->MAIN_SUBMODULE_EXPEDITION)) -{ - $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php"; - $head[$h][1] = $langs->trans("Sending"); - $h++; -} - -if (! empty($conf->global->MAIN_SUBMODULE_LIVRAISON)) -{ - $head[$h][0] = DOL_URL_ROOT."/admin/livraison.php"; - $head[$h][1] = $langs->trans("Receivings"); - $h++; -} - -dol_fiche_head($head, $hselected, $langs->trans("ModuleSetup")); - -/* - * Carrier List - */ -if ($action=='edit_carrier' || $action=='setvalue') -{ - // Carrier Edit - if ($carrier!='') $object->list_delivery_methods($carrier); - print_titre($langs->trans("CarrierEdit")); - - print '
'; - print ''; - print ''; - - - print ''; - - $var=true; - print ''; - print ''; - print ''; - print "\n"; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - if ($carrier) - { - print ''; - } - else - { - print ''; - } - - print '
'.$langs->trans("CarrierParameter").''.$langs->trans("Value").'
'; - print $langs->trans("Code").''; - print ''; - print '   '.$langs->trans("Example").': CODE'; - print '
'; - print $langs->trans("Name").''; - print ''; - print '
'; - print $langs->trans("Description").''; - print ''; - print '
'; - print $langs->trans("Tracking").''; - print ''; - print '   '.$langs->trans("Example").': http://www.website.com/dir/{TRACKID}'; - print '


'; - print '
'; - -} -else -{ - // Display List - $object->list_delivery_methods(); - $var=true; - print_titre($langs->trans("CarrierList")); - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - $numlistmeths=count($object->listmeths); - for ($i=0; $i<$numlistmeths; $i++) - { - $var=!$var; - print ""; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - } - print ''; - - print '
'.$langs->trans("Code").''.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("TrackingUrl").''.$langs->trans("Status").''.$langs->trans("Edit").'
'.$object->listmeths[$i]['code'].''.$object->listmeths[$i]['libelle'].''.$object->listmeths[$i]['description'].''.dol_trunc($object->listmeths[$i]['tracking'],92,'middle').''; - if($object->listmeths[$i]['active'] == 0) - { - print ''.img_picto($langs->trans("Disabled"),'switch_off').''; - } - else - { - print ''.img_picto($langs->trans("Enabled"),'switch_on').''; - } - print ''; - print ''.img_picto($langs->trans("Edit"),'edit').''; - print '

'.$langs->trans("Add").'

'; - - print ''; -} - -llxFooter(); - -$db->close(); -?> diff --git a/htdocs/admin/confexped.php b/htdocs/admin/confexped.php index 6653badfb36..d9be768461f 100644 --- a/htdocs/admin/confexped.php +++ b/htdocs/admin/confexped.php @@ -84,10 +84,6 @@ $head[$h][1] = $langs->trans("Setup"); $hselected=$h; $h++; -$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php"; -$head[$h][1] = $langs->trans("Carriers"); -$h++; - if (! empty($conf->global->MAIN_SUBMODULE_EXPEDITION)) { $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php"; diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index 34535b1d321..28e5b912de2 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -201,10 +201,6 @@ $head[$h][0] = DOL_URL_ROOT."/admin/confexped.php"; $head[$h][1] = $langs->trans("Setup"); $h++; -$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php"; -$head[$h][1] = $langs->trans("Carriers"); -$h++; - $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php"; $head[$h][1] = $langs->trans("Sending"); $hselected=$h; diff --git a/htdocs/admin/livraison.php b/htdocs/admin/livraison.php index 49cbeee9026..677e2b3773b 100644 --- a/htdocs/admin/livraison.php +++ b/htdocs/admin/livraison.php @@ -189,10 +189,6 @@ $head[$h][0] = DOL_URL_ROOT."/admin/confexped.php"; $head[$h][1] = $langs->trans("Setup"); $h++; -$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php"; -$head[$h][1] = $langs->trans("Carriers"); -$h++; - if (! empty($conf->global->MAIN_SUBMODULE_EXPEDITION)) { $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php"; diff --git a/htdocs/core/modules/expedition/methode_expedition.modules.php b/htdocs/core/modules/expedition/methode_expedition.modules.php deleted file mode 100644 index 3ea7ba97ce9..00000000000 --- a/htdocs/core/modules/expedition/methode_expedition.modules.php +++ /dev/null @@ -1,68 +0,0 @@ - - * Copyright (C) 2007 Laurent Destailleur - * - * 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/expedition/methode_expedition.modules.php - * \ingroup expedition - * \brief Fichier contenant la classe mere de generation de bon de livraison en PDF - * et la classe mere de numerotation des bons de livraisons - */ -require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; - - -/** - * Parent class for shipping method classes - */ -class ModeleShippingMethod -{ - /** - * Constructo - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - $this->name = "NOT DEFINED"; - $this->description = "ERROR IN MODULE DESCRIPTION"; - } - - - /** - * Return list of active generation modules - * - * @param DoliDB $db Database handler - * @param string $maxfilenamelength Max length of value to show - * @return array List of templates - */ - static function liste_modeles($db,$maxfilenamelength=0) - { - global $conf; - - $type='???'; - $liste=array(); - - include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $liste=getListOfModels($db,$type,$maxfilenamelength); - - return $liste; - } -} - -?> diff --git a/htdocs/core/modules/expedition/methode_expedition_colsui.modules.php b/htdocs/core/modules/expedition/methode_expedition_colsui.modules.php deleted file mode 100644 index fca7ffc38ff..00000000000 --- a/htdocs/core/modules/expedition/methode_expedition_colsui.modules.php +++ /dev/null @@ -1,56 +0,0 @@ - - * Copyright (C) 2008 Bearstech - http://bearstech.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 . - */ - -/** - * \file htdocs/core/modules/expedition/methode_expedition_colsui.modules.php - * \ingroup expedition - */ -include_once 'methode_expedition.modules.php'; - -/** - * Class to manage shipment Colsui - */ -class methode_expedition_colsui extends ModeleShippingMethod -{ - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db=0) - { - $this->db = $db; - $this->id = 3; // Do not change this value - $this->code = "COLSUI"; // Do not change this value - $this->name = "Colissimo Suivi"; - $this->description = "Colissimo Suivi"; - } - - /** - * Return URL of provider - * - * @param string $tracking_number Tracking number - * @return string URL for tracking - */ - function provider_url_status($tracking_number) - { - return sprintf("http://www.coliposte.net/particulier/suivi_particulier.jsp?colispart=%s",$tracking_number); - } -} - -?> diff --git a/htdocs/core/modules/expedition/methode_expedition_enl.modules.php b/htdocs/core/modules/expedition/methode_expedition_enl.modules.php deleted file mode 100644 index 17e5cf35be9..00000000000 --- a/htdocs/core/modules/expedition/methode_expedition_enl.modules.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * 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 . - */ - -/** - * \file htdocs/core/modules/expedition/methode_expedition_enl.modules.php - * \ingroup expedition - */ -include_once 'methode_expedition.modules.php'; - - -/** - * Class to manage shipment Enl - */ -class methode_expedition_enl extends ModeleShippingMethod -{ - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db=0) - { - global $langs; - $this->db = $db; - $this->id = 1; // Do not change this value - $this->name = "Enlevement"; - $this->code = "ENL"; - $this->description = $langs->trans("Enlevement"); - } - - /** - * Return URL of provider - * - * @param string $tracking_number Tracking number - * @return string URL for tracking - */ - function provider_url_status($tracking_number) - { - return ''; - } -} - -?> diff --git a/htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php b/htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php deleted file mode 100644 index c8150af9497..00000000000 --- a/htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * 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 . - */ - -/** - * \file htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php - * \ingroup expedition - */ - -include_once 'methode_expedition.modules.php'; - - -/** - * Class to manage shipment lettremax - */ -class methode_expedition_lettremax extends ModeleShippingMethod -{ - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db=0) - { - $this->db = $db; - $this->id = 4; // Do not change this value - $this->code = "LETTREMAX"; // Do not change this value - $this->name = "Lettre max"; - $this->description = "Courrier suivi et lettre max"; - } - - /** - * Return URL of provider - * - * @param string $tracking_number Tracking number - * @return string URL for tracking - */ - function provider_url_status($tracking_number) - { - return sprintf("http://www.csuivi.courrier.laposte.fr/default.asp?EZ_ACTION=rechercheRapide&numObjet=%s",$tracking_number); - } -} - -?> diff --git a/htdocs/core/modules/expedition/methode_expedition_trans.modules.php b/htdocs/core/modules/expedition/methode_expedition_trans.modules.php deleted file mode 100644 index d974b7c161a..00000000000 --- a/htdocs/core/modules/expedition/methode_expedition_trans.modules.php +++ /dev/null @@ -1,59 +0,0 @@ - - * - * 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 . - */ - -/** - * \file htdocs/core/modules/expedition/methode_expedition_trans.modules.php - * \ingroup expedition - */ -include_once 'methode_expedition.modules.php'; - - -/** - * Class to manage shipment Trans - */ -class methode_expedition_trans extends ModeleShippingMethod -{ - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db=0) - { - global $langs; - - $this->db = $db; - $this->id = 2; // Ne pas changer cette valeur - $this->code = "TRANS"; - $this->name = "Transporteur"; - $this->description = $langs->trans("GenericTransport"); - } - - /** - * Return URL of provider - * - * @param string $tracking_number Tracking number - * @return string URL for tracking - */ - function provider_url_status($tracking_number) - { - return ''; - } -} - -?> diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index f3db4dafc8b..99621b2d16c 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -1309,8 +1309,6 @@ class Expedition extends CommonObject */ function GetUrlTrackingStatus($value='') { - $code=''; - if (! empty($this->shipping_method_id)) { $sql = "SELECT em.code, em.tracking"; @@ -1322,46 +1320,21 @@ class Expedition extends CommonObject { if ($obj = $this->db->fetch_object($resql)) { - $code = $obj->code; - $tracking = $obj->tracking; + $tracking = $obj->tracking; } } } - if ($tracking) - { - $url = str_replace('{TRACKID}', $value, $tracking); - $this->tracking_url = sprintf(''.($value?$value:'url').'',$url,$url); - } - else - { - if ($code) - { - $classname = "methode_expedition_".strtolower($code); - - $url=''; - if (file_exists(DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($code).".modules.php") && ! empty($this->tracking_number)) - { - require_once DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($code).'.modules.php'; - $shipmethod = new $classname(); - $url = $shipmethod->provider_url_status($this->tracking_number); - } - - if ($url) - { - $this->tracking_url = sprintf(''.($value?$value:'url').'',$url,$url); - } - else - { - $this->tracking_url = $value; - } - } - else - { - $this->tracking_url = $value; - } - } - } + if (!empty($tracking)) + { + $url = str_replace('{TRACKID}', $value, $tracking); + $this->tracking_url = sprintf(''.($value?$value:'url').'',$url,$url); + } + else + { + $this->tracking_url = $value; + } + } /** * Classify the shipping as invoiced From 458b1cdf60da94a89f2412d1b0d0edfd21511054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Fri, 19 Apr 2013 23:33:54 +0200 Subject: [PATCH 33/97] Improved dictionary translations + minor bug fix --- ChangeLog | 2 +- htdocs/admin/dict.php | 7 ++++--- htdocs/langs/en_US/admin.lang | 2 ++ htdocs/langs/es_ES/admin.lang | 4 +++- htdocs/langs/es_ES/bills.lang | 2 +- htdocs/langs/fr_FR/admin.lang | 2 ++ 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index e605a1f3cfb..e7991515f6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,7 +6,7 @@ English Dolibarr ChangeLog ***** ChangeLog for 3.3.2 compared to 3.3.1 ***** -- Fix: Ducth (nl_NL) translation +- Fix: Dutch (nl_NL) translation - Fix: [ bug #790 ] Spanish localtax RE not being correctly calculated - Generalize fix: file with a specific mask not found, again - Fix: translations and BILL_SUPPLIER_BUILDDOC trigger diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 281ae05a65b..5a4db149b87 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -439,14 +439,14 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) // Other checks if ($tabname[$id] == MAIN_DB_PREFIX."c_actioncomm" && isset($_POST["type"]) && in_array($_POST["type"],array('system','systemauto'))) { $ok=0; - $msg.="Value 'system' and 'systemauto' for type is reserved. You can use 'user' as value to add your own record.
"; + $msg.= $langs->transnoentities('ErrorReservedTypeSystemSystemAuto').'
'; } - if (isset($_POST["code"]) + if (isset($_POST["code"])) { if ($_POST["code"]=='0') { $ok=0; - $msg.="Code can't contains value 0
"; + $msg.= $langs->transnoentities('ErrorCodeCantContainZero').'
'; } if (!is_numeric($_POST['code'])) { @@ -988,6 +988,7 @@ if ($id) $valuetoshow=($obj->code && $key != "Civility".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]); } else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_type_contact') { + $langs->load('agenda'); $key=$langs->trans("TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)); $valuetoshow=($obj->code && $key != "TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]); } diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 8d613053e3a..736a24cc635 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -46,6 +46,8 @@ ErrorModuleRequireDolibarrVersion=Error, this module requires Dolibarr version % ErrorDecimalLargerThanAreForbidden=Error, a precision higher than %s is not supported. DictionnarySetup=Dictionary setup Dictionnary=Dictionaries +ErrorReservedTypeSystemSystemAuto=Value 'system' and 'systemauto' for type is reserved. You can use 'user' as value to add your own record +ErrorCodeCantContainZero=Code can't contain value 0 DisableJavascript=Disable JavaScript and Ajax functions ConfirmAjax=Use Ajax confirmation popups UseSearchToSelectCompany=Use autocompletion fields to choose third parties (instead of using a list box).

Also if you have a large number of third parties (> 100 000), you can increase speed by setting constant SOCIETE_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string. diff --git a/htdocs/langs/es_ES/admin.lang b/htdocs/langs/es_ES/admin.lang index ad4a06a6f79..162fc8a38d0 100644 --- a/htdocs/langs/es_ES/admin.lang +++ b/htdocs/langs/es_ES/admin.lang @@ -46,6 +46,8 @@ ErrorModuleRequireDolibarrVersion=Error, este módulo requiere una versión %s o ErrorDecimalLargerThanAreForbidden=Error, las precisiones superiores a %s no están soportadas. DictionnarySetup=Diccionarios Dictionnary=Diccionarios +ErrorReservedTypeSystemSystemAuto=El uso del tipo 'system' and 'systemauto' está reservado. Puede utilizar 'user' como valor para añadir su propio registro +ErrorCodeCantContainZero=El código no puede contener el valor 0 DisableJavascript=Desactivar las funciones Javascript ConfirmAjax=Utilizar los popups de confirmación Ajax UseSearchToSelectCompany=Utilizar un formulario de búsqueda para buscar terceros (en vez de lista desplegable)

Tenga en cuenta que si tiene un gran número de productos o servicios (>100 000), puede mejorar el rendimiento mediante la constante SOCIETE_DONOTSEARCH_ANYWHERE a 1 en Configuración->Varios. La búsqueda se limitará entonces al inicio de la cadena. @@ -294,7 +296,7 @@ ServerNotAvailableOnIPOrPort=Servidor no disponible en la dirección %s e DoTestServerAvailability=Probar conectividad con el servidor DoTestSend=Probar envío DoTestSendHTML=Probar envío HTML -ErrorCantUseRazInStartedYearIfNoYearMonthInMask=Error, no se puede usar opción @ si la secuencia {yy}{mm} o {yyyy}{mm} no se encuentra en la máscara. +ErrorCantUseRazInStartedYearIfNoYearMonthInMask=Error, no se puede usar la opción @ si la secuencia {yy}{mm} o {yyyy}{mm} no se encuentra en la máscara. UMask=Parámetro UMask de nuevos archivos en Unix/Linux/BSD. UMaskExplanation=Este parámetro determina los derechos de los archivos creados en el servidor Dolibarr (durante la subida, por ejemplo).
Este debe ser el valor octal (por ejemplo, 0666 significa lectura / escritura para todos).
Este parámetro no tiene ningún efecto sobre un servidor Windows. SeeWikiForAllTeam=Vea el wiki para más detalles de todos los actores y de su organización diff --git a/htdocs/langs/es_ES/bills.lang b/htdocs/langs/es_ES/bills.lang index 2ac03e256db..7f2fbf259ec 100644 --- a/htdocs/langs/es_ES/bills.lang +++ b/htdocs/langs/es_ES/bills.lang @@ -250,7 +250,7 @@ Deposit=Anticipo Deposits=Anticipos DiscountFromCreditNote=Descuento resultante del abono %s DiscountFromDeposit=Pagos de la factura de anticipo %s -AbsoluteDiscountUse=Este tipo de crédito no puede ser utilizado en una factura antes de su validación +AbsoluteDiscountUse=Este tipo de descuento no puede ser utilizado en una factura antes de su validación CreditNoteDepositUse=La factura debe de estar validada para poder utilizar este tipo de créditos NewGlobalDiscount=Nuevo descuento fijo NewRelativeDiscount=Nuevo descuento diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 616cfc6d550..66c398df90b 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -45,6 +45,8 @@ ErrorModuleRequireDolibarrVersion= Erreur, ce module requiert une version %s ou ErrorDecimalLargerThanAreForbidden= Erreur, les précisions supérieures à %s ne sont pas supportées. DictionnarySetup= Dictionnaires Dictionnary= Dictionnaires +ErrorReservedTypeSystemSystemAuto= +ErrorCodeCantContainZero= DisableJavascript= Désactiver les fonctions Javascript et Ajax ConfirmAjax= Utiliser les popups de confirmation Ajax UseSearchToSelectCompany= Utiliser un champ avec autocomplétion pour choisir un tiers (plutôt qu'une liste déroulante).

Notez que si vous avez un nombre important de produits ou services (> 100 000), vous pouvez améliorer les performances en définissant la constante SOCIETE_DONOTSEARCH_ANYWHERE à 1 dans Configuration->Divers. La recherche sera alors limitée au début de la chaine. From 40a9ab9772bf67106e40c9f12be38348902a48ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sat, 20 Apr 2013 00:08:09 +0200 Subject: [PATCH 34/97] Added missing translations --- htdocs/admin/menus/edit.php | 1 + htdocs/langs/en_US/admin.lang | 1 + htdocs/langs/en_US/commercial.lang | 1 + htdocs/langs/en_US/holiday.lang | 7 ++++++- htdocs/langs/es_ES/admin.lang | 3 ++- htdocs/langs/es_ES/commercial.lang | 1 + htdocs/langs/es_ES/holiday.lang | 7 ++++++- htdocs/langs/fr_FR/admin.lang | 1 + htdocs/langs/fr_FR/commercial.lang | 1 + htdocs/langs/fr_FR/holiday.lang | 7 ++++++- 10 files changed, 26 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index f223f1f9d52..fd1c03ea52e 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -29,6 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/menubase.class.php'; $langs->load("admin"); +$langs->load('other'); if (! $user->admin) accessforbidden(); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 736a24cc635..2347bcdf22c 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -526,6 +526,7 @@ Permission98=Dispatch invoice accountancy lines Permission101=Read sendings Permission102=Create/modify sendings Permission104=Validate sendings +Permission106=Export sendings Permission109=Delete sendings Permission111=Read financial accounts Permission112=Create/modify/delete and compare transactions diff --git a/htdocs/langs/en_US/commercial.lang b/htdocs/langs/en_US/commercial.lang index baac58e4642..c17ddf2e8be 100644 --- a/htdocs/langs/en_US/commercial.lang +++ b/htdocs/langs/en_US/commercial.lang @@ -81,6 +81,7 @@ ActionAC_SHIP=Send shipping by mail ActionAC_SUP_ORD=Send supplier order by mail ActionAC_SUP_INV=Send supplier invoice by mail ActionAC_OTH=Other +ActionAC_OTH_AUTO=Other (automatically inserted events) ActionAC_MANUAL=Manually inserted events ActionAC_AUTO=Automatically inserted events Stats=Sales statistics diff --git a/htdocs/langs/en_US/holiday.lang b/htdocs/langs/en_US/holiday.lang index 67adb36dfeb..8a5a55f6e01 100755 --- a/htdocs/langs/en_US/holiday.lang +++ b/htdocs/langs/en_US/holiday.lang @@ -131,4 +131,9 @@ NoCPforMonth=No leave this month. Jours=days nbJours=Number days TitleAdminCP=Configuration of Holidays -Permission20001=Read / Modify all requests of holidays +Permission20001=Read/create/modify their holidays +Permission20002=Read/modify all requests of holidays +Permission20003=Delete their holidays requests +Permission20004=Define users holidays +Permission20005=Review log of modified holidays +Permission20006=Access holidays monthly report \ No newline at end of file diff --git a/htdocs/langs/es_ES/admin.lang b/htdocs/langs/es_ES/admin.lang index 162fc8a38d0..ac215d36feb 100644 --- a/htdocs/langs/es_ES/admin.lang +++ b/htdocs/langs/es_ES/admin.lang @@ -46,7 +46,7 @@ ErrorModuleRequireDolibarrVersion=Error, este módulo requiere una versión %s o ErrorDecimalLargerThanAreForbidden=Error, las precisiones superiores a %s no están soportadas. DictionnarySetup=Diccionarios Dictionnary=Diccionarios -ErrorReservedTypeSystemSystemAuto=El uso del tipo 'system' and 'systemauto' está reservado. Puede utilizar 'user' como valor para añadir su propio registro +ErrorReservedTypeSystemSystemAuto=El uso del tipo 'system' y 'systemauto' está reservado. Puede utilizar 'user' como valor para añadir su propio registro ErrorCodeCantContainZero=El código no puede contener el valor 0 DisableJavascript=Desactivar las funciones Javascript ConfirmAjax=Utilizar los popups de confirmación Ajax @@ -527,6 +527,7 @@ Permission98=Desglosar líneas de facturas Permission101=Consultar expediciones Permission102=Crear/modificar expediciones Permission104=Validar expediciones +Permission106=Exportar expediciones Permission109=Eliminar expediciones Permission111=Consultar cuentas financieras (cuentas bancarias, cajas) Permission112=Crear/modificar cantidad/eliminar registros bancarios diff --git a/htdocs/langs/es_ES/commercial.lang b/htdocs/langs/es_ES/commercial.lang index 3b5d007aac9..9d774606bf0 100644 --- a/htdocs/langs/es_ES/commercial.lang +++ b/htdocs/langs/es_ES/commercial.lang @@ -81,6 +81,7 @@ ActionAC_SHIP=Envío expedición por correo ActionAC_SUP_ORD=Envío pedido a proveedor por correo ActionAC_SUP_INV=Envío factura de proveedor por correo ActionAC_OTH=Otra +ActionAC_OTH_AUTO=Otra (eventos insertados automáticamente) ActionAC_MANUAL=Eventos creados manualmente ActionAC_AUTO=Eventos creados automáticamente Stats=Estadísticas de venta diff --git a/htdocs/langs/es_ES/holiday.lang b/htdocs/langs/es_ES/holiday.lang index ebf1a0457d9..93387f29525 100644 --- a/htdocs/langs/es_ES/holiday.lang +++ b/htdocs/langs/es_ES/holiday.lang @@ -132,4 +132,9 @@ NoCPforMonth=Sin vacaciones este mes. Jours=días nbJours=Número de días TitleAdminCP=Configuración de las vacaciones -Permission20001=Leer / Crear / Modificar sus vacaciones \ No newline at end of file +Permission20001=Consultar/crear/modificar sus vacaciones +Permission20002=Consultar/modificar todas las solicitudes de permisos retribuídos +Permission20003=Eliminar las solicitudes de permisos retribuídos +Permission20004=Definir los permisos retribuídos de los usuarios +Permission20005=Consultar el historial de modificaciones de permisos retribuidos +Permission20006=Acceder al informe mensual de permisos retribuidos \ No newline at end of file diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 66c398df90b..51966eebcf2 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -520,6 +520,7 @@ Permission98= Ventiler les lignes de factures Permission101= Consulter les expéditions Permission102= Créer/modifier les expéditions Permission104= Valider les expéditions +Permission106= Exporter les expéditions Permission109= Supprimer les expéditions Permission111= Consulter les comptes financiers (comptes bancaires, caisses) Permission112= Créer/modifier montant/supprimer écritures bancaires diff --git a/htdocs/langs/fr_FR/commercial.lang b/htdocs/langs/fr_FR/commercial.lang index 79937cb84fb..e9ab93d8f37 100644 --- a/htdocs/langs/fr_FR/commercial.lang +++ b/htdocs/langs/fr_FR/commercial.lang @@ -81,6 +81,7 @@ ActionAC_SHIP=Envoi bon d'expédition par mail ActionAC_SUP_ORD=Envoi commande fournisseur par mail ActionAC_SUP_INV=Envoi facture fournisseur par mail ActionAC_OTH=Autre +ActionAC_OTH_AUTO=Autre (evênements insérés automatiquement) ActionAC_MANUAL=Evênements insérés manuellement ActionAC_AUTO=Evênements insérés automatiquement Stats=Statistiques de vente diff --git a/htdocs/langs/fr_FR/holiday.lang b/htdocs/langs/fr_FR/holiday.lang index c01d84218bf..e09d0de2cbd 100644 --- a/htdocs/langs/fr_FR/holiday.lang +++ b/htdocs/langs/fr_FR/holiday.lang @@ -130,4 +130,9 @@ NoCPforMonth=Aucun congé ce mois-ci. Jours=jours nbJours=Nombre jours TitleAdminCP=Configuration des Congés -Permission20001=Lire / Créer / modifier ses congès \ No newline at end of file +Permission20001=Lire / Créer / modifier ses congès +Permission20002=Lire / Modifier toutes les demandes de congés payés +Permission20003=Supprimer des demandes de congés payés +Permission20004=Définir les congés payés des utilisateurs +Permission20005=Voir les logs de modification des congés payés +Permission20006=Accéder au rapport mensuel des congés payés \ No newline at end of file From e2d0d0d41403b3da92ad0614a7e21ec731bec3e4 Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 20 Apr 2013 00:10:20 +0200 Subject: [PATCH 35/97] Fix fix as Eldy wish it --- htdocs/admin/stock.php | 4 +- htdocs/compta/facture.php | 6308 +++++++++-------- htdocs/compta/facture/class/facture.class.php | 2 +- htdocs/core/class/commonobject.class.php | 4 +- htdocs/langs/en_US/stocks.lang | 1 + htdocs/langs/es_ES/stocks.lang | 1 + htdocs/langs/fr_FR/stocks.lang | 1 + .../product/class/html.formproduct.class.php | 5 +- 8 files changed, 3200 insertions(+), 3126 deletions(-) diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index 96502bbdb10..0390efcdda4 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -62,8 +62,7 @@ if ($action == 'STOCK_CALCULATE_ON_BILL' // Mode of stock increase if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL' || $action == 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER' -|| $action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER' -|| $action == 'STOCK_CALCULATE_ON_DELETE_INVOICE') +|| $action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') { $db->begin(); $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_BILL", '','chaine',0,'',$conf->entity); @@ -73,7 +72,6 @@ if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL' if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_BILL", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_BILL','alpha'),'chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER','alpha'),'chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER','alpha'),'chaine',0,'',$conf->entity); - if ($action == 'STOCK_CALCULATE_ON_DELETE_INVOICE') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_DELETE_INVOICE", GETPOST('STOCK_CALCULATE_ON_DELETE_INVOICE','alpha'),'chaine',0,'',$conf->entity); } if($action) diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 6ba029d63b4..590901a937a 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1,34 +1,34 @@ * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2004-2013 Laurent Destailleur - * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2010-2013 Juanjo Menent - * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2013 Jean-Francois FERRY - * Copyright (C) 2013 Florian Henry - * - * 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 . - */ +* Copyright (C) 2004-2013 Laurent Destailleur +* Copyright (C) 2005 Marc Barilley / Ocebo +* Copyright (C) 2005-2012 Regis Houssin +* Copyright (C) 2006 Andre Cianfarani +* Copyright (C) 2010-2013 Juanjo Menent +* Copyright (C) 2012 Christophe Battarel +* Copyright (C) 2013 Jean-Francois FERRY +* Copyright (C) 2013 Florian Henry +* +* 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 . +*/ /** * \file htdocs/compta/facture.php - * \ingroup facture - * \brief Page to create/see an invoice - */ +* \ingroup facture +* \brief Page to create/see an invoice +*/ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; @@ -99,7 +99,7 @@ $hookmanager->initHooks(array('invoicecard')); /* * Actions - */ +*/ $parameters=array('socid'=>$socid); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks @@ -108,47 +108,47 @@ $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Action clone object if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer) { - if (1==0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) - { - $mesgs[]='
'.$langs->trans("NoCloneOptionsSpecified").'
'; - } - else - { - if ($object->fetch($id) > 0) - { - $result=$object->createFromClone($socid); - if ($result > 0) - { - header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$result); - exit; - } - else - { - $mesgs[]=$object->error; - $action=''; - } - } - } + if (1==0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) + { + $mesgs[]='
'.$langs->trans("NoCloneOptionsSpecified").'
'; + } + else + { + if ($object->fetch($id) > 0) + { + $result=$object->createFromClone($socid); + if ($result > 0) + { + header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$result); + exit; + } + else + { + $mesgs[]=$object->error; + $action=''; + } + } + } } // Change status of invoice else if ($action == 'reopen' && $user->rights->facture->creer) { - $result = $object->fetch($id); - if ($object->statut == 2 - || ($object->statut == 3 && $object->close_code != 'replaced')) - { - $result = $object->set_unpaid($user); - if ($result > 0) - { - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); - exit; - } - else - { - $mesgs[]='
'.$object->error.'
'; - } - } + $result = $object->fetch($id); + if ($object->statut == 2 + || ($object->statut == 3 && $object->close_code != 'replaced')) + { + $result = $object->set_unpaid($user); + if ($result > 0) + { + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); + exit; + } + else + { + $mesgs[]='
'.$object->error.'
'; + } + } } // Delete invoice @@ -156,20 +156,19 @@ else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->fact { $result = $object->fetch($id); $object->fetch_thirdparty(); - + $idwarehouse=GETPOST('idwarehouse'); - - //Check for warehouse - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_DELETE_INVOICE) && $object->hasProductsOrServices(1) && $object->statut>=1) + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - if (! $idwarehouse || $idwarehouse == -1) - { - $error++; - setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors'); - $action=''; - } + $qualified_for_stock_change=$object->hasProductsOrServices(2); } - + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + $result = $object->delete(0,0,$idwarehouse); if ($result > 0) { @@ -222,146 +221,146 @@ else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights-> // Delete link of credit note to invoice else if ($action == 'unlinkdiscount' && $user->rights->facture->creer) { - $discount=new DiscountAbsolute($db); - $result=$discount->fetch($_GET["discountid"]); - $discount->unlink_invoice(); + $discount=new DiscountAbsolute($db); + $result=$discount->fetch($_GET["discountid"]); + $discount->unlink_invoice(); } // Validation else if ($action == 'valid' && $user->rights->facture->creer) { - $object->fetch($id); + $object->fetch($id); - // On verifie signe facture - if ($object->type == 2) - { - // Si avoir, le signe doit etre negatif - if ($object->total_ht >= 0) - { - $mesgs[]='
'.$langs->trans("ErrorInvoiceAvoirMustBeNegative").'
'; - $action=''; - } - } - else - { - // Si non avoir, le signe doit etre positif - if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) - { - $mesgs[]='
'.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive").'
'; - $action=''; - } - } + // On verifie signe facture + if ($object->type == 2) + { + // Si avoir, le signe doit etre negatif + if ($object->total_ht >= 0) + { + $mesgs[]='
'.$langs->trans("ErrorInvoiceAvoirMustBeNegative").'
'; + $action=''; + } + } + else + { + // Si non avoir, le signe doit etre positif + if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) + { + $mesgs[]='
'.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive").'
'; + $action=''; + } + } } else if ($action == 'set_thirdparty' && $user->rights->facture->creer) { - $object->fetch($id); - $object->setValueFrom('fk_soc',$socid); + $object->fetch($id); + $object->setValueFrom('fk_soc',$socid); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); - exit; + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); + exit; } else if ($action == 'classin' && $user->rights->facture->creer) { - $object->fetch($id); - $object->setProject($_POST['projectid']); + $object->fetch($id); + $object->setProject($_POST['projectid']); } else if ($action == 'setmode' && $user->rights->facture->creer) { - $object->fetch($id); - $result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int')); - if ($result < 0) dol_print_error($db,$object->error); + $object->fetch($id); + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int')); + if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setinvoicedate' && $user->rights->facture->creer) { - $object->fetch($id); - $old_date_lim_reglement=$object->date_lim_reglement; - $object->date=dol_mktime(12,0,0,$_POST['invoicedatemonth'],$_POST['invoicedateday'],$_POST['invoicedateyear']); - $new_date_lim_reglement=$object->calculate_date_lim_reglement(); - if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement; - if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date; - $result=$object->update($user); - if ($result < 0) dol_print_error($db,$object->error); + $object->fetch($id); + $old_date_lim_reglement=$object->date_lim_reglement; + $object->date=dol_mktime(12,0,0,$_POST['invoicedatemonth'],$_POST['invoicedateday'],$_POST['invoicedateyear']); + $new_date_lim_reglement=$object->calculate_date_lim_reglement(); + if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement; + if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date; + $result=$object->update($user); + if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setconditions' && $user->rights->facture->creer) { - $object->fetch($id); - $object->cond_reglement_code=0; // To clean property - $object->cond_reglement_id=0; // To clean property - $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int')); - if ($result < 0) dol_print_error($db,$object->error); + $object->fetch($id); + $object->cond_reglement_code=0; // To clean property + $object->cond_reglement_id=0; // To clean property + $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int')); + if ($result < 0) dol_print_error($db,$object->error); - $old_date_lim_reglement=$object->date_lim_reglement; - $new_date_lim_reglement=$object->calculate_date_lim_reglement(); - if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement; - if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date; - $result=$object->update($user); - if ($result < 0) dol_print_error($db,$object->error); + $old_date_lim_reglement=$object->date_lim_reglement; + $new_date_lim_reglement=$object->calculate_date_lim_reglement(); + if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement; + if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date; + $result=$object->update($user); + if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setpaymentterm' && $user->rights->facture->creer) { - $object->fetch($id); - $object->date_lim_reglement=dol_mktime(12,0,0,$_POST['paymenttermmonth'],$_POST['paymenttermday'],$_POST['paymenttermyear']); - if ($object->date_lim_reglement < $object->date) - { - $object->date_lim_reglement=$object->calculate_date_lim_reglement(); - setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"),'warnings'); - } - $result=$object->update($user); - if ($result < 0) dol_print_error($db,$object->error); + $object->fetch($id); + $object->date_lim_reglement=dol_mktime(12,0,0,$_POST['paymenttermmonth'],$_POST['paymenttermday'],$_POST['paymenttermyear']); + if ($object->date_lim_reglement < $object->date) + { + $object->date_lim_reglement=$object->calculate_date_lim_reglement(); + setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"),'warnings'); + } + $result=$object->update($user); + if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setrevenuestamp' && $user->rights->facture->creer) { - $object->fetch($id); - $object->revenuestamp=GETPOST('revenuestamp'); - $result=$object->update($user); - $object->update_price(1); - if ($result < 0) dol_print_error($db,$object->error); + $object->fetch($id); + $object->revenuestamp=GETPOST('revenuestamp'); + $result=$object->update($user); + $object->update_price(1); + if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setremisepercent' && $user->rights->facture->creer) { - $object->fetch($id); - $result = $object->set_remise($user, $_POST['remise_percent']); + $object->fetch($id); + $result = $object->set_remise($user, $_POST['remise_percent']); } else if ($action == "setabsolutediscount" && $user->rights->facture->creer) { - // POST[remise_id] ou POST[remise_id_for_payment] - if (! empty($_POST["remise_id"])) - { - $ret=$object->fetch($id); - if ($ret > 0) - { - $result=$object->insert_discount($_POST["remise_id"]); - if ($result < 0) - { - $mesgs[]='
'.$object->error.'
'; - } - } - else - { - dol_print_error($db,$object->error); - } - } - if (! empty($_POST["remise_id_for_payment"])) - { - require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - $discount = new DiscountAbsolute($db); - $discount->fetch($_POST["remise_id_for_payment"]); + // POST[remise_id] ou POST[remise_id_for_payment] + if (! empty($_POST["remise_id"])) + { + $ret=$object->fetch($id); + if ($ret > 0) + { + $result=$object->insert_discount($_POST["remise_id"]); + if ($result < 0) + { + $mesgs[]='
'.$object->error.'
'; + } + } + else + { + dol_print_error($db,$object->error); + } + } + if (! empty($_POST["remise_id_for_payment"])) + { + require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; + $discount = new DiscountAbsolute($db); + $discount->fetch($_POST["remise_id_for_payment"]); - $result=$discount->link_to_invoice(0,$id); - if ($result < 0) - { - $mesgs[]='
'.$discount->error.'
'; - } - } + $result=$discount->link_to_invoice(0,$id); + if ($result < 0) + { + $mesgs[]='
'.$discount->error.'
'; + } + } } else if ($action == 'set_ref_client' && $user->rights->facture->creer) { - $object->fetch($id); - $object->set_ref_client($_POST['ref_client']); + $object->fetch($id); + $object->set_ref_client($_POST['ref_client']); } else if ($action == 'setnote_public' && $user->rights->facture->creer) @@ -381,864 +380,894 @@ else if ($action == 'setnote_private' && $user->rights->facture->creer) // Classify to validated else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider) { - $idwarehouse=GETPOST('idwarehouse'); + $idwarehouse=GETPOST('idwarehouse'); - $object->fetch($id); - $object->fetch_thirdparty(); + $object->fetch($id); + $object->fetch_thirdparty(); - // Check parameters + // Check parameters - // Check for mandatory prof id - for ($i = 1; $i < 5; $i++) - { + // Check for mandatory prof id + for ($i = 1; $i < 5; $i++) + { - $idprof_mandatory ='SOCIETE_IDPROF'.($i).'_INVOICE_MANDATORY'; - $idprof='idprof'.$i; - if (! $object->thirdparty->$idprof && ! empty($conf->global->$idprof_mandatory)) - { - if (! $error) $langs->load("errors"); - $error++; + $idprof_mandatory ='SOCIETE_IDPROF'.($i).'_INVOICE_MANDATORY'; + $idprof='idprof'.$i; + if (! $object->thirdparty->$idprof && ! empty($conf->global->$idprof_mandatory)) + { + if (! $error) $langs->load("errors"); + $error++; - setEventMessage($langs->trans('ErrorProdIdIsMandatory',$langs->transcountry('ProfId'.$i, $object->thirdparty->country_code)),'errors'); - } - } + setEventMessage($langs->trans('ErrorProdIdIsMandatory',$langs->transcountry('ProfId'.$i, $object->thirdparty->country_code)),'errors'); + } + } - //Check for warehouse - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) - { - if (! $idwarehouse || $idwarehouse == -1) - { - $error++; - setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors'); - $action=''; - } - } + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } - if (! $error) - { - $result = $object->validate($user,'',$idwarehouse); - if ($result >= 0) - { - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $ret=$object->fetch($id); // Reload to get new records - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } - else - { - setEventMessage($object->error,'errors'); - } - } + //Check for warehouse + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors'); + $action=''; + } + } + + if (! $error) + { + $result = $object->validate($user,'',$idwarehouse); + if ($result >= 0) + { + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $ret=$object->fetch($id); // Reload to get new records + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + else + { + setEventMessage($object->error,'errors'); + } + } } // Go back to draft status (unvalidate) else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)) { - $idwarehouse=GETPOST('idwarehouse'); + $idwarehouse=GETPOST('idwarehouse'); - $object->fetch($id); - $object->fetch_thirdparty(); + $object->fetch($id); + $object->fetch_thirdparty(); - // Check parameters - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) - { - if (! $idwarehouse || $idwarehouse == -1) - { - $error++; - setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors'); - $action=''; - } - } + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } - if (! $error) - { - // On verifie si la facture a des paiements - $sql = 'SELECT pf.amount'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf'; - $sql.= ' WHERE pf.fk_facture = '.$object->id; + // Check parameters + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors'); + $action=''; + } + } - $result = $db->query($sql); - if ($result) - { - $i = 0; - $num = $db->num_rows($result); + if (! $error) + { + // On verifie si la facture a des paiements + $sql = 'SELECT pf.amount'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf'; + $sql.= ' WHERE pf.fk_facture = '.$object->id; - while ($i < $num) - { - $objp = $db->fetch_object($result); - $totalpaye += $objp->amount; - $i++; - } - } - else - { - dol_print_error($db,''); - } + $result = $db->query($sql); + if ($result) + { + $i = 0; + $num = $db->num_rows($result); - $resteapayer = $object->total_ttc - $totalpaye; + while ($i < $num) + { + $objp = $db->fetch_object($result); + $totalpaye += $objp->amount; + $i++; + } + } + else + { + dol_print_error($db,''); + } - // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees - $ventilExportCompta = $object->getVentilExportCompta(); + $resteapayer = $object->total_ttc - $totalpaye; - // On verifie si aucun paiement n'a ete effectue - if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) - { - $object->set_draft($user, $idwarehouse); + // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees + $ventilExportCompta = $object->getVentilExportCompta(); - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $ret=$object->fetch($id); // Reload to get new records - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } - } + // On verifie si aucun paiement n'a ete effectue + if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) + { + $object->set_draft($user, $idwarehouse); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $ret=$object->fetch($id); // Reload to get new records + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + } } // Classify "paid" else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement) { - $object->fetch($id); - $result = $object->set_paid($user); + $object->fetch($id); + $result = $object->set_paid($user); } // Classif "paid partialy" else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement) { - $object->fetch($id); - $close_code=$_POST["close_code"]; - $close_note=$_POST["close_note"]; - if ($close_code) - { - $result = $object->set_paid($user,$close_code,$close_note); - } - else - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors'); - } + $object->fetch($id); + $close_code=$_POST["close_code"]; + $close_note=$_POST["close_note"]; + if ($close_code) + { + $result = $object->set_paid($user,$close_code,$close_note); + } + else + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors'); + } } // Classify "abandoned" else if ($action == 'confirm_canceled' && $confirm == 'yes') { - $object->fetch($id); - $close_code=$_POST["close_code"]; - $close_note=$_POST["close_note"]; - if ($close_code) - { - $result = $object->set_canceled($user,$close_code,$close_note); - } - else - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors'); - } + $object->fetch($id); + $close_code=$_POST["close_code"]; + $close_note=$_POST["close_note"]; + if ($close_code) + { + $result = $object->set_canceled($user,$close_code,$close_note); + } + else + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors'); + } } // Convertir en reduc else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer) { - $db->begin(); + $db->begin(); - $object->fetch($id); - $object->fetch_thirdparty(); - $object->fetch_lines(); + $object->fetch($id); + $object->fetch_thirdparty(); + $object->fetch_lines(); - if (! $object->paye) // protection against multiple submit - { - // Boucle sur chaque taux de tva - $i=0; - foreach($object->lines as $line) - { - $amount_ht[$line->tva_tx]+=$line->total_ht; - $amount_tva[$line->tva_tx]+=$line->total_tva; - $amount_ttc[$line->tva_tx]+=$line->total_ttc; - $i++; - } + if (! $object->paye) // protection against multiple submit + { + // Boucle sur chaque taux de tva + $i=0; + foreach($object->lines as $line) + { + $amount_ht[$line->tva_tx]+=$line->total_ht; + $amount_tva[$line->tva_tx]+=$line->total_tva; + $amount_ttc[$line->tva_tx]+=$line->total_ttc; + $i++; + } - // Insert one discount by VAT rate category - $discount = new DiscountAbsolute($db); - if ($object->type == 2) $discount->description='(CREDIT_NOTE)'; - elseif ($object->type == 3) $discount->description='(DEPOSIT)'; - else { - $this->error="CantConvertToReducAnInvoiceOfThisType"; - return -1; - } - $discount->tva_tx=abs($object->total_ttc); - $discount->fk_soc=$object->socid; - $discount->fk_facture_source=$object->id; + // Insert one discount by VAT rate category + $discount = new DiscountAbsolute($db); + if ($object->type == 2) $discount->description='(CREDIT_NOTE)'; + elseif ($object->type == 3) $discount->description='(DEPOSIT)'; + else { + $this->error="CantConvertToReducAnInvoiceOfThisType"; + return -1; + } + $discount->tva_tx=abs($object->total_ttc); + $discount->fk_soc=$object->socid; + $discount->fk_facture_source=$object->id; - $error=0; - foreach($amount_ht as $tva_tx => $xxx) - { - $discount->amount_ht=abs($amount_ht[$tva_tx]); - $discount->amount_tva=abs($amount_tva[$tva_tx]); - $discount->amount_ttc=abs($amount_ttc[$tva_tx]); - $discount->tva_tx=abs($tva_tx); + $error=0; + foreach($amount_ht as $tva_tx => $xxx) + { + $discount->amount_ht=abs($amount_ht[$tva_tx]); + $discount->amount_tva=abs($amount_tva[$tva_tx]); + $discount->amount_ttc=abs($amount_ttc[$tva_tx]); + $discount->tva_tx=abs($tva_tx); - $result=$discount->create($user); - if ($result < 0) - { - $error++; - break; - } - } + $result=$discount->create($user); + if ($result < 0) + { + $error++; + break; + } + } - if (! $error) - { - // Classe facture - $result=$object->set_paid($user); - if ($result > 0) - { - //$mesgs[]='OK'.$discount->id; - $db->commit(); - } - else - { - $mesgs[]='
'.$object->error.'
'; - $db->rollback(); - } - } - else - { - $mesgs[]='
'.$discount->error.'
'; - $db->rollback(); - } - } + if (! $error) + { + // Classe facture + $result=$object->set_paid($user); + if ($result > 0) + { + //$mesgs[]='OK'.$discount->id; + $db->commit(); + } + else + { + $mesgs[]='
'.$object->error.'
'; + $db->rollback(); + } + } + else + { + $mesgs[]='
'.$discount->error.'
'; + $db->rollback(); + } + } } /* * Insert new invoice in database - */ +*/ else if ($action == 'add' && $user->rights->facture->creer) { if ($socid>0) - $object->socid=GETPOST('socid','int'); + $object->socid=GETPOST('socid','int'); - $db->begin(); + $db->begin(); - $error=0; + $error=0; - // Get extra fields - foreach($_POST as $key => $value) - { - if (preg_match("/^options_/",$key)) - { - $object->array_options[$key]=GETPOST($key); - } - } + // Get extra fields + foreach($_POST as $key => $value) + { + if (preg_match("/^options_/",$key)) + { + $object->array_options[$key]=GETPOST($key); + } + } - // Replacement invoice - if ($_POST['type'] == 1) - { - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } + // Replacement invoice + if ($_POST['type'] == 1) + { + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } - if (! ($_POST['fac_replacement'] > 0)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("ReplaceInvoice")),'errors'); - } + if (! ($_POST['fac_replacement'] > 0)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("ReplaceInvoice")),'errors'); + } - if (! $error) - { - // This is a replacement invoice - $result=$object->fetch($_POST['fac_replacement']); - $object->fetch_thirdparty(); + if (! $error) + { + // This is a replacement invoice + $result=$object->fetch($_POST['fac_replacement']); + $object->fetch_thirdparty(); - $object->date = $datefacture; - $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = $_POST['cond_reglement_id']; - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; + $object->date = $datefacture; + $object->note_public = trim($_POST['note_public']); + $object->note = trim($_POST['note']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = $_POST['cond_reglement_id']; + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; - // Proprietes particulieres a facture de remplacement - $object->fk_facture_source = $_POST['fac_replacement']; - $object->type = 1; + // Proprietes particulieres a facture de remplacement + $object->fk_facture_source = $_POST['fac_replacement']; + $object->type = 1; - $id=$object->createFromCurrent($user); - if ($id <= 0) $mesgs[]=$object->error; - } - } + $id=$object->createFromCurrent($user); + if ($id <= 0) $mesgs[]=$object->error; + } + } - // Credit note invoice - if ($_POST['type'] == 2) - { - if (! $_POST['fac_avoir'] > 0) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CorrectInvoice")),'errors'); - } + // Credit note invoice + if ($_POST['type'] == 2) + { + if (! $_POST['fac_avoir'] > 0) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CorrectInvoice")),'errors'); + } - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("Date")),'errors'); - } + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("Date")),'errors'); + } - if (! $error) - { - // Si facture avoir - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (! $error) + { + // Si facture avoir + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - //$result=$object->fetch($_POST['fac_avoir']); + //$result=$object->fetch($_POST['fac_avoir']); - $object->socid = GETPOST('socid','int'); - $object->number = $_POST['facnumber']; - $object->date = $datefacture; - $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = 0; - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; + $object->socid = GETPOST('socid','int'); + $object->number = $_POST['facnumber']; + $object->date = $datefacture; + $object->note_public = trim($_POST['note_public']); + $object->note = trim($_POST['note']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = 0; + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; - // Proprietes particulieres a facture avoir - $object->fk_facture_source = $_POST['fac_avoir']; - $object->type = 2; + // Proprietes particulieres a facture avoir + $object->fk_facture_source = $_POST['fac_avoir']; + $object->type = 2; - $id = $object->create($user); + $id = $object->create($user); - // Add predefined lines - for ($i = 1; $i <= $NBLINES; $i++) - { - if ($_POST['idprod'.$i]) - { - $product=new Product($db); - $product->fetch($_POST['idprod'.$i]); - $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']); - $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']); - $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); - } - } - } - } + // Add predefined lines + for ($i = 1; $i <= $NBLINES; $i++) + { + if ($_POST['idprod'.$i]) + { + $product=new Product($db); + $product->fetch($_POST['idprod'.$i]); + $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']); + $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']); + $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); + } + } + } + } - // Standard invoice or Deposit invoice created from a Predefined invoice - if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0) - { - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } + // Standard invoice or Deposit invoice created from a Predefined invoice + if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0) + { + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } - if (! $error) - { - $object->socid = GETPOST('socid','int'); - $object->type = $_POST['type']; - $object->number = $_POST['facnumber']; - $object->date = $datefacture; - $object->note_public = trim($_POST['note_public']); - $object->note_private = trim($_POST['note_private']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; + if (! $error) + { + $object->socid = GETPOST('socid','int'); + $object->type = $_POST['type']; + $object->number = $_POST['facnumber']; + $object->date = $datefacture; + $object->note_public = trim($_POST['note_public']); + $object->note_private = trim($_POST['note_private']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; - // Source facture - $object->fac_rec = $_POST['fac_rec']; + // Source facture + $object->fac_rec = $_POST['fac_rec']; - $id = $object->create($user); - } - } + $id = $object->create($user); + } + } - // Standard or deposit or proforma invoice - if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) - { - if (GETPOST('socid','int')<1) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors'); - } + // Standard or deposit or proforma invoice + if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) + { + if (GETPOST('socid','int')<1) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors'); + } - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } - if (! $error) - { - // Si facture standard - $object->socid = GETPOST('socid','int'); - $object->type = GETPOST('type'); - $object->number = $_POST['facnumber']; - $object->date = $datefacture; - $object->note_public = trim($_POST['note_public']); - $object->note_private = trim($_POST['note_private']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = ($_POST['type'] == 3?1:$_POST['cond_reglement_id']); - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->amount = $_POST['amount']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; - $object->fetch_thirdparty(); + if (! $error) + { + // Si facture standard + $object->socid = GETPOST('socid','int'); + $object->type = GETPOST('type'); + $object->number = $_POST['facnumber']; + $object->date = $datefacture; + $object->note_public = trim($_POST['note_public']); + $object->note_private = trim($_POST['note_private']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = ($_POST['type'] == 3?1:$_POST['cond_reglement_id']); + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->amount = $_POST['amount']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; + $object->fetch_thirdparty(); - // If creation from another object of another module (Example: origin=propal, originid=1) - if ($_POST['origin'] && $_POST['originid']) - { - // Parse element/subelement (ex: project_task) - $element = $subelement = $_POST['origin']; - if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs)) - { - $element = $regs[1]; - $subelement = $regs[2]; - } + // If creation from another object of another module (Example: origin=propal, originid=1) + if ($_POST['origin'] && $_POST['originid']) + { + // Parse element/subelement (ex: project_task) + $element = $subelement = $_POST['origin']; + if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs)) + { + $element = $regs[1]; + $subelement = $regs[2]; + } - // For compatibility - if ($element == 'order') { $element = $subelement = 'commande'; } - if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; } - if ($element == 'contract') { $element = $subelement = 'contrat'; } - if ($element == 'inter') { $element = $subelement = 'ficheinter'; } - if ($element == 'shipping') { $element = $subelement = 'expedition'; } + // For compatibility + if ($element == 'order') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } + if ($element == 'inter') { + $element = $subelement = 'ficheinter'; + } + if ($element == 'shipping') { + $element = $subelement = 'expedition'; + } - $object->origin = $_POST['origin']; - $object->origin_id = $_POST['originid']; + $object->origin = $_POST['origin']; + $object->origin_id = $_POST['originid']; - // Possibility to add external linked objects with hooks - $object->linked_objects[$object->origin] = $object->origin_id; - if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) - { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); - } + // Possibility to add external linked objects with hooks + $object->linked_objects[$object->origin] = $object->origin_id; + if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) + { + $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + } - $id = $object->create($user); + $id = $object->create($user); - if ($id > 0) - { - dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); + if ($id > 0) + { + dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); - $classname = ucfirst($subelement); - $srcobject = new $classname($db); + $classname = ucfirst($subelement); + $srcobject = new $classname($db); - dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines"); - $result=$srcobject->fetch($object->origin_id); - if ($result > 0) - { - $lines = $srcobject->lines; - if (empty($lines) && method_exists($srcobject,'fetch_lines')) $lines = $srcobject->fetch_lines(); + dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines"); + $result=$srcobject->fetch($object->origin_id); + if ($result > 0) + { + $lines = $srcobject->lines; + if (empty($lines) && method_exists($srcobject,'fetch_lines')) $lines = $srcobject->fetch_lines(); - $fk_parent_line=0; - $num=count($lines); + $fk_parent_line=0; + $num=count($lines); - for ($i=0;$i<$num;$i++) - { - $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); - $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); + for ($i=0;$i<$num;$i++) + { + $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); + $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); - if ($lines[$i]->subprice < 0) - { - // Negative line, we create a discount line - $discount = new DiscountAbsolute($db); - $discount->fk_soc=$object->socid; - $discount->amount_ht=abs($lines[$i]->total_ht); - $discount->amount_tva=abs($lines[$i]->total_tva); - $discount->amount_ttc=abs($lines[$i]->total_ttc); - $discount->tva_tx=$lines[$i]->tva_tx; - $discount->fk_user=$user->id; - $discount->description=$desc; - $discountid=$discount->create($user); - if ($discountid > 0) - { - $result=$object->insert_discount($discountid); // This include link_to_invoice - } - else - { - $mesgs[]=$discount->error; - $error++; - break; - } - } - else - { - // Positive line - $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); + if ($lines[$i]->subprice < 0) + { + // Negative line, we create a discount line + $discount = new DiscountAbsolute($db); + $discount->fk_soc=$object->socid; + $discount->amount_ht=abs($lines[$i]->total_ht); + $discount->amount_tva=abs($lines[$i]->total_tva); + $discount->amount_ttc=abs($lines[$i]->total_ttc); + $discount->tva_tx=$lines[$i]->tva_tx; + $discount->fk_user=$user->id; + $discount->description=$desc; + $discountid=$discount->create($user); + if ($discountid > 0) + { + $result=$object->insert_discount($discountid); // This include link_to_invoice + } + else + { + $mesgs[]=$discount->error; + $error++; + break; + } + } + else + { + // Positive line + $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); - // Date start - $date_start=false; - if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; - if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; - if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; + // Date start + $date_start=false; + if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; + if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; + if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; - //Date end - $date_end=false; - if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; - if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; - if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; + //Date end + $date_end=false; + if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; + if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; + if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; - // Reset fk_parent_line for no child products and special product - if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { - $fk_parent_line = 0; - } + // Reset fk_parent_line for no child products and special product + if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { + $fk_parent_line = 0; + } - $result = $object->addline( - $id, - $desc, - $lines[$i]->subprice, - $lines[$i]->qty, - $lines[$i]->tva_tx, - $lines[$i]->localtax1_tx, - $lines[$i]->localtax2_tx, - $lines[$i]->fk_product, - $lines[$i]->remise_percent, - $date_start, - $date_end, - 0, - $lines[$i]->info_bits, - $lines[$i]->fk_remise_except, - 'HT', - 0, - $product_type, - $lines[$i]->rang, - $lines[$i]->special_code, - $object->origin, - $lines[$i]->rowid, - $fk_parent_line, - $lines[$i]->fk_fournprice, - $lines[$i]->pa_ht, - $label - ); + $result = $object->addline( + $id, + $desc, + $lines[$i]->subprice, + $lines[$i]->qty, + $lines[$i]->tva_tx, + $lines[$i]->localtax1_tx, + $lines[$i]->localtax2_tx, + $lines[$i]->fk_product, + $lines[$i]->remise_percent, + $date_start, + $date_end, + 0, + $lines[$i]->info_bits, + $lines[$i]->fk_remise_except, + 'HT', + 0, + $product_type, + $lines[$i]->rang, + $lines[$i]->special_code, + $object->origin, + $lines[$i]->rowid, + $fk_parent_line, + $lines[$i]->fk_fournprice, + $lines[$i]->pa_ht, + $label + ); - if ($result > 0) - { - $lineid=$result; - } - else - { - $lineid=0; - $error++; - break; - } + if ($result > 0) + { + $lineid=$result; + } + else + { + $lineid=0; + $error++; + break; + } - // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) { - $fk_parent_line = $result; - } - } - } + // Defined the new fk_parent_line + if ($result > 0 && $lines[$i]->product_type == 9) { + $fk_parent_line = $result; + } + } + } - // Hooks - $parameters=array('objFrom'=>$srcobject); - $reshook=$hookmanager->executeHooks('createFrom',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if ($reshook < 0) $error++; - } - else - { - $mesgs[]=$srcobject->error; - $error++; - } - } - else - { - $mesgs[]=$object->error; - $error++; - } - } - // If some invoice's lines already known - else - { - $id = $object->create($user); + // Hooks + $parameters=array('objFrom'=>$srcobject); + $reshook=$hookmanager->executeHooks('createFrom',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) $error++; + } + else + { + $mesgs[]=$srcobject->error; + $error++; + } + } + else + { + $mesgs[]=$object->error; + $error++; + } + } + // If some invoice's lines already known + else + { + $id = $object->create($user); - for ($i = 1; $i <= $NBLINES; $i++) - { - if ($_POST['idprod'.$i]) - { - $product=new Product($db); - $product->fetch($_POST['idprod'.$i]); - $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']); - $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']); - $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); - } - } - } - } - } + for ($i = 1; $i <= $NBLINES; $i++) + { + if ($_POST['idprod'.$i]) + { + $product=new Product($db); + $product->fetch($_POST['idprod'.$i]); + $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']); + $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']); + $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); + } + } + } + } + } - // End of object creation, we show it - if ($id > 0 && ! $error) - { - $db->commit(); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); - exit; - } - else - { - $db->rollback(); - $action='create'; - $_GET["origin"]=$_POST["origin"]; - $_GET["originid"]=$_POST["originid"]; - $mesgs[]='
'.$object->error.'
'; - } + // End of object creation, we show it + if ($id > 0 && ! $error) + { + $db->commit(); + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); + exit; + } + else + { + $db->rollback(); + $action='create'; + $_GET["origin"]=$_POST["origin"]; + $_GET["originid"]=$_POST["originid"]; + $mesgs[]='
'.$object->error.'
'; + } } // Add a new line else if (($action == 'addline' || $action == 'addline_predef') && $user->rights->facture->creer) { $langs->load('errors'); - $error = 0; + $error = 0; - $idprod=GETPOST('idprod', 'int'); + $idprod=GETPOST('idprod', 'int'); $product_desc = (GETPOST('product_desc')?GETPOST('product_desc'):(GETPOST('np_desc')?GETPOST('np_desc'):(GETPOST('dp_desc')?GETPOST('dp_desc'):''))); $price_ht = GETPOST('price_ht'); $tva_tx=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); if ((empty($idprod) || GETPOST('usenewaddlineform')) && ($price_ht < 0) && (GETPOST('qty') < 0)) - { - setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error++; - } - if (empty($idprod) && GETPOST('type') < 0) - { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); - $error++; - } + { + setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error++; + } + if (empty($idprod) && GETPOST('type') < 0) + { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); + $error++; + } if ((empty($idprod) || GETPOST('usenewaddlineform')) && (!($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' { setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); $error++; } - if (! GETPOST('qty') && GETPOST('qty') == '') - { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error++; - } - if (empty($idprod) && empty($product_desc)) - { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); - $error++; - } + if (! GETPOST('qty') && GETPOST('qty') == '') + { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error++; + } + if (empty($idprod) && empty($product_desc)) + { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); + $error++; + } - if (! $error && (GETPOST('qty') >= 0) && (! empty($product_desc) || ! empty($idprod))) - { - $ret=$object->fetch($id); - if ($ret < 0) - { - dol_print_error($db,$object->error); - exit; - } - $ret=$object->fetch_thirdparty(); + if (! $error && (GETPOST('qty') >= 0) && (! empty($product_desc) || ! empty($idprod))) + { + $ret=$object->fetch($id); + if ($ret < 0) + { + dol_print_error($db,$object->error); + exit; + } + $ret=$object->fetch_thirdparty(); - // Clean parameters - $predef=((! empty($idprod) && $conf->global->MAIN_FEATURES_LEVEL < 2) ? '_predef' : ''); - $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); - $date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); - $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); + // Clean parameters + $predef=((! empty($idprod) && $conf->global->MAIN_FEATURES_LEVEL < 2) ? '_predef' : ''); + $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); + $date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); + $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); - // Define special_code for special lines - $special_code=0; - //if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices + // Define special_code for special lines + $special_code=0; + //if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - // Ecrase $base_price_type par celui du produit - if (! empty($idprod)) - { - $prod = new Product($db); - $prod->fetch($idprod); + // Ecrase $pu par celui du produit + // Ecrase $desc par celui du produit + // Ecrase $txtva par celui du produit + // Ecrase $base_price_type par celui du produit + if (! empty($idprod)) + { + $prod = new Product($db); + $prod->fetch($idprod); - $label = ((GETPOST('product_label') && GETPOST('product_label')!=$prod->label)?GETPOST('product_label'):''); + $label = ((GETPOST('product_label') && GETPOST('product_label')!=$prod->label)?GETPOST('product_label'):''); - // Update if prices fields are defined - if (GETPOST('usenewaddlineform')) - { - $pu_ht=price2num($price_ht, 'MU'); + // Update if prices fields are defined + if (GETPOST('usenewaddlineform')) + { + $pu_ht=price2num($price_ht, 'MU'); $pu_ttc=price2num(GETPOST('price_ttc'), 'MU'); $tva_npr=(preg_match('/\*/', $tva_tx)?1:0); $tva_tx=str_replace('*','', $tva_tx); $desc = $product_desc; - } - else + } + else { - $tva_tx = get_default_tva($mysoc,$object->client,$prod->id); - $tva_npr = get_default_npr($mysoc,$object->client,$prod->id); + $tva_tx = get_default_tva($mysoc,$object->client,$prod->id); + $tva_npr = get_default_npr($mysoc,$object->client,$prod->id); - // We define price for product - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) - { - $pu_ht = $prod->multiprices[$object->client->price_level]; - $pu_ttc = $prod->multiprices_ttc[$object->client->price_level]; - $price_min = $prod->multiprices_min[$object->client->price_level]; - $price_base_type = $prod->multiprices_base_type[$object->client->price_level]; - } - else - { - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - } + // We define price for product + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) + { + $pu_ht = $prod->multiprices[$object->client->price_level]; + $pu_ttc = $prod->multiprices_ttc[$object->client->price_level]; + $price_min = $prod->multiprices_min[$object->client->price_level]; + $price_base_type = $prod->multiprices_base_type[$object->client->price_level]; + } + else + { + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + } - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - if ($tva_tx != $prod->tva_tx) - { - if ($price_base_type != 'HT') - { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU'); - } - else - { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); - } - } + // On reevalue prix selon taux tva car taux tva transaction peut etre different + // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + if ($tva_tx != $prod->tva_tx) + { + if ($price_base_type != 'HT') + { + $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU'); + } + else + { + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); + } + } - $desc=''; + $desc=''; - // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) - { - $outputlangs = $langs; - $newlang=''; - if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); - if (empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) + { + $outputlangs = $langs; + $newlang=''; + if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); + if (empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } - $desc = (! empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description; - } - else - { - $desc = $prod->description; - } + $desc = (! empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description; + } + else + { + $desc = $prod->description; + } - $desc=dol_concatdesc($desc,$product_desc); + $desc=dol_concatdesc($desc,$product_desc); - // Add custom code and origin country into description - if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) - { - $tmptxt='('; - if (! empty($prod->customcode)) $tmptxt.=$langs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode; - if (! empty($prod->customcode) && ! empty($prod->country_code)) $tmptxt.=' - '; - if (! empty($prod->country_code)) $tmptxt.=$langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code,0,$db,$langs,0); - $tmptxt.=')'; - $desc= dol_concatdesc($desc, $tmptxt); - } - } + // Add custom code and origin country into description + if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) + { + $tmptxt='('; + if (! empty($prod->customcode)) $tmptxt.=$langs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode; + if (! empty($prod->customcode) && ! empty($prod->country_code)) $tmptxt.=' - '; + if (! empty($prod->country_code)) $tmptxt.=$langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code,0,$db,$langs,0); + $tmptxt.=')'; + $desc= dol_concatdesc($desc, $tmptxt); + } + } - $type = $prod->type; - } - else - { - $pu_ht = price2num($price_ht, 'MU'); + $type = $prod->type; + } + else + { + $pu_ht = price2num($price_ht, 'MU'); $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); $tva_npr = (preg_match('/\*/', $tva_tx)?1:0); $tva_tx = str_replace('*', '', $tva_tx); $label = (GETPOST('product_label')?GETPOST('product_label'):''); $desc = $product_desc; $type = GETPOST('type'); - } + } - // Margin - $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):''); + // Margin + $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):''); $buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):''); - // Local Taxes - $localtax1_tx= get_localtax($tva_tx, 1, $object->client); - $localtax2_tx= get_localtax($tva_tx, 2, $object->client); + // Local Taxes + $localtax1_tx= get_localtax($tva_tx, 1, $object->client); + $localtax2_tx= get_localtax($tva_tx, 2, $object->client); - $info_bits=0; - if ($tva_npr) $info_bits |= 0x01; + $info_bits=0; + if ($tva_npr) $info_bits |= 0x01; - if (! empty($price_min) && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) - { - $mesg = $langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').$langs->getCurrencySymbol($conf->currency)); + if (! empty($price_min) && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) + { + $mesg = $langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').$langs->getCurrencySymbol($conf->currency)); setEventMessage($mesg, 'errors'); - } - else - { - // Insert line - $result = $object->addline( - $id, - $desc, - $pu_ht, - GETPOST('qty'), - $tva_tx, - $localtax1_tx, - $localtax2_tx, - $idprod, - GETPOST('remise_percent'), - $date_start, - $date_end, - 0, - $info_bits, - '', - $price_base_type, - $pu_ttc, - $type, - -1, - $special_code, - '', - 0, - GETPOST('fk_parent_line'), - $fournprice, - $buyingprice, - $label - ); + } + else + { + // Insert line + $result = $object->addline( + $id, + $desc, + $pu_ht, + GETPOST('qty'), + $tva_tx, + $localtax1_tx, + $localtax2_tx, + $idprod, + GETPOST('remise_percent'), + $date_start, + $date_end, + 0, + $info_bits, + '', + $price_base_type, + $pu_ttc, + $type, + -1, + $special_code, + '', + 0, + GETPOST('fk_parent_line'), + $fournprice, + $buyingprice, + $label + ); - if ($result > 0) - { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - $newlang=GETPOST('lang_id','alpha'); - if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } + if ($result > 0) + { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + $newlang=GETPOST('lang_id','alpha'); + if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } - $ret=$object->fetch($id); // Reload to get new records - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } + $ret=$object->fetch($id); // Reload to get new records + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['idprod']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['idprod']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); unset($_POST['price_ttc']); unset($_POST['tva_tx']); unset($_POST['product_ref']); @@ -1250,99 +1279,99 @@ else if (($action == 'addline' || $action == 'addline_predef') && $user->rights- // old method unset($_POST['np_desc']); unset($_POST['dp_desc']); - } - else - { - setEventMessage($object->error, 'errors'); - } + } + else + { + setEventMessage($object->error, 'errors'); + } - $action=''; - } - } + $action=''; + } + } } else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['save'] == $langs->trans('Save')) { - if (! $object->fetch($id) > 0) dol_print_error($db); - $object->fetch_thirdparty(); + if (! $object->fetch($id) > 0) dol_print_error($db); + $object->fetch_thirdparty(); - // Clean parameters - $date_start=''; - $date_end=''; - $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description=dol_htmlcleanlastbr(GETPOST('product_desc')); - $pu_ht=GETPOST('price_ht'); - $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); + // Clean parameters + $date_start=''; + $date_end=''; + $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + $description=dol_htmlcleanlastbr(GETPOST('product_desc')); + $pu_ht=GETPOST('price_ht'); + $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); - // Define info_bits - $info_bits=0; - if (preg_match('/\*/', $vat_rate)) $info_bits |= 0x01; + // Define info_bits + $info_bits=0; + if (preg_match('/\*/', $vat_rate)) $info_bits |= 0x01; - // Define vat_rate - $vat_rate=str_replace('*','',$vat_rate); - $localtax1_rate=get_localtax($vat_rate,1,$object->client); - $localtax2_rate=get_localtax($vat_rate,2,$object->client); + // Define vat_rate + $vat_rate=str_replace('*','',$vat_rate); + $localtax1_rate=get_localtax($vat_rate,1,$object->client); + $localtax2_rate=get_localtax($vat_rate,2,$object->client); - // Add buying price + // Add buying price $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):''); $buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):''); - // Check minimum price + // Check minimum price $productid = GETPOST('productid', 'int'); - if (! empty($productid)) - { - $product = new Product($db); - $product->fetch($productid); + if (! empty($productid)) + { + $product = new Product($db); + $product->fetch($productid); - $type=$product->type; + $type=$product->type; - $price_min = $product->price_min; - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) - $price_min = $product->multiprices_min[$object->client->price_level]; + $price_min = $product->price_min; + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) + $price_min = $product->multiprices_min[$object->client->price_level]; - $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label'):''); + $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label'):''); - if ($price_min && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) - { - setEventMessage($langs->trans("CantBeLessThanMinPrice", price2num($price_min,'MU')).$langs->getCurrencySymbol($conf->currency), 'errors'); - $error++; - } - } - else - { - $type = GETPOST('type'); - $label = (GETPOST('product_label') ? GETPOST('product_label'):''); + if ($price_min && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) + { + setEventMessage($langs->trans("CantBeLessThanMinPrice", price2num($price_min,'MU')).$langs->getCurrencySymbol($conf->currency), 'errors'); + $error++; + } + } + else + { + $type = GETPOST('type'); + $label = (GETPOST('product_label') ? GETPOST('product_label'):''); - // Check parameters - if (GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors'); - $error++; - } - } + // Check parameters + if (GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors'); + $error++; + } + } // Update line if (! $error) { $result = $object->updateline( - GETPOST('lineid'), - $description, - $pu_ht, - GETPOST('qty'), - GETPOST('remise_percent'), - $date_start, - $date_end, - $vat_rate, - $localtax1_rate, - $localtax2_rate, - 'HT', - $info_bits, - $type, - GETPOST('fk_parent_line'), - 0, - $fournprice, - $buyingprice, - $label + GETPOST('lineid'), + $description, + $pu_ht, + GETPOST('qty'), + GETPOST('remise_percent'), + $date_start, + $date_end, + $vat_rate, + $localtax1_rate, + $localtax2_rate, + 'HT', + $info_bits, + $type, + GETPOST('fk_parent_line'), + 0, + $fournprice, + $buyingprice, + $label ); if ($result >= 0) @@ -1381,2262 +1410,2303 @@ else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['sa { setEventMessage($object->error, 'errors'); } - } + } } else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel')) { - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); // Pour reaffichage de la fiche en cours d'edition - exit; + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); // Pour reaffichage de la fiche en cours d'edition + exit; } // Modify line position (up) else if ($action == 'up' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); - $object->line_up($_GET['rowid']); + $object->fetch($id); + $object->fetch_thirdparty(); + $object->line_up($_GET['rowid']); - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']); - exit; + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']); + exit; } // Modify line position (down) else if ($action == 'down' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); - $object->line_down($_GET['rowid']); + $object->fetch($id); + $object->fetch_thirdparty(); + $object->line_down($_GET['rowid']); - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']); - exit; + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']); + exit; } /* * Add file in email form - */ +*/ if (GETPOST('addfile')) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - // Set tmp user directory - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; + // Set tmp user directory + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir_tmp = $vardir.'/temp'; - dol_add_file_process($upload_dir_tmp,0,0); - $action='presend'; + dol_add_file_process($upload_dir_tmp,0,0); + $action='presend'; } /* * Remove file in email form - */ +*/ if (! empty($_POST['removedfile'])) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - // Set tmp user directory - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; + // Set tmp user directory + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir_tmp = $vardir.'/temp'; // TODO Delete only files that was uploaded from email form - dol_remove_file_process($_POST['removedfile'],0); - $action='presend'; + dol_remove_file_process($_POST['removedfile'],0); + $action='presend'; } /* * Send mail - */ +*/ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_POST['removedfile'] && ! $_POST['cancel']) { - $langs->load('mails'); + $langs->load('mails'); - $actiontypecode='';$subject='';$actionmsg='';$actionmsg2=''; + $actiontypecode='';$subject='';$actionmsg='';$actionmsg2=''; - $result=$object->fetch($id); - $result=$object->fetch_thirdparty(); + $result=$object->fetch($id); + $result=$object->fetch_thirdparty(); - if ($result > 0) - { -// $ref = dol_sanitizeFileName($object->ref); -// $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf'; - -// if (is_readable($file)) -// { - if ($_POST['sendto']) - { - // Le destinataire a ete fourni via le champ libre - $sendto = $_POST['sendto']; - $sendtoid = 0; - } - elseif ($_POST['receiver'] != '-1') - { - // Recipient was provided from combo list - if ($_POST['receiver'] == 'thirdparty') // Id of third party - { - $sendto = $object->client->email; - $sendtoid = 0; - } - else // Id du contact - { - $sendto = $object->client->contact_get_property($_POST['receiver'],'email'); - $sendtoid = $_POST['receiver']; - } - } - - if (dol_strlen($sendto)) - { - $langs->load("commercial"); - - $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>'; - $replyto = $_POST['replytoname']. ' <' . $_POST['replytomail'].'>'; - $message = $_POST['message']; - $sendtocc = $_POST['sendtocc']; - $deliveryreceipt = $_POST['deliveryreceipt']; - - if ($action == 'send') - { - if (dol_strlen($_POST['subject'])) $subject = $_POST['subject']; - else $subject = $langs->transnoentities('Bill').' '.$object->ref; - $actiontypecode='AC_FAC'; - $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; - if ($message) - { - $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; - $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; - $actionmsg.=$message; - } - //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode); - } - if ($action == 'relance') - { - if (dol_strlen($_POST['subject'])) $subject = $_POST['subject']; - else $subject = $langs->transnoentities('Relance facture '.$object->ref); - $actiontypecode='AC_FAC'; - $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; - if ($message) { - $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; - $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; - $actionmsg.=$message; - } - //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode); - } - - // Create form object - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - - $attachedfiles=$formmail->get_attached_files(); - $filepath = $attachedfiles['paths']; - $filename = $attachedfiles['names']; - $mimetype = $attachedfiles['mimes']; - - // Send mail - require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); - if ($mailfile->error) - { - $mesgs[]='
'.$mailfile->error.'
'; - } - else - { - $result=$mailfile->sendfile(); - if ($result) - { - $error=0; - - // Initialisation donnees - $object->sendtoid = $sendtoid; - $object->actiontypecode = $actiontypecode; - $object->actionmsg = $actionmsg; // Long text - $object->actionmsg2 = $actionmsg2; // Short text - $object->fk_element = $object->id; - $object->elementtype = $object->element; - - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($db); - $result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - - if ($error) - { - dol_print_error($db); - } - else - { - // Redirect here - // This avoid sending mail twice if going out and then back to page - $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); - setEventMessage($mesg); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id); - exit; - } - } - else - { - $langs->load("other"); - $mesg='
'; - if ($mailfile->error) - { - $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); - $mesg.='
'.$mailfile->error; - } - else - { - $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; - } - $mesg.='
'; - $mesgs[]=$mesg; - } - } -/* } - else - { - $langs->load("other"); - $mesgs[]='
'.$langs->trans('ErrorMailRecipientIsEmpty').'
'; - dol_syslog('Recipient email is empty'); - }*/ - } - else - { - $langs->load("errors"); - $mesgs[]='
'.$langs->trans('ErrorCantReadFile',$file).'
'; - dol_syslog('Failed to read file: '.$file); - } - } - else - { - $langs->load("other"); - $mesgs[]='
'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'
'; - dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.'); - } - - $action = 'presend'; -} - -/* - * Generate document - */ -else if ($action == 'builddoc') // En get ou en post -{ - $object->fetch($id); - $object->fetch_thirdparty(); - - if (GETPOST('model')) $object->setDocModel($user, GETPOST('model')); - if (GETPOST('fk_bank')) $object->fk_bank=GETPOST('fk_bank'); - - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } - else - { - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); - exit; - } -} - -// Remove file in doc form -else if ($action == 'remove_file') -{ - if ($object->fetch($id)) + if ($result > 0) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + // $ref = dol_sanitizeFileName($object->ref); + // $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf'; - $object->fetch_thirdparty(); - - $langs->load("other"); - $upload_dir = $conf->facture->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret=dol_delete_file($file,0,0,0,$object); - if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); - else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); - $action=''; - } -} - -if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) -{ - if ($action == 'addcontact') - { - $result = $object->fetch($id); - - if ($result > 0 && $id > 0) + // if (is_readable($file)) + // { + if ($_POST['sendto']) { - $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); - $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); + // Le destinataire a ete fourni via le champ libre + $sendto = $_POST['sendto']; + $sendtoid = 0; } - - if ($result >= 0) + elseif ($_POST['receiver'] != '-1') { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else - { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + // Recipient was provided from combo list + if ($_POST['receiver'] == 'thirdparty') // Id of third party { - $langs->load("errors"); - $mesgs[] = '
'.$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType").'
'; + $sendto = $object->client->email; + $sendtoid = 0; + } + else // Id du contact + { + $sendto = $object->client->contact_get_property($_POST['receiver'],'email'); + $sendtoid = $_POST['receiver']; + } + } + + if (dol_strlen($sendto)) + { + $langs->load("commercial"); + + $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>'; + $replyto = $_POST['replytoname']. ' <' . $_POST['replytomail'].'>'; + $message = $_POST['message']; + $sendtocc = $_POST['sendtocc']; + $deliveryreceipt = $_POST['deliveryreceipt']; + + if ($action == 'send') + { + if (dol_strlen($_POST['subject'])) $subject = $_POST['subject']; + else $subject = $langs->transnoentities('Bill').' '.$object->ref; + $actiontypecode='AC_FAC'; + $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; + if ($message) + { + $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; + $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; + $actionmsg.=$message; + } + //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode); + } + if ($action == 'relance') + { + if (dol_strlen($_POST['subject'])) $subject = $_POST['subject']; + else $subject = $langs->transnoentities('Relance facture '.$object->ref); + $actiontypecode='AC_FAC'; + $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; + if ($message) { + $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; + $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; + $actionmsg.=$message; + } + //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode); + } + + // Create form object + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $attachedfiles=$formmail->get_attached_files(); + $filepath = $attachedfiles['paths']; + $filename = $attachedfiles['names']; + $mimetype = $attachedfiles['mimes']; + + // Send mail + require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); + if ($mailfile->error) + { + $mesgs[]='
'.$mailfile->error.'
'; } else { - $mesgs[] = '
'.$object->error.'
'; + $result=$mailfile->sendfile(); + if ($result) + { + $error=0; + + // Initialisation donnees + $object->sendtoid = $sendtoid; + $object->actiontypecode = $actiontypecode; + $object->actionmsg = $actionmsg; // Long text + $object->actionmsg2 = $actionmsg2; // Short text + $object->fk_element = $object->id; + $object->elementtype = $object->element; + + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($db); + $result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + + if ($error) + { + dol_print_error($db); + } + else + { + // Redirect here + // This avoid sending mail twice if going out and then back to page + $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); + setEventMessage($mesg); + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id); + exit; + } + } + else + { + $langs->load("other"); + $mesg='
'; + if ($mailfile->error) + { + $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); + $mesg.='
'.$mailfile->error; + } + else + { + $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + } + $mesg.='
'; + $mesgs[]=$mesg; + } } + /* } + else + { + $langs->load("other"); + $mesgs[]='
'.$langs->trans('ErrorMailRecipientIsEmpty').'
'; + dol_syslog('Recipient email is empty'); + }*/ + } + else + { + $langs->load("errors"); + $mesgs[]='
'.$langs->trans('ErrorCantReadFile',$file).'
'; + dol_syslog('Failed to read file: '.$file); + } + } + else + { + $langs->load("other"); + $mesgs[]='
'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'
'; + dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.'); + } + + $action = 'presend'; + } + + /* + * Generate document + */ + else if ($action == 'builddoc') // En get ou en post + { + $object->fetch($id); + $object->fetch_thirdparty(); + + if (GETPOST('model')) $object->setDocModel($user, GETPOST('model')); + if (GETPOST('fk_bank')) $object->fk_bank=GETPOST('fk_bank'); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + else + { + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); + exit; } } - // bascule du statut d'un contact - else if ($action == 'swapstatut') + // Remove file in doc form + else if ($action == 'remove_file') { if ($object->fetch($id)) { - $result=$object->swapContactStatus(GETPOST('ligne')); - } - else - { - dol_print_error($db); + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $object->fetch_thirdparty(); + + $langs->load("other"); + $upload_dir = $conf->facture->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret=dol_delete_file($file,0,0,0,$object); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + $action=''; } } - // Efface un contact - else if ($action == 'deletecontact') + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) { - $object->fetch($id); - $result = $object->delete_contact($lineid); - - if ($result >= 0) + if ($action == 'addcontact') { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else { - dol_print_error($db); - } - } -} + $result = $object->fetch($id); -if ($action == 'update_extras') -{ - // Fill array 'array_options' with data from add form - $extralabels=$extrafields->fetch_name_optionals_label('facture'); - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('invoicedao')); - $parameters=array('id'=>$object->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$object->insertExtraFields(); - if ($result < 0) + if ($result > 0 && $id > 0) { - $error++; + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); + } + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $langs->load("errors"); + $mesgs[] = '
'.$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType").'
'; + } + else + { + $mesgs[] = '
'.$object->error.'
'; + } + } + } + + // bascule du statut d'un contact + else if ($action == 'swapstatut') + { + if ($object->fetch($id)) + { + $result=$object->swapContactStatus(GETPOST('ligne')); + } + else + { + dol_print_error($db); + } + } + + // Efface un contact + else if ($action == 'deletecontact') + { + $object->fetch($id); + $result = $object->delete_contact($lineid); + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else { + dol_print_error($db); } } } - else if ($reshook < 0) $error++; -} - - -/* - * View - */ - -$form = new Form($db); -$formother=new FormOther($db); -$formfile = new FormFile($db); -$bankaccountstatic=new Account($db); -$now=dol_now(); - -llxHeader('',$langs->trans('Bill'),'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes'); - - - -/********************************************************************* - * - * Mode creation - * - **********************************************************************/ -if ($action == 'create') -{ - $facturestatic=new Facture($db); - $extralabels=$extrafields->fetch_name_optionals_label('facture'); - - print_fiche_titre($langs->trans('NewBill')); - - $soc = new Societe($db); - if ($socid>0) $res=$soc->fetch($socid); - - if (! empty($origin) && ! empty($originid)) - { - // Parse element/subelement (ex: project_task) - $element = $subelement = $origin; - if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) - { - $element = $regs[1]; - $subelement = $regs[2]; - } - - if ($element == 'project') - { - $projectid=$originid; - } - else - { - // For compatibility - if ($element == 'order' || $element == 'commande') { $element = $subelement = 'commande'; } - if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; } - if ($element == 'contract') { $element = $subelement = 'contrat'; } - if ($element == 'shipping') { $element = $subelement = 'expedition'; } - - dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); - - $classname = ucfirst($subelement); - $objectsrc = new $classname($db); - $objectsrc->fetch($originid); - if (empty($objectsrc->lines) && method_exists($objectsrc,'fetch_lines')) $objectsrc->fetch_lines(); - $objectsrc->fetch_thirdparty(); - - $projectid = (! empty($objectsrc->fk_project)?$objectsrc->fk_project:''); - $ref_client = (! empty($objectsrc->ref_client)?$objectsrc->ref_client:''); - $ref_int = (! empty($objectsrc->ref_int)?$objectsrc->ref_int:''); - - $soc = $objectsrc->thirdparty; - $cond_reglement_id = (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1)); - $mode_reglement_id = (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0)); - $remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0)); - $remise_absolue = (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0)); - $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; - } - } - else - { - $cond_reglement_id = $soc->cond_reglement_id; - $mode_reglement_id = $soc->mode_reglement_id; - $remise_percent = $soc->remise_percent; - $remise_absolue = 0; - $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; - } - $absolute_discount=$soc->getAvailableDiscounts(); - - - if (! empty($conf->use_javascript_ajax)) - { - print ajax_combobox('fac_replacement'); - print ajax_combobox('fac_avoir'); - } - - print '
'; - print ''; - print ''; - if ($soc->id > 0) - print '' ."\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - - print ''; - - // Ref - print ''; - - // Factures predefinies - if (empty($origin) && empty($originid) && $socid>0) - { - $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; - $sql.= ' WHERE r.fk_soc = '.$soc->id; - - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - $i = 0; - - if ($num > 0) - { - print ''; - } - $db->free($resql); - } - else - { - dol_print_error($db); - } - } - - // Tiers - print ''; - print ''; - if($soc->id > 0) - { - print ''; - } - else - { - print ''; - } - print ''."\n"; - - // Type de facture - $facids=$facturestatic->list_replacable_invoices($soc->id); - if ($facids < 0) - { - dol_print_error($db,$facturestatic); - exit; - } - $options=""; - foreach ($facids as $facparam) - { - $options.=''; - } - - $facids=$facturestatic->list_qualified_avoir_invoices($soc->id); - if ($facids < 0) - { - dol_print_error($db,$facturestatic); - exit; - } - $optionsav=""; - $newinvoice_static=new Facture($db); - foreach ($facids as $key => $valarray) - { - $newinvoice_static->id=$key; - $newinvoice_static->ref=$valarray['ref']; - $newinvoice_static->statut=$valarray['status']; - $newinvoice_static->type=$valarray['type']; - $newinvoice_static->paye=$valarray['paye']; - - $optionsav.=''; - } - - print ''; - - if ($socid > 0) - { - // Discounts for third party - print ''; - } - - // Date invoice - print ''; - - // Payment term - print ''; - - // Payment mode - print ''; - - // Project - if (! empty($conf->projet->enabled) && $socid>0) - { - $langs->load('projects'); - print ''; - } - - // Other attributes - $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - print $object->showOptionals($extrafields,'edit'); - } - - // Modele PDF - print ''; - print '"; - - // Public note - print ''; - print ''; - print ''; - - // Private note - if (empty($user->societe_id)) - { - print ''; - print ''; - print ''; - } - - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) - { - // TODO for compatibility - if ($origin == 'contrat') - { - // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva - $objectsrc->remise_absolue=$remise_absolue; - $objectsrc->remise_percent=$remise_percent; - $objectsrc->update_price(1,-1,1); - } - - print "\n"; - print "\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''; - print ''; - - $newclassname=$classname; - if ($newclassname == 'Propal') $newclassname = 'CommercialProposal'; - elseif ($newclassname == 'Commande') $newclassname = 'Order'; - - print ''; - print ''; - print '"; - if ($mysoc->localtax1_assuj=="1") //Localtax1 RE - { - print '"; - } - - if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF - { - print '"; - } - print '"; - } - else - { - // Show deprecated optional form to add product line here - if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) - { - print ''; - } - } - - print "
'.$langs->trans('Ref').''.$langs->trans('Draft').'
'.$langs->trans('CreateFromRepeatableInvoice').''; - print '
'.$langs->trans('Customer').''; - print $soc->getNomUrl(1); - print ''; - print ''; - print $form->select_company('','socid','s.client = 1 OR s.client = 3',1); - print '
'.$langs->trans('Type').''; - print ''."\n"; - - // Standard invoice - print ''."\n"; - - // Proforma - if (! empty($conf->global->FACTURE_USE_PROFORMAT)) - { - print ''."\n"; - } - - if (empty($origin)) - { - // Deposit - print ''."\n"; - } - - if ($socid > 0) + if ($action == 'update_extras') { - // Replacement - print ''."\n"; - } - - if (empty($origin) && $socid > 0) - { - // Credit note - print ''."\n"; - } - - print '
'; - print ''; - print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $text=$langs->trans("InvoiceReplacementAsk").' '; - $text.=''; - $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $text=$langs->transnoentities("InvoiceAvoirAsk").' '; - // $text.=''; - $text.=''; - $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1); - print $desc; - print '
'; - print '
'.$langs->trans('Discounts').''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",''.$soc->remise_client.''); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - print ' ('.$langs->trans("EditRelativeDiscount").')'; - print '. '; - print '
'; - if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",''.price($absolute_discount).'',$langs->trans("Currency".$conf->currency)); - else print $langs->trans("CompanyHasNoAbsoluteDiscount"); - print ' ('.$langs->trans("EditGlobalDiscounts").')'; - print '.'; - print '
'.$langs->trans('Date').''; - $form->select_date($dateinvoice,'','','','',"add",1,1); - print '
'.$langs->trans('PaymentConditionsShort').''; - $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id'); - print '
'.$langs->trans('PaymentMode').''; - $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id'); - print '
'.$langs->trans('Project').''; - select_projects($soc->id, $projectid, 'projectid'); - print '
'.$langs->trans('Model').''; - include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php'; - $liste=ModelePDFFactures::liste_modeles($db); - print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF); - print "
'.$langs->trans('NotePublic').''; - $note_public=''; - if (is_object($objectsrc)) // Take value from source object - { - $note_public=$objectsrc->note_public; - } - $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); - print $doleditor->Create(1); - - //print '
'.$langs->trans('NotePrivate').''; - $note_private=''; - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) // Take value from source object - { - $note_private=$objectsrc->note_private; - } - $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); - print $doleditor->Create(1); - //print '
'.$langs->trans($newclassname).''.$objectsrc->getNomUrl(1).'
'.$langs->trans('TotalHT').''.price($objectsrc->total_ht).'
'.$langs->trans('TotalVAT').''.price($objectsrc->total_tva)."
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($objectsrc->total_localtax1)."
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($objectsrc->total_localtax2)."
'.$langs->trans('TotalTTC').''.price($objectsrc->total_ttc)."
'; - - // Zone de choix des produits predefinis a la creation - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if (! empty($conf->service->enabled)) - { - print ''; - } - print ''; - for ($i = 1 ; $i <= $NBLINES ; $i++) - { - print ''; - print ''; - print ''; - print ''; - print ''; - // Si le module service est actif, on propose des dates de debut et fin a la ligne - if (! empty($conf->service->enabled)) - { - print ''; - } - print "\n"; - } - - print '
'.$langs->trans('ProductsAndServices').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').'     '.$langs->trans('ServiceLimitedDuration').'
'; - // multiprix - if (! empty($conf->global->PRODUIT_MULTIPRICES)) - $form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level); - else - $form->select_produits('','idprod'.$i,'',$conf->product->limit_size); - print '% '; - print ''; - print ''; - print '
'; - print $langs->trans('From').' '; - print ''; - print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add"); - print '
'; - print $langs->trans('to').' '; - print ''; - print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add"); - print '
'; - print '
'; - print '
\n"; - - // Button "Create Draft" - print '
'; - - print "
\n"; - - // Show origin lines - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) - { - print '
'; - - $title=$langs->trans('ProductsAndServices'); - print_titre($title); - - print ''; - - $objectsrc->printOriginLinesList(); - - print '
'; - } - -} -else if ($id > 0 || ! empty($ref)) -{ - /* - * Show object in view mode - */ - - $result=$object->fetch($id,$ref); - - // fetch optionals attributes and labels - $extralabels=$extrafields->fetch_name_optionals_label('facture'); - - if ($result > 0) - { - if ($user->societe_id>0 && $user->societe_id!=$object->socid) accessforbidden('',0); - - $result=$object->fetch_thirdparty(); - - $soc = new Societe($db); - $soc->fetch($object->socid); - $selleruserevenustamp=$mysoc->useRevenueStamp(); - - $totalpaye = $object->getSommePaiement(); - $totalcreditnotes = $object->getSumCreditNotesUsed(); - $totaldeposits = $object->getSumDepositsUsed(); - //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." selleruserrevenuestamp=".$selleruserevenustamp; - - // We can also use bcadd to avoid pb with floating points - // For example print 239.2 - 229.3 - 9.9; does not return 0. - //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); - //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); - $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT'); - - if ($object->paye) $resteapayer=0; - $resteapayeraffiche=$resteapayer; - - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) - { - $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - } - else - { - $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; - $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; - } - - $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount); - $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote); - $absolute_discount=price2num($absolute_discount,'MT'); - $absolute_creditnote=price2num($absolute_creditnote,'MT'); - - $author = new User($db); - if ($object->user_author) - { - $author->fetch($object->user_author); - } - - $objectidnext=$object->getIdReplacingInvoice(); - - - $head = facture_prepare_head($object); - - dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill'); - - $formconfirm=''; - - // Confirmation de la conversion de l'avoir en reduc - if ($action == 'converttoreduc') - { - $text=$langs->trans('ConfirmConvertToReduc'); - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2); - } - - // Confirmation to delete invoice - if ($action == 'delete') - { - $text=$langs->trans('ConfirmDeleteBill',$object->ref); - $formquestion=array(); - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_DELETE_INVOICE) && $object->hasProductsOrServices(1) && $object->statut>=1) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete',$formquestion,"yes",1); - }else { - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','','',1); - } - } - - // Confirmation de la validation - if ($action == 'valid') - { - // on verifie si l'objet est en numerotation provisoire - $objectref = substr($object->ref, 1, 4); - if ($objectref == 'PROV') - { - $savdate=$object->date; - if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) - { - $object->date=dol_now(); - $object->date_lim_reglement=$object->calculate_date_lim_reglement(); - } - $numref = $object->getNextNumRef($soc); - //$object->date=$savdate; - } - else - { - $numref = $object->ref; - } - - $text=$langs->trans('ConfirmValidateBill',$numref); - if (! empty($conf->notification->enabled)) - { - require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; - $notify=new Notify($db); - $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_FAC',$object->socid); - } - $formquestion=array(); - - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease"); - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); - } - if ($object->type != 2 && $object->total_ttc < 0) // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on - { - $text.='
'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive"); - } - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2)); - } - - // Confirm back to draft status - if ($action == 'modif') - { - $text=$langs->trans('ConfirmUnvalidateBill',$object->ref); - $formquestion=array(); - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); - } - - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1); - } - - // Confirmation du classement paye - if ($action == 'paid' && $resteapayer <= 0) - { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1); - } - if ($action == 'paid' && $resteapayer > 0) - { - // Code - $i=0; - $close[$i]['code']='discount_vat';$i++; - $close[$i]['code']='badcustomer';$i++; - // Help - $i=0; - $close[$i]['label']=$langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++; - $close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++; - // Texte - $i=0; - $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; - $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; - // arrayreasons[code]=reason - foreach($close as $key => $val) - { - $arrayreasons[$close[$key]['code']]=$close[$key]['reason']; - } - - // Cree un tableau formulaire - $formquestion=array( - 'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"), - array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), - array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') - ); - // Paiement incomplet. On demande si motif = escompte ou autre - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes"); - } - - // Confirmation du classement abandonne - if ($action == 'canceled') - { - // S'il y a une facture de remplacement pas encore validee (etat brouillon), - // on ne permet pas de classer abandonner la facture. - if ($objectidnext) - { - $facturereplacement=new Facture($db); - $facturereplacement->fetch($objectidnext); - $statusreplacement=$facturereplacement->statut; - } - if ($objectidnext && $statusreplacement == 0) - { - print '
'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'
'; - } - else - { - // Code - $close[1]['code']='badcustomer'; - $close[2]['code']='abandon'; - // Help - $close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc"); - $close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc"); - // Texte - $close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1); - $close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1); - // arrayreasons - $arrayreasons[$close[1]['code']]=$close[1]['reason']; - $arrayreasons[$close[2]['code']]=$close[2]['reason']; - - // Cree un tableau formulaire - $formquestion=array( - 'text' => $langs->trans("ConfirmCancelBillQuestion"), - array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), - array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') - ); - - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes"); - } - } - - // Confirmation de la suppression d'une ligne produit - if ($action == 'ask_deleteline') - { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1); - } - - // Clone confirmation - if ($action == 'clone') - { - // Create an array for form - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1) - ); - // Paiement incomplet. On demande si motif = escompte ou autre - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',1); - } - - if (! $formconfirm) - { - $parameters=array('lineid'=>$lineid); - $formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - } - - // Print form confirm - print $formconfirm; - - - // Invoice content - - print ''; - - $linkback = ''.$langs->trans("BackToList").''; - - // Ref - print ''; - print ''; - - // Ref customer - print ''; - print ''; + + // Third party + print ''; + + // Type + print ''; + + // Relative and absolute discounts + $addrelativediscount=''.$langs->trans("EditRelativeDiscounts").''; + $addabsolutediscount=''.$langs->trans("EditGlobalDiscounts").''; + $addcreditnote=''.$langs->trans("AddCreditNote").''; + + print ''; + + // Date invoice + print ''; + + + /* + * List of payments + */ + + $sign=1; + if ($object->type == 2) $sign=-1; + + $nbrows=8; $nbcols=2; + if (! empty($conf->projet->enabled)) $nbrows++; + if (! empty($conf->banque->enabled)) $nbcols++; + if($mysoc->localtax1_assuj=="1") $nbrows++; + if($mysoc->localtax2_assuj=="1") $nbrows++; + if ($selleruserevenustamp) $nbrows++; + + print ''; + + // Conditions de reglement + print ''; + + // Date payment term + print ''; + + // Payment mode + print ''; + + // Amount + print ''; + print ''; + print ''; + print ''; + + // Amount Local Taxes + if ($mysoc->localtax1_assuj=="1" && $mysoc->useLocalTax(1)) //Localtax1 (example RE) + { + print ''; + print ''; + } + if ($mysoc->localtax2_assuj=="1" && $mysoc->useLocalTax(2)) //Localtax2 (example IRPF) + { + print ''; + print ''; + } + + // Revenue stamp + if ($selleruserevenustamp) // Test company use revenue stamp + { + print ''; + } + + // Total with tax + print ''; + + // Statut + print ''; + print ''; + + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load('projects'); + print ''; + print ''; + print ''; + } + + // Other attributes + $res=$object->fetch_optionals($object->id,$extralabels); + $parameters=array('colspan' => ' colspan="2"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + + if ($action == 'edit_extras') + { + print ''; + print ''; + print ''; + print ''; + } + + foreach($extrafields->attribute_label as $key=>$label) + { + $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); + if ($extrafields->attribute_type[$key] == 'separate') + { + print $extrafields->showSeparator($key); + } + else + { + print 'attribute_required[$key])) print ' class="fieldrequired"'; + print '>'.$label.''."\n"; + } + } + + if(count($extrafields->attribute_label) > 0) { + + if ($action == 'edit_extras' && $user->rights->facture->creer) + { + print ''; + + } + else { + if ($object->statut == 0 && $user->rights->facture->creer) + { + print ''; + } + } + } + } + + print '
'.$langs->trans('Ref').''; - $morehtmlref=''; - $discount=new DiscountAbsolute($db); - $result=$discount->fetch(0,$object->id); - if ($result > 0) - { - $morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')'; - } - if ($result < 0) - { - dol_print_error('',$discount->error); - } - print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref); - print '
'; - print ''; - if ($action != 'refclient' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('RefCustomer'); - print ''.img_edit($langs->trans('Modify')).'
'; - print '
'; - if ($user->rights->facture->creer && $action == 'refclient') + // Fill array 'array_options' with data from add form + $extralabels=$extrafields->fetch_name_optionals_label('facture'); + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('invoicedao')); + $parameters=array('id'=>$object->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) { - print '
'; - print ''; - print ''; - print ''; - print ' '; - print '
'; + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$object->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + + } + + + /* + * View + */ + + $form = new Form($db); + $formother=new FormOther($db); + $formfile = new FormFile($db); + $bankaccountstatic=new Account($db); + $now=dol_now(); + + llxHeader('',$langs->trans('Bill'),'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes'); + + + + /********************************************************************* + * + * Mode creation + * + **********************************************************************/ + if ($action == 'create') + { + $facturestatic=new Facture($db); + $extralabels=$extrafields->fetch_name_optionals_label('facture'); + + print_fiche_titre($langs->trans('NewBill')); + + $soc = new Societe($db); + if ($socid>0) $res=$soc->fetch($socid); + + if (! empty($origin) && ! empty($originid)) + { + // Parse element/subelement (ex: project_task) + $element = $subelement = $origin; + if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) + { + $element = $regs[1]; + $subelement = $regs[2]; + } + + if ($element == 'project') + { + $projectid=$originid; + } + else + { + // For compatibility + if ($element == 'order' || $element == 'commande') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } + if ($element == 'shipping') { + $element = $subelement = 'expedition'; + } + + dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); + + $classname = ucfirst($subelement); + $objectsrc = new $classname($db); + $objectsrc->fetch($originid); + if (empty($objectsrc->lines) && method_exists($objectsrc,'fetch_lines')) $objectsrc->fetch_lines(); + $objectsrc->fetch_thirdparty(); + + $projectid = (! empty($objectsrc->fk_project)?$objectsrc->fk_project:''); + $ref_client = (! empty($objectsrc->ref_client)?$objectsrc->ref_client:''); + $ref_int = (! empty($objectsrc->ref_int)?$objectsrc->ref_int:''); + + $soc = $objectsrc->thirdparty; + $cond_reglement_id = (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1)); + $mode_reglement_id = (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0)); + $remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0)); + $remise_absolue = (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0)); + $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; + } } else { - print $object->ref_client; + $cond_reglement_id = $soc->cond_reglement_id; + $mode_reglement_id = $soc->mode_reglement_id; + $remise_percent = $soc->remise_percent; + $remise_absolue = 0; + $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; } + $absolute_discount=$soc->getAvailableDiscounts(); + + + if (! empty($conf->use_javascript_ajax)) + { + print ajax_combobox('fac_replacement'); + print ajax_combobox('fac_avoir'); + } + + print '
'; + print ''; + print ''; + if ($soc->id > 0) + print '' ."\n"; + print ''; + print ''; + print ''; + print ''; + print ''; + + print ''; + + // Ref + print ''; + + // Factures predefinies + if (empty($origin) && empty($originid) && $socid>0) + { + $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; + $sql.= ' WHERE r.fk_soc = '.$soc->id; + + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + if ($num > 0) + { + print ''; + } + $db->free($resql); + } + else + { + dol_print_error($db); + } + } + + // Tiers + print ''; + print ''; + if($soc->id > 0) + { + print ''; + } + else + { + print ''; + } + print ''."\n"; + + // Type de facture + $facids=$facturestatic->list_replacable_invoices($soc->id); + if ($facids < 0) + { + dol_print_error($db,$facturestatic); + exit; + } + $options=""; + foreach ($facids as $facparam) + { + $options.=''; + } + + $facids=$facturestatic->list_qualified_avoir_invoices($soc->id); + if ($facids < 0) + { + dol_print_error($db,$facturestatic); + exit; + } + $optionsav=""; + $newinvoice_static=new Facture($db); + foreach ($facids as $key => $valarray) + { + $newinvoice_static->id=$key; + $newinvoice_static->ref=$valarray['ref']; + $newinvoice_static->statut=$valarray['status']; + $newinvoice_static->type=$valarray['type']; + $newinvoice_static->paye=$valarray['paye']; + + $optionsav.=''; + } + + print ''; - // Third party - print ''; - - // Type - print ''; - - // Relative and absolute discounts - $addrelativediscount=''.$langs->trans("EditRelativeDiscounts").''; - $addabsolutediscount=''.$langs->trans("EditGlobalDiscounts").''; - $addcreditnote=''.$langs->trans("AddCreditNote").''; - - print ''; - - // Date invoice - print ''; - - - /* - * List of payments - */ - - $sign=1; - if ($object->type == 2) $sign=-1; - - $nbrows=8; $nbcols=2; - if (! empty($conf->projet->enabled)) $nbrows++; - if (! empty($conf->banque->enabled)) $nbcols++; - if($mysoc->localtax1_assuj=="1") $nbrows++; - if($mysoc->localtax2_assuj=="1") $nbrows++; - if ($selleruserevenustamp) $nbrows++; - - print ''; } - print ''; + // Date invoice + print ''; - // Conditions de reglement - print ''; + // Payment term + print ''; - // Date payment term - print ''; + // Payment mode + print ''; - // Payment mode - print ''; + // Project + if (! empty($conf->projet->enabled) && $socid>0) + { + $langs->load('projects'); + print ''; + } - // Amount - print ''; - print ''; - print ''; - print ''; + // Other attributes + $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + print $object->showOptionals($extrafields,'edit'); + } - // Amount Local Taxes - if ($mysoc->localtax1_assuj=="1" && $mysoc->useLocalTax(1)) //Localtax1 (example RE) - { - print ''; - print ''; - } - if ($mysoc->localtax2_assuj=="1" && $mysoc->useLocalTax(2)) //Localtax2 (example IRPF) - { - print ''; - print ''; - } + // Modele PDF + print ''; + print '"; - // Revenue stamp - if ($selleruserevenustamp) // Test company use revenue stamp - { - print ''; + print ''; + print ''; + + // Private note + if (empty($user->societe_id)) + { + print ''; + print ''; + print ''; + } + + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) + { + // TODO for compatibility + if ($origin == 'contrat') + { + // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva + $objectsrc->remise_absolue=$remise_absolue; + $objectsrc->remise_percent=$remise_percent; + $objectsrc->update_price(1,-1,1); + } + + print "\n"; + print "\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''; + print ''; + + $newclassname=$classname; + if ($newclassname == 'Propal') $newclassname = 'CommercialProposal'; + elseif ($newclassname == 'Commande') $newclassname = 'Order'; + + print ''; + print ''; + print '"; + if ($mysoc->localtax1_assuj=="1") //Localtax1 RE + { + print '"; + } + + if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF + { + print '"; + } + print '"; + } + else + { + // Show deprecated optional form to add product line here + if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) + { + print ''; + } + } + + print "
'.$langs->trans('Ref').''.$langs->trans('Draft').'
'.$langs->trans('CreateFromRepeatableInvoice').''; + print '
'.$langs->trans('Customer').''; + print $soc->getNomUrl(1); + print ''; + print ''; + print $form->select_company('','socid','s.client = 1 OR s.client = 3',1); + print '
'.$langs->trans('Type').''; + print ''."\n"; + + // Standard invoice + print ''."\n"; + + // Proforma + if (! empty($conf->global->FACTURE_USE_PROFORMAT)) + { + print ''."\n"; + } + + if (empty($origin)) + { + // Deposit + print ''."\n"; + } + + if ($socid > 0) + { + // Replacement + print ''."\n"; + } + + if (empty($origin) && $socid > 0) + { + // Credit note + print ''."\n"; + } + + print '
'; + print ''; + print ''; + $desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1); + print $desc; + print '
'; + print ''; + print ''; + $desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1); + print $desc; + print '
'; + print ''; + print ''; + $desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1); + print $desc; + print '
'; + print ''; + print ''; + $text=$langs->trans("InvoiceReplacementAsk").' '; + $text.=''; + $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1); + print $desc; + print '
'; + print ''; + print ''; + $text=$langs->transnoentities("InvoiceAvoirAsk").' '; + // $text.=''; + $text.=''; + $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1); + print $desc; + print '
'; print '
'; - print ''; - print ''; - print ''; - print '
'.$langs->trans('Company').''; - if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer) - print 'id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'
'; - print '
'; - if ($action == 'editthirdparty') - { - $form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid'); - } - else - { - print '  '.$soc->getNomUrl(1,'compta'); - print '   ('.$langs->trans('OtherBills').')'; - } - print '
'.$langs->trans('Type').''; - print $object->getLibType(); - if ($object->type == 1) - { - $facreplaced=new Facture($db); - $facreplaced->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; - } - if ($object->type == 2) - { - $facusing=new Facture($db); - $facusing->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; - } - - $facidavoir=$object->getListIdAvoirFromInvoice(); - if (count($facidavoir) > 0) - { - print ' ('.$langs->transnoentities("InvoiceHasAvoir"); - $i=0; - foreach($facidavoir as $id) - { - if ($i==0) print ' '; - else print ','; - $facavoir=new Facture($db); - $facavoir->fetch($id); - print $facavoir->getNomUrl(1); - } - print ')'; - } - if ($objectidnext > 0) - { - $facthatreplace=new Facture($db); - $facthatreplace->fetch($objectidnext); - print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; - } - print '
'.$langs->trans('Discounts'); - print ''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - //print ' ('.$addrelativediscount.')'; - - if ($absolute_discount > 0) - { - print '. '; - if ($object->statut > 0 || $object->type == 2 || $object->type == 3) - { - if ($object->statut == 0) - { - print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - print '. '; - } - else - { - if ($object->statut < 1 || $object->type == 2 || $object->type == 3) - { - $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - print '
'.$text.'.
'; - } - else - { - $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - $text2=$langs->trans("AbsoluteDiscountUse"); - print $form->textwithpicto($text,$text2); - } - } - } - else - { - // Remise dispo de type remise fixe (not credit note) - print '
'; - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')'); - } - } - else - { - if ($absolute_creditnote > 0) // If not, link will be added later - { - if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; - else print '. '; - } - else print '. '; - } - if ($absolute_creditnote > 0) - { - // If validated, we show link "add credit note to payment" - if ($object->statut != 1 || $object->type == 2 || $object->type == 3) - { - if ($object->statut == 0 && $object->type != 3) - { - $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)); - print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse")); - } - else - { - print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.'; - } - } - else - { - // Remise dispo de type avoir - if (! $absolute_discount) print '
'; - //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer); - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher - } - } - if (! $absolute_discount && ! $absolute_creditnote) - { - print $langs->trans("CompanyHasNoAbsoluteDiscount"); - if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; - else print '. '; - } - /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3) - { - if (! $absolute_discount && ! $absolute_creditnote) print '
'; - //print '   -   '; - print $addabsolutediscount; - //print '   -   '.$addcreditnote; // We disbale link to credit note - }*/ - print '
'; - print ''; - if ($object->type != 2 && $action != 'editinvoicedate' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('Date'); - print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; - print '
'; - - if ($object->type != 2) - { - if ($action == 'editinvoicedate') - { - $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate'); - } - else - { - print dol_print_date($object->date,'daytext'); - } - } - else - { - print dol_print_date($object->date,'daytext'); - } - print ''; - - print ''; - - // List of payments already done - print ''; - print ''; - print ''; - if (! empty($conf->banque->enabled)) print ''; - print ''; - print ''; - print ''; - - $var=true; - - // Payments already done (from payment on this invoice) - $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,'; - $sql.= ' c.code as payment_code, c.libelle as payment_label,'; - $sql.= ' pf.amount,'; - $sql.= ' ba.rowid as baid, ba.ref, ba.label'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; - $sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid'; - $sql.= ' ORDER BY p.datep, p.tms'; - - $result = $db->query($sql); - if ($result) - { - $num = $db->num_rows($result); - $i = 0; - - //if ($object->type != 2) - //{ - if ($num > 0) - { - while ($i < $num) - { - $objp = $db->fetch_object($result); - $var=!$var; - print ''; - $label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label; - print ''; - if (! empty($conf->banque->enabled)) - { - $bankaccountstatic->id=$objp->baid; - $bankaccountstatic->ref=$objp->ref; - $bankaccountstatic->label=$objp->ref; - print ''; - } - print ''; - print ''; - print ''; - $i++; - } - } - else - { - print ''; - } - //} - $db->free($result); - } - else - { - dol_print_error($db); - } - - if ($object->type != 2) - { - // Total already paid - print ''; - - $resteapayeraffiche=$resteapayer; - - // Loop on each credit note or deposit amount applied - $creditnoteamount=0; - $depositamount=0; - $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; - $sql.= " re.description, re.fk_facture_source"; - $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; - $sql.= " WHERE fk_facture = ".$object->id; - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - $i = 0; - $invoice=new Facture($db); - while ($i < $num) - { - $obj = $db->fetch_object($resql); - $invoice->fetch($obj->fk_facture_source); - print ''; - print ''; - print ''; - $i++; - if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc; - if ($invoice->type == 3) $depositamount += $obj->amount_ttc; - } - } - else - { - dol_print_error($db); - } - - // Paye partiellement 'escompte' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat') - { - print ''; - $resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'badcustomer' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer') - { - print ''; - //$resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'product_returned' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned') - { - print ''; - $resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'abandon' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon') - { - print ''; - $resteapayeraffiche=0; - } - - // Billed - print ''; - - // Remainder to pay - print ''; - print ''; - print ''; - } - else // Credit note - { - // Total already paid back - print ''; - - // Billed - print ''; - - // Remainder to pay back - print ''; - print ''; - print ''; - - // Sold credit note - //print ''; - //print ''; - } - - print '
'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).''.$langs->trans('Type').''.$langs->trans('BankAccount').''.$langs->trans('Amount').' 
'; - print ''.img_object($langs->trans('ShowPayment'),'payment').' '; - print dol_print_date($db->jdate($objp->dp),'day').''.$label.' '.$objp->num_paiement.''; - if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions'); - print ''.price($sign * $objp->amount).' 
'.$langs->trans("None").'
'; - if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits'); - else print $langs->trans('AlreadyPaid'); - print ' :'.price($totalpaye).' 
'; - if ($invoice->type == 2) print $langs->trans("CreditNote").' '; - if ($invoice->type == 3) print $langs->trans("Deposit").' '; - print $invoice->getNomUrl(0); - print ' :'.price($obj->amount_ttc).''; - print 'rowid.'">'.img_delete().''; - print '
'; - print $form->textwithpicto($langs->trans("Discount").':',$langs->trans("HelpEscompte"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - $text=$langs->trans("HelpAbandonOther"); - if ($object->close_note) $text.='

'.$langs->trans("Reason").':'.$object->close_note; - print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1); - print '
'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'.$langs->trans("Billed").' :'.price($object->total_ttc).' 
'; - if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay'); - else print $langs->trans('ExcessReceived'); - print ' :'.price($resteapayeraffiche).' 
'; - print $langs->trans('AlreadyPaidBack'); - print ' :'.price($sign * $totalpaye).' 
'.$langs->trans("Billed").' :'.price($sign * $object->total_ttc).' 
'; - if ($resteapayeraffiche <= 0) print $langs->trans('RemainderToPayBack'); - else print $langs->trans('ExcessPaydBack'); - print ' :'.price($sign * $resteapayeraffiche).' 
'.$langs->trans('TotalTTC').' :'.price($sign * $object->total_ttc).' 
'; - - // Margin Infos - if (! empty($conf->margin->enabled)) + if ($socid > 0) { - print '
'; - $object->displayMarginInfos($object->statut > 0); + // Discounts for third party + print '
'.$langs->trans('Discounts').''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",''.$soc->remise_client.''); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + print ' ('.$langs->trans("EditRelativeDiscount").')'; + print '. '; + print '
'; + if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",''.price($absolute_discount).'',$langs->trans("Currency".$conf->currency)); + else print $langs->trans("CompanyHasNoAbsoluteDiscount"); + print ' ('.$langs->trans("EditGlobalDiscounts").')'; + print '.'; + print '
'.$langs->trans('Date').''; + $form->select_date($dateinvoice,'','','','',"add",1,1); + print '
'; - print ''; - if ($object->type != 2 && $action != 'editconditions' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('PaymentConditionsShort'); - print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; - print '
'; - if ($object->type != 2) - { - if ($action == 'editconditions') - { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); - } - else - { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none'); - } - } - else - { - print ' '; - } - print '
'.$langs->trans('PaymentConditionsShort').''; + $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id'); + print '
'; - print ''; - if ($object->type != 2 && $action != 'editpaymentterm' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('DateMaxPayment'); - print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; - print '
'; - if ($object->type != 2) - { - if ($action == 'editpaymentterm') - { - $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm'); - } - else - { - print dol_print_date($object->date_lim_reglement,'daytext'); - if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! isset($object->am)) print img_warning($langs->trans('Late')); - } - } - else - { - print ' '; - } - print '
'.$langs->trans('PaymentMode').''; + $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id'); + print '
'; - print ''; - if ($action != 'editmode' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('PaymentMode'); - print 'id.'">'.img_edit($langs->trans('SetMode'),1).'
'; - print '
'; - if ($action == 'editmode') - { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); - } - else - { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none'); - } - print '
'.$langs->trans('Project').''; + select_projects($soc->id, $projectid, 'projectid'); + print '
'.$langs->trans('AmountHT').''.price($object->total_ht,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('AmountVAT').''.price($object->total_tva,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($object->total_localtax1,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($object->total_localtax2,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('Model').''; + include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php'; + $liste=ModelePDFFactures::liste_modeles($db); + print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF); + print "
'; - print ''; - if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('RevenueStamp'); - print 'id.'">'.img_edit($langs->trans('SetRevenuStamp'),1).'
'; - print '
'; - if ($action == 'editrevenuestamp') - { + // Public note + print '
'.$langs->trans('NotePublic').''; + $note_public=''; + if (is_object($objectsrc)) // Take value from source object + { + $note_public=$objectsrc->note_public; + } + $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + + //print '
'.$langs->trans('NotePrivate').''; + $note_private=''; + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) // Take value from source object + { + $note_private=$objectsrc->note_private; + } + $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + //print '
'.$langs->trans($newclassname).''.$objectsrc->getNomUrl(1).'
'.$langs->trans('TotalHT').''.price($objectsrc->total_ht).'
'.$langs->trans('TotalVAT').''.price($objectsrc->total_tva)."
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($objectsrc->total_localtax1)."
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($objectsrc->total_localtax2)."
'.$langs->trans('TotalTTC').''.price($objectsrc->total_ttc)."
'; + + // Zone de choix des produits predefinis a la creation + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->service->enabled)) + { + print ''; + } + print ''; + for ($i = 1 ; $i <= $NBLINES ; $i++) + { + print ''; + print ''; + print ''; + print ''; + print ''; + // Si le module service est actif, on propose des dates de debut et fin a la ligne + if (! empty($conf->service->enabled)) + { + print ''; + } + print "\n"; + } + + print '
'.$langs->trans('ProductsAndServices').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').'     '.$langs->trans('ServiceLimitedDuration').'
'; + // multiprix + if (! empty($conf->global->PRODUIT_MULTIPRICES)) + $form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level); + else + $form->select_produits('','idprod'.$i,'',$conf->product->limit_size); + print '% '; + print ''; + print ''; + print '
'; + print $langs->trans('From').' '; + print ''; + print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add"); + print '
'; + print $langs->trans('to').' '; + print ''; + print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add"); + print '
'; + print '
'; + print '
\n"; + + // Button "Create Draft" + print '
'; + + print "
\n"; + + // Show origin lines + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) + { + print '
'; + + $title=$langs->trans('ProductsAndServices'); + print_titre($title); + + print ''; + + $objectsrc->printOriginLinesList(); + + print '
'; + } + + } + else if ($id > 0 || ! empty($ref)) + { + /* + * Show object in view mode + */ + + $result=$object->fetch($id,$ref); + + // fetch optionals attributes and labels + $extralabels=$extrafields->fetch_name_optionals_label('facture'); + + if ($result > 0) + { + if ($user->societe_id>0 && $user->societe_id!=$object->socid) accessforbidden('',0); + + $result=$object->fetch_thirdparty(); + + $soc = new Societe($db); + $soc->fetch($object->socid); + $selleruserevenustamp=$mysoc->useRevenueStamp(); + + $totalpaye = $object->getSommePaiement(); + $totalcreditnotes = $object->getSumCreditNotesUsed(); + $totaldeposits = $object->getSumDepositsUsed(); + //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." selleruserrevenuestamp=".$selleruserevenustamp; + + // We can also use bcadd to avoid pb with floating points + // For example print 239.2 - 229.3 - 9.9; does not return 0. + //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); + //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); + $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT'); + + if ($object->paye) $resteapayer=0; + $resteapayeraffiche=$resteapayer; + + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) + { + $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + } + else + { + $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; + $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; + } + + $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount); + $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote); + $absolute_discount=price2num($absolute_discount,'MT'); + $absolute_creditnote=price2num($absolute_creditnote,'MT'); + + $author = new User($db); + if ($object->user_author) + { + $author->fetch($object->user_author); + } + + $objectidnext=$object->getIdReplacingInvoice(); + + + $head = facture_prepare_head($object); + + dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill'); + + $formconfirm=''; + + // Confirmation de la conversion de l'avoir en reduc + if ($action == 'converttoreduc') + { + $text=$langs->trans('ConfirmConvertToReduc'); + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2); + } + + // Confirmation to delete invoice + if ($action == 'delete') + { + $text=$langs->trans('ConfirmDeleteBill',$object->ref); + $formquestion=array(); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change && $object->statut>=1) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1,0,0,$langs->trans("NoStockAction")))); + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete',$formquestion,"yes",1); + }else { + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','','',1); + } + } + + // Confirmation de la validation + if ($action == 'valid') + { + // on verifie si l'objet est en numerotation provisoire + $objectref = substr($object->ref, 1, 4); + if ($objectref == 'PROV') + { + $savdate=$object->date; + if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) + { + $object->date=dol_now(); + $object->date_lim_reglement=$object->calculate_date_lim_reglement(); + } + $numref = $object->getNextNumRef($soc); + //$object->date=$savdate; + } + else + { + $numref = $object->ref; + } + + $text=$langs->trans('ConfirmValidateBill',$numref); + if (! empty($conf->notification->enabled)) + { + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage('NOTIFY_VAL_FAC',$object->socid); + } + $formquestion=array(); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease"); + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); + } + if ($object->type != 2 && $object->total_ttc < 0) // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on + { + $text.='
'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive"); + } + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2)); + } + + // Confirm back to draft status + if ($action == 'modif') + { + $text=$langs->trans('ConfirmUnvalidateBill',$object->ref); + $formquestion=array(); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); + } + + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1); + } + + // Confirmation du classement paye + if ($action == 'paid' && $resteapayer <= 0) + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1); + } + if ($action == 'paid' && $resteapayer > 0) + { + // Code + $i=0; + $close[$i]['code']='discount_vat';$i++; + $close[$i]['code']='badcustomer';$i++; + // Help + $i=0; + $close[$i]['label']=$langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++; + $close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++; + // Texte + $i=0; + $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; + $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; + // arrayreasons[code]=reason + foreach($close as $key => $val) + { + $arrayreasons[$close[$key]['code']]=$close[$key]['reason']; + } + + // Cree un tableau formulaire + $formquestion=array( + 'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"), + array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), + array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') + ); + // Paiement incomplet. On demande si motif = escompte ou autre + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes"); + } + + // Confirmation du classement abandonne + if ($action == 'canceled') + { + // S'il y a une facture de remplacement pas encore validee (etat brouillon), + // on ne permet pas de classer abandonner la facture. + if ($objectidnext) + { + $facturereplacement=new Facture($db); + $facturereplacement->fetch($objectidnext); + $statusreplacement=$facturereplacement->statut; + } + if ($objectidnext && $statusreplacement == 0) + { + print '
'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'
'; + } + else + { + // Code + $close[1]['code']='badcustomer'; + $close[2]['code']='abandon'; + // Help + $close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc"); + $close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc"); + // Texte + $close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1); + $close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1); + // arrayreasons + $arrayreasons[$close[1]['code']]=$close[1]['reason']; + $arrayreasons[$close[2]['code']]=$close[2]['reason']; + + // Cree un tableau formulaire + $formquestion=array( + 'text' => $langs->trans("ConfirmCancelBillQuestion"), + array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), + array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') + ); + + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes"); + } + } + + // Confirmation de la suppression d'une ligne produit + if ($action == 'ask_deleteline') + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1); + } + + // Clone confirmation + if ($action == 'clone') + { + // Create an array for form + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1) + ); + // Paiement incomplet. On demande si motif = escompte ou autre + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',1); + } + + if (! $formconfirm) + { + $parameters=array('lineid'=>$lineid); + $formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + } + + // Print form confirm + print $formconfirm; + + + // Invoice content + + print ''; + + $linkback = ''.$langs->trans("BackToList").''; + + // Ref + print ''; + print ''; + + // Ref customer + print ''; + print ''; - } - - // Total with tax - print ''; - - // Statut - print ''; - print ''; - - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load('projects'); - print ''; - print ''; - print ''; - } - - // Other attributes - $res=$object->fetch_optionals($object->id,$extralabels); - $parameters=array('colspan' => ' colspan="2"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - - if ($action == 'edit_extras') - { - print ''; - print ''; - print ''; - print ''; - } - - foreach($extrafields->attribute_label as $key=>$label) - { - $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); - if ($extrafields->attribute_type[$key] == 'separate') - { - print $extrafields->showSeparator($key); - } - else - { - print 'attribute_required[$key])) print ' class="fieldrequired"'; - print '>'.$label.''."\n"; - } - } - - if(count($extrafields->attribute_label) > 0) { - - if ($action == 'edit_extras' && $user->rights->facture->creer) - { - print ''; - - } - else { - if ($object->statut == 0 && $user->rights->facture->creer) - { - print ''; - } - } - } - } - - print '
'.$langs->trans('Ref').''; + $morehtmlref=''; + $discount=new DiscountAbsolute($db); + $result=$discount->fetch(0,$object->id); + if ($result > 0) + { + $morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')'; + } + if ($result < 0) + { + dol_print_error('',$discount->error); + } + print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref); + print '
'; + print ''; + if ($action != 'refclient' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('RefCustomer'); + print ''.img_edit($langs->trans('Modify')).'
'; + print '
'; + if ($user->rights->facture->creer && $action == 'refclient') + { print '
'; print ''; - print ''; - print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code); - //print ''; + print ''; + print ''; print ' '; print '
'; - } - else - { - print price($object->revenuestamp,1,'',1,-1,-1,$conf->currency); - } - print '
'.$langs->trans('AmountTTC').''.price($object->total_ttc,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('Status').''.($object->getLibStatut(4,$totalpaye)).'
'; - - print ''; - if ($action != 'classify') - { - print ''; - } - print '
'; - print $langs->trans('Project'); - print 'id.'">'; - print img_edit($langs->trans('SetProject'),1); - print '
'; - - print '
'; - if ($action == 'classify') - { - $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid'); - } - else - { - $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none'); - } - print '
'; - // Convert date into timestamp format - if (in_array($extrafields->attribute_type[$key],array('date','datetime'))) - { - $value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key]; - } - - if ($action == 'edit_extras' && $user->rights->facture->creer) - { - print $extrafields->showInputField($key,$value); - } - else - { - print $extrafields->showOutputField($key,$value); - } - print '
'; - print ''; - print ''; - print '
'.img_picto('','edit').' '.$langs->trans('Modify').'

'; - - if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) - { - $blocname = 'contacts'; - $title = $langs->trans('ContactsAddresses'); - include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; - } - - if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) - { - $blocname = 'notes'; - $title = $langs->trans('Notes'); - include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; - } - - /* - * Lines - */ - $result = $object->getLinesArray(); - - if (! empty($conf->use_javascript_ajax) && $object->statut == 0) - { - include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; - } - - print ''; - - // Show object lines - if (! empty($object->lines)) - $ret=$object->printObjectLines($action,$mysoc,$soc,$lineid,1); - - /* - * Form to add new line - */ - if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline') - { - $var=true; - - if ($conf->global->MAIN_FEATURES_LEVEL > 1) - { - // Add free or predefined products/services - $object->formAddObjectLine(1,$mysoc,$soc); - } - else - { - // Add free products/services - $object->formAddFreeProduct(1,$mysoc,$soc); - - // Add predefined products/services - if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) - { - $var=!$var; - $object->formAddPredefinedProduct(1,$mysoc,$soc); - } - } - - $parameters=array(); - $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - } - - print "
\n"; - - print "\n"; - - - /* - * Boutons actions - */ - - if ($action != 'prerelance' && $action != 'presend') - { - if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline') - { - print '
'; - - // Editer une facture deja validee, sans paiement effectue et pas exporte en compta - if ($object->statut == 1) - { - // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees - $ventilExportCompta = $object->getVentilExportCompta(); - - if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) - { - if (! $objectidnext) - { - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) - { - print ''; - } - else - { - print '
'.$langs->trans('Modify').'
'; - } - } - else - { - print '
'.$langs->trans('Modify').'
'; - } - } - } - - // Reopen a standard paid invoice - if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3)) // A paid invoice (partially or completely) - { - if (! $objectidnext && $object->close_code != 'replaced') // Not replaced by another invoice - { - print ''; - } - else - { - print '
'.$langs->trans('ReOpen').'
'; - } - } - - // Validate - if ($object->statut == 0 && count($object->lines) > 0 && - ( - (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) - || ($object->type == 2 && $object->total_ttc <= 0)) - ) - { - if ($user->rights->facture->valider) - { - print ''; - } - } - - // Send by mail - if (($object->statut == 1 || $object->statut == 2)) - { - if ($objectidnext) - { - print '
'.$langs->trans('SendByMail').'
'; - } - else - { - if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) - { - print ''; - } - else print ''; - } - } - - if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) // For backward compatibility - { - if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) - { - if ($objectidnext) - { - print '
'.$langs->trans('SendRemindByMail').'
'; - } - else - { - if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) - { - print ''; - } - else print ''; - } - } - } - - // Create payment - if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) - { - if ($objectidnext) - { - print '
'.$langs->trans('DoPayment').'
'; - } - else - { - if ($resteapayer == 0) - { - print '
'.$langs->trans('DoPayment').'
'; - } - else - { - print ''; - } - } - } - - // Reverse back money or convert to reduction - if ($object->type == 2 || $object->type == 3) - { - // For credit note only - if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) - { - print ''; - } - // For credit note - if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0) - { - print ''; - } - // For deposit invoice - if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer) - { - print ''; - } - } - - // Classify paid (if not deposit and not credit note. Such invoice are "converted") - if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement && - (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) ) - { - print ''; - } - - // Classify 'closed not completely paid' (possible si validee et pas encore classee payee) - if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 - && $user->rights->facture->paiement) - { - if ($totalpaye > 0 || $totalcreditnotes > 0) - { - // If one payment or one credit note was linked to this invoice - print ''; - } - else - { - if ($objectidnext) - { - print '
'.$langs->trans('ClassifyCanceled').'
'; - } - else - { - print ''; - } - } - } - - // Clone - if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer) - { - print ''; - } - - // Clone as predefined - if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer) - { - if (! $objectidnext) - { - print ''; - } - } - - // Delete - if ($user->rights->facture->supprimer) - { - if (! $object->is_erasable()) - { - print ''; - } - else if ($objectidnext) - { - print ''; - } - elseif ($object->getSommePaiement()) - { - print ''; - } - else - { - print ''; - } - } - else - { - print ''; - } - - print '
'; - } - } - print '
'; - - if ($action != 'prerelance' && $action != 'presend') - { - print '
'; - //print '
'; - //print ''; // ancre - - /* - * Documents generes - */ - $filename=dol_sanitizeFileName($object->ref); - $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref); - $urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id; - $genallowed=$user->rights->facture->creer; - $delallowed=$user->rights->facture->supprimer; - - print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); - $somethingshown=$formfile->numoffiles; - - /* - * Linked object block - */ - $somethingshown=$object->showLinkedObjectBlock(); - - // Link for paypal payment - if (! empty($conf->paypal->enabled) && $object->statut != 0) - { - include_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; - print showPaypalPaymentUrl('invoice',$object->ref); - } - - print '
'; - //print '
'; - - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions=new FormActions($db); - $somethingshown=$formactions->showactions($object,'invoice',$socid); - - //print '
'; - print '
'; - } - else - { - /* - * Affiche formulaire mail - */ - - // By default if $action=='presend' - $titreform='SendBillByMail'; - $topicmail='SendBillRef'; - $action='send'; - $modelmail='facture_send'; - - if ($action == 'prerelance') // For backward compatibility - { - $titrefrom='SendReminderBillByMail'; - $topicmail='SendReminderBillRef'; - $action='relance'; - $modelmail='facture_relance'; - } - - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); - $file=$fileparams['fullname']; - - // Build document if it not exists - if (! $file || ! is_readable($file)) - { - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - - $result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); - $file=$fileparams['fullname']; - } - - print '
'; - print_titre($langs->trans($titreform)); - - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->fromtype = 'user'; - $formmail->fromid = $user->id; - $formmail->fromname = $user->getFullName($langs); - $formmail->frommail = $user->email; - $formmail->withfrom=1; - $liste=array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; - $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; - $formmail->withtocc=$liste; - $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; - $formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__'); - $formmail->withfile=2; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - $formmail->withcancel=1; - // Tableau des substitutions - $formmail->substit['__FACREF__']=$object->ref; - $formmail->substit['__SIGNATURE__']=$user->signature; - $formmail->substit['__PERSONALIZED__']=''; - $formmail->substit['__CONTACTCIVNAME__']=''; - - //Find the good contact adress - $custcontact=''; - $contactarr=array(); - $contactarr=$object->liste_contact(-1,'external'); - - if (is_array($contactarr) && count($contactarr)>0) { - foreach($contactarr as $contact) { - if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { - - require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; - - $contactstatic=new Contact($db); - $contactstatic->fetch($contact['id']); - $custcontact=$contactstatic->getFullName($langs,1); - } - } - - if (!empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__']=$custcontact; - } - } - - - // Tableau des parametres complementaires du post - $formmail->param['action']=$action; - $formmail->param['models']=$modelmail; - $formmail->param['facid']=$object->id; - $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; - - // Init list of files - if (GETPOST("mode")=='init') - { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); - } - - $formmail->show_form(); - - print '
'; - } - } - else - { - dol_print_error($db,$object->error); - } -} - -dol_htmloutput_mesg('',$mesgs); - -llxFooter(); -$db->close(); -?> + } + else + { + print $object->ref_client; + } + print '
'; + print ''; + print ''; + print ''; + print '
'.$langs->trans('Company').''; + if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer) + print 'id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'
'; + print '
'; + if ($action == 'editthirdparty') + { + $form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid'); + } + else + { + print '  '.$soc->getNomUrl(1,'compta'); + print '   ('.$langs->trans('OtherBills').')'; + } + print '
'.$langs->trans('Type').''; + print $object->getLibType(); + if ($object->type == 1) + { + $facreplaced=new Facture($db); + $facreplaced->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; + } + if ($object->type == 2) + { + $facusing=new Facture($db); + $facusing->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; + } + + $facidavoir=$object->getListIdAvoirFromInvoice(); + if (count($facidavoir) > 0) + { + print ' ('.$langs->transnoentities("InvoiceHasAvoir"); + $i=0; + foreach($facidavoir as $id) + { + if ($i==0) print ' '; + else print ','; + $facavoir=new Facture($db); + $facavoir->fetch($id); + print $facavoir->getNomUrl(1); + } + print ')'; + } + if ($objectidnext > 0) + { + $facthatreplace=new Facture($db); + $facthatreplace->fetch($objectidnext); + print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; + } + print '
'.$langs->trans('Discounts'); + print ''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + //print ' ('.$addrelativediscount.')'; + + if ($absolute_discount > 0) + { + print '. '; + if ($object->statut > 0 || $object->type == 2 || $object->type == 3) + { + if ($object->statut == 0) + { + print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + print '. '; + } + else + { + if ($object->statut < 1 || $object->type == 2 || $object->type == 3) + { + $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + print '
'.$text.'.
'; + } + else + { + $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + $text2=$langs->trans("AbsoluteDiscountUse"); + print $form->textwithpicto($text,$text2); + } + } + } + else + { + // Remise dispo de type remise fixe (not credit note) + print '
'; + $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')'); + } + } + else + { + if ($absolute_creditnote > 0) // If not, link will be added later + { + if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; + else print '. '; + } + else print '. '; + } + if ($absolute_creditnote > 0) + { + // If validated, we show link "add credit note to payment" + if ($object->statut != 1 || $object->type == 2 || $object->type == 3) + { + if ($object->statut == 0 && $object->type != 3) + { + $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)); + print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse")); + } + else + { + print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.'; + } + } + else + { + // Remise dispo de type avoir + if (! $absolute_discount) print '
'; + //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer); + $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher + } + } + if (! $absolute_discount && ! $absolute_creditnote) + { + print $langs->trans("CompanyHasNoAbsoluteDiscount"); + if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; + else print '. '; + } + /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3) + { + if (! $absolute_discount && ! $absolute_creditnote) print '
'; + //print '   -   '; + print $addabsolutediscount; + //print '   -   '.$addcreditnote; // We disbale link to credit note + }*/ + print '
'; + print ''; + if ($object->type != 2 && $action != 'editinvoicedate' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('Date'); + print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; + print '
'; + + if ($object->type != 2) + { + if ($action == 'editinvoicedate') + { + $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate'); + } + else + { + print dol_print_date($object->date,'daytext'); + } + } + else + { + print dol_print_date($object->date,'daytext'); + } + print ''; + + print ''; + + // List of payments already done + print ''; + print ''; + print ''; + if (! empty($conf->banque->enabled)) print ''; + print ''; + print ''; + print ''; + + $var=true; + + // Payments already done (from payment on this invoice) + $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,'; + $sql.= ' c.code as payment_code, c.libelle as payment_label,'; + $sql.= ' pf.amount,'; + $sql.= ' ba.rowid as baid, ba.ref, ba.label'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; + $sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid'; + $sql.= ' ORDER BY p.datep, p.tms'; + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + $i = 0; + + //if ($object->type != 2) + //{ + if ($num > 0) + { + while ($i < $num) + { + $objp = $db->fetch_object($result); + $var=!$var; + print ''; + $label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label; + print ''; + if (! empty($conf->banque->enabled)) + { + $bankaccountstatic->id=$objp->baid; + $bankaccountstatic->ref=$objp->ref; + $bankaccountstatic->label=$objp->ref; + print ''; + } + print ''; + print ''; + print ''; + $i++; + } + } + else + { + print ''; + } + //} + $db->free($result); + } + else + { + dol_print_error($db); + } + + if ($object->type != 2) + { + // Total already paid + print ''; + + $resteapayeraffiche=$resteapayer; + + // Loop on each credit note or deposit amount applied + $creditnoteamount=0; + $depositamount=0; + $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; + $sql.= " re.description, re.fk_facture_source"; + $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; + $sql.= " WHERE fk_facture = ".$object->id; + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + $invoice=new Facture($db); + while ($i < $num) + { + $obj = $db->fetch_object($resql); + $invoice->fetch($obj->fk_facture_source); + print ''; + print ''; + print ''; + $i++; + if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc; + if ($invoice->type == 3) $depositamount += $obj->amount_ttc; + } + } + else + { + dol_print_error($db); + } + + // Paye partiellement 'escompte' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat') + { + print ''; + $resteapayeraffiche=0; + } + // Paye partiellement ou Abandon 'badcustomer' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer') + { + print ''; + //$resteapayeraffiche=0; + } + // Paye partiellement ou Abandon 'product_returned' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned') + { + print ''; + $resteapayeraffiche=0; + } + // Paye partiellement ou Abandon 'abandon' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon') + { + print ''; + $resteapayeraffiche=0; + } + + // Billed + print ''; + + // Remainder to pay + print ''; + print ''; + print ''; + } + else // Credit note + { + // Total already paid back + print ''; + + // Billed + print ''; + + // Remainder to pay back + print ''; + print ''; + print ''; + + // Sold credit note + //print ''; + //print ''; + } + + print '
'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).''.$langs->trans('Type').''.$langs->trans('BankAccount').''.$langs->trans('Amount').' 
'; + print ''.img_object($langs->trans('ShowPayment'),'payment').' '; + print dol_print_date($db->jdate($objp->dp),'day').''.$label.' '.$objp->num_paiement.''; + if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions'); + print ''.price($sign * $objp->amount).' 
'.$langs->trans("None").'
'; + if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits'); + else print $langs->trans('AlreadyPaid'); + print ' :'.price($totalpaye).' 
'; + if ($invoice->type == 2) print $langs->trans("CreditNote").' '; + if ($invoice->type == 3) print $langs->trans("Deposit").' '; + print $invoice->getNomUrl(0); + print ' :'.price($obj->amount_ttc).''; + print 'rowid.'">'.img_delete().''; + print '
'; + print $form->textwithpicto($langs->trans("Discount").':',$langs->trans("HelpEscompte"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + $text=$langs->trans("HelpAbandonOther"); + if ($object->close_note) $text.='

'.$langs->trans("Reason").':'.$object->close_note; + print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1); + print '
'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'.$langs->trans("Billed").' :'.price($object->total_ttc).' 
'; + if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay'); + else print $langs->trans('ExcessReceived'); + print ' :'.price($resteapayeraffiche).' 
'; + print $langs->trans('AlreadyPaidBack'); + print ' :'.price($sign * $totalpaye).' 
'.$langs->trans("Billed").' :'.price($sign * $object->total_ttc).' 
'; + if ($resteapayeraffiche <= 0) print $langs->trans('RemainderToPayBack'); + else print $langs->trans('ExcessPaydBack'); + print ' :'.price($sign * $resteapayeraffiche).' 
'.$langs->trans('TotalTTC').' :'.price($sign * $object->total_ttc).' 
'; + + // Margin Infos + if (! empty($conf->margin->enabled)) + { + print '
'; + $object->displayMarginInfos($object->statut > 0); + } + + print '
'; + print ''; + if ($object->type != 2 && $action != 'editconditions' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('PaymentConditionsShort'); + print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; + print '
'; + if ($object->type != 2) + { + if ($action == 'editconditions') + { + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); + } + else + { + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none'); + } + } + else + { + print ' '; + } + print '
'; + print ''; + if ($object->type != 2 && $action != 'editpaymentterm' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('DateMaxPayment'); + print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; + print '
'; + if ($object->type != 2) + { + if ($action == 'editpaymentterm') + { + $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm'); + } + else + { + print dol_print_date($object->date_lim_reglement,'daytext'); + if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! isset($object->am)) print img_warning($langs->trans('Late')); + } + } + else + { + print ' '; + } + print '
'; + print ''; + if ($action != 'editmode' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('PaymentMode'); + print 'id.'">'.img_edit($langs->trans('SetMode'),1).'
'; + print '
'; + if ($action == 'editmode') + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); + } + else + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none'); + } + print '
'.$langs->trans('AmountHT').''.price($object->total_ht,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('AmountVAT').''.price($object->total_tva,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($object->total_localtax1,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($object->total_localtax2,1,'',1,-1,-1,$conf->currency).'
'; + print ''; + if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('RevenueStamp'); + print 'id.'">'.img_edit($langs->trans('SetRevenuStamp'),1).'
'; + print '
'; + if ($action == 'editrevenuestamp') + { + print '
'; + print ''; + print ''; + print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code); + //print ''; + print ' '; + print '
'; + } + else + { + print price($object->revenuestamp,1,'',1,-1,-1,$conf->currency); + } + print '
'.$langs->trans('AmountTTC').''.price($object->total_ttc,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('Status').''.($object->getLibStatut(4,$totalpaye)).'
'; + + print ''; + if ($action != 'classify') + { + print ''; + } + print '
'; + print $langs->trans('Project'); + print 'id.'">'; + print img_edit($langs->trans('SetProject'),1); + print '
'; + + print '
'; + if ($action == 'classify') + { + $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid'); + } + else + { + $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none'); + } + print '
'; + // Convert date into timestamp format + if (in_array($extrafields->attribute_type[$key],array('date','datetime'))) + { + $value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key]; + } + + if ($action == 'edit_extras' && $user->rights->facture->creer) + { + print $extrafields->showInputField($key,$value); + } + else + { + print $extrafields->showOutputField($key,$value); + } + print '
'; + print ''; + print ''; + print '
'.img_picto('','edit').' '.$langs->trans('Modify').'

'; + + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) + { + $blocname = 'contacts'; + $title = $langs->trans('ContactsAddresses'); + include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; + } + + if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) + { + $blocname = 'notes'; + $title = $langs->trans('Notes'); + include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; + } + + /* + * Lines + */ + $result = $object->getLinesArray(); + + if (! empty($conf->use_javascript_ajax) && $object->statut == 0) + { + include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; + } + + print ''; + + // Show object lines + if (! empty($object->lines)) + $ret=$object->printObjectLines($action,$mysoc,$soc,$lineid,1); + + /* + * Form to add new line + */ + if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline') + { + $var=true; + + if ($conf->global->MAIN_FEATURES_LEVEL > 1) + { + // Add free or predefined products/services + $object->formAddObjectLine(1,$mysoc,$soc); + } + else + { + // Add free products/services + $object->formAddFreeProduct(1,$mysoc,$soc); + + // Add predefined products/services + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) + { + $var=!$var; + $object->formAddPredefinedProduct(1,$mysoc,$soc); + } + } + + $parameters=array(); + $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + } + + print "
\n"; + + print "\n"; + + + /* + * Boutons actions + */ + + if ($action != 'prerelance' && $action != 'presend') + { + if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline') + { + print '
'; + + // Editer une facture deja validee, sans paiement effectue et pas exporte en compta + if ($object->statut == 1) + { + // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees + $ventilExportCompta = $object->getVentilExportCompta(); + + if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) + { + if (! $objectidnext) + { + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) + { + print ''; + } + else + { + print '
'.$langs->trans('Modify').'
'; + } + } + else + { + print '
'.$langs->trans('Modify').'
'; + } + } + } + + // Reopen a standard paid invoice + if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3)) // A paid invoice (partially or completely) + { + if (! $objectidnext && $object->close_code != 'replaced') // Not replaced by another invoice + { + print ''; + } + else + { + print '
'.$langs->trans('ReOpen').'
'; + } + } + + // Validate + if ($object->statut == 0 && count($object->lines) > 0 && + ( + (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) + || ($object->type == 2 && $object->total_ttc <= 0)) + ) + { + if ($user->rights->facture->valider) + { + print ''; + } + } + + // Send by mail + if (($object->statut == 1 || $object->statut == 2)) + { + if ($objectidnext) + { + print '
'.$langs->trans('SendByMail').'
'; + } + else + { + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) + { + print ''; + } + else print ''; + } + } + + if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) // For backward compatibility + { + if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) + { + if ($objectidnext) + { + print '
'.$langs->trans('SendRemindByMail').'
'; + } + else + { + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) + { + print ''; + } + else print ''; + } + } + } + + // Create payment + if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) + { + if ($objectidnext) + { + print '
'.$langs->trans('DoPayment').'
'; + } + else + { + if ($resteapayer == 0) + { + print '
'.$langs->trans('DoPayment').'
'; + } + else + { + print ''; + } + } + } + + // Reverse back money or convert to reduction + if ($object->type == 2 || $object->type == 3) + { + // For credit note only + if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) + { + print ''; + } + // For credit note + if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0) + { + print ''; + } + // For deposit invoice + if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer) + { + print ''; + } + } + + // Classify paid (if not deposit and not credit note. Such invoice are "converted") + if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement && + (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) ) + { + print ''; + } + + // Classify 'closed not completely paid' (possible si validee et pas encore classee payee) + if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 + && $user->rights->facture->paiement) + { + if ($totalpaye > 0 || $totalcreditnotes > 0) + { + // If one payment or one credit note was linked to this invoice + print ''; + } + else + { + if ($objectidnext) + { + print '
'.$langs->trans('ClassifyCanceled').'
'; + } + else + { + print ''; + } + } + } + + // Clone + if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer) + { + print ''; + } + + // Clone as predefined + if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer) + { + if (! $objectidnext) + { + print ''; + } + } + + // Delete + if ($user->rights->facture->supprimer) + { + if (! $object->is_erasable()) + { + print ''; + } + else if ($objectidnext) + { + print ''; + } + elseif ($object->getSommePaiement()) + { + print ''; + } + else + { + print ''; + } + } + else + { + print ''; + } + + print '
'; + } + } + print '
'; + + if ($action != 'prerelance' && $action != 'presend') + { + print '
'; + //print '
'; + //print ''; // ancre + + /* + * Documents generes + */ + $filename=dol_sanitizeFileName($object->ref); + $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref); + $urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id; + $genallowed=$user->rights->facture->creer; + $delallowed=$user->rights->facture->supprimer; + + print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); + $somethingshown=$formfile->numoffiles; + + /* + * Linked object block + */ + $somethingshown=$object->showLinkedObjectBlock(); + + // Link for paypal payment + if (! empty($conf->paypal->enabled) && $object->statut != 0) + { + include_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; + print showPaypalPaymentUrl('invoice',$object->ref); + } + + print '
'; + //print '
'; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + $formactions=new FormActions($db); + $somethingshown=$formactions->showactions($object,'invoice',$socid); + + //print '
'; + print '
'; + } + else + { + /* + * Affiche formulaire mail + */ + + // By default if $action=='presend' + $titreform='SendBillByMail'; + $topicmail='SendBillRef'; + $action='send'; + $modelmail='facture_send'; + + if ($action == 'prerelance') // For backward compatibility + { + $titrefrom='SendReminderBillByMail'; + $topicmail='SendReminderBillRef'; + $action='relance'; + $modelmail='facture_relance'; + } + + $ref = dol_sanitizeFileName($object->ref); + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); + $file=$fileparams['fullname']; + + // Build document if it not exists + if (! $file || ! is_readable($file)) + { + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + $result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); + $file=$fileparams['fullname']; + } + + print '
'; + print_titre($langs->trans($titreform)); + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->fromtype = 'user'; + $formmail->fromid = $user->id; + $formmail->fromname = $user->getFullName($langs); + $formmail->frommail = $user->email; + $formmail->withfrom=1; + $liste=array(); + foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; + $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; + $formmail->withtocc=$liste; + $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; + $formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__'); + $formmail->withfile=2; + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + $formmail->substit['__FACREF__']=$object->ref; + $formmail->substit['__SIGNATURE__']=$user->signature; + $formmail->substit['__PERSONALIZED__']=''; + $formmail->substit['__CONTACTCIVNAME__']=''; + + //Find the good contact adress + $custcontact=''; + $contactarr=array(); + $contactarr=$object->liste_contact(-1,'external'); + + if (is_array($contactarr) && count($contactarr)>0) { + foreach($contactarr as $contact) { + if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { + + require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; + + $contactstatic=new Contact($db); + $contactstatic->fetch($contact['id']); + $custcontact=$contactstatic->getFullName($langs,1); + } + } + + if (!empty($custcontact)) { + $formmail->substit['__CONTACTCIVNAME__']=$custcontact; + } + } + + + // Tableau des parametres complementaires du post + $formmail->param['action']=$action; + $formmail->param['models']=$modelmail; + $formmail->param['facid']=$object->id; + $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + + // Init list of files + if (GETPOST("mode")=='init') + { + $formmail->clear_attached_files(); + $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); + } + + $formmail->show_form(); + + print '
'; + } + } + else + { + dol_print_error($db,$object->error); + } + } + + dol_htmloutput_mesg('',$mesgs); + + llxFooter(); + $db->close(); + ?> diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index a8f80335496..58e57d7f88c 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1298,7 +1298,7 @@ class Facture extends CommonInvoice } // If we decrament stock on invoice validation, we increment - if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_DELETE_INVOICE)) + if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse!=-1) { require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; $langs->load("agenda"); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9f8a2aabf7d..cdd9faf4bfa 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2310,7 +2310,7 @@ abstract class CommonObject /** * Function to say how many lines object contains * - * @param int $predefined -1=All, 0=Count free product/service only, 1=Count predefined product/service only + * @param int $predefined -1=All, 0=Count free product/service only, 1=Count predefined product/service only, 2=Count predefined product, 3=Count predefined service * @return int <0 if KO, 0 if no predefined products, nb of lines with predefined products if found */ function hasProductsOrServices($predefined=-1) @@ -2323,6 +2323,8 @@ abstract class CommonObject if ($predefined == -1) $qualified=1; if ($predefined == 1 && $val->fk_product > 0) $qualified=1; if ($predefined == 0 && $val->fk_product <= 0) $qualified=1; + if ($predefined == 2 && $val->fk_product > 0 && $val->product_type==0) $qualified=1; + if ($predefined == 3 && $val->fk_product > 0 && $val->product_type==1) $qualified=1; if ($qualified) $nb++; } dol_syslog(get_class($this).'::hasProductsOrServices we found '.$nb.' qualified lines of products/servcies'); diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 9f4923c82ce..8a836c7b3dc 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -87,4 +87,5 @@ PersonalStock=Personal stock %s ThisWarehouseIsPersonalStock=This warehouse represents personal stock of %s %s SelectWarehouseForStockDecrease=Choose warehouse to use for stock decrease SelectWarehouseForStockIncrease=Choose warehouse to use for stock increase +NoStockAction=No stock action LastWaitingSupplierOrders=Orders waiting for receptions \ No newline at end of file diff --git a/htdocs/langs/es_ES/stocks.lang b/htdocs/langs/es_ES/stocks.lang index d8ee6854a1d..be0bf800bb8 100644 --- a/htdocs/langs/es_ES/stocks.lang +++ b/htdocs/langs/es_ES/stocks.lang @@ -86,4 +86,5 @@ PersonalStock=Stock personal %s ThisWarehouseIsPersonalStock=Este almacén representa el stock personal de %s %s SelectWarehouseForStockDecrease=Seleccione el almacén a usar en el decremento de stock SelectWarehouseForStockIncrease=Seleccione el almacén a usar en el incremento de stock +NoStockAction=Sin acciones sobre el stock LastWaitingSupplierOrders=Pedidos en espera de recepción \ No newline at end of file diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index e8219f5faf8..1b2daaf9521 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -87,4 +87,5 @@ PersonalStock=Stock personnel %s ThisWarehouseIsPersonalStock=Cet entrepôt représente le stock personnel de %s %s SelectWarehouseForStockDecrease=Sélectionner l'entrepôt à utiliser pour la décrémentation du stock SelectWarehouseForStockIncrease=Sélectionner l'entrepôt à utiliser pour l'incrémentation du stock +NoStockAction=Pas d'action sur l'entrepot LastWaitingSupplierOrders=Commandes en attente de réception \ No newline at end of file diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php index 422f93eff16..45b0a129808 100644 --- a/htdocs/product/class/html.formproduct.class.php +++ b/htdocs/product/class/html.formproduct.class.php @@ -109,9 +109,10 @@ class FormProduct * @param int $empty 1=Can be empty, 0 if not * @param int $disabled 1=Select is disabled * @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0. + * @param string $empty_label Empty label if needed (only if $empty=1) * @return string HTML select */ - function selectWarehouses($selected='',$htmlname='idwarehouse',$filtertype='',$empty=0,$disabled=0,$fk_product=0) + function selectWarehouses($selected='',$htmlname='idwarehouse',$filtertype='',$empty=0,$disabled=0,$fk_product=0,$empty_label='') { global $langs,$user; @@ -120,7 +121,7 @@ class FormProduct $this->loadWarehouses($fk_product); $out=''; - print ''; - print ''; - } - - // TODO : use showOptionals($extrafields) function - foreach($extrafields->attribute_label as $key=>$label) - { - $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); - if ($extrafields->attribute_type[$key] == 'separate') - { - print $extrafields->showSeparator($key); - } - else - { - print 'attribute_required[$key])) print ' class="fieldrequired"'; - print '>'.$label.''; - - // Convert date into timestamp format - if (in_array($extrafields->attribute_type[$key],array('date','datetime'))) - { - $value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key]; - } - - if ($action == 'edit_extras' && $user->rights->propal->creer) - { - print $extrafields->showInputField($key,$value); - } - else - { - print $extrafields->showOutputField($key,$value); - } - print ''."\n"; - } - } - if(count($extrafields->attribute_label) > 0) { + if ($action == 'edit_extras') + { + print '
'; + print ''; + print ''; + print ''; + } + + + if ($action == 'edit_extras' && $user->rights->propal->creer) { + print $object->showOptionals($extrafields,'edit'); + } + else { + print $object->showOptionals($extrafields); + } + if ($action == 'edit_extras' && $user->rights->propal->creer) { print ''; @@ -2307,7 +2282,7 @@ else /* * Boutons actions - */ + */ if ($action != 'presend') { if ($user->societe_id == 0 && $action <> 'editline') @@ -2447,7 +2422,7 @@ else /* * Documents generes - */ + */ $comref = dol_sanitizeFileName($object->ref); $file = $conf->commande->dir_output . '/' . $comref . '/' . $comref . '.pdf'; $relativepath = $comref.'/'.$comref.'.pdf'; @@ -2461,7 +2436,7 @@ else /* * Linked object block - */ + */ $somethingshown=$object->showLinkedObjectBlock(); print '
'; @@ -2473,7 +2448,7 @@ else $somethingshown=$formactions->showactions($object,'order',$socid); //print ''; - print '
'; + print ''; } From 96043bd3d38a3ed4612f07baabce1dec765434bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Sat, 20 Apr 2013 05:37:52 +0200 Subject: [PATCH 39/97] Hide database password behind a password field --- htdocs/install/default.css | 4 ++-- htdocs/install/fileconf.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/install/default.css b/htdocs/install/default.css index b5f8773db75..d6c354e092c 100644 --- a/htdocs/install/default.css +++ b/htdocs/install/default.css @@ -61,10 +61,10 @@ padding: 0px 0px 0px 0px; margin: 0px 0px 0px 0px; } -input[type=text] { +input[type=text], input[type=password] { border: 1px solid #ACBCBB; } -input[type=text]:focus, textarea:focus, select:focus { +input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus { border: 1px solid #ACBCBB; box-shadow: 0 0 5px #C091AF; } diff --git a/htdocs/install/fileconf.php b/htdocs/install/fileconf.php index 5e58d07d28c..7a8e1ad1ee9 100644 --- a/htdocs/install/fileconf.php +++ b/htdocs/install/fileconf.php @@ -406,7 +406,7 @@ if (! empty($force_install_message)) trans("Password"); ?> - trans("Password"); ?> - begin(); - $res=$fuser->update_note($_POST["note"],$user); + $res=$fuser->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); if ($res < 0) { $mesg='
'.$adh->error.'
'; From 62f0f6011fb29a1299b0adb00bb558b6ab9359a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Sat, 20 Apr 2013 06:35:11 +0200 Subject: [PATCH 44/97] Fixed note typo --- htdocs/contrat/note.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/contrat/note.php b/htdocs/contrat/note.php index ee66e4583f7..c8edf493f63 100644 --- a/htdocs/contrat/note.php +++ b/htdocs/contrat/note.php @@ -50,7 +50,7 @@ $object->fetch($id,$ref); if ($action == 'setnote_public' && $user->rights->contrat->creer) { - $result=$object->update_note(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_public')), ENT_QUOTES),'_pubic'); + $result=$object->update_note(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_public')), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } From a564edbb871eafaeb44a8badabc3cc281a6f74ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Sat, 20 Apr 2013 06:36:07 +0200 Subject: [PATCH 45/97] Fixed private note update --- htdocs/projet/class/task.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 0adc21eb6cc..ac29870106b 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -1064,7 +1064,7 @@ class Task extends CommonObject } $this->db->begin(); - $res=$clone_task->update_note(dol_html_entity_decode($clone_task->note_private, ENT_QUOTES)); + $res=$clone_task->update_note(dol_html_entity_decode($clone_task->note_private, ENT_QUOTES), '_private'); if ($res < 0) { $this->error.=$clone_task->error; From 13c48d49700fd2ec2ea5d055c2da0682b2c59c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Sat, 20 Apr 2013 06:39:03 +0200 Subject: [PATCH 46/97] Fixed more private note updates --- htdocs/fichinter/fiche.php | 2 +- htdocs/projet/note.php | 2 +- htdocs/projet/tasks/note.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/fichinter/fiche.php b/htdocs/fichinter/fiche.php index 70fed335c93..0684c4695ce 100644 --- a/htdocs/fichinter/fiche.php +++ b/htdocs/fichinter/fiche.php @@ -386,7 +386,7 @@ else if ($action == 'setnote_public' && $user->rights->ficheinter->creer) else if ($action == 'setnote_private' && $user->rights->ficheinter->creer) { $object->fetch($id); - $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/projet/note.php b/htdocs/projet/note.php index 26eafbc16d2..dddab2a5e79 100644 --- a/htdocs/projet/note.php +++ b/htdocs/projet/note.php @@ -63,7 +63,7 @@ if ($action == 'setnote_public' && $user->rights->projet->creer) if ($action == 'setnote_private' && $user->rights->projet->creer) { $object->fetch($id); - $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/projet/tasks/note.php b/htdocs/projet/tasks/note.php index 9931bde0510..1b6bebeb9d5 100644 --- a/htdocs/projet/tasks/note.php +++ b/htdocs/projet/tasks/note.php @@ -93,7 +93,7 @@ if ($action == 'setnote_public' && ! empty($permission)) else if ($action == 'setnote_private' && ! empty($permission)) { - $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private'); if ($result < 0) dol_print_error($db,$object->error); } From 75194ddb577c78f21b6dcbba852fb6991a8f9376 Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 20 Apr 2013 07:05:31 +0200 Subject: [PATCH 47/97] Ifo user visibility and maxlength product label regarding db column size --- htdocs/core/lib/usergroups.lib.php | 7 ++++--- htdocs/product/fiche.php | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index b9f12ca3f6c..ab53f0272dc 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -78,14 +78,15 @@ function user_prepare_head($object) $head[$h][2] = 'clicktodial'; $h++; } - + print $user->societe_id; // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab // $this->tabs = array('entity:-tabname); to remove a tab complete_head_from_modules($conf,$langs,$object,$head,$h,'user'); - - if (! empty($user->societe_id)) + + //Info on users is visible only by internal user + if (empty($user->societe_id)) { $head[$h][0] = DOL_URL_ROOT.'/user/note.php?id='.$object->id; $head[$h][1] = $langs->trans("Note"); diff --git a/htdocs/product/fiche.php b/htdocs/product/fiche.php index e8775f44621..143ed6e9551 100644 --- a/htdocs/product/fiche.php +++ b/htdocs/product/fiche.php @@ -693,7 +693,7 @@ else print ''; // Label - print ''.$langs->trans("Label").''; + print ''.$langs->trans("Label").''; // On sell print ''.$langs->trans("Status").' ('.$langs->trans("Sell").')'; @@ -866,7 +866,7 @@ else print ''.$langs->trans("Ref").''; // Label - print ''.$langs->trans("Label").''; + print ''.$langs->trans("Label").''; // Status print ''.$langs->trans("Status").' ('.$langs->trans("Sell").')'; From 62c9366d69bbd8688c9c8265e8aefcbd34b38735 Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 20 Apr 2013 07:21:26 +0200 Subject: [PATCH 48/97] fix debug --- htdocs/core/lib/usergroups.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index ab53f0272dc..10099ab7feb 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -78,7 +78,7 @@ function user_prepare_head($object) $head[$h][2] = 'clicktodial'; $h++; } - print $user->societe_id; + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab From f2bd1461b24b81dddc47eb9e63606cae6a95b4af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Sat, 20 Apr 2013 07:33:10 +0200 Subject: [PATCH 49/97] Improved reports Added amount without VAT for "CREANCES-DETTES" mode Added turnover by products/services Added categories filter for users and products/services Added period management Added list sorting --- htdocs/compta/stats/cabyuser.php | 248 +++++++++++++++----- htdocs/compta/stats/casoc.php | 300 ++++++++++++++++++------ htdocs/core/menus/standard/eldy.lib.php | 2 + htdocs/langs/en_US/compta.lang | 3 +- htdocs/langs/en_US/errors.lang | 3 +- htdocs/langs/fr_FR/compta.lang | 3 +- htdocs/langs/fr_FR/errors.lang | 3 +- 7 files changed, 427 insertions(+), 135 deletions(-) diff --git a/htdocs/compta/stats/cabyuser.php b/htdocs/compta/stats/cabyuser.php index 86f16cf3684..d4ef827ad0f 100644 --- a/htdocs/compta/stats/cabyuser.php +++ b/htdocs/compta/stats/cabyuser.php @@ -2,6 +2,7 @@ /* Copyright (C) 2001-2003 Rodolphe Quiedeville * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2013 Antoine Iauch * * 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 @@ -46,6 +47,12 @@ if (! $sortfield) $sortfield="name"; // Date range $year=GETPOST("year"); $month=GETPOST("month"); +$date_startyear = GETPOST("date_startyear"); +$date_startmonth = GETPOST("date_startmonth"); +$date_startday = GETPOST("date_startday"); +$date_endyear = GETPOST("date_endyear"); +$date_endmonth = GETPOST("date_endmonth"); +$date_endday = GETPOST("date_endday"); if (empty($year)) { $year_current = strftime("%Y",dol_now()); @@ -89,9 +96,34 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end else { // TODO We define q - } +$commonparams=array(); +$commonparams['modecompta']=$modecompta; +$commonparams['sortorder'] = $sortorder; +$commonparams['sortfield'] = $sortfield; + +$headerparams = array(); +$headerparams['date_startyear'] = $date_startyear; +$headerparams['date_startmonth'] = $date_startmonth; +$headerparams['date_startday'] = $date_startday; +$headerparams['date_endyear'] = $date_endyear; +$headerparams['date_endmonth'] = $date_endmonth; +$headerparams['date_endday'] = $date_endday; +$headerparams['q'] = $q; + +$tableparams = array(); +$tableparams['search_categ'] = $selected_cat; +$tableparams['subcat'] = ($subcat === true)?'yes':''; + +// Adding common parameters +$allparams = array_merge($commonparams, $headerparams, $tableparams); +$headerparams = array_merge($commonparams, $headerparams); +$tableparams = array_merge($commonparams, $tableparams); + +foreach($allparams as $key => $value) { + $paramslink .= '&' . $key . '=' . $value; +} /* * View @@ -102,9 +134,8 @@ llxHeader(); $form=new Form($db); -// Affiche en-tete du rapport -if ($modecompta=="CREANCES-DETTES") -{ +// Show report header +if ($modecompta=="CREANCES-DETTES") { $nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByUserAuthorOfInvoice"); $nom.='
('.$langs->trans("SeeReportInInputOutputMode",'','').')'; $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); @@ -114,8 +145,7 @@ if ($modecompta=="CREANCES-DETTES") else $description.= $langs->trans("DepositsAreIncluded"); $builddate=time(); //$exportlink=$langs->trans("NotYetAvailable"); -} -else { +} else { $nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByUserAuthorOfInvoice"); $nom.='
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); @@ -131,31 +161,42 @@ if (! empty($modecompta)) $moreparam['modecompta']=$modecompta; report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$moreparam); -// Charge tableau -$catotal=0; -if ($modecompta == 'CREANCES-DETTES') +// Show array +print ''; +// Extra parameters management +foreach($headerparams as $key => $value) { + print ''; +} + +$catotal=0; +if ($modecompta == 'CREANCES-DETTES') { $sql = "SELECT u.rowid as rowid, u.lastname as name, u.firstname as firstname, sum(f.total) as amount, sum(f.total_ttc) as amount_ttc"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.fk_user_author = u.rowid"; $sql.= " WHERE f.fk_statut in (1,2)"; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)"; - else $sql.= " AND f.type IN (0,1,2,3)"; - if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; -} -else -{ + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql.= " AND f.type IN (0,1,2)"; + } else { + $sql.= " AND f.type IN (0,1,2,3)"; + } + if ($date_start && $date_end) { + $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; + } +} else { /* * Liste des paiements (les anciens paiements ne sont pas vus par cette requete car, sur les * vieilles versions, ils n'etaient pas lies via paiement_facture. On les ajoute plus loin) */ - $sql = "SELECT u.rowid as rowid, u.lastname as name, u.firstname as firstname, sum(pf.amount) as amount_ttc"; + $sql = "SELECT u.rowid as rowid, u.lastname as name, u.firstname as firstname, sum(DISTINCT pf.amount) as amount_ttc"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u" ; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.fk_user_author = u.rowid "; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_facture = f.rowid"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement as p ON p.rowid = pf.fk_paiement"; $sql.= " WHERE 1=1"; - if ($date_start && $date_end) $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + if ($date_start && $date_end) { + $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + } } $sql.= " AND f.entity = ".$conf->entity; if ($socid) $sql.= " AND f.fk_soc = ".$socid; @@ -163,27 +204,25 @@ $sql .= " GROUP BY u.rowid, u.lastname, u.firstname"; $sql .= " ORDER BY u.rowid"; $result = $db->query($sql); -if ($result) -{ +if ($result) { $num = $db->num_rows($result); $i=0; - while ($i < $num) - { + while ($i < $num) { $obj = $db->fetch_object($result); - $amount[$obj->rowid] = $obj->amount_ttc; - $name[$obj->rowid] = $obj->lastname.' '.$obj->firstname; - $catotal+=$obj->amount_ttc; - $i++; + $amount_ht[$obj->rowid] = $obj->amount; + $amount[$obj->rowid] = $obj->amount_ttc; + $name[$obj->rowid] = $obj->name.' '.$obj->firstname; + $catotal_ht+=$obj->amount; + $catotal+=$obj->amount_ttc; + $i++; } -} -else { +} else { dol_print_error($db); } -// On ajoute les paiements ancienne version, non lies par paiement_facture donc sans user -if ($modecompta != 'CREANCES-DETTES') -{ - $sql = "SELECT -1 as rowidx, '' as lastname, '' as firstname, sum(p.amount) as amount_ttc"; +// Adding old-version payments, non-bound by "paiement_facture" then without User +if ($modecompta != 'CREANCES-DETTES') { + $sql = "SELECT -1 as rowidx, '' as name, '' as firstname, sum(DISTINCT p.amount) as amount_ttc"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; $sql.= ", ".MAIN_DB_PREFIX."bank_account as ba"; $sql.= ", ".MAIN_DB_PREFIX."paiement as p"; @@ -192,42 +231,86 @@ if ($modecompta != 'CREANCES-DETTES') $sql.= " AND p.fk_bank = b.rowid"; $sql.= " AND b.fk_account = ba.rowid"; $sql.= " AND ba.entity = ".$conf->entity; - if ($date_start && $date_end) $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + if ($date_start && $date_end) { + $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + } $sql.= " GROUP BY rowidx, name, firstname"; $sql.= " ORDER BY rowidx"; $result = $db->query($sql); - if ($result) - { + if ($result) { $num = $db->num_rows($result); $i=0; - while ($i < $num) - { + while ($i < $num) { $obj = $db->fetch_object($result); $amount[$obj->rowidx] = $obj->amount_ttc; - $name[$obj->rowidx] = $obj->lastname.' '.$obj->firstname; + $name[$obj->rowidx] = $obj->name.' '.$obj->firstname; $catotal+=$obj->amount_ttc; $i++; } - } - else { + } else { dol_print_error($db); } } - $i = 0; print ""; print ""; -print_liste_field_titre($langs->trans("User"),$_SERVER["PHP_SELF"],"name","",'&year='.($year).'&modecompta='.$modecompta,"",$sortfield,$sortorder); -print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"amount_ttc","",'&year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Percentage"),$_SERVER["PHP_SELF"],"amount_ttc","",'&year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("OtherStatistics"),$_SERVER["PHP_SELF"],"","","",'align="center" width="20%"'); +print_liste_field_titre( + $langs->trans("User"), + $_SERVER["PHP_SELF"], + "name", + "", + $paramslink, + "", + $sortfield, + $sortorder + ); +if ($modecompta == 'CREANCES-DETTES') { + print_liste_field_titre( + $langs->trans('AmountHT'), + $_SERVER["PHP_SELF"], + "amount_ht", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + } else { + print ''; +} +print_liste_field_titre( + $langs->trans("AmountTTC"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); +print_liste_field_titre( + $langs->trans("Percentage"), + $_SERVER["PHP_SELF"],"amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); +print_liste_field_titre( + $langs->trans("OtherStatistics"), + $_SERVER["PHP_SELF"], + "", + "", + "", + 'align="center" width="20%"' + ); print "\n"; $var=true; -if (count($amount)) -{ +if (count($amount)) { $arrayforsort=$name; // We define arrayforsort @@ -239,6 +322,14 @@ if (count($amount)) arsort($name); $arrayforsort=$name; } + if ($sortfield == 'amount_ht' && $sortorder == 'asc') { + asort($amount_ht); + $arrayforsort=$amount_ht; + } + if ($sortfield == 'amount_ht' && $sortorder == 'desc') { + arsort($amount_ht); + $arrayforsort=$amount_ht; + } if ($sortfield == 'amount_ttc' && $sortorder == 'asc') { asort($amount); $arrayforsort=$amount; @@ -248,8 +339,7 @@ if (count($amount)) $arrayforsort=$amount; } - foreach($arrayforsort as $key => $value) - { + foreach($arrayforsort as $key => $value) { $var=!$var; print ""; @@ -257,23 +347,44 @@ if (count($amount)) $fullname=$name[$key]; if ($key >= 0) { $linkname=''.img_object($langs->trans("ShowUser"),'user').' '.$fullname.''; - } - else { + } else { $linkname=$langs->trans("PaymentsNotLinkedToUser"); } print "\n"; - // Amount + // Amount w/o VAT print ''; + + // Amount with VAT + print ''; @@ -283,17 +394,30 @@ if (count($amount)) // Other stats print ''; - print "\n"; $i++; } // Total - print ''; + print ''; + print ''; + if ($modecompta != 'CREANCES-DETTES') { + print ''; + } else { + print ''; + } + print ''; + print ''; print ''; print ''; diff --git a/htdocs/compta/stats/casoc.php b/htdocs/compta/stats/casoc.php index b658cf636d6..32d527cc779 100644 --- a/htdocs/compta/stats/casoc.php +++ b/htdocs/compta/stats/casoc.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2007 Franky Van Liedekerke + * Copyright (C) 2013 Antoine Iauch * * 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 @@ -27,8 +28,10 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; $langs->load("companies"); +$langs->load("categories"); // Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES') $modecompta = $conf->global->COMPTA_MODE; @@ -41,6 +44,13 @@ if (! $sortfield) $sortfield="nom"; $socid = GETPOST('socid','int'); +// Category +$selected_cat = (int)GETPOST('search_categ', 'int'); +$subcat = false; +if (GETPOST('subcat', 'alpha') === 'yes') { + $subcat = true; +} + // Security check if ($user->societe_id > 0) $socid = $user->societe_id; if (! empty($conf->comptabilite->enabled)) $result=restrictedArea($user,'compta','','','resultat'); @@ -49,6 +59,12 @@ if (! empty($conf->accounting->enabled)) $result=restrictedArea($user,'accountin // Date range $year=GETPOST("year"); $month=GETPOST("month"); +$date_startyear = GETPOST("date_startyear"); +$date_startmonth = GETPOST("date_startmonth"); +$date_startday = GETPOST("date_startday"); +$date_endyear = GETPOST("date_endyear"); +$date_endmonth = GETPOST("date_endmonth"); +$date_endday = GETPOST("date_endday"); if (empty($year)) { $year_current = strftime("%Y",dol_now()); @@ -92,10 +108,34 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end else { // TODO We define q - } +$commonparams=array(); +$commonparams['modecompta']=$modecompta; +$commonparams['sortorder'] = $sortorder; +$commonparams['sortfield'] = $sortfield; +$headerparams = array(); +$headerparams['date_startyear'] = $date_startyear; +$headerparams['date_startmonth'] = $date_startmonth; +$headerparams['date_startday'] = $date_startday; +$headerparams['date_endyear'] = $date_endyear; +$headerparams['date_endmonth'] = $date_endmonth; +$headerparams['date_endday'] = $date_endday; +$headerparams['q'] = $q; + +$tableparams = array(); +$tableparams['search_categ'] = $selected_cat; +$tableparams['subcat'] = ($subcat === true)?'yes':''; + +// Adding common parameters +$allparams = array_merge($commonparams, $headerparams, $tableparams); +$headerparams = array_merge($commonparams, $headerparams); +$tableparams = array_merge($commonparams, $tableparams); + +foreach($allparams as $key => $value) { + $paramslink .= '&' . $key . '=' . $value; +} /* * View @@ -105,8 +145,9 @@ llxHeader(); $form=new Form($db); $thirdparty_static=new Societe($db); +$formother = new FormOther($db); -// Affiche en-tete de rapport +// Show report header if ($modecompta=="CREANCES-DETTES") { $nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByThirdParties"); @@ -118,8 +159,7 @@ if ($modecompta=="CREANCES-DETTES") else $description.= $langs->trans("DepositsAreIncluded"); $builddate=time(); //$exportlink=$langs->trans("NotYetAvailable"); -} -else { +} else { $nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByThirdParties"); $nom.='
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); @@ -129,26 +169,44 @@ else { $builddate=time(); //$exportlink=$langs->trans("NotYetAvailable"); } -$moreparam=array(); -if (! empty($modecompta)) $moreparam['modecompta']=$modecompta; -report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$moreparam); + +report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$tableparams); -// Charge tableau +// Show Array $catotal=0; -if ($modecompta == 'CREANCES-DETTES') -{ - $sql = "SELECT s.rowid as socid, s.nom as name, sum(f.total) as amount, sum(f.total_ttc) as amount_ttc"; +if ($modecompta == 'CREANCES-DETTES') { + $sql = "SELECT DISTINCT s.rowid as socid, s.nom as name,"; + $sql.= " sum(DISTINCT f.total) as amount, sum(DISTINCT f.total_ttc) as amount_ttc"; $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - $sql.= ", ".MAIN_DB_PREFIX."facture as f"; + $sql.= " JOIN ".MAIN_DB_PREFIX."facture as f"; + if ($selected_cat === -2) { + $sql.= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON s.rowid = cs.fk_societe"; + } + if ($selected_cat && $selected_cat !== -2) { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = ".$selected_cat; + if (subcat) { + $sql.=" OR c.fk_parent = " . $selected_cat; + } + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON cs.fk_categorie = c.rowid"; + } $sql.= " WHERE f.fk_statut in (1,2)"; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)"; - else $sql.= " AND f.type IN (0,1,2,3)"; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql.= " AND f.type IN (0,1,2)"; + } else { + $sql.= " AND f.type IN (0,1,2,3)"; + } $sql.= " AND f.fk_soc = s.rowid"; - if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; -} -else -{ + if ($date_start && $date_end) { + $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; + } + if ($selected_cat === -2) { + $sql.=" AND cs.fk_societe is null"; + } + if ($selected_cat && $selected_cat !== -2) { + $sql.= " AND cs.fk_societe = s.rowid"; + } + } else { /* * Liste des paiements (les anciens paiements ne sont pas vus par cette requete car, sur les * vieilles versions, ils n'etaient pas lies via paiement_facture. On les ajoute plus loin) @@ -161,7 +219,9 @@ else $sql .= " WHERE p.rowid = pf.fk_paiement"; $sql.= " AND pf.fk_facture = f.rowid"; $sql.= " AND f.fk_soc = s.rowid"; - if ($date_start && $date_end) $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + if ($date_start && $date_end) { + $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + } } $sql.= " AND f.entity = ".$conf->entity; if ($socid) $sql.= " AND f.fk_soc = ".$socid; @@ -169,27 +229,26 @@ $sql.= " GROUP BY s.rowid, s.nom"; $sql.= " ORDER BY s.rowid"; $result = $db->query($sql); -if ($result) -{ +if ($result) { $num = $db->num_rows($result); $i=0; - while ($i < $num) - { + while ($i < $num) { $obj = $db->fetch_object($result); - $amount[$obj->socid] += $obj->amount_ttc; - $name[$obj->socid] = $obj->name; - $catotal+=$obj->amount_ttc; - $i++; + $amount_ht[$obj->socid] = $obj->amount; + $amount[$obj->socid] = $obj->amount_ttc; + $name[$obj->socid] = $obj->name.' '.$obj->firstname; + $catotal_ht+=$obj->amount; + $catotal+=$obj->amount_ttc; + $i++; + } -} -else { +} else { dol_print_error($db); } // On ajoute les paiements anciennes version, non lies par paiement_facture -if ($modecompta != 'CREANCES-DETTES') -{ - $sql = "SELECT '0' as socid, 'Autres' as name, sum(p.amount) as amount_ttc"; +if ($modecompta != 'CREANCES-DETTES') { + $sql = "SELECT '0' as socid, 'Autres' as name, sum(DISTINCT p.amount) as amount_ttc"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; $sql.= ", ".MAIN_DB_PREFIX."bank_account as ba"; $sql.= ", ".MAIN_DB_PREFIX."paiement as p"; @@ -203,20 +262,17 @@ if ($modecompta != 'CREANCES-DETTES') $sql.= " ORDER BY name"; $result = $db->query($sql); - if ($result) - { + if ($result) { $num = $db->num_rows($result); $i=0; - while ($i < $num) - { + while ($i < $num) { $obj = $db->fetch_object($result); $amount[$obj->rowid] += $obj->amount_ttc; $name[$obj->rowid] = $obj->name; $catotal+=$obj->amount_ttc; $i++; } - } - else { + } else { dol_print_error($db); } } @@ -224,20 +280,87 @@ if ($modecompta != 'CREANCES-DETTES') // Show array $i = 0; +print ''; +// Extra parameters management +foreach($headerparams as $key => $value) +{ + print ''; +} print "
".$linkname."'; if ($modecompta != 'CREANCES-DETTES') { - if ($key > 0) print ''; - else print ''; + if ($key > 0) { + print ''; + } else { + print ''; + } + } else { + if ($key > 0) { + print ''; + } else { + print ''; + } + print price($amount_ht[$key]); } - else - { - if ($key > 0) print ''; - else print ''; + print ''; + if ($modecompta != 'CREANCES-DETTES') { + if ($key > 0) { + print ''; + } else { + print ''; + } + } else { + if ($key > 0) { + print ''; + } else { + print ''; + } } print price($amount[$key]); print ''; - if (! empty($conf->propal->enabled) && $key>0) print ' '.img_picto($langs->trans("ProposalStats"),"stats").' '; - if (! empty($conf->commande->enabled) && $key>0) print ' '.img_picto($langs->trans("OrderStats"),"stats").' '; - if (! empty($conf->facture->enabled) && $key>0) print ' '.img_picto($langs->trans("InvoiceStats"),"stats").' '; + if (! empty($conf->propal->enabled) && $key>0) { + print ' '.img_picto($langs->trans("ProposalStats"),"stats").' '; + } + if (! empty($conf->commande->enabled) && $key>0) { + print ' '.img_picto($langs->trans("OrderStats"),"stats").' '; + } + if (! empty($conf->facture->enabled) && $key>0) { + print ' '.img_picto($langs->trans("InvoiceStats"),"stats").' '; + } print '
'.$langs->trans("Total").''.price($catotal).' 
'.$langs->trans("Total").''.price($catotal_ht).''.price($catotal).'  
"; -print ""; -print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"nom","",'&year='.($year).'&modecompta='.$modecompta,"",$sortfield,$sortorder); -print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"amount_ttc","",'&year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Percentage"),$_SERVER["PHP_SELF"],"amount_ttc","",'&year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("OtherStatistics"),$_SERVER["PHP_SELF"],"","","",'align="center" width="20%"'); + // Category filter +print ''; +print ''; +print ''; +print ''; + // Array titles +print ""; +print_liste_field_titre( + $langs->trans("Company"), + $_SERVER["PHP_SELF"], + "nom", + "", + $paramslink, + "", + $sortfield,$sortorder + ); +if ($modecompta == 'CREANCES-DETTES') { + print_liste_field_titre( + $langs->trans('AmountHT'), + $_SERVER["PHP_SELF"], + "amount_ht", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + } else { + print ''; +} +print_liste_field_titre( + $langs->trans("AmountTTC"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); +print_liste_field_titre( + $langs->trans("Percentage"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); +print_liste_field_titre( + $langs->trans("OtherStatistics"), + $_SERVER["PHP_SELF"], + "", + "", + "", + 'align="center" width="20%"' + ); print "\n"; $var=true; -if (count($amount)) -{ +if (count($amount)) { $arrayforsort=$name; - - // On definit tableau arrayforsort + // Defining array arrayforsort if ($sortfield == 'nom' && $sortorder == 'asc') { asort($name); $arrayforsort=$name; @@ -246,6 +369,14 @@ if (count($amount)) arsort($name); $arrayforsort=$name; } + if ($sortfield == 'amount_ht' && $sortorder == 'asc') { + asort($amount_ht); + $arrayforsort=$amount_ht; + } + if ($sortfield == 'amount_ht' && $sortorder == 'desc') { + arsort($amount_ht); + $arrayforsort=$amount_ht; + } if ($sortfield == 'amount_ttc' && $sortorder == 'asc') { asort($amount); $arrayforsort=$amount; @@ -255,8 +386,7 @@ if (count($amount)) $arrayforsort=$amount; } - foreach($arrayforsort as $key=>$value) - { + foreach($arrayforsort as $key=>$value) { $var=!$var; print ""; @@ -267,23 +397,43 @@ if (count($amount)) $thirdparty_static->name=$fullname; $thirdparty_static->client=1; $linkname=$thirdparty_static->getNomUrl(1,'customer'); - } - else { + } else { $linkname=$langs->trans("PaymentsNotLinkedToInvoice"); } print "\n"; - // Amount + // Amount w/o VAT print ''; + + // Amount with VAT + print ''; - - print "\n"; - $i++; + print "\n"; + $i++; } // Total - print ''; + print ''; + print ''; + if ($modecompta != 'CREANCES-DETTES') { + print ''; + } else { + print ''; + } + print ''; + print ''; print ''; print ''; @@ -312,8 +475,7 @@ if (count($amount)) } print "
'; +print $langs->trans("Category") . ': ' . $formother->select_categories(2, $selected_cat, 'search_categ', true); +print ' '; +print $langs->trans("SubCats") . '? '; +print ''; +print ''; +print '
".$linkname."'; - if ($modecompta != 'CREANCES-DETTES') - { - if ($key > 0) print ''; - else print ''; + if ($modecompta != 'CREANCES-DETTES') { + if ($key > 0) { + print ''; + } else { + print ''; + } + } else { + if ($key > 0) { + print ''; + } else { + print ''; + } + print price($amount_ht[$key]); } - else - { - if ($key > 0) print ''; - else print ''; + print ''; + if ($modecompta != 'CREANCES-DETTES') { + if ($key > 0) { + print ''; + } else { + print ''; + } + } else { + if ($key > 0) { + print ''; + } else { + print ''; + } } print price($amount[$key]); print ''; @@ -294,17 +444,30 @@ if (count($amount)) // Other stats print ''; - if (! empty($conf->propal->enabled) && $key>0) print ' '.img_picto($langs->trans("ProposalStats"),"stats").' '; - if (! empty($conf->commande->enabled) && $key>0) print ' '.img_picto($langs->trans("OrderStats"),"stats").' '; - if (! empty($conf->facture->enabled) && $key>0) print ' '.img_picto($langs->trans("InvoiceStats"),"stats").' '; + if (! empty($conf->propal->enabled) && $key>0) { + print ' '.img_picto($langs->trans("ProposalStats"),"stats").' '; + } + if (! empty($conf->commande->enabled) && $key>0) { + print ' '.img_picto($langs->trans("OrderStats"),"stats").' '; + } + if (! empty($conf->facture->enabled) && $key>0) { + print ' '.img_picto($langs->trans("InvoiceStats"),"stats").' '; + } print '
'.$langs->trans("Total").''.price($catotal).' 
'.$langs->trans("Total").''.price($catotal_ht).''.price($catotal).'  
"; -print '
'; - +print ''; llxFooter(); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 641925f42a9..f4d7f3581db 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -852,6 +852,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu */ if (empty($leftmenu) || $leftmenu=="ca") $newmenu->add("/compta/stats/casoc.php?leftmenu=ca",$langs->trans("ByCompanies"),2,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire); if (empty($leftmenu) || $leftmenu=="ca") $newmenu->add("/compta/stats/cabyuser.php?leftmenu=ca",$langs->trans("ByUsers"),2,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || $leftmenu=="ca") $newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=ca", $langs->trans("ByProductsAndServices"),2,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire); + // Journaux //if ($leftmenu=="ca") $newmenu->add("/compta/journaux/index.php?leftmenu=ca",$langs->trans("Journaux"),1,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire); diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index 5e3a36e5051..a1b3cba5004 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -152,4 +152,5 @@ Pcg_type=Pcg type Pcg_subtype=Pcg subtype InvoiceLinesToDispatch=Invoice lines to dispatch InvoiceDispatched=Dispatched invoices -AccountancyDashboard=Accountancy summary \ No newline at end of file +AccountancyDashboard=Accountancy summary +ByProductsAndServices=By products and services diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 48795ba2ce7..3cfee357c81 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -136,4 +136,5 @@ WarningLockFileDoesNotExists=Warning, once setup is finished, you must disable i WarningUntilDirRemoved=All security warnings (visible by admin users only) will remain active as long as the vulnerability is present (or that constant MAIN_REMOVE_INSTALL_WARNING is added in Setup->Other setup). WarningCloseAlways=Warning, closing is done even if amount differs between source and target elements. Enable this feature with caution. WarningUsingThisBoxSlowDown=Warning, using this box slow down seriously all pages showing the box. -WarningClickToDialUserSetupNotComplete=Setup of ClickToDial information for your user are not complete (see tab ClickToDial onto your user card). \ No newline at end of file +WarningClickToDialUserSetupNotComplete=Setup of ClickToDial information for your user are not complete (see tab ClickToDial onto your user card). +WarningNotRelevant=Irrelevant operation for this dataset diff --git a/htdocs/langs/fr_FR/compta.lang b/htdocs/langs/fr_FR/compta.lang index 1491a7820f4..227b6b734ad 100644 --- a/htdocs/langs/fr_FR/compta.lang +++ b/htdocs/langs/fr_FR/compta.lang @@ -163,4 +163,5 @@ Pcg_type=Classe de compte Pcg_subtype=Sous classe de compte InvoiceLinesToDispatch=Lignes de factures à ventiler InvoiceDispatched=Factures ventilées -AccountancyDashboard=Synthèse compta/tréso \ No newline at end of file +AccountancyDashboard=Synthèse compta/tréso +ByProductsAndServices=Par produits et services diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index f1316e03d13..5081f66d5f7 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -137,4 +137,5 @@ WarningLockFileDoesNotExists=Attention, une fois l'installation terminée, les o WarningUntilDirRemoved=Les alertes de sécurité sont visibles par les administrateurs uniquement et resteront actives tant que la vulnérabilité sera avérée (ou que la constante MAIN_REMOVE_INSTALL_WARNING aura été définie dans Configuration->Divers) WarningCloseAlways=Attention, la fermeture se fait même lorsque le montant diffère. N'activez cette fonctionnalité qu'en connaissance de cause. WarningUsingThisBoxSlowDown=Attention, l'utilisation de cette boite provoque de sérieux ralentissement des pages affichant cette boite. -WarningClickToDialUserSetupNotComplete=La configuration ClickToDial pour votre compte utilisateur n'est pas complète (voir l'onglet ClickToDial sur votre fiche utilisateur) \ No newline at end of file +WarningClickToDialUserSetupNotComplete=La configuration ClickToDial pour votre compte utilisateur n'est pas complète (voir l'onglet ClickToDial sur votre fiche utilisateur) +WarningNotRelevant=Opération non pertinente pour cet ensemble de données From 413ee7ec784701891ca7fd55eade32de51db8301 Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 20 Apr 2013 10:44:01 +0200 Subject: [PATCH 50/97] Add hidden option MAIN_ODT_AS_PDF to save ODT as PDF (only if libreoffice/jodconverter/exec shell right) --- .../doc/doc_generic_order_odt.modules.php | 8 +++- .../doc/doc_generic_invoice_odt.modules.php | 8 +++- .../pdf/doc_generic_project_odt.modules.php | 10 +++-- .../doc/doc_generic_proposal_odt.modules.php | 8 +++- .../societe/doc/doc_generic_odt.modules.php | 8 +++- htdocs/includes/odtphp/odf.php | 42 ++++++++++++++++--- htdocs/includes/odtphp/odt2pdf.sh | 4 +- 7 files changed, 70 insertions(+), 18 deletions(-) mode change 100644 => 100755 htdocs/includes/odtphp/odt2pdf.sh diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php index 00658b7b9cb..3330f491e70 100644 --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -519,8 +519,12 @@ class doc_generic_order_odt extends ModelePDFCommandes $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php index 512bf98be8b..8aa417c83c0 100644 --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -497,8 +497,12 @@ class doc_generic_invoice_odt extends ModelePDFFactures $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php index 1fbd02bbe6f..4c81babaa55 100644 --- a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php +++ b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php @@ -650,7 +650,7 @@ class doc_generic_project_odt extends ModelePDFProjects //Time ressources $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note"; - $sql.= ", u.name, u.firstname"; + $sql.= ", u.lastname, u.firstname"; $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; $sql .= " , ".MAIN_DB_PREFIX."user as u"; $sql .= " WHERE t.fk_task =".$task->id; @@ -973,8 +973,12 @@ class doc_generic_project_odt extends ModelePDFProjects // Write new file - $odfHandler->saveToDisk($file); - //$odfHandler->exportAsAttachedPDF($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index 26d67f09a32..d4e485562a4 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -482,8 +482,12 @@ class doc_generic_proposal_odt extends ModelePDFPropales $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php index acf14c67139..ca93ab1880e 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -313,8 +313,12 @@ class doc_generic_odt extends ModeleThirdPartyDoc $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 7e72eb6f7e2..41b64343bc1 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -450,10 +450,39 @@ IMG; { if( $name == "" ) $name = md5(uniqid()); - $this->saveToDisk("$name.odt"); - exec("./odt2pdf.sh $name",$output,$ret_val); - if($ret_val == 0) - { + dol_syslog(get_class($this).'::exportAsAttachedPDF $name='.$name, LOG_DEBUG); + $this->saveToDisk($name); + + $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2); // 1 or 2 + $command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name; + dol_syslog('$execmethod='.$execmethod.' Run command='.$command); + if ($execmethod == 1) + { + exec($command, $output_arr, $retval); + } + if ($execmethod == 2) + { + $ok=0; + $handle = fopen($outputfile, 'w'); + if ($handle) + { + dol_syslog("Run command ".$command); + $handlein = popen($command, 'r'); + while (!feof($handlein)) + { + $read = fgets($handlein); + fwrite($handle,$read); + $output_arr[]=$read; + } + pclose($handlein); + fclose($handle); + } + if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + } + + if($retval == 0) + { + dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); if (headers_sent($filename, $linenum)) { throw new OdfException("headers already sent ($filename at $linenum)"); } @@ -464,9 +493,12 @@ IMG; unlink("$name.odt"); unlink("$name.pdf"); } else { + dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); + dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr,true), LOG_DEBUG); echo "Error occured:
"; - foreach($output as $line) + foreach($output_arr as $line) echo $line."
"; + dol_syslog(get_class($this).'::exportAsAttachedPDF ERROR $line='.$line, LOG_DEBUG); } } diff --git a/htdocs/includes/odtphp/odt2pdf.sh b/htdocs/includes/odtphp/odt2pdf.sh old mode 100644 new mode 100755 index b9710682465..a2bd617dfa8 --- a/htdocs/includes/odtphp/odt2pdf.sh +++ b/htdocs/includes/odtphp/odt2pdf.sh @@ -1,7 +1,7 @@ #!/bin/bash # @copyright GPL License 2010 - Vikas Mahajan - http://vikasmahajan.wordpress.com -if [ -f "$1.odt" ] +if [ -f $1 ] then pgrep -U `id -u` soffice if [ $? -ne 0 ] @@ -9,7 +9,7 @@ then soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard sleep 2 fi -jodconverter "$1.odt" "$1.pdf" +jodconverter $1 "$1.pdf" if [ $? -ne 0 ] then echo "Error while converting odt to pdf" From 96126d9c9957e189c1c18311c46b1e94fdb1dc85 Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 20 Apr 2013 10:54:11 +0200 Subject: [PATCH 51/97] Save PDF file --- htdocs/includes/odtphp/odf.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 41b64343bc1..b25a7c40b84 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -450,12 +450,12 @@ IMG; { if( $name == "" ) $name = md5(uniqid()); - dol_syslog(get_class($this).'::exportAsAttachedPDF $name='.$name, LOG_DEBUG); + //dol_syslog(get_class($this).'::exportAsAttachedPDF $name='.$name, LOG_DEBUG); $this->saveToDisk($name); $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2); // 1 or 2 $command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name; - dol_syslog('$execmethod='.$execmethod.' Run command='.$command); + //dol_syslog('$execmethod='.$execmethod.' Run command='.$command); if ($execmethod == 1) { exec($command, $output_arr, $retval); @@ -482,7 +482,7 @@ IMG; if($retval == 0) { - dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); + //dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); if (headers_sent($filename, $linenum)) { throw new OdfException("headers already sent ($filename at $linenum)"); } @@ -490,15 +490,15 @@ IMG; header('Content-type: application/pdf'); header('Content-Disposition: attachment; filename="'.$name.'.pdf"'); readfile("$name.pdf"); - unlink("$name.odt"); - unlink("$name.pdf"); + //unlink("$name.odt"); + //unlink("$name.pdf"); } else { - dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); - dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr,true), LOG_DEBUG); + //dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); + //dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr,true), LOG_DEBUG); echo "Error occured:
"; foreach($output_arr as $line) echo $line."
"; - dol_syslog(get_class($this).'::exportAsAttachedPDF ERROR $line='.$line, LOG_DEBUG); + //dol_syslog(get_class($this).'::exportAsAttachedPDF ERROR $line='.$line, LOG_DEBUG); } } From ffb97010c92ae3471f74e1345527bccd0a61c92d Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 20 Apr 2013 11:03:23 +0200 Subject: [PATCH 52/97] Better file name management --- htdocs/includes/odtphp/odf.php | 985 +++++++++++++++--------------- htdocs/includes/odtphp/odt2pdf.sh | 4 +- 2 files changed, 497 insertions(+), 492 deletions(-) diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index b25a7c40b84..4f91157438b 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -18,152 +18,152 @@ class OdfException extends Exception class Odf { protected $config = array( - 'ZIP_PROXY' => 'PclZipProxy', // PclZipProxy, PhpZipProxy - 'DELIMITER_LEFT' => '{', - 'DELIMITER_RIGHT' => '}', - 'PATH_TO_TMP' => '/tmp' - ); - protected $file; - protected $contentXml; // To store content of content.xml file - protected $stylesXml; // To store content of styles.xml file - protected $manifestXml; // To store content of META-INF/manifest.xml file - protected $tmpfile; - protected $tmpdir=''; - protected $images = array(); - protected $vars = array(); - protected $segments = array(); - const PIXEL_TO_CM = 0.026458333; - /** - * Class constructor - * - * @param string $filename the name of the odt file - * @throws OdfException - */ - public function __construct($filename, $config = array()) - { - clearstatcache(); + 'ZIP_PROXY' => 'PclZipProxy', // PclZipProxy, PhpZipProxy + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}', + 'PATH_TO_TMP' => '/tmp' + ); + protected $file; + protected $contentXml; // To store content of content.xml file + protected $stylesXml; // To store content of styles.xml file + protected $manifestXml; // To store content of META-INF/manifest.xml file + protected $tmpfile; + protected $tmpdir=''; + protected $images = array(); + protected $vars = array(); + protected $segments = array(); + const PIXEL_TO_CM = 0.026458333; + /** + * Class constructor + * + * @param string $filename the name of the odt file + * @throws OdfException + */ + public function __construct($filename, $config = array()) + { + clearstatcache(); - if (! is_array($config)) { - throw new OdfException('Configuration data must be provided as array'); + if (! is_array($config)) { + throw new OdfException('Configuration data must be provided as array'); + } + foreach ($config as $configKey => $configValue) { + if (array_key_exists($configKey, $this->config)) { + $this->config[$configKey] = $configValue; } - foreach ($config as $configKey => $configValue) { - if (array_key_exists($configKey, $this->config)) { - $this->config[$configKey] = $configValue; - } - } - - $md5uniqid = md5(uniqid()); - if ($this->config['PATH_TO_TMP']) $this->tmpdir = preg_replace('|[\/]$|','',$this->config['PATH_TO_TMP']); // Remove last \ or / - $this->tmpdir .= ($this->tmpdir?'/':'').$md5uniqid; - $this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt'; // We keep .odt extension to allow OpenOffice usage during debug. - - // A working directory is required for some zip proxy like PclZipProxy - if (in_array($this->config['ZIP_PROXY'],array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) { - throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists'); - } - - // Create tmp direcoty (will be deleted in destructor) - if (!file_exists($this->tmpdir)) { - $result=mkdir($this->tmpdir); - } - - // Load zip proxy - $zipHandler = $this->config['ZIP_PROXY']; - if (!defined('PCLZIP_TEMPORARY_DIR')) define('PCLZIP_TEMPORARY_DIR',$this->tmpdir); - include_once('zip/'.$zipHandler.'.php'); - if (! class_exists($this->config['ZIP_PROXY'])) { - throw new OdfException($this->config['ZIP_PROXY'] . ' class not found - check your php settings'); - } - $this->file = new $zipHandler($this->tmpdir); - - - if ($this->file->open($filename) !== true) { // This also create the tmpdir directory - throw new OdfException("Error while Opening the file '$filename' - Check your odt filename"); - } - if (($this->contentXml = $this->file->getFromName('content.xml')) === false) { - throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'"); - } - if (($this->manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) { - throw new OdfException("Something is wrong with META-INF/manifest.xml in source file '$filename'"); - } - if (($this->stylesXml = $this->file->getFromName('styles.xml')) === false) { - throw new OdfException("Nothing to parse - Check that the styles.xml file is correctly formed in source file '$filename'"); - } - $this->file->close(); - - - //print "tmpdir=".$tmpdir; - //print "filename=".$filename; - //print "tmpfile=".$tmpfile; - - copy($filename, $this->tmpfile); - - $this->_moveRowSegments(); } - /** - * Assing a template variable - * - * @param string $key name of the variable within the template - * @param string $value replacement value - * @param bool $encode if true, special XML characters are encoded - * @throws OdfException - * @return odf - */ - public function setVars($key, $value, $encode = true, $charset = 'ISO-8859') - { - $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; - // TODO Warning string may be: - // {aaa} - // instead of {aaa} so we should enhance this function. - //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; - if (strpos($this->contentXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { - //if (strpos($this->contentXml, '">'. $key . '') === false) { - throw new OdfException("var $key not found in the document"); - //} - } - $value = $encode ? htmlspecialchars($value) : $value; - $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; - $this->vars[$tag] = str_replace("\n", "", $value); - return $this; + $md5uniqid = md5(uniqid()); + if ($this->config['PATH_TO_TMP']) $this->tmpdir = preg_replace('|[\/]$|','',$this->config['PATH_TO_TMP']); // Remove last \ or / + $this->tmpdir .= ($this->tmpdir?'/':'').$md5uniqid; + $this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt'; // We keep .odt extension to allow OpenOffice usage during debug. + + // A working directory is required for some zip proxy like PclZipProxy + if (in_array($this->config['ZIP_PROXY'],array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) { + throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists'); } - - /** - * Assing a template variable - * - * @param string $key name of the variable within the template - * @param string $value replacement value - * @param bool $encode if true, special XML characters are encoded - * @throws OdfException - * @return odf - */ - public function setVarsHeadFooter($key, $value, $encode = true, $charset = 'ISO-8859') - { - $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; - // TODO Warning string may be: - // {aaa} - // instead of {aaa} so we should enhance this function. - //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; - if (strpos($this->stylesXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { + + // Create tmp direcoty (will be deleted in destructor) + if (!file_exists($this->tmpdir)) { + $result=mkdir($this->tmpdir); + } + + // Load zip proxy + $zipHandler = $this->config['ZIP_PROXY']; + if (!defined('PCLZIP_TEMPORARY_DIR')) define('PCLZIP_TEMPORARY_DIR',$this->tmpdir); + include_once('zip/'.$zipHandler.'.php'); + if (! class_exists($this->config['ZIP_PROXY'])) { + throw new OdfException($this->config['ZIP_PROXY'] . ' class not found - check your php settings'); + } + $this->file = new $zipHandler($this->tmpdir); + + + if ($this->file->open($filename) !== true) { // This also create the tmpdir directory + throw new OdfException("Error while Opening the file '$filename' - Check your odt filename"); + } + if (($this->contentXml = $this->file->getFromName('content.xml')) === false) { + throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'"); + } + if (($this->manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) { + throw new OdfException("Something is wrong with META-INF/manifest.xml in source file '$filename'"); + } + if (($this->stylesXml = $this->file->getFromName('styles.xml')) === false) { + throw new OdfException("Nothing to parse - Check that the styles.xml file is correctly formed in source file '$filename'"); + } + $this->file->close(); + + + //print "tmpdir=".$tmpdir; + //print "filename=".$filename; + //print "tmpfile=".$tmpfile; + + copy($filename, $this->tmpfile); + + $this->_moveRowSegments(); + } + + /** + * Assing a template variable + * + * @param string $key name of the variable within the template + * @param string $value replacement value + * @param bool $encode if true, special XML characters are encoded + * @throws OdfException + * @return odf + */ + public function setVars($key, $value, $encode = true, $charset = 'ISO-8859') + { + $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; + // TODO Warning string may be: + // {aaa} + // instead of {aaa} so we should enhance this function. + //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; + if (strpos($this->contentXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { //if (strpos($this->contentXml, '">'. $key . '') === false) { - throw new OdfException("var $key not found in the document"); - //} - } - $value = $encode ? htmlspecialchars($value) : $value; - $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; - $this->vars[$tag] = str_replace("\n", "", $value); - return $this; + throw new OdfException("var $key not found in the document"); + //} } + $value = $encode ? htmlspecialchars($value) : $value; + $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; + $this->vars[$tag] = str_replace("\n", "", $value); + return $this; + } - /** - * Evaluating php codes inside the ODT and output the buffer (print, echo) inplace of the code - * - */ - public function phpEval() - { - preg_match_all('/[\{\<]\?(php)?\s+(?P.+)\?[\}\>]/iU',$this->contentXml, $matches); // detecting all {?php code ?} or - for ($i=0;$i < count($matches['content']);$i++) { - try { + /** + * Assing a template variable + * + * @param string $key name of the variable within the template + * @param string $value replacement value + * @param bool $encode if true, special XML characters are encoded + * @throws OdfException + * @return odf + */ + public function setVarsHeadFooter($key, $value, $encode = true, $charset = 'ISO-8859') + { + $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; + // TODO Warning string may be: + // {aaa} + // instead of {aaa} so we should enhance this function. + //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; + if (strpos($this->stylesXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { + //if (strpos($this->contentXml, '">'. $key . '') === false) { + throw new OdfException("var $key not found in the document"); + //} + } + $value = $encode ? htmlspecialchars($value) : $value; + $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; + $this->vars[$tag] = str_replace("\n", "", $value); + return $this; + } + + /** + * Evaluating php codes inside the ODT and output the buffer (print, echo) inplace of the code + * + */ + public function phpEval() + { + preg_match_all('/[\{\<]\?(php)?\s+(?P.+)\?[\}\>]/iU',$this->contentXml, $matches); // detecting all {?php code ?} or + for ($i=0;$i < count($matches['content']);$i++) { + try { $ob_output = ''; // flush the output for each code. This var will be filled in by the eval($code) and output buffering : any print or echo or output will be redirected into this variable $code = $matches['content'][$i]; ob_start(); @@ -171,395 +171,400 @@ class Odf $ob_output = ob_get_contents(); // send the content of the buffer into $ob_output $this->contentXml = str_replace($matches[0][$i], $ob_output, $this->contentXml); ob_end_clean(); - } catch (Exception $e) { - ob_end_clean(); - $this->contentXml = str_replace($matches[0][$i], 'ERROR: there was a problem while evaluating this portion of code, please fix it: '.$e, $this->contentXml); - } + } catch (Exception $e) { + ob_end_clean(); + $this->contentXml = str_replace($matches[0][$i], 'ERROR: there was a problem while evaluating this portion of code, please fix it: '.$e, $this->contentXml); } - return 0; } + return 0; + } - /** - * Assign a template variable as a picture - * - * @param string $key name of the variable within the template - * @param string $value path to the picture - * @throws OdfException - * @return odf - */ - public function setImage($key, $value) - { - $filename = strtok(strrchr($value, '/'), '/.'); - $file = substr(strrchr($value, '/'), 1); - $size = @getimagesize($value); - if ($size === false) { - throw new OdfException("Invalid image"); - } - list ($width, $height) = $size; - $width *= self::PIXEL_TO_CM; - $height *= self::PIXEL_TO_CM; - $xml = << IMG; - $this->images[$value] = $file; - $this->setVars($key, $xml, false); - return $this; - } + $this->images[$value] = $file; + $this->setVars($key, $xml, false); + return $this; + } - /** - * Move segment tags for lines of tables - * Called automatically within the constructor - * - * @return void - */ - private function _moveRowSegments() + /** + * Move segment tags for lines of tables + * Called automatically within the constructor + * + * @return void + */ + private function _moveRowSegments() + { + // Search all possible rows in the document + $reg1 = "#]*>(.*)#smU"; + preg_match_all($reg1, $this->contentXml, $matches); + for ($i = 0, $size = count($matches[0]); $i < $size; $i++) { + // Check if the current row contains a segment row.* + $reg2 = '#\[!--\sBEGIN\s(row.[\S]*)\s--\](.*)\[!--\sEND\s\\1\s--\]#sm'; + if (preg_match($reg2, $matches[0][$i], $matches2)) { + $balise = str_replace('row.', '', $matches2[1]); + // Move segment tags around the row + $replace = array( + '[!-- BEGIN ' . $matches2[1] . ' --]' => '', + '[!-- END ' . $matches2[1] . ' --]' => '', + ' '[!-- BEGIN ' . $balise . ' --]' => '[!-- END ' . $balise . ' --]' + ); + $replacedXML = str_replace(array_keys($replace), array_values($replace), $matches[0][$i]); + $this->contentXml = str_replace($matches[0][$i], $replacedXML, $this->contentXml); + } + } + } + + /** + * Merge template variables + * Called automatically for a save + * + * @param string $type 'content' or 'styles' + * @return void + */ + private function _parse($type='content') + { + // Conditionals substitution + // Note: must be done before content substitution, else the variable will be replaced by its value and the conditional won't work anymore + foreach($this->vars as $key => $value) { - // Search all possible rows in the document - $reg1 = "#]*>(.*)#smU"; - preg_match_all($reg1, $this->contentXml, $matches); - for ($i = 0, $size = count($matches[0]); $i < $size; $i++) { - // Check if the current row contains a segment row.* - $reg2 = '#\[!--\sBEGIN\s(row.[\S]*)\s--\](.*)\[!--\sEND\s\\1\s--\]#sm'; - if (preg_match($reg2, $matches[0][$i], $matches2)) { - $balise = str_replace('row.', '', $matches2[1]); - // Move segment tags around the row - $replace = array( - '[!-- BEGIN ' . $matches2[1] . ' --]' => '', - '[!-- END ' . $matches2[1] . ' --]' => '', - ' '[!-- BEGIN ' . $balise . ' --]' => '[!-- END ' . $balise . ' --]' - ); - $replacedXML = str_replace(array_keys($replace), array_values($replace), $matches[0][$i]); - $this->contentXml = str_replace($matches[0][$i], $replacedXML, $this->contentXml); + // If value is true (not 0 nor false nor null nor empty string) + if($value) + { + // Remove the IF tag + $this->contentXml = str_replace('[!-- IF '.$key.' --]', '', $this->contentXml); + // Remove everything between the ELSE tag (if it exists) and the ENDIF tag + $reg = '@(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy + $this->contentXml = preg_replace($reg, '', $this->contentXml); + } + // Else the value is false, then two cases: no ELSE and we're done, or there is at least one place where there is an ELSE clause, then we replace it + else + { + // Find all conditional blocks for this variable: from IF to ELSE and to ENDIF + $reg = '@\[!--\sIF\s' . $key . '\s--\](.*)(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy + preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER); + foreach($matches as $match) { // For each match, if there is an ELSE clause, we replace the whole block by the value in the ELSE clause + if (!empty($match[3])) $this->contentXml = str_replace($match[0], $match[3], $this->contentXml); } + // Cleanup the other conditional blocks (all the others where there were no ELSE clause, we can just remove them altogether) + $this->contentXml = preg_replace($reg, '', $this->contentXml); } } - /** - * Merge template variables - * Called automatically for a save - * - * @param string $type 'content' or 'styles' - * @return void - */ - private function _parse($type='content') - { - // Conditionals substitution - // Note: must be done before content substitution, else the variable will be replaced by its value and the conditional won't work anymore - foreach($this->vars as $key => $value) - { - // If value is true (not 0 nor false nor null nor empty string) - if($value) - { - // Remove the IF tag - $this->contentXml = str_replace('[!-- IF '.$key.' --]', '', $this->contentXml); - // Remove everything between the ELSE tag (if it exists) and the ENDIF tag - $reg = '@(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy - $this->contentXml = preg_replace($reg, '', $this->contentXml); - } - // Else the value is false, then two cases: no ELSE and we're done, or there is at least one place where there is an ELSE clause, then we replace it - else - { - // Find all conditional blocks for this variable: from IF to ELSE and to ENDIF - $reg = '@\[!--\sIF\s' . $key . '\s--\](.*)(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy - preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER); - foreach($matches as $match) { // For each match, if there is an ELSE clause, we replace the whole block by the value in the ELSE clause - if (!empty($match[3])) $this->contentXml = str_replace($match[0], $match[3], $this->contentXml); - } - // Cleanup the other conditional blocks (all the others where there were no ELSE clause, we can just remove them altogether) - $this->contentXml = preg_replace($reg, '', $this->contentXml); - } - } + // Content (variable) substitution + if ($type == 'content') $this->contentXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->contentXml); + // Styles substitution + if ($type == 'styles') $this->stylesXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->stylesXml); - // Content (variable) substitution - if ($type == 'content') $this->contentXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->contentXml); - // Styles substitution - if ($type == 'styles') $this->stylesXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->stylesXml); + } + /** + * Add the merged segment to the document + * + * @param Segment $segment + * @throws OdfException + * @return odf + */ + public function mergeSegment(Segment $segment) + { + if (! array_key_exists($segment->getName(), $this->segments)) { + throw new OdfException($segment->getName() . 'cannot be parsed, has it been set yet ?'); } + $string = $segment->getName(); + // $reg = '@]*>\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]<\/text:p>@smU'; + $reg = '@\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]@smU'; + $this->contentXml = preg_replace($reg, $segment->getXmlParsed(), $this->contentXml); + return $this; + } - /** - * Add the merged segment to the document - * - * @param Segment $segment - * @throws OdfException - * @return odf - */ - public function mergeSegment(Segment $segment) - { - if (! array_key_exists($segment->getName(), $this->segments)) { - throw new OdfException($segment->getName() . 'cannot be parsed, has it been set yet ?'); - } - $string = $segment->getName(); - // $reg = '@]*>\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]<\/text:p>@smU'; - $reg = '@\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]@smU'; - $this->contentXml = preg_replace($reg, $segment->getXmlParsed(), $this->contentXml); - return $this; - } + /** + * Display all the current template variables + * + * @return string + */ + public function printVars() + { + return print_r('
' . print_r($this->vars, true) . '
', true); + } - /** - * Display all the current template variables - * - * @return string - */ - public function printVars() - { - return print_r('
' . print_r($this->vars, true) . '
', true); - } + /** + * Display the XML content of the file from odt document + * as it is at the moment + * + * @return string + */ + public function __toString() + { + return $this->contentXml; + } - /** - * Display the XML content of the file from odt document - * as it is at the moment - * - * @return string - */ - public function __toString() - { - return $this->contentXml; - } + /** + * Display loop segments declared with setSegment() + * + * @return string + */ + public function printDeclaredSegments() + { + return '
' . print_r(implode(' ', array_keys($this->segments)), true) . '
'; + } - /** - * Display loop segments declared with setSegment() - * - * @return string - */ - public function printDeclaredSegments() - { - return '
' . print_r(implode(' ', array_keys($this->segments)), true) . '
'; - } - - /** - * Declare a segment in order to use it in a loop - * - * @param string $segment - * @throws OdfException - * @return Segment - */ - public function setSegment($segment) - { - if (array_key_exists($segment, $this->segments)) { - return $this->segments[$segment]; - } - // $reg = "#\[!--\sBEGIN\s$segment\s--\]<\/text:p>(.*)\[!--\sEND\s$segment\s--\]#sm"; - $reg = "#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm"; - if (preg_match($reg, html_entity_decode($this->contentXml), $m) == 0) { - throw new OdfException("'$segment' segment not found in the document"); - } - $this->segments[$segment] = new Segment($segment, $m[1], $this); + /** + * Declare a segment in order to use it in a loop + * + * @param string $segment + * @throws OdfException + * @return Segment + */ + public function setSegment($segment) + { + if (array_key_exists($segment, $this->segments)) { return $this->segments[$segment]; } - /** - * Save the odt file on the disk - * - * @param string $file name of the desired file - * @throws OdfException - * @return void - */ - public function saveToDisk($file = null) - { - if ($file !== null && is_string($file)) { - if (file_exists($file) && !(is_file($file) && is_writable($file))) { - throw new OdfException('Permission denied : can\'t create ' . $file); - } - $this->_save(); - copy($this->tmpfile, $file); - } else { - $this->_save(); - } + // $reg = "#\[!--\sBEGIN\s$segment\s--\]<\/text:p>(.*)\[!--\sEND\s$segment\s--\]#sm"; + $reg = "#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm"; + if (preg_match($reg, html_entity_decode($this->contentXml), $m) == 0) { + throw new OdfException("'$segment' segment not found in the document"); } - - /** - * Write output file onto disk - * - * @throws OdfException - * @return void - */ - private function _save() - { - $res=$this->file->open($this->tmpfile); // tmpfile is odt template - $this->_parse('content'); - $this->_parse('styles'); - - if (! $this->file->addFromString('content.xml', $this->contentXml)) { - throw new OdfException('Error during file export addFromString'); + $this->segments[$segment] = new Segment($segment, $m[1], $this); + return $this->segments[$segment]; + } + /** + * Save the odt file on the disk + * + * @param string $file name of the desired file + * @throws OdfException + * @return void + */ + public function saveToDisk($file = null) + { + if ($file !== null && is_string($file)) { + if (file_exists($file) && !(is_file($file) && is_writable($file))) { + throw new OdfException('Permission denied : can\'t create ' . $file); } - if (! $this->file->addFromString('styles.xml', $this->stylesXml)) { - throw new OdfException('Error during file export addFromString'); - } - foreach ($this->images as $imageKey => $imageValue) { - // Add the image inside the ODT document - $this->file->addFile($imageKey, 'Pictures/' . $imageValue); - // Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice) - $this->addImageToManifest($imageValue); - } - if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) { - throw new OdfException('Error during file export: manifest.xml'); - } - $this->file->close(); - } - - /** - * Update Manifest file according to added image files - * - * @param string $file Image file to add into manifest content - */ - public function addImageToManifest($file) - { - // Get the file extension - $ext = substr(strrchr($val, '.'), 1); - // Create the correct image XML entry to add to the manifest (this is necessary because ODT format requires that we keep a list of the images in the manifest.xml) - $add = ' '."\n"; - // Append the image to the manifest - $this->manifestXml = str_replace('', $add.'', $this->manifestXml); // we replace the manifest closing tag by the image XML entry + manifest closing tag (this results in appending the data, we do not overwrite anything) - } - - /** - * Export the file as attached file by HTTP - * - * @param string $name (optional) - * @throws OdfException - * @return void - */ - public function exportAsAttachedFile($name="") - { $this->_save(); + copy($this->tmpfile, $file); + } else { + $this->_save(); + } + } + + /** + * Write output file onto disk + * + * @throws OdfException + * @return void + */ + private function _save() + { + $res=$this->file->open($this->tmpfile); // tmpfile is odt template + $this->_parse('content'); + $this->_parse('styles'); + + if (! $this->file->addFromString('content.xml', $this->contentXml)) { + throw new OdfException('Error during file export addFromString'); + } + if (! $this->file->addFromString('styles.xml', $this->stylesXml)) { + throw new OdfException('Error during file export addFromString'); + } + foreach ($this->images as $imageKey => $imageValue) { + // Add the image inside the ODT document + $this->file->addFile($imageKey, 'Pictures/' . $imageValue); + // Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice) + $this->addImageToManifest($imageValue); + } + if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) { + throw new OdfException('Error during file export: manifest.xml'); + } + $this->file->close(); + } + + /** + * Update Manifest file according to added image files + * + * @param string $file Image file to add into manifest content + */ + public function addImageToManifest($file) + { + // Get the file extension + $ext = substr(strrchr($val, '.'), 1); + // Create the correct image XML entry to add to the manifest (this is necessary because ODT format requires that we keep a list of the images in the manifest.xml) + $add = ' '."\n"; + // Append the image to the manifest + $this->manifestXml = str_replace('', $add.'', $this->manifestXml); // we replace the manifest closing tag by the image XML entry + manifest closing tag (this results in appending the data, we do not overwrite anything) + } + + /** + * Export the file as attached file by HTTP + * + * @param string $name (optional) + * @throws OdfException + * @return void + */ + public function exportAsAttachedFile($name="") + { + $this->_save(); + if (headers_sent($filename, $linenum)) { + throw new OdfException("headers already sent ($filename at $linenum)"); + } + + if( $name == "" ) + { + $name = md5(uniqid()) . ".odt"; + } + + header('Content-type: application/vnd.oasis.opendocument.text'); + header('Content-Disposition: attachment; filename="'.$name.'"'); + header('Content-Length: '.filesize($this->tmpfile)); + readfile($this->tmpfile); + } + + /** + * Convert the ODT file to PDF and export the file as attached file by HTTP + * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh + * + * @param string $name (optional) + * @throws OdfException + * @return void + */ + public function exportAsAttachedPDF($name="") + { + global $conf; + + if( $name == "" ) $name = md5(uniqid()); + + //dol_syslog(get_class($this).'::exportAsAttachedPDF $name='.$name, LOG_DEBUG); + $this->saveToDisk($name); + + $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2); // 1 or 2 + + $name=str_replace('.odt', '', $name); + $command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name; + //dol_syslog('$execmethod='.$execmethod.' Run command='.$command); + if ($execmethod == 1) + { + exec($command, $output_arr, $retval); + } + if ($execmethod == 2) + { + $ok=0; + $handle = fopen($outputfile, 'w'); + if ($handle) + { + dol_syslog("Run command ".$command); + $handlein = popen($command, 'r'); + while (!feof($handlein)) + { + $read = fgets($handlein); + fwrite($handle,$read); + $output_arr[]=$read; + } + pclose($handlein); + fclose($handle); + } + if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + } + + if($retval == 0) + { + //dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); if (headers_sent($filename, $linenum)) { throw new OdfException("headers already sent ($filename at $linenum)"); } - if( $name == "" ) - { - $name = md5(uniqid()) . ".odt"; + if (!empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + header('Content-type: application/pdf'); + header('Content-Disposition: attachment; filename="'.$name.'.pdf"'); + readfile("$name.pdf"); } + unlink("$name.odt"); + } else { + //dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); + //dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr,true), LOG_DEBUG); + echo "Error occured:
"; + foreach($output_arr as $line) + echo $line."
"; + //dol_syslog(get_class($this).'::exportAsAttachedPDF ERROR $line='.$line, LOG_DEBUG); + } + } - header('Content-type: application/vnd.oasis.opendocument.text'); - header('Content-Disposition: attachment; filename="'.$name.'"'); - header('Content-Length: '.filesize($this->tmpfile)); - readfile($this->tmpfile); + /** + * Returns a variable of configuration + * + * @return string The requested variable of configuration + */ + public function getConfig($configKey) + { + if (array_key_exists($configKey, $this->config)) { + return $this->config[$configKey]; + } + return false; + } + /** + * Returns the temporary working file + * + * @return string le chemin vers le fichier temporaire de travail + */ + public function getTmpfile() + { + return $this->tmpfile; + } + + /** + * Delete the temporary file when the object is destroyed + */ + public function __destruct() + { + if (file_exists($this->tmpfile)) { + unlink($this->tmpfile); } - /** - * Convert the ODT file to PDF and export the file as attached file by HTTP - * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh - * - * @param string $name (optional) - * @throws OdfException - * @return void - */ - public function exportAsAttachedPDF($name="") - { - if( $name == "" ) $name = md5(uniqid()); - - //dol_syslog(get_class($this).'::exportAsAttachedPDF $name='.$name, LOG_DEBUG); - $this->saveToDisk($name); - - $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2); // 1 or 2 - $command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name; - //dol_syslog('$execmethod='.$execmethod.' Run command='.$command); - if ($execmethod == 1) - { - exec($command, $output_arr, $retval); - } - if ($execmethod == 2) - { - $ok=0; - $handle = fopen($outputfile, 'w'); - if ($handle) - { - dol_syslog("Run command ".$command); - $handlein = popen($command, 'r'); - while (!feof($handlein)) - { - $read = fgets($handlein); - fwrite($handle,$read); - $output_arr[]=$read; - } - pclose($handlein); - fclose($handle); - } - if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); - } - - if($retval == 0) - { - //dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); - if (headers_sent($filename, $linenum)) { - throw new OdfException("headers already sent ($filename at $linenum)"); - } - - header('Content-type: application/pdf'); - header('Content-Disposition: attachment; filename="'.$name.'.pdf"'); - readfile("$name.pdf"); - //unlink("$name.odt"); - //unlink("$name.pdf"); - } else { - //dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); - //dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr,true), LOG_DEBUG); - echo "Error occured:
"; - foreach($output_arr as $line) - echo $line."
"; - //dol_syslog(get_class($this).'::exportAsAttachedPDF ERROR $line='.$line, LOG_DEBUG); - } + if (file_exists($this->tmpdir)) { + $this->_rrmdir($this->tmpdir); + rmdir($this->tmpdir); } + } - /** - * Returns a variable of configuration - * - * @return string The requested variable of configuration - */ - public function getConfig($configKey) - { - if (array_key_exists($configKey, $this->config)) { - return $this->config[$configKey]; - } - return false; - } - /** - * Returns the temporary working file - * - * @return string le chemin vers le fichier temporaire de travail - */ - public function getTmpfile() - { - return $this->tmpfile; - } - - /** - * Delete the temporary file when the object is destroyed - */ - public function __destruct() - { - if (file_exists($this->tmpfile)) { - unlink($this->tmpfile); - } - - if (file_exists($this->tmpdir)) { - $this->_rrmdir($this->tmpdir); - rmdir($this->tmpdir); - } - } - - /** - * Empty the temporary working directory recursively - * @param $dir the temporary working directory - * @return void - */ - private function _rrmdir($dir) - { - if ($handle = opendir($dir)) { - while (false !== ($file = readdir($handle))) { - if ($file != '.' && $file != '..') { - if (is_dir($dir . '/' . $file)) { - $this->_rrmdir($dir . '/' . $file); - rmdir($dir . '/' . $file); - } else { - unlink($dir . '/' . $file); - } + /** + * Empty the temporary working directory recursively + * @param $dir the temporary working directory + * @return void + */ + private function _rrmdir($dir) + { + if ($handle = opendir($dir)) { + while (false !== ($file = readdir($handle))) { + if ($file != '.' && $file != '..') { + if (is_dir($dir . '/' . $file)) { + $this->_rrmdir($dir . '/' . $file); + rmdir($dir . '/' . $file); + } else { + unlink($dir . '/' . $file); } } - closedir($handle); } + closedir($handle); } + } } ?> \ No newline at end of file diff --git a/htdocs/includes/odtphp/odt2pdf.sh b/htdocs/includes/odtphp/odt2pdf.sh index a2bd617dfa8..b9710682465 100755 --- a/htdocs/includes/odtphp/odt2pdf.sh +++ b/htdocs/includes/odtphp/odt2pdf.sh @@ -1,7 +1,7 @@ #!/bin/bash # @copyright GPL License 2010 - Vikas Mahajan - http://vikasmahajan.wordpress.com -if [ -f $1 ] +if [ -f "$1.odt" ] then pgrep -U `id -u` soffice if [ $? -ne 0 ] @@ -9,7 +9,7 @@ then soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard sleep 2 fi -jodconverter $1 "$1.pdf" +jodconverter "$1.odt" "$1.pdf" if [ $? -ne 0 ] then echo "Error while converting odt to pdf" From a9974f66b29eb941c7863d7b9386803e37426095 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 20 Apr 2013 11:03:36 +0200 Subject: [PATCH 53/97] Fix : url was given even if value of tracking was empty + remove old use of "methode_expedition..." files --- htdocs/expedition/class/expedition.class.php | 24 +++----------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 99621b2d16c..95b18e1d814 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -1199,7 +1199,7 @@ class Expedition extends CommonObject { global $langs; - $listmeths = array(); + $this->listmeths = array(); $i=0; $sql = "SELECT em.rowid, em.code, em.libelle, em.description, em.tracking, em.active"; @@ -1216,29 +1216,11 @@ class Expedition extends CommonObject $label=$langs->trans('SendingMethod'.$obj->code); $this->listmeths[$i]['libelle'] = ($label != 'SendingMethod'.$obj->code?$label:$obj->libelle); $this->listmeths[$i]['description'] = $obj->description; - if ($obj->tracking) - { - $this->listmeths[$i]['tracking'] = $obj->tracking; - } - else - { - if ($obj->code) - { - $classname = "methode_expedition_".strtolower($obj->code); - - if (file_exists(DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($obj->code).".modules.php") ) - { - require_once DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($obj->code).'.modules.php'; - $shipmethod = new $classname(); - $this->listmeths[$i]['tracking'] = $shipmethod->provider_url_status('{TRACKID}'); - } - } - } + $this->listmeths[$i]['tracking'] = $obj->tracking; $this->listmeths[$i]['active'] = $obj->active; $i++; } } - else dol_print_error($this->db,''); } /** @@ -1325,7 +1307,7 @@ class Expedition extends CommonObject } } - if (!empty($tracking)) + if (!empty($tracking) && !empty($value)) { $url = str_replace('{TRACKID}', $value, $tracking); $this->tracking_url = sprintf(''.($value?$value:'url').'',$url,$url); From 651b1ae7ce0fc83fe3de9a577aa3cc9b6c9f9da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sat, 20 Apr 2013 12:55:31 +0200 Subject: [PATCH 54/97] Refactor + es_ES translations improvement + minor stetic change --- htdocs/admin/compta.php | 2 +- htdocs/admin/dict.php | 24 ++-- htdocs/admin/modules.php | 4 +- htdocs/compta/journal/purchasesjournal.php | 135 +++++++++------------ htdocs/compta/journal/sellsjournal.php | 128 +++++++++---------- htdocs/holiday/admin/holiday.php | 2 +- htdocs/langs/es_ES/admin.lang | 2 +- 7 files changed, 133 insertions(+), 164 deletions(-) diff --git a/htdocs/admin/compta.php b/htdocs/admin/compta.php index a5213413d54..c30af26f1c0 100644 --- a/htdocs/admin/compta.php +++ b/htdocs/admin/compta.php @@ -107,7 +107,7 @@ print '
'; $h = 0; $head[$h][0] = DOL_URL_ROOT."/admin/compta.php"; -$head[$h][1] = $langs->trans("Compta"); +$head[$h][1] = $langs->trans("Accountancy"); $head[$h][2] = 'Compta'; $hselected=$h; $h++; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index cf93f472019..39e8bbf0a2d 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -1084,15 +1084,23 @@ if ($id) } // Est-ce une entree du dictionnaire qui peut etre desactivee ? - $iserasable=1; // Oui par defaut - if (isset($obj->code) && ($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) $iserasable=0; - if (isset($obj->code) && $obj->code == 'RECEP') $iserasable=0; - if (isset($obj->code) && $obj->code == 'EF0') $iserasable=0; + // True by default + $iserasable=1; + + if (isset($obj->code)) + { + if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) $iserasable = 0; + else if ($obj->code == 'RECEP') $iserasable = 0; + else if ($obj->code == 'EF0') $iserasable = 0; + } + if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto'))) $iserasable=0; + $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?$obj->code:'').'&id='.$id.'&'; + // Active print ''; - if ($iserasable) print ''.$actl[$obj->active].''; + if ($iserasable) print ''.$actl[$obj->active].''; else { if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto')) && empty($obj->active)) print $langs->trans("Deprecated"); @@ -1101,11 +1109,11 @@ if ($id) print ""; // Modify link - if ($iserasable) print 'rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'">'.img_edit().''; + if ($iserasable) print ''.img_edit().''; else print ' '; // Delete link - if ($iserasable) print ''.img_delete().''; + if ($iserasable) print ''.img_delete().''; else print ' '; print "\n"; @@ -1153,7 +1161,7 @@ else $var=!$var; $value=$tabname[$i]; - print ''; + print ''; if (! empty($tabcond[$i])) { print ''.$langs->trans($tablib[$i]).''; diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 4440d632b2e..acdf756eb86 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -194,7 +194,7 @@ asort($orders); $nbofactivatedmodules=count($conf->modules); $moreinfo=$langs->trans("TotalNumberOfActivatedModules",($nbofactivatedmodules-1)); - +if ($nbofactivatedmodules <= 1) $moreinfo .= ' '.img_warning($langs->trans("YouMustEnableOneModule")); print load_fiche_titre($langs->trans("ModulesSetup"),$moreinfo,'setup'); // Start to show page @@ -206,7 +206,7 @@ if ($mode==='functional') print $langs->trans("ModulesJobDesc")."
\n"; if ($mode==='marketplace') print $langs->trans("ModulesMarketPlaceDesc")."
\n"; if ($mode==='expdev') print $langs->trans("ModuleFamilyExperimental")."
\n"; -if ($nbofactivatedmodules <= 1) print ' '.img_warning($langs->trans("YouMustEnableOneModule")); + //print '
'."\n"; diff --git a/htdocs/compta/journal/purchasesjournal.php b/htdocs/compta/journal/purchasesjournal.php index a37d5c240df..124ae380d09 100755 --- a/htdocs/compta/journal/purchasesjournal.php +++ b/htdocs/compta/journal/purchasesjournal.php @@ -4,6 +4,7 @@ * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin * Copyright (C) 2011-2012 Alexandre Spangaro + * Copyright (C) 2013 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 @@ -166,7 +167,6 @@ else { /* * Show result array */ -$i = 0; print ""; print ""; ///print ""; @@ -177,96 +177,71 @@ print "\n"; $var=true; -$r=''; $invoicestatic=new FactureFournisseur($db); $companystatic=new Fournisseur($db); foreach ($tabfac as $key => $val) { - $invoicestatic->id=$key; - $invoicestatic->ref=$val["ref"]; - $invoicestatic->type=$val["type"]; + $invoicestatic->id = $key; + $invoicestatic->ref = $val["ref"]; + $invoicestatic->type = $val["type"]; - // product - foreach ($tabht[$key] as $k => $mt) + $companystatic->id = $tabcompany[$key]['id']; + $companystatic->name = $tabcompany[$key]['name']; + + $lines = array( + array( + 'var' => $tabht[$key], + 'label' => $langs->trans('Products'), + ), + array( + 'var' => $tabtva[$key], + 'label' => $langs->trans('VAT') + ), + array( + 'var' => $tablocaltax1[$key], + 'label' => $langs->transcountry('LT1', $mysoc->country_code) + ), + array( + 'var' => $tablocaltax2[$key], + 'label' => $langs->transcountry('LT2', $mysoc->country_code) + ), + array( + 'var' => $tabttc[$key], + 'label' => $langs->trans('ThirdParty').' ('.$companystatic->getNomUrl(0, 'supplier', 16).')', + 'nomtcheck' => true, + 'inv' => true + ) + ); + + foreach ($lines as $line) { - if ($mt) + foreach ($line['var'] as $k => $mt) { - print ""; - //print ""; - print ""; - print ""; - print ""; - print '"; - print '"; - print ""; + if (isset($line['nomtcheck']) || $mt) + { + print ""; + //print ""; + print ""; + print ""; + print ""; + + if (isset($line['inv'])) + { + print '"; + print '"; + } + else + { + print '"; + print '"; + } + + print ""; + } } } - // vat - foreach ($tabtva[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - print '"; - print '"; - print ""; - } - } - // localtax1 - foreach ($tablocaltax1[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - } - } - // localtax2 - foreach ($tablocaltax2[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - } - } - print ""; - // third party - //print ""; - print ""; - print ""; - - foreach ($tabttc[$key] as $k => $mt) - { - $companystatic->id=$tabcompany[$key]['id']; - $companystatic->name=$tabcompany[$key]['name']; - - print ""; - print '"; - print '"; - } - print ""; $var = !$var; } diff --git a/htdocs/compta/journal/sellsjournal.php b/htdocs/compta/journal/sellsjournal.php index ddb12839bf4..1192248ebac 100755 --- a/htdocs/compta/journal/sellsjournal.php +++ b/htdocs/compta/journal/sellsjournal.php @@ -178,17 +178,15 @@ else { */ -$i = 0; -print "
".$langs->trans("JournalNum")."".$langs->trans("Type")."".$langs->trans("Debi print "
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$langs->trans("Products")."'.($mt>=0?price($mt):'')."'.($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$line['label']."'.($mt<0?price(-$mt):'')."'.($mt>=0?price($mt):'')."'.($mt>=0?price($mt):'')."'.($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$langs->trans("VAT")."'.($mt>=0?price($mt):'')."'.($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$langs->transcountrynoentities("LT1",$mysoc->country_code)."".($mt>=0?price($mt):'')."".($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$langs->transcountrynoentities("LT2",$mysoc->country_code)."".($mt>=0?price($mt):'')."".($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->trans("ThirdParty"); - print ' ('.$companystatic->getNomUrl(0,'supplier',16).')'; - print "'.($mt<0?price(-$mt):'')."'.($mt>=0?price($mt):'')."
"; -print ""; +print '
'; +print ''; //print ""; -print ""; -print ""; -print ""; +print ''; +print ''; +print ''; print "\n"; $var=true; -$r=''; $invoicestatic=new Facture($db); $companystatic=new Client($db); @@ -199,74 +197,62 @@ foreach ($tabfac as $key => $val) $invoicestatic->ref=$val["ref"]; $invoicestatic->type=$val["type"]; - print ""; - // third party - //print ""; - print ""; - print ""; - foreach ($tabttc[$key] as $k => $mt) + $companystatic->id=$tabcompany[$key]['id']; + $companystatic->name=$tabcompany[$key]['name']; + $companystatic->client=$tabcompany[$key]['client']; + + $lines = array( + array( + 'var' => $tabttc[$key], + 'label' => $langs->trans('ThirdParty').' ('.$companystatic->getNomUrl(0, 'customer', 16).')', + 'nomtcheck' => true, + 'inv' => true + ), + array( + 'var' => $tabht[$key], + 'label' => $langs->trans('Products'), + ), + array( + 'var' => $tabtva[$key], + 'label' => $langs->trans('VAT') + ), + array( + 'var' => $tablocaltax1[$key], + 'label' => $langs->transcountry('LT1', $mysoc->country_code) + ), + array( + 'var' => $tablocaltax2[$key], + 'label' => $langs->transcountry('LT2', $mysoc->country_code) + ) + ); + + foreach ($lines as $line) { - $companystatic->id=$tabcompany[$key]['id']; - $companystatic->name=$tabcompany[$key]['name']; - $companystatic->client=$tabcompany[$key]['client']; - print ""; - } - print ""; - // product - foreach ($tabht[$key] as $k => $mt) - { - if ($mt) + foreach ($line['var'] as $k => $mt) { - print ""; - //print ""; - print ""; - print ""; - print ""; + if (isset($line['nomtcheck']) || $mt) + { + print ""; + //print ""; + print ""; + print ""; + print ""; + + if (isset($line['inv'])) + { + print '"; + print '"; + } + else + { + print '"; + print '"; + } + + print ""; + } } } - // vat - foreach ($tabtva[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - } - } - // localtax1 - foreach ($tablocaltax1[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - } - } - // localtax2 - foreach ($tablocaltax2[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - } - } $var = !$var; } diff --git a/htdocs/holiday/admin/holiday.php b/htdocs/holiday/admin/holiday.php index 583ab228c9a..6e7216332ea 100644 --- a/htdocs/holiday/admin/holiday.php +++ b/htdocs/holiday/admin/holiday.php @@ -278,7 +278,7 @@ $var=true; /*$var=!$var; print ''."\n"; -print ''."\n"; +print ''."\n"; print ''."\n"; print ''."\n"; */ diff --git a/htdocs/langs/es_ES/admin.lang b/htdocs/langs/es_ES/admin.lang index c42a026c87f..ec45e7eb6a9 100644 --- a/htdocs/langs/es_ES/admin.lang +++ b/htdocs/langs/es_ES/admin.lang @@ -336,7 +336,7 @@ EnterRefToBuildUrl=Introduzca la referencia del objeto %s GetSecuredUrl=Obtener la URL calculada ButtonHideUnauthorized=Ocultar los botones de acciones no autorizadas en vez de mostrarlos atenuados TotalNumberOfActivatedModules=Número total de módulos activados: %s -YouMustEnableOneModule=Debe activar al menos 1 módulo. +YouMustEnableOneModule=Debe activar al menos un módulo. ProductVatMassChange=Modificar IVA en masa ProductVatMassChangeDesc=Esta página le permite cambiar el tipo de IVA definido en los productos o servicios de un valor a otro. Tenga en cuenta que el cambio se lleva a cabo en masa sobre toda la base de datos. OldVATRates=Tasa de IVA antigua From c3c57351d05c38e90ec7776fed7d06d0da4e9ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sat, 20 Apr 2013 12:57:50 +0200 Subject: [PATCH 55/97] Updated copyright --- htdocs/admin/dict.php | 4 ++-- htdocs/compta/journal/sellsjournal.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 39e8bbf0a2d..ac69dc90d8a 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -6,9 +6,9 @@ * Copyright (C) 2010-2011 Juanjo Menent * Copyright (C) 2011 Philippe Grand * Copyright (C) 2011 Remy Younes - * Copyright (C) 2012 Marcos García + * Copyright (C) 2012-2013 Marcos García * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2011-2012 Alexandre Spangaro + * Copyright (C) 2011-2012 Alexandre Spangaro * * 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 diff --git a/htdocs/compta/journal/sellsjournal.php b/htdocs/compta/journal/sellsjournal.php index 1192248ebac..c4f5180ab8f 100755 --- a/htdocs/compta/journal/sellsjournal.php +++ b/htdocs/compta/journal/sellsjournal.php @@ -3,8 +3,8 @@ * Copyright (C) 2007-2010 Jean Heimburger * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin - * Copyright (C) 2011-2012 Alexandre Spangaro - * Copyright (C) 2013 Marcos García + * Copyright (C) 2011-2012 Alexandre Spangaro + * Copyright (C) 2013 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 From 1e00ccd07dd0cda704028b0f6bf16f0af0aa2f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sat, 20 Apr 2013 12:59:34 +0200 Subject: [PATCH 56/97] Purchases and sellsjournal used tabs in their copyright comment. Restored 'em --- htdocs/compta/journal/purchasesjournal.php | 4 ++-- htdocs/compta/journal/sellsjournal.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/journal/purchasesjournal.php b/htdocs/compta/journal/purchasesjournal.php index 124ae380d09..d3b5e2da41c 100755 --- a/htdocs/compta/journal/purchasesjournal.php +++ b/htdocs/compta/journal/purchasesjournal.php @@ -3,8 +3,8 @@ * Copyright (C) 2007-2010 Jean Heimburger * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin - * Copyright (C) 2011-2012 Alexandre Spangaro - * Copyright (C) 2013 Marcos García + * Copyright (C) 2011-2012 Alexandre spangaro + * Copyright (C) 2013 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 diff --git a/htdocs/compta/journal/sellsjournal.php b/htdocs/compta/journal/sellsjournal.php index c4f5180ab8f..e1d780fcce4 100755 --- a/htdocs/compta/journal/sellsjournal.php +++ b/htdocs/compta/journal/sellsjournal.php @@ -4,7 +4,7 @@ * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin * Copyright (C) 2011-2012 Alexandre Spangaro - * Copyright (C) 2013 Marcos García + * Copyright (C) 2013 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 From dd8a84bce349a49995fb9950cea9379a5398f351 Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 20 Apr 2013 13:08:06 +0200 Subject: [PATCH 57/97] Fix [ bug #833 ] Accounting journals are broken --- htdocs/compta/journal/purchasesjournal.php | 13 +++++++++---- htdocs/compta/journal/sellsjournal.php | 16 +++++++++------- htdocs/core/lib/functions.lib.php | 8 ++++---- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/htdocs/compta/journal/purchasesjournal.php b/htdocs/compta/journal/purchasesjournal.php index a37d5c240df..a67fab41761 100755 --- a/htdocs/compta/journal/purchasesjournal.php +++ b/htdocs/compta/journal/purchasesjournal.php @@ -99,12 +99,12 @@ $sql = "SELECT f.rowid, f.ref_supplier, f.type, f.datef, f.libelle,"; $sql.= " fd.total_ttc, fd.tva_tx, fd.total_ht, fd.tva as total_tva, fd.product_type, fd.localtax1_tx, fd.localtax2_tx, fd.total_localtax1, fd.total_localtax2,"; $sql.= " s.rowid as socid, s.nom as name, s.code_compta_fournisseur,"; $sql.= " p.rowid as pid, p.ref as ref, p.accountancy_code_buy,"; -$sql.= " ct.accountancy_code_buy as account_tva, ct.recuperableonly,"; -$sql.= " ctl1.accountancy_code_buy as account_localtax1, ctl2.accountancy_code_buy as account_localtax2"; +$sql.= " ct.accountancy_code_buy as account_tva, ct.recuperableonly"; +//$sql.= " ctl1.accountancy_code_buy as account_localtax1, ctl2.accountancy_code_buy as account_localtax2"; $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn_det fd"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ct ON fd.tva_tx = ct.taux AND fd.info_bits = ct.recuperableonly AND ct.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl1 ON fd.localtax1_tx = ctl1.localtax1 AND ctl1.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl2 ON fd.localtax2_tx = ctl2.localtax2 AND ctl2.fk_pays = '".$idpays."'"; +//$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl1 ON fd.localtax1_tx = ctl1.localtax1 AND ctl1.fk_pays = '".$idpays."'"; +//$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl2 ON fd.localtax2_tx = ctl2.localtax2 AND ctl2.fk_pays = '".$idpays."'"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = fd.fk_product"; $sql.= " JOIN ".MAIN_DB_PREFIX."facture_fourn f ON f.rowid = fd.fk_facture_fourn"; $sql.= " JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid = f.fk_soc" ; @@ -145,6 +145,11 @@ if ($result) $compta_localtax1 = (! empty($obj->account_localtax1)?$obj->account_localtax1:$langs->trans("CodeNotDef")); $compta_localtax2 = (! empty($obj->account_localtax2)?$obj->account_localtax2:$langs->trans("CodeNotDef")); + $account_localtax1=getLocalTaxesFromRate($obj->tva_tx, 1, $mysoc); + $compta_localtax1= (! empty($account_localtax1[2])?$account_localtax1[2]:$langs->trans("CodeNotDef")); + $account_localtax2=getLocalTaxesFromRate($obj->tva_tx, 2, $mysoc); + $compta_localtax2= (! empty($account_localtax2[2])?$account_localtax2[2]:$langs->trans("CodeNotDef")); + $tabfac[$obj->rowid]["date"] = $obj->datef; $tabfac[$obj->rowid]["ref"] = $obj->ref_supplier; $tabfac[$obj->rowid]["type"] = $obj->type; diff --git a/htdocs/compta/journal/sellsjournal.php b/htdocs/compta/journal/sellsjournal.php index ddb12839bf4..e6ee371dd1d 100755 --- a/htdocs/compta/journal/sellsjournal.php +++ b/htdocs/compta/journal/sellsjournal.php @@ -102,15 +102,12 @@ $sql = "SELECT f.rowid, f.facnumber, f.type, f.datef, f.ref_client,"; $sql.= " fd.product_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.total_ttc, fd.localtax1_tx, fd.localtax2_tx, fd.total_localtax1, fd.total_localtax2,"; $sql.= " s.rowid as socid, s.nom as name, s.code_compta, s.client,"; $sql.= " p.rowid as pid, p.ref as pref, p.accountancy_code_sell,"; -$sql.= " ct.accountancy_code_sell as account_tva, ct.recuperableonly,"; -$sql.= " ctl1.accountancy_code_sell as account_localtax1, ctl2.accountancy_code_sell as account_localtax2"; +$sql.= " ct.accountancy_code_sell as account_tva, ct.recuperableonly"; $sql.= " FROM ".MAIN_DB_PREFIX."facturedet fd"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = fd.fk_product"; $sql.= " JOIN ".MAIN_DB_PREFIX."facture f ON f.rowid = fd.fk_facture"; $sql.= " JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid = f.fk_soc"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ct ON fd.tva_tx = ct.taux AND fd.info_bits = ct.recuperableonly AND ct.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl1 ON fd.localtax1_tx = ctl1.localtax1 AND ctl1.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl2 ON fd.localtax2_tx = ctl2.localtax2 AND ctl2.fk_pays = '".$idpays."'"; $sql.= " WHERE f.entity = ".$conf->entity; $sql.= " AND f.fk_statut > 0"; if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)"; @@ -118,7 +115,7 @@ else $sql.= " AND f.type IN (0,1,2,3)"; $sql.= " AND fd.product_type IN (0,1)"; if ($date_start && $date_end) $sql .= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; $sql.= " ORDER BY f.rowid"; - +print $sql; $result = $db->query($sql); if ($result) { @@ -129,6 +126,8 @@ if ($result) $tablocaltax2 = array(); $tabttc = array(); $tabcompany = array(); + $account_localtax1=0; + $account_localtax2=0; $num = $db->num_rows($result); $i=0; @@ -147,9 +146,12 @@ if ($result) } $cpttva = (! empty($conf->global->COMPTA_VAT_ACCOUNT)?$conf->global->COMPTA_VAT_ACCOUNT:$langs->trans("CodeNotDef")); $compta_tva = (! empty($obj->account_tva)?$obj->account_tva:$cpttva); - $compta_localtax1 = (! empty($obj->account_localtax1)?$obj->account_localtax1:$langs->trans("CodeNotDef")); - $compta_localtax2 = (! empty($obj->account_localtax2)?$obj->account_localtax2:$langs->trans("CodeNotDef")); + $account_localtax1=getLocalTaxesFromRate($obj->tva_tx, 1, $mysoc); + $compta_localtax1= (! empty($account_localtax1[3])?$account_localtax1[3]:$langs->trans("CodeNotDef")); + $account_localtax2=getLocalTaxesFromRate($obj->tva_tx, 2, $mysoc); + $compta_localtax2= (! empty($account_localtax2[3])?$account_localtax2[3]:$langs->trans("CodeNotDef")); + //la ligne facture $tabfac[$obj->rowid]["date"] = $obj->datef; $tabfac[$obj->rowid]["ref"] = $obj->facnumber; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 46f65283a3e..ae35ca9bcee 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2846,7 +2846,7 @@ function getLocalTaxesFromRate($vatrate, $local, $thirdparty) dol_syslog("getLocalTaxesFromRate vatrate=".$vatrate." local=".$local." thirdparty id=".(is_object($thirdparty)?$thirdparty->id:'')); // Search local taxes - $sql = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type"; + $sql = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type,t.accountancy_code_sell,t.accountancy_code_buy"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_pays as p"; $sql .= " WHERE t.fk_pays = p.rowid AND p.code = '".$thirdparty->country_code."'"; $sql .= " AND t.taux = ".$vatrate." AND t.active = 1"; @@ -2855,9 +2855,9 @@ function getLocalTaxesFromRate($vatrate, $local, $thirdparty) if ($resql) { $obj = $db->fetch_object($resql); - if ($local == 1) return array($obj->localtax1_type, $obj->localtax1); - elseif ($local == 2) return array($obj->localtax2_type, $obj->localtax2); - else return array($obj->localtax1_type, $obj->localtax1, $obj->localtax2_type, $obj->localtax2); + if ($local == 1) return array($obj->localtax1_type, $obj->localtax1,$obj->accountancy_code_sell,$obj->accountancy_code_buy); + elseif ($local == 2) return array($obj->localtax2_type, $obj->localtax2,$obj->accountancy_code_sell,$obj->accountancy_code_buy); + else return array($obj->localtax1_type, $obj->localtax1, $obj->localtax2_type, $obj->localtax2,$obj->accountancy_code_sell,$obj->accountancy_code_buy); } return 0; From 571037d39641e416315ac5e47a231e1dd801c8a1 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 20 Apr 2013 13:09:26 +0200 Subject: [PATCH 58/97] Fix : consumption on company --- htdocs/societe/consumption.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index 7c0a4c0332f..b364dbd9461 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -295,14 +295,14 @@ if ($sql_select) // Define output language if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - $this->fetch_thirdparty(); + //$object->fetch_thirdparty(); $prod = new Product($db); $prod->fetch($objp->fk_product); $outputlangs = $langs; $newlang=''; if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); - if (empty($newlang)) $newlang=$this->client->default_lang; + if (empty($newlang)) $newlang=$object->default_lang; if (! empty($newlang)) { $outputlangs = new Translate("",$conf); From 129da11a52b957065d9659f01b8c096a9e21efeb Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 20 Apr 2013 13:13:33 +0200 Subject: [PATCH 59/97] Fix : consumption --- htdocs/societe/consumption.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index b364dbd9461..aff1fded6d3 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -295,7 +295,6 @@ if ($sql_select) // Define output language if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - //$object->fetch_thirdparty(); $prod = new Product($db); $prod->fetch($objp->fk_product); From 61b78666a2550e249d4c45f2440f5b3cf3a6ac98 Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 20 Apr 2013 13:29:40 +0200 Subject: [PATCH 60/97] Change-Id: I07221687a67be28376ee9146eaa46567486300ce --- htdocs/compta/journal/purchasesjournal.php | 3 --- htdocs/compta/journal/sellsjournal.php | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/htdocs/compta/journal/purchasesjournal.php b/htdocs/compta/journal/purchasesjournal.php index a67fab41761..c091382fa6c 100755 --- a/htdocs/compta/journal/purchasesjournal.php +++ b/htdocs/compta/journal/purchasesjournal.php @@ -100,11 +100,8 @@ $sql.= " fd.total_ttc, fd.tva_tx, fd.total_ht, fd.tva as total_tva, fd.product_t $sql.= " s.rowid as socid, s.nom as name, s.code_compta_fournisseur,"; $sql.= " p.rowid as pid, p.ref as ref, p.accountancy_code_buy,"; $sql.= " ct.accountancy_code_buy as account_tva, ct.recuperableonly"; -//$sql.= " ctl1.accountancy_code_buy as account_localtax1, ctl2.accountancy_code_buy as account_localtax2"; $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn_det fd"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ct ON fd.tva_tx = ct.taux AND fd.info_bits = ct.recuperableonly AND ct.fk_pays = '".$idpays."'"; -//$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl1 ON fd.localtax1_tx = ctl1.localtax1 AND ctl1.fk_pays = '".$idpays."'"; -//$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl2 ON fd.localtax2_tx = ctl2.localtax2 AND ctl2.fk_pays = '".$idpays."'"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = fd.fk_product"; $sql.= " JOIN ".MAIN_DB_PREFIX."facture_fourn f ON f.rowid = fd.fk_facture_fourn"; $sql.= " JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid = f.fk_soc" ; diff --git a/htdocs/compta/journal/sellsjournal.php b/htdocs/compta/journal/sellsjournal.php index e6ee371dd1d..3963cce7954 100755 --- a/htdocs/compta/journal/sellsjournal.php +++ b/htdocs/compta/journal/sellsjournal.php @@ -115,7 +115,7 @@ else $sql.= " AND f.type IN (0,1,2,3)"; $sql.= " AND fd.product_type IN (0,1)"; if ($date_start && $date_end) $sql .= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; $sql.= " ORDER BY f.rowid"; -print $sql; + $result = $db->query($sql); if ($result) { From ef13ea8690df67a35e500a66a14e7bcb4eb00037 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 20 Apr 2013 14:33:00 +0200 Subject: [PATCH 61/97] New # 786 : can link project from supplier invoice creation --- htdocs/fourn/class/fournisseur.facture.class.php | 2 ++ htdocs/fourn/facture/fiche.php | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 759258888cf..ac138636b08 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -141,6 +141,7 @@ class FactureFournisseur extends CommonInvoice $sql.= ", fk_soc"; $sql.= ", datec"; $sql.= ", datef"; + $sql.= ", fk_projet"; $sql.= ", note_private"; $sql.= ", note_public"; $sql.= ", fk_user_author"; @@ -154,6 +155,7 @@ class FactureFournisseur extends CommonInvoice $sql.= ", ".$this->socid; $sql.= ", '".$this->db->idate($now)."'"; $sql.= ", '".$this->db->idate($this->date)."'"; + $sql.= ", ".$this->fk_project; $sql.= ", '".$this->db->escape($this->note_private)."'"; $sql.= ", '".$this->db->escape($this->note_public)."'"; $sql.= ", ".$user->id.","; diff --git a/htdocs/fourn/facture/fiche.php b/htdocs/fourn/facture/fiche.php index 6ed624b82fa..23ed291c681 100644 --- a/htdocs/fourn/facture/fiche.php +++ b/htdocs/fourn/facture/fiche.php @@ -41,6 +41,8 @@ if (!empty($conf->produit->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; if (!empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +if (! empty($conf->projet->enabled)) + require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; $langs->load('bills'); @@ -271,6 +273,7 @@ elseif ($action == 'add' && $user->rights->fournisseur->facture->creer) // Creation facture $object->ref = $_POST['ref']; $object->ref_supplier = $_POST['ref_supplier']; + $object->fk_project = GETPOST('projectid'); $object->socid = $_POST['socid']; $object->libelle = $_POST['libelle']; $object->date = $datefacture; @@ -1153,6 +1156,15 @@ if ($action == 'create') print ''; + + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load('projects'); + print ''; + } print ''; print ''; + } + } + + print "
".$langs->trans("JournalNum")."".$langs->trans("Date")."".$langs->trans("Piece").' ('.$langs->trans("InvoiceRef").")".$langs->trans("Account")."".$langs->trans("Type")."".$langs->trans("Debit")."".$langs->trans("Credit")."'.$langs->trans('Date').''.$langs->trans('Piece').' ('.$langs->trans('InvoiceRef').')'.$langs->trans('Account').''.$langs->trans('Type').''.$langs->trans('Debit').''.$langs->trans('Credit').'
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->trans("ThirdParty"); - print ' ('.$companystatic->getNomUrl(0,'customer',16).')'; - print "".($mt>=0?price($mt):'')."".($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->trans("Products")."".($mt<0?price(-$mt):'')."".($mt>=0?price($mt):'')."
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$line['label']."'.($mt>=0?price($mt):'')."'.($mt<0?price(-$mt):'')."'.($mt<0?price(-$mt):'')."'.($mt>=0?price($mt):'')."
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->trans("VAT")."".($mt<0?price(-$mt):'')."".($mt>=0?price($mt):'')."
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->transcountrynoentities("LT1",$mysoc->country_code)."".($mt<0?price(-$mt):'')."".($mt>=0?price($mt):'')."
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->transcountrynoentities("LT2",$mysoc->country_code)."".($mt<0?price(-$mt):'')."".($mt>=0?price($mt):'')."
'.$langs->trans('GroupToValidateCP').''.$langs->trans('GroupToValidateCP').''.$cp->selectUserGroup('userGroup').'
'.$langs->trans('DateMaxPayment').''; $form->select_date($datedue,'ech','','','',"add",1,1); print '
'.$langs->trans('Project').''; + select_projects(-1, $projectid, 'projectid'); + print '
'.$langs->trans('NotePublic').''; From cae761d522642888fbe409b21d04aafd3fc52f39 Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 20 Apr 2013 17:10:03 +0200 Subject: [PATCH 62/97] [ task #640 ] Better deposit invoice management --- htdocs/compta/facture.php | 3875 +++++++++++++++++---------------- htdocs/langs/en_US/bills.lang | 2 + htdocs/langs/es_ES/bills.lang | 2 + htdocs/langs/fr_FR/bills.lang | 2 + 4 files changed, 1983 insertions(+), 1898 deletions(-) diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 590901a937a..2a02522bbcc 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -794,6 +794,8 @@ else if ($action == 'add' && $user->rights->facture->creer) } } + + // Standard or deposit or proforma invoice if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) { @@ -872,126 +874,197 @@ else if ($action == 'add' && $user->rights->facture->creer) if ($id > 0) { - dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); - - $classname = ucfirst($subelement); - $srcobject = new $classname($db); - - dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines"); - $result=$srcobject->fetch($object->origin_id); - if ($result > 0) - { - $lines = $srcobject->lines; - if (empty($lines) && method_exists($srcobject,'fetch_lines')) $lines = $srcobject->fetch_lines(); - - $fk_parent_line=0; - $num=count($lines); - - for ($i=0;$i<$num;$i++) - { - $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); - $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); - - if ($lines[$i]->subprice < 0) + //If deposit invoice + if ($_POST['type'] == 3) { + $typeamount=GETPOST('typedeposit','alpha'); + $valuedeposit=GETPOST('valuedeposit','int'); + + if ($typeamount=='amount') { + $amountdeposit=$valuedeposit; + }else { + $amountdeposit=0; + + dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add deposit line"); + $result=$srcobject->fetch($object->origin_id); + if ($result > 0) { - // Negative line, we create a discount line - $discount = new DiscountAbsolute($db); - $discount->fk_soc=$object->socid; - $discount->amount_ht=abs($lines[$i]->total_ht); - $discount->amount_tva=abs($lines[$i]->total_tva); - $discount->amount_ttc=abs($lines[$i]->total_ttc); - $discount->tva_tx=$lines[$i]->tva_tx; - $discount->fk_user=$user->id; - $discount->description=$desc; - $discountid=$discount->create($user); - if ($discountid > 0) + $totalamount=0; + $lines = $srcobject->lines; + $num=count($lines); + for ($i=0;$i<$num;$i++) { - $result=$object->insert_discount($discountid); // This include link_to_invoice + $totalamount=+$lines[$i]->subprice; } - else - { - $mesgs[]=$discount->error; - $error++; - break; + + if ($totalamount!=0) { + $amountdeposit=($totalamount*$valuedeposit)/100; } } else { - // Positive line - $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); + $mesgs[]=$srcobject->error; + $error++; + } + + } + + $result = $object->addline( + $id, + $langs->trans('Deposit'), + $amountdeposit, //subprice + 1, //quantity + $lines[$i]->tva_tx, + 0, //localtax1_tx + 0, //localtax2_tx + 0, //fk_product + 0, //remise_percent + 0, //date_start + 0, //date_end + 0, + $lines[$i]->info_bits, //info_bits + 0, //info_bits + 'HT', + 0, + 0, //product_type + 1, + $lines[$i]->special_code, + $object->origin, + 0, + 0, + 0, + 0, + $langs->trans('Deposit') + ); + - // Date start - $date_start=false; - if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; - if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; - if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; + }else { - //Date end - $date_end=false; - if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; - if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; - if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; + dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); - // Reset fk_parent_line for no child products and special product - if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { - $fk_parent_line = 0; - } + $classname = ucfirst($subelement); + $srcobject = new $classname($db); - $result = $object->addline( - $id, - $desc, - $lines[$i]->subprice, - $lines[$i]->qty, - $lines[$i]->tva_tx, - $lines[$i]->localtax1_tx, - $lines[$i]->localtax2_tx, - $lines[$i]->fk_product, - $lines[$i]->remise_percent, - $date_start, - $date_end, - 0, - $lines[$i]->info_bits, - $lines[$i]->fk_remise_except, - 'HT', - 0, - $product_type, - $lines[$i]->rang, - $lines[$i]->special_code, - $object->origin, - $lines[$i]->rowid, - $fk_parent_line, - $lines[$i]->fk_fournprice, - $lines[$i]->pa_ht, - $label - ); + dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines"); + $result=$srcobject->fetch($object->origin_id); + if ($result > 0) + { + $lines = $srcobject->lines; + if (empty($lines) && method_exists($srcobject,'fetch_lines')) $lines = $srcobject->fetch_lines(); - if ($result > 0) + $fk_parent_line=0; + $num=count($lines); + + for ($i=0;$i<$num;$i++) + { + $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); + $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); + + if ($lines[$i]->subprice < 0) { - $lineid=$result; + // Negative line, we create a discount line + $discount = new DiscountAbsolute($db); + $discount->fk_soc=$object->socid; + $discount->amount_ht=abs($lines[$i]->total_ht); + $discount->amount_tva=abs($lines[$i]->total_tva); + $discount->amount_ttc=abs($lines[$i]->total_ttc); + $discount->tva_tx=$lines[$i]->tva_tx; + $discount->fk_user=$user->id; + $discount->description=$desc; + $discountid=$discount->create($user); + if ($discountid > 0) + { + $result=$object->insert_discount($discountid); // This include link_to_invoice + } + else + { + $mesgs[]=$discount->error; + $error++; + break; + } } else { - $lineid=0; - $error++; - break; - } + // Positive line + $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); - // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) { - $fk_parent_line = $result; + // Date start + $date_start=false; + if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; + if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; + if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; + + //Date end + $date_end=false; + if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; + if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; + if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; + + // Reset fk_parent_line for no child products and special product + if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { + $fk_parent_line = 0; + } + + $result = $object->addline( + $id, + $desc, + $lines[$i]->subprice, + $lines[$i]->qty, + $lines[$i]->tva_tx, + $lines[$i]->localtax1_tx, + $lines[$i]->localtax2_tx, + $lines[$i]->fk_product, + $lines[$i]->remise_percent, + $date_start, + $date_end, + 0, + $lines[$i]->info_bits, + $lines[$i]->fk_remise_except, + 'HT', + 0, + $product_type, + $lines[$i]->rang, + $lines[$i]->special_code, + $object->origin, + $lines[$i]->rowid, + $fk_parent_line, + $lines[$i]->fk_fournprice, + $lines[$i]->pa_ht, + $label + ); + + if ($result > 0) + { + $lineid=$result; + } + else + { + $lineid=0; + $error++; + break; + } + + // Defined the new fk_parent_line + if ($result > 0 && $lines[$i]->product_type == 9) { + $fk_parent_line = $result; + } } } - } - // Hooks - $parameters=array('objFrom'=>$srcobject); - $reshook=$hookmanager->executeHooks('createFrom',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if ($reshook < 0) $error++; - } - else - { - $mesgs[]=$srcobject->error; - $error++; + // Hooks + $parameters=array('objFrom'=>$srcobject); + $reshook=$hookmanager->executeHooks('createFrom',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) $error++; + } + else + { + $mesgs[]=$srcobject->error; + $error++; + } } } else @@ -1513,7 +1586,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO // $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf'; // if (is_readable($file)) - // { + // { if ($_POST['sendto']) { // Le destinataire a ete fourni via le champ libre @@ -1658,2055 +1731,2061 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO $mesgs[]='
'.$langs->trans('ErrorCantReadFile',$file).'
'; dol_syslog('Failed to read file: '.$file); } - } - else - { - $langs->load("other"); - $mesgs[]='
'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'
'; - dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.'); - } - - $action = 'presend'; + } + else + { + $langs->load("other"); + $mesgs[]='
'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'
'; + dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.'); } - /* - * Generate document - */ - else if ($action == 'builddoc') // En get ou en post + $action = 'presend'; +} + +/* + * Generate document +*/ +else if ($action == 'builddoc') // En get ou en post +{ + $object->fetch($id); + $object->fetch_thirdparty(); + + if (GETPOST('model')) $object->setDocModel($user, GETPOST('model')); + if (GETPOST('fk_bank')) $object->fk_bank=GETPOST('fk_bank'); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) { - $object->fetch($id); + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + else + { + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); + exit; + } +} + +// Remove file in doc form +else if ($action == 'remove_file') +{ + if ($object->fetch($id)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $object->fetch_thirdparty(); - if (GETPOST('model')) $object->setDocModel($user, GETPOST('model')); - if (GETPOST('fk_bank')) $object->fk_bank=GETPOST('fk_bank'); + $langs->load("other"); + $upload_dir = $conf->facture->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret=dol_delete_file($file,0,0,0,$object); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + $action=''; + } +} - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) +if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) +{ + if ($action == 'addcontact') + { + $result = $object->fetch($id); + + if ($result > 0 && $id > 0) { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); } - $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) + + if ($result >= 0) { - dol_print_error($db,$result); + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); exit; } else { - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); - exit; + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $langs->load("errors"); + $mesgs[] = '
'.$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType").'
'; + } + else + { + $mesgs[] = '
'.$object->error.'
'; + } } } - // Remove file in doc form - else if ($action == 'remove_file') + // bascule du statut d'un contact + else if ($action == 'swapstatut') { if ($object->fetch($id)) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $object->fetch_thirdparty(); - - $langs->load("other"); - $upload_dir = $conf->facture->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret=dol_delete_file($file,0,0,0,$object); - if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); - else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); - $action=''; - } - } - - if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) - { - if ($action == 'addcontact') - { - $result = $object->fetch($id); - - if ($result > 0 && $id > 0) - { - $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); - $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); - } - - if ($result >= 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else - { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') - { - $langs->load("errors"); - $mesgs[] = '
'.$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType").'
'; - } - else - { - $mesgs[] = '
'.$object->error.'
'; - } - } - } - - // bascule du statut d'un contact - else if ($action == 'swapstatut') - { - if ($object->fetch($id)) - { - $result=$object->swapContactStatus(GETPOST('ligne')); - } - else - { - dol_print_error($db); - } - } - - // Efface un contact - else if ($action == 'deletecontact') - { - $object->fetch($id); - $result = $object->delete_contact($lineid); - - if ($result >= 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else { - dol_print_error($db); - } - } - } - - if ($action == 'update_extras') - { - // Fill array 'array_options' with data from add form - $extralabels=$extrafields->fetch_name_optionals_label('facture'); - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('invoicedao')); - $parameters=array('id'=>$object->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$object->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - else if ($reshook < 0) $error++; - - } - - - /* - * View - */ - - $form = new Form($db); - $formother=new FormOther($db); - $formfile = new FormFile($db); - $bankaccountstatic=new Account($db); - $now=dol_now(); - - llxHeader('',$langs->trans('Bill'),'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes'); - - - - /********************************************************************* - * - * Mode creation - * - **********************************************************************/ - if ($action == 'create') - { - $facturestatic=new Facture($db); - $extralabels=$extrafields->fetch_name_optionals_label('facture'); - - print_fiche_titre($langs->trans('NewBill')); - - $soc = new Societe($db); - if ($socid>0) $res=$soc->fetch($socid); - - if (! empty($origin) && ! empty($originid)) - { - // Parse element/subelement (ex: project_task) - $element = $subelement = $origin; - if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) - { - $element = $regs[1]; - $subelement = $regs[2]; - } - - if ($element == 'project') - { - $projectid=$originid; - } - else - { - // For compatibility - if ($element == 'order' || $element == 'commande') { - $element = $subelement = 'commande'; - } - if ($element == 'propal') { - $element = 'comm/propal'; $subelement = 'propal'; - } - if ($element == 'contract') { - $element = $subelement = 'contrat'; - } - if ($element == 'shipping') { - $element = $subelement = 'expedition'; - } - - dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); - - $classname = ucfirst($subelement); - $objectsrc = new $classname($db); - $objectsrc->fetch($originid); - if (empty($objectsrc->lines) && method_exists($objectsrc,'fetch_lines')) $objectsrc->fetch_lines(); - $objectsrc->fetch_thirdparty(); - - $projectid = (! empty($objectsrc->fk_project)?$objectsrc->fk_project:''); - $ref_client = (! empty($objectsrc->ref_client)?$objectsrc->ref_client:''); - $ref_int = (! empty($objectsrc->ref_int)?$objectsrc->ref_int:''); - - $soc = $objectsrc->thirdparty; - $cond_reglement_id = (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1)); - $mode_reglement_id = (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0)); - $remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0)); - $remise_absolue = (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0)); - $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; - } + $result=$object->swapContactStatus(GETPOST('ligne')); } else { - $cond_reglement_id = $soc->cond_reglement_id; - $mode_reglement_id = $soc->mode_reglement_id; - $remise_percent = $soc->remise_percent; - $remise_absolue = 0; + dol_print_error($db); + } + } + + // Efface un contact + else if ($action == 'deletecontact') + { + $object->fetch($id); + $result = $object->delete_contact($lineid); + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else { + dol_print_error($db); + } + } +} + +if ($action == 'update_extras') +{ + // Fill array 'array_options' with data from add form + $extralabels=$extrafields->fetch_name_optionals_label('facture'); + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('invoicedao')); + $parameters=array('id'=>$object->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$object->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + +} + + +/* + * View +*/ + +$form = new Form($db); +$formother=new FormOther($db); +$formfile = new FormFile($db); +$bankaccountstatic=new Account($db); +$now=dol_now(); + +llxHeader('',$langs->trans('Bill'),'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes'); + + + +/********************************************************************* + * +* Mode creation +* +**********************************************************************/ +if ($action == 'create') +{ + $facturestatic=new Facture($db); + $extralabels=$extrafields->fetch_name_optionals_label('facture'); + + print_fiche_titre($langs->trans('NewBill')); + + $soc = new Societe($db); + if ($socid>0) $res=$soc->fetch($socid); + + if (! empty($origin) && ! empty($originid)) + { + // Parse element/subelement (ex: project_task) + $element = $subelement = $origin; + if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) + { + $element = $regs[1]; + $subelement = $regs[2]; + } + + if ($element == 'project') + { + $projectid=$originid; + } + else + { + // For compatibility + if ($element == 'order' || $element == 'commande') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } + if ($element == 'shipping') { + $element = $subelement = 'expedition'; + } + + dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); + + $classname = ucfirst($subelement); + $objectsrc = new $classname($db); + $objectsrc->fetch($originid); + if (empty($objectsrc->lines) && method_exists($objectsrc,'fetch_lines')) $objectsrc->fetch_lines(); + $objectsrc->fetch_thirdparty(); + + $projectid = (! empty($objectsrc->fk_project)?$objectsrc->fk_project:''); + $ref_client = (! empty($objectsrc->ref_client)?$objectsrc->ref_client:''); + $ref_int = (! empty($objectsrc->ref_int)?$objectsrc->ref_int:''); + + $soc = $objectsrc->thirdparty; + $cond_reglement_id = (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1)); + $mode_reglement_id = (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0)); + $remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0)); + $remise_absolue = (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0)); $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; } - $absolute_discount=$soc->getAvailableDiscounts(); + } + else + { + $cond_reglement_id = $soc->cond_reglement_id; + $mode_reglement_id = $soc->mode_reglement_id; + $remise_percent = $soc->remise_percent; + $remise_absolue = 0; + $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; + } + $absolute_discount=$soc->getAvailableDiscounts(); - if (! empty($conf->use_javascript_ajax)) + if (! empty($conf->use_javascript_ajax)) + { + print ajax_combobox('fac_replacement'); + print ajax_combobox('fac_avoir'); + } + + print '
'; + print ''; + print ''; + if ($soc->id > 0) + print '' ."\n"; + print ''; + print ''; + print ''; + print ''; + print ''; + + print ''; + + // Ref + print ''; + + // Factures predefinies + if (empty($origin) && empty($originid) && $socid>0) + { + $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; + $sql.= ' WHERE r.fk_soc = '.$soc->id; + + $resql=$db->query($sql); + if ($resql) { - print ajax_combobox('fac_replacement'); - print ajax_combobox('fac_avoir'); - } + $num = $db->num_rows($resql); + $i = 0; - print ''; - print ''; - print ''; - if ($soc->id > 0) - print '' ."\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - - print '
'.$langs->trans('Ref').''.$langs->trans('Draft').'
'; - - // Ref - print ''; - - // Factures predefinies - if (empty($origin) && empty($originid) && $socid>0) - { - $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; - $sql.= ' WHERE r.fk_soc = '.$soc->id; - - $resql=$db->query($sql); - if ($resql) + if ($num > 0) { - $num = $db->num_rows($resql); - $i = 0; - - if ($num > 0) + print ''; + $objp = $db->fetch_object($resql); + print ''; + $i++; } - $db->free($resql); + print ''; } - else - { - dol_print_error($db); - } - } - - // Tiers - print ''; - print ''; - if($soc->id > 0) - { - print ''; + $db->free($resql); } else { - print ''; + dol_print_error($db); } - print ''."\n"; + } - // Type de facture - $facids=$facturestatic->list_replacable_invoices($soc->id); - if ($facids < 0) - { - dol_print_error($db,$facturestatic); - exit; - } - $options=""; - foreach ($facids as $facparam) - { - $options.=''; - } + // Tiers + print ''; + print ''; + if($soc->id > 0) + { + print ''; + } + else + { + print ''; + } + print ''."\n"; - $facids=$facturestatic->list_qualified_avoir_invoices($soc->id); - if ($facids < 0) - { - dol_print_error($db,$facturestatic); - exit; - } - $optionsav=""; - $newinvoice_static=new Facture($db); - foreach ($facids as $key => $valarray) - { - $newinvoice_static->id=$key; - $newinvoice_static->ref=$valarray['ref']; - $newinvoice_static->statut=$valarray['status']; - $newinvoice_static->type=$valarray['type']; - $newinvoice_static->paye=$valarray['paye']; + // Type de facture + $facids=$facturestatic->list_replacable_invoices($soc->id); + if ($facids < 0) + { + dol_print_error($db,$facturestatic); + exit; + } + $options=""; + foreach ($facids as $facparam) + { + $options.=''; + } - $optionsav.=''; - } + $facids=$facturestatic->list_qualified_avoir_invoices($soc->id); + if ($facids < 0) + { + dol_print_error($db,$facturestatic); + exit; + } + $optionsav=""; + $newinvoice_static=new Facture($db); + foreach ($facids as $key => $valarray) + { + $newinvoice_static->id=$key; + $newinvoice_static->ref=$valarray['ref']; + $newinvoice_static->statut=$valarray['status']; + $newinvoice_static->type=$valarray['type']; + $newinvoice_static->paye=$valarray['paye']; - print ''; + + if ($socid > 0) + { + // Discounts for third party + print ''; + } + + // Date invoice + print ''; + + // Payment term + print ''; + + // Payment mode + print ''; + + // Project + if (! empty($conf->projet->enabled) && $socid>0) + { + $langs->load('projects'); + print ''; + } + + // Other attributes + $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + print $object->showOptionals($extrafields,'edit'); + } + + // Modele PDF + print ''; + print '"; + + // Public note + print ''; + print ''; + print ''; + + // Private note + if (empty($user->societe_id)) + { + print ''; + print ''; + print ''; + } + + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) + { + // TODO for compatibility + if ($origin == 'contrat') + { + // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva + $objectsrc->remise_absolue=$remise_absolue; + $objectsrc->remise_percent=$remise_percent; + $objectsrc->update_price(1,-1,1); + } + + print "\n"; + print "\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''; + print ''; + + $newclassname=$classname; + if ($newclassname == 'Propal') $newclassname = 'CommercialProposal'; + elseif ($newclassname == 'Commande') $newclassname = 'Order'; + + print ''; + print ''; + print '"; + if ($mysoc->localtax1_assuj=="1") //Localtax1 RE + { + print '"; + } + + if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF + { + print '"; + } + print '"; + } + else + { + // Show deprecated optional form to add product line here + if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) + { + print ''; + print "\n"; } - } - - print "
'.$langs->trans('Ref').''.$langs->trans('Draft').'
'.$langs->trans('CreateFromRepeatableInvoice').''; + print '
'.$langs->trans('CreateFromRepeatableInvoice').''; - print '
'.$langs->trans('Customer').''; - print $soc->getNomUrl(1); - print ''; - print ''; - print $form->select_company('','socid','s.client = 1 OR s.client = 3',1); - print '
'.$langs->trans('Customer').''; + print $soc->getNomUrl(1); + print ''; + print ''; + print $form->select_company('','socid','s.client = 1 OR s.client = 3',1); + print '
'.$langs->trans('Type').''; - print ''."\n"; + $optionsav.=''; + } - // Standard invoice + print ''; - - if ($socid > 0) - { - // Discounts for third party - print ''; - } - - // Date invoice - print ''; - - // Payment term - print ''; - - // Payment mode - print ''; - - // Project - if (! empty($conf->projet->enabled) && $socid>0) - { - $langs->load('projects'); - print ''; - } - - // Other attributes - $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - print $object->showOptionals($extrafields,'edit'); - } - - // Modele PDF - print ''; - print '"; - - // Public note - print ''; - print ''; - print ''; - - // Private note - if (empty($user->societe_id)) - { - print ''; - print ''; - print ''; - } - - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) - { - // TODO for compatibility - if ($origin == 'contrat') - { - // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva - $objectsrc->remise_absolue=$remise_absolue; - $objectsrc->remise_percent=$remise_percent; - $objectsrc->update_price(1,-1,1); - } - - print "\n"; - print "\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''; - print ''; - - $newclassname=$classname; - if ($newclassname == 'Propal') $newclassname = 'CommercialProposal'; - elseif ($newclassname == 'Commande') $newclassname = 'Order'; - - print ''; - print ''; - print '"; - if ($mysoc->localtax1_assuj=="1") //Localtax1 RE - { - print '"; - } - - if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF - { - print '"; - } - print '"; + $text.=''; + $text.=$options; } else { - // Show deprecated optional form to add product line here - if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) - { - print ''."\n"; + } - // Zone de choix des produits predefinis a la creation - print '
'.$langs->trans('Type').''; + print ''."\n"; + + // Standard invoice + print ''."\n"; + + // Proforma + if (! empty($conf->global->FACTURE_USE_PROFORMAT)) + { print ''."\n"; + } - // Proforma - if (! empty($conf->global->FACTURE_USE_PROFORMAT)) - { - print ''."\n"; + if ((empty($origin)) || (($origin=='propal') && (!empty($originid)))) + { + // Deposit + print ''."\n"; + } - if (empty($origin)) + if ($socid > 0) + { + // Replacement + print ''."\n"; - } - - if ($socid > 0) - { - // Replacement - print ''."\n"; - } - - if (empty($origin) && $socid > 0) - { - // Credit note - print ''."\n"; - } - - print '
'; + print ''; + print ''; + $desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1); + print $desc; + print '
'; - print ''; + print ''; print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1); + $desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1); print $desc; print '
'; - print ''; - print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1); - print $desc; - print '
'; + print ''; + print ''; + $desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1); + print ''; + if (($origin=='propal') ) { + print ''; + print '
'.$desc.''.$langs->trans('Value').':'; } + print '
'; + print '
'; + print ''; + print ''; + $text=$langs->trans("InvoiceReplacementAsk").' '; + $text.=''; - print ''; - print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $text=$langs->trans("InvoiceReplacementAsk").' '; - $text.=''; - $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $text=$langs->transnoentities("InvoiceAvoirAsk").' '; - // $text.=''; - $text.=''; - $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1); - print $desc; - print '
'; - print '
'.$langs->trans('Discounts').''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",''.$soc->remise_client.''); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - print ' ('.$langs->trans("EditRelativeDiscount").')'; - print '. '; - print '
'; - if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",''.price($absolute_discount).'',$langs->trans("Currency".$conf->currency)); - else print $langs->trans("CompanyHasNoAbsoluteDiscount"); - print ' ('.$langs->trans("EditGlobalDiscounts").')'; - print '.'; - print '
'.$langs->trans('Date').''; - $form->select_date($dateinvoice,'','','','',"add",1,1); - print '
'.$langs->trans('PaymentConditionsShort').''; - $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id'); - print '
'.$langs->trans('PaymentMode').''; - $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id'); - print '
'.$langs->trans('Project').''; - select_projects($soc->id, $projectid, 'projectid'); - print '
'.$langs->trans('Model').''; - include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php'; - $liste=ModelePDFFactures::liste_modeles($db); - print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF); - print "
'.$langs->trans('NotePublic').''; - $note_public=''; - if (is_object($objectsrc)) // Take value from source object - { - $note_public=$objectsrc->note_public; - } - $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); - print $doleditor->Create(1); - - //print '
'.$langs->trans('NotePrivate').''; - $note_private=''; - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) // Take value from source object - { - $note_private=$objectsrc->note_private; - } - $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); - print $doleditor->Create(1); - //print '
'.$langs->trans($newclassname).''.$objectsrc->getNomUrl(1).'
'.$langs->trans('TotalHT').''.price($objectsrc->total_ht).'
'.$langs->trans('TotalVAT').''.price($objectsrc->total_tva)."
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($objectsrc->total_localtax1)."
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($objectsrc->total_localtax2)."
'.$langs->trans('TotalTTC').''.price($objectsrc->total_ttc)."
'; + $text.=''; + } + $text.=''; + $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1); + print $desc; + print '
'; + if (empty($origin) && $socid > 0) + { + // Credit note + print ''."\n"; + } + + print '
'; + print ''; + print ''; + $text=$langs->transnoentities("InvoiceAvoirAsk").' '; + // $text.=''; + $text.=''; + $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1); + print $desc; + print '
'; + print '
'.$langs->trans('Discounts').''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",''.$soc->remise_client.''); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + print ' ('.$langs->trans("EditRelativeDiscount").')'; + print '. '; + print '
'; + if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",''.price($absolute_discount).'',$langs->trans("Currency".$conf->currency)); + else print $langs->trans("CompanyHasNoAbsoluteDiscount"); + print ' ('.$langs->trans("EditGlobalDiscounts").')'; + print '.'; + print '
'.$langs->trans('Date').''; + $form->select_date($dateinvoice,'','','','',"add",1,1); + print '
'.$langs->trans('PaymentConditionsShort').''; + $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id'); + print '
'.$langs->trans('PaymentMode').''; + $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id'); + print '
'.$langs->trans('Project').''; + select_projects($soc->id, $projectid, 'projectid'); + print '
'.$langs->trans('Model').''; + include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php'; + $liste=ModelePDFFactures::liste_modeles($db); + print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF); + print "
'.$langs->trans('NotePublic').''; + $note_public=''; + if (is_object($objectsrc)) // Take value from source object + { + $note_public=$objectsrc->note_public; + } + $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + + //print '
'.$langs->trans('NotePrivate').''; + $note_private=''; + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) // Take value from source object + { + $note_private=$objectsrc->note_private; + } + $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + //print '
'.$langs->trans($newclassname).''.$objectsrc->getNomUrl(1).'
'.$langs->trans('TotalHT').''.price($objectsrc->total_ht).'
'.$langs->trans('TotalVAT').''.price($objectsrc->total_tva)."
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($objectsrc->total_localtax1)."
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($objectsrc->total_localtax2)."
'.$langs->trans('TotalTTC').''.price($objectsrc->total_ttc)."
'; + + // Zone de choix des produits predefinis a la creation + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->service->enabled)) + { + print ''; + } + print ''; + for ($i = 1 ; $i <= $NBLINES ; $i++) + { print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + // Si le module service est actif, on propose des dates de debut et fin a la ligne if (! empty($conf->service->enabled)) { - print ''; - } - print ''; - for ($i = 1 ; $i <= $NBLINES ; $i++) - { - print ''; - print ''; - print ''; - print ''; - print ''; - // Si le module service est actif, on propose des dates de debut et fin a la ligne - if (! empty($conf->service->enabled)) - { - print ''; - } - print "\n"; } - - print '
'.$langs->trans('ProductsAndServices').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').'     '.$langs->trans('ServiceLimitedDuration').'
'.$langs->trans('ProductsAndServices').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').'     '; + // multiprix + if (! empty($conf->global->PRODUIT_MULTIPRICES)) + $form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level); + else + $form->select_produits('','idprod'.$i,'',$conf->product->limit_size); + print '% '.$langs->trans('ServiceLimitedDuration').'
'; - // multiprix - if (! empty($conf->global->PRODUIT_MULTIPRICES)) - $form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level); - else - $form->select_produits('','idprod'.$i,'',$conf->product->limit_size); + print ''; + print ''; + print ''; + print '
'; + print $langs->trans('From').' '; + print ''; + print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add"); + print '
'; + print $langs->trans('to').' '; + print ''; + print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add"); + print '
'; print '
% '; - print ''; - print ''; - print '
'; - print $langs->trans('From').' '; - print ''; - print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add"); - print '
'; - print $langs->trans('to').' '; - print ''; - print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add"); - print '
'; - print '
'; - print '
\n"; - - // Button "Create Draft" - print '
'; - - print "
\n"; - - // Show origin lines - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) - { - print '
'; - - $title=$langs->trans('ProductsAndServices'); - print_titre($title); - - print ''; - - $objectsrc->printOriginLinesList(); print '
'; + print '
\n"; + + // Button "Create Draft" + print '
'; + + print "\n"; + + // Show origin lines + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) + { + print '
'; + + $title=$langs->trans('ProductsAndServices'); + print_titre($title); + + print ''; + + $objectsrc->printOriginLinesList(); + + print '
'; + } + +} +else if ($id > 0 || ! empty($ref)) +{ + /* + * Show object in view mode + */ + + $result=$object->fetch($id,$ref); + + // fetch optionals attributes and labels + $extralabels=$extrafields->fetch_name_optionals_label('facture'); + + if ($result > 0) + { + if ($user->societe_id>0 && $user->societe_id!=$object->socid) accessforbidden('',0); + + $result=$object->fetch_thirdparty(); + + $soc = new Societe($db); + $soc->fetch($object->socid); + $selleruserevenustamp=$mysoc->useRevenueStamp(); + + $totalpaye = $object->getSommePaiement(); + $totalcreditnotes = $object->getSumCreditNotesUsed(); + $totaldeposits = $object->getSumDepositsUsed(); + //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." selleruserrevenuestamp=".$selleruserevenustamp; + + // We can also use bcadd to avoid pb with floating points + // For example print 239.2 - 229.3 - 9.9; does not return 0. + //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); + //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); + $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT'); + + if ($object->paye) $resteapayer=0; + $resteapayeraffiche=$resteapayer; + + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) + { + $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + } + else + { + $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; + $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; } - } - else if ($id > 0 || ! empty($ref)) - { - /* - * Show object in view mode - */ + $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount); + $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote); + $absolute_discount=price2num($absolute_discount,'MT'); + $absolute_creditnote=price2num($absolute_creditnote,'MT'); - $result=$object->fetch($id,$ref); - - // fetch optionals attributes and labels - $extralabels=$extrafields->fetch_name_optionals_label('facture'); - - if ($result > 0) + $author = new User($db); + if ($object->user_author) { - if ($user->societe_id>0 && $user->societe_id!=$object->socid) accessforbidden('',0); + $author->fetch($object->user_author); + } - $result=$object->fetch_thirdparty(); + $objectidnext=$object->getIdReplacingInvoice(); - $soc = new Societe($db); - $soc->fetch($object->socid); - $selleruserevenustamp=$mysoc->useRevenueStamp(); - $totalpaye = $object->getSommePaiement(); - $totalcreditnotes = $object->getSumCreditNotesUsed(); - $totaldeposits = $object->getSumDepositsUsed(); - //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." selleruserrevenuestamp=".$selleruserevenustamp; + $head = facture_prepare_head($object); - // We can also use bcadd to avoid pb with floating points - // For example print 239.2 - 229.3 - 9.9; does not return 0. - //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); - //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); - $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT'); + dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill'); - if ($object->paye) $resteapayer=0; - $resteapayeraffiche=$resteapayer; + $formconfirm=''; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) + // Confirmation de la conversion de l'avoir en reduc + if ($action == 'converttoreduc') + { + $text=$langs->trans('ConfirmConvertToReduc'); + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2); + } + + // Confirmation to delete invoice + if ($action == 'delete') + { + $text=$langs->trans('ConfirmDeleteBill',$object->ref); + $formquestion=array(); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $qualified_for_stock_change=$object->hasProductsOrServices(2); } else { - $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; - $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; + $qualified_for_stock_change=$object->hasProductsOrServices(1); } - $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount); - $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote); - $absolute_discount=price2num($absolute_discount,'MT'); - $absolute_creditnote=price2num($absolute_creditnote,'MT'); - - $author = new User($db); - if ($object->user_author) + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change && $object->statut>=1) { - $author->fetch($object->user_author); + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1,0,0,$langs->trans("NoStockAction")))); + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete',$formquestion,"yes",1); + }else { + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','','',1); } + } - $objectidnext=$object->getIdReplacingInvoice(); - - - $head = facture_prepare_head($object); - - dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill'); - - $formconfirm=''; - - // Confirmation de la conversion de l'avoir en reduc - if ($action == 'converttoreduc') + // Confirmation de la validation + if ($action == 'valid') + { + // on verifie si l'objet est en numerotation provisoire + $objectref = substr($object->ref, 1, 4); + if ($objectref == 'PROV') { - $text=$langs->trans('ConfirmConvertToReduc'); - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2); + $savdate=$object->date; + if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) + { + $object->date=dol_now(); + $object->date_lim_reglement=$object->calculate_date_lim_reglement(); + } + $numref = $object->getNextNumRef($soc); + //$object->date=$savdate; } - - // Confirmation to delete invoice - if ($action == 'delete') + else { - $text=$langs->trans('ConfirmDeleteBill',$object->ref); - $formquestion=array(); - - $qualified_for_stock_change=0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) - { - $qualified_for_stock_change=$object->hasProductsOrServices(2); - } - else - { - $qualified_for_stock_change=$object->hasProductsOrServices(1); - } - - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change && $object->statut>=1) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1,0,0,$langs->trans("NoStockAction")))); - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete',$formquestion,"yes",1); - }else { - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','','',1); - } + $numref = $object->ref; } - // Confirmation de la validation - if ($action == 'valid') + $text=$langs->trans('ConfirmValidateBill',$numref); + if (! empty($conf->notification->enabled)) { - // on verifie si l'objet est en numerotation provisoire - $objectref = substr($object->ref, 1, 4); - if ($objectref == 'PROV') - { - $savdate=$object->date; - if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) - { - $object->date=dol_now(); - $object->date_lim_reglement=$object->calculate_date_lim_reglement(); - } - $numref = $object->getNextNumRef($soc); - //$object->date=$savdate; - } - else - { - $numref = $object->ref; - } - - $text=$langs->trans('ConfirmValidateBill',$numref); - if (! empty($conf->notification->enabled)) - { - require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; - $notify=new Notify($db); - $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_FAC',$object->socid); - } - $formquestion=array(); - - $qualified_for_stock_change=0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) - { - $qualified_for_stock_change=$object->hasProductsOrServices(2); - } - else - { - $qualified_for_stock_change=$object->hasProductsOrServices(1); - } - - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease"); - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); - } - if ($object->type != 2 && $object->total_ttc < 0) // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on - { - $text.='
'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive"); - } - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2)); + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage('NOTIFY_VAL_FAC',$object->socid); } + $formquestion=array(); - // Confirm back to draft status - if ($action == 'modif') + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $text=$langs->trans('ConfirmUnvalidateBill',$object->ref); - $formquestion=array(); - - $qualified_for_stock_change=0; - if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) - { - $qualified_for_stock_change=$object->hasProductsOrServices(2); - } - else - { - $qualified_for_stock_change=$object->hasProductsOrServices(1); - } - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); - } - - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1); + $qualified_for_stock_change=$object->hasProductsOrServices(2); } - - // Confirmation du classement paye - if ($action == 'paid' && $resteapayer <= 0) + else { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1); + $qualified_for_stock_change=$object->hasProductsOrServices(1); } - if ($action == 'paid' && $resteapayer > 0) + + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease"); + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); + } + if ($object->type != 2 && $object->total_ttc < 0) // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on + { + $text.='
'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive"); + } + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2)); + } + + // Confirm back to draft status + if ($action == 'modif') + { + $text=$langs->trans('ConfirmUnvalidateBill',$object->ref); + $formquestion=array(); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); + } + + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1); + } + + // Confirmation du classement paye + if ($action == 'paid' && $resteapayer <= 0) + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1); + } + if ($action == 'paid' && $resteapayer > 0) + { + // Code + $i=0; + $close[$i]['code']='discount_vat';$i++; + $close[$i]['code']='badcustomer';$i++; + // Help + $i=0; + $close[$i]['label']=$langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++; + $close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++; + // Texte + $i=0; + $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; + $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; + // arrayreasons[code]=reason + foreach($close as $key => $val) + { + $arrayreasons[$close[$key]['code']]=$close[$key]['reason']; + } + + // Cree un tableau formulaire + $formquestion=array( + 'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"), + array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), + array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') + ); + // Paiement incomplet. On demande si motif = escompte ou autre + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes"); + } + + // Confirmation du classement abandonne + if ($action == 'canceled') + { + // S'il y a une facture de remplacement pas encore validee (etat brouillon), + // on ne permet pas de classer abandonner la facture. + if ($objectidnext) + { + $facturereplacement=new Facture($db); + $facturereplacement->fetch($objectidnext); + $statusreplacement=$facturereplacement->statut; + } + if ($objectidnext && $statusreplacement == 0) + { + print '
'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'
'; + } + else { // Code - $i=0; - $close[$i]['code']='discount_vat';$i++; - $close[$i]['code']='badcustomer';$i++; + $close[1]['code']='badcustomer'; + $close[2]['code']='abandon'; // Help - $i=0; - $close[$i]['label']=$langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++; - $close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++; + $close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc"); + $close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc"); // Texte - $i=0; - $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; - $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; - // arrayreasons[code]=reason - foreach($close as $key => $val) - { - $arrayreasons[$close[$key]['code']]=$close[$key]['reason']; - } + $close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1); + $close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1); + // arrayreasons + $arrayreasons[$close[1]['code']]=$close[1]['reason']; + $arrayreasons[$close[2]['code']]=$close[2]['reason']; // Cree un tableau formulaire $formquestion=array( - 'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"), + 'text' => $langs->trans("ConfirmCancelBillQuestion"), array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') ); - // Paiement incomplet. On demande si motif = escompte ou autre - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes"); - } - // Confirmation du classement abandonne - if ($action == 'canceled') + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes"); + } + } + + // Confirmation de la suppression d'une ligne produit + if ($action == 'ask_deleteline') + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1); + } + + // Clone confirmation + if ($action == 'clone') + { + // Create an array for form + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1) + ); + // Paiement incomplet. On demande si motif = escompte ou autre + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',1); + } + + if (! $formconfirm) + { + $parameters=array('lineid'=>$lineid); + $formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + } + + // Print form confirm + print $formconfirm; + + + // Invoice content + + print ''; + + $linkback = ''.$langs->trans("BackToList").''; + + // Ref + print ''; + print ''; + + // Ref customer + print ''; + print ''; + + // Third party + print ''; + + // Type + print ''; + + // Relative and absolute discounts + $addrelativediscount=''.$langs->trans("EditRelativeDiscounts").''; + $addabsolutediscount=''.$langs->trans("EditGlobalDiscounts").''; + $addcreditnote=''.$langs->trans("AddCreditNote").''; + + print ''; + + // Conditions de reglement + print ''; - - // Conditions de reglement - print ''; + } + else + { + print ' '; + } + print ''; - // Date payment term - print ''; + } + else + { + print ' '; + } + print ''; - // Payment mode + // Payment mode + print ''; + + // Amount + print ''; + print ''; + print ''; + print ''; + + // Amount Local Taxes + if ($mysoc->localtax1_assuj=="1" && $mysoc->useLocalTax(1)) //Localtax1 (example RE) + { + print ''; + print ''; + } + if ($mysoc->localtax2_assuj=="1" && $mysoc->useLocalTax(2)) //Localtax2 (example IRPF) + { + print ''; + print ''; + } + + // Revenue stamp + if ($selleruserevenustamp) // Test company use revenue stamp + { print ''; + } - // Amount - print ''; - print ''; - print ''; + // Total with tax + print ''; + + // Statut + print ''; + print ''; + + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load('projects'); + print ''; + print ''; print ''; + } - // Amount Local Taxes - if ($mysoc->localtax1_assuj=="1" && $mysoc->useLocalTax(1)) //Localtax1 (example RE) + // Other attributes + $res=$object->fetch_optionals($object->id,$extralabels); + $parameters=array('colspan' => ' colspan="2"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + + if ($action == 'edit_extras') { - print ''; - print ''; - } - if ($mysoc->localtax2_assuj=="1" && $mysoc->useLocalTax(2)) //Localtax2 (example IRPF) - { - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; } - // Revenue stamp - if ($selleruserevenustamp) // Test company use revenue stamp + foreach($extrafields->attribute_label as $key=>$label) { - print ''; - } - - // Total with tax - print ''; - - // Statut - print ''; - print ''; - - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load('projects'); - print ''; - print ''; - print ''; - } - - // Other attributes - $res=$object->fetch_optionals($object->id,$extralabels); - $parameters=array('colspan' => ' colspan="2"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - - if ($action == 'edit_extras') - { - print ''; - print ''; - print ''; - print ''; - } - - foreach($extrafields->attribute_label as $key=>$label) - { - $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); - if ($extrafields->attribute_type[$key] == 'separate') + print 'attribute_required[$key])) print ' class="fieldrequired"'; + print '>'.$label.'attribute_required[$key])) print ' class="fieldrequired"'; - print '>'.$label.''."\n"; - } - } - - if(count($extrafields->attribute_label) > 0) { if ($action == 'edit_extras' && $user->rights->facture->creer) { - print ''; - + print $extrafields->showInputField($key,$value); } - else { - if ($object->statut == 0 && $user->rights->facture->creer) - { - print ''; - } - } - } - } - - print '
'.$langs->trans('Ref').''; + $morehtmlref=''; + $discount=new DiscountAbsolute($db); + $result=$discount->fetch(0,$object->id); + if ($result > 0) + { + $morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')'; + } + if ($result < 0) + { + dol_print_error('',$discount->error); + } + print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref); + print '
'; + print ''; + if ($action != 'refclient' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('RefCustomer'); + print ''.img_edit($langs->trans('Modify')).'
'; + print '
'; + if ($user->rights->facture->creer && $action == 'refclient') + { + print '
'; + print ''; + print ''; + print ''; + print ' '; + print '
'; + } + else + { + print $object->ref_client; + } + print '
'; + print ''; + print ''; + print ''; + print '
'.$langs->trans('Company').''; + if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer) + print 'id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'
'; + print '
'; + if ($action == 'editthirdparty') + { + $form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid'); + } + else + { + print '  '.$soc->getNomUrl(1,'compta'); + print '   ('.$langs->trans('OtherBills').')'; + } + print '
'.$langs->trans('Type').''; + print $object->getLibType(); + if ($object->type == 1) + { + $facreplaced=new Facture($db); + $facreplaced->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; + } + if ($object->type == 2) + { + $facusing=new Facture($db); + $facusing->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; + } + + $facidavoir=$object->getListIdAvoirFromInvoice(); + if (count($facidavoir) > 0) + { + print ' ('.$langs->transnoentities("InvoiceHasAvoir"); + $i=0; + foreach($facidavoir as $id) { - // S'il y a une facture de remplacement pas encore validee (etat brouillon), - // on ne permet pas de classer abandonner la facture. - if ($objectidnext) + if ($i==0) print ' '; + else print ','; + $facavoir=new Facture($db); + $facavoir->fetch($id); + print $facavoir->getNomUrl(1); + } + print ')'; + } + if ($objectidnext > 0) + { + $facthatreplace=new Facture($db); + $facthatreplace->fetch($objectidnext); + print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; + } + print '
'.$langs->trans('Discounts'); + print ''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + //print ' ('.$addrelativediscount.')'; + + if ($absolute_discount > 0) + { + print '. '; + if ($object->statut > 0 || $object->type == 2 || $object->type == 3) + { + if ($object->statut == 0) { - $facturereplacement=new Facture($db); - $facturereplacement->fetch($objectidnext); - $statusreplacement=$facturereplacement->statut; - } - if ($objectidnext && $statusreplacement == 0) - { - print '
'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'
'; + print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + print '. '; } else { - // Code - $close[1]['code']='badcustomer'; - $close[2]['code']='abandon'; - // Help - $close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc"); - $close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc"); - // Texte - $close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1); - $close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1); - // arrayreasons - $arrayreasons[$close[1]['code']]=$close[1]['reason']; - $arrayreasons[$close[2]['code']]=$close[2]['reason']; - - // Cree un tableau formulaire - $formquestion=array( - 'text' => $langs->trans("ConfirmCancelBillQuestion"), - array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), - array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') - ); - - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes"); - } - } - - // Confirmation de la suppression d'une ligne produit - if ($action == 'ask_deleteline') - { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1); - } - - // Clone confirmation - if ($action == 'clone') - { - // Create an array for form - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1) - ); - // Paiement incomplet. On demande si motif = escompte ou autre - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',1); - } - - if (! $formconfirm) - { - $parameters=array('lineid'=>$lineid); - $formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - } - - // Print form confirm - print $formconfirm; - - - // Invoice content - - print ''; - - $linkback = ''.$langs->trans("BackToList").''; - - // Ref - print ''; - print ''; - - // Ref customer - print ''; - print ''; - - // Third party - print ''; - - // Type - print ''; - - // Relative and absolute discounts - $addrelativediscount=''.$langs->trans("EditRelativeDiscounts").''; - $addabsolutediscount=''.$langs->trans("EditGlobalDiscounts").''; - $addcreditnote=''.$langs->trans("AddCreditNote").''; - - print ''; - - // Date invoice - print ''; + + // Date invoice + print ''; + } + else + { + print dol_print_date($object->date,'daytext'); + } + print ''; - /* - * List of payments - */ + /* + * List of payments + */ - $sign=1; - if ($object->type == 2) $sign=-1; + $sign=1; + if ($object->type == 2) $sign=-1; - $nbrows=8; $nbcols=2; - if (! empty($conf->projet->enabled)) $nbrows++; - if (! empty($conf->banque->enabled)) $nbcols++; - if($mysoc->localtax1_assuj=="1") $nbrows++; - if($mysoc->localtax2_assuj=="1") $nbrows++; - if ($selleruserevenustamp) $nbrows++; + $nbrows=8; $nbcols=2; + if (! empty($conf->projet->enabled)) $nbrows++; + if (! empty($conf->banque->enabled)) $nbcols++; + if($mysoc->localtax1_assuj=="1") $nbrows++; + if($mysoc->localtax2_assuj=="1") $nbrows++; + if ($selleruserevenustamp) $nbrows++; - print ''; - // Margin Infos - if (! empty($conf->margin->enabled)) + // Remainder to pay + print ''; + print ''; + print ''; + } + else // Credit note + { + // Total already paid back + print ''; + + // Billed + print ''; + + // Remainder to pay back + print ''; + print ''; + print ''; + + // Sold credit note + //print ''; + //print ''; + } + + print '
'.$langs->trans('Ref').''; - $morehtmlref=''; - $discount=new DiscountAbsolute($db); - $result=$discount->fetch(0,$object->id); - if ($result > 0) - { - $morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')'; - } - if ($result < 0) - { - dol_print_error('',$discount->error); - } - print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref); - print '
'; - print ''; - if ($action != 'refclient' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('RefCustomer'); - print ''.img_edit($langs->trans('Modify')).'
'; - print '
'; - if ($user->rights->facture->creer && $action == 'refclient') - { - print '
'; - print ''; - print ''; - print ''; - print ' '; - print '
'; - } - else - { - print $object->ref_client; - } - print '
'; - print ''; - print ''; - print ''; - print '
'.$langs->trans('Company').''; - if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer) - print 'id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'
'; - print '
'; - if ($action == 'editthirdparty') - { - $form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid'); - } - else - { - print '  '.$soc->getNomUrl(1,'compta'); - print '   ('.$langs->trans('OtherBills').')'; - } - print '
'.$langs->trans('Type').''; - print $object->getLibType(); - if ($object->type == 1) - { - $facreplaced=new Facture($db); - $facreplaced->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; - } - if ($object->type == 2) - { - $facusing=new Facture($db); - $facusing->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; - } - - $facidavoir=$object->getListIdAvoirFromInvoice(); - if (count($facidavoir) > 0) - { - print ' ('.$langs->transnoentities("InvoiceHasAvoir"); - $i=0; - foreach($facidavoir as $id) - { - if ($i==0) print ' '; - else print ','; - $facavoir=new Facture($db); - $facavoir->fetch($id); - print $facavoir->getNomUrl(1); - } - print ')'; - } - if ($objectidnext > 0) - { - $facthatreplace=new Facture($db); - $facthatreplace->fetch($objectidnext); - print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; - } - print '
'.$langs->trans('Discounts'); - print ''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - //print ' ('.$addrelativediscount.')'; - - if ($absolute_discount > 0) - { - print '. '; - if ($object->statut > 0 || $object->type == 2 || $object->type == 3) - { - if ($object->statut == 0) + if ($object->statut < 1 || $object->type == 2 || $object->type == 3) { - print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - print '. '; + $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + print '
'.$text.'.
'; } else { - if ($object->statut < 1 || $object->type == 2 || $object->type == 3) - { - $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - print '
'.$text.'.
'; - } - else - { - $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - $text2=$langs->trans("AbsoluteDiscountUse"); - print $form->textwithpicto($text,$text2); - } + $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + $text2=$langs->trans("AbsoluteDiscountUse"); + print $form->textwithpicto($text,$text2); } } - else - { - // Remise dispo de type remise fixe (not credit note) - print '
'; - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')'); - } } else { - if ($absolute_creditnote > 0) // If not, link will be added later - { - if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; - else print '. '; - } - else print '. '; + // Remise dispo de type remise fixe (not credit note) + print '
'; + $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')'); } - if ($absolute_creditnote > 0) + } + else + { + if ($absolute_creditnote > 0) // If not, link will be added later { - // If validated, we show link "add credit note to payment" - if ($object->statut != 1 || $object->type == 2 || $object->type == 3) - { - if ($object->statut == 0 && $object->type != 3) - { - $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)); - print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse")); - } - else - { - print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.'; - } - } - else - { - // Remise dispo de type avoir - if (! $absolute_discount) print '
'; - //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer); - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher - } - } - if (! $absolute_discount && ! $absolute_creditnote) - { - print $langs->trans("CompanyHasNoAbsoluteDiscount"); if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; else print '. '; } - /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3) - { - if (! $absolute_discount && ! $absolute_creditnote) print '
'; - //print '   -   '; - print $addabsolutediscount; - //print '   -   '.$addcreditnote; // We disbale link to credit note - }*/ - print '
'; - print ''; - if ($object->type != 2 && $action != 'editinvoicedate' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('Date'); - print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; - print '
'; - - if ($object->type != 2) + else print '. '; + } + if ($absolute_creditnote > 0) + { + // If validated, we show link "add credit note to payment" + if ($object->statut != 1 || $object->type == 2 || $object->type == 3) { - if ($action == 'editinvoicedate') + if ($object->statut == 0 && $object->type != 3) { - $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate'); + $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)); + print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse")); } else { - print dol_print_date($object->date,'daytext'); + print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.'; } } else + { + // Remise dispo de type avoir + if (! $absolute_discount) print '
'; + //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer); + $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher + } + } + if (! $absolute_discount && ! $absolute_creditnote) + { + print $langs->trans("CompanyHasNoAbsoluteDiscount"); + if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; + else print '. '; + } + /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3) + { + if (! $absolute_discount && ! $absolute_creditnote) print '
'; + //print '   -   '; + print $addabsolutediscount; + //print '   -   '.$addcreditnote; // We disbale link to credit note + }*/ + print '
'; + print ''; + if ($object->type != 2 && $action != 'editinvoicedate' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('Date'); + print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; + print '
'; + + if ($object->type != 2) + { + if ($action == 'editinvoicedate') + { + $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate'); + } + else { print dol_print_date($object->date,'daytext'); } - print ''; + print ''; - print ''; + print '
'; - // List of payments already done - print ''; - print ''; - print ''; - if (! empty($conf->banque->enabled)) print ''; - print ''; - print ''; - print ''; + // List of payments already done + print ''; + print ''; + print ''; + if (! empty($conf->banque->enabled)) print ''; + print ''; + print ''; + print ''; - $var=true; + $var=true; - // Payments already done (from payment on this invoice) - $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,'; - $sql.= ' c.code as payment_code, c.libelle as payment_label,'; - $sql.= ' pf.amount,'; - $sql.= ' ba.rowid as baid, ba.ref, ba.label'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; - $sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid'; - $sql.= ' ORDER BY p.datep, p.tms'; + // Payments already done (from payment on this invoice) + $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,'; + $sql.= ' c.code as payment_code, c.libelle as payment_label,'; + $sql.= ' pf.amount,'; + $sql.= ' ba.rowid as baid, ba.ref, ba.label'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; + $sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid'; + $sql.= ' ORDER BY p.datep, p.tms'; - $result = $db->query($sql); - if ($result) + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + $i = 0; + + //if ($object->type != 2) + //{ + if ($num > 0) { - $num = $db->num_rows($result); - $i = 0; - - //if ($object->type != 2) - //{ - if ($num > 0) + while ($i < $num) { + $objp = $db->fetch_object($result); + $var=!$var; + print ''; + $label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label; + print ''; + if (! empty($conf->banque->enabled)) + { + $bankaccountstatic->id=$objp->baid; + $bankaccountstatic->ref=$objp->ref; + $bankaccountstatic->label=$objp->ref; + print ''; + } + print ''; + print ''; + print ''; + $i++; + } + } + else + { + print ''; + } + //} + $db->free($result); + } + else + { + dol_print_error($db); + } + + if ($object->type != 2) + { + // Total already paid + print ''; + + $resteapayeraffiche=$resteapayer; + + // Loop on each credit note or deposit amount applied + $creditnoteamount=0; + $depositamount=0; + $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; + $sql.= " re.description, re.fk_facture_source"; + $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; + $sql.= " WHERE fk_facture = ".$object->id; + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + $invoice=new Facture($db); while ($i < $num) { - $objp = $db->fetch_object($result); - $var=!$var; - print ''; - $label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label; - print ''; - if (! empty($conf->banque->enabled)) - { - $bankaccountstatic->id=$objp->baid; - $bankaccountstatic->ref=$objp->ref; - $bankaccountstatic->label=$objp->ref; - print ''; - } - print ''; - print ''; - print ''; + $obj = $db->fetch_object($resql); + $invoice->fetch($obj->fk_facture_source); + print ''; + print ''; + print ''; $i++; + if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc; + if ($invoice->type == 3) $depositamount += $obj->amount_ttc; } } else - { - print ''; - } - //} - $db->free($result); - } - else { dol_print_error($db); } - if ($object->type != 2) + // Paye partiellement 'escompte' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat') { - // Total already paid - print ''; - - $resteapayeraffiche=$resteapayer; - - // Loop on each credit note or deposit amount applied - $creditnoteamount=0; - $depositamount=0; - $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; - $sql.= " re.description, re.fk_facture_source"; - $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; - $sql.= " WHERE fk_facture = ".$object->id; - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - $i = 0; - $invoice=new Facture($db); - while ($i < $num) - { - $obj = $db->fetch_object($resql); - $invoice->fetch($obj->fk_facture_source); - print ''; - print ''; - print ''; - $i++; - if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc; - if ($invoice->type == 3) $depositamount += $obj->amount_ttc; - } - } - else - { - dol_print_error($db); - } - - // Paye partiellement 'escompte' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat') - { - print ''; - $resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'badcustomer' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer') - { - print ''; - //$resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'product_returned' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned') - { - print ''; - $resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'abandon' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon') - { - print ''; - $resteapayeraffiche=0; - } - - // Billed - print ''; - - // Remainder to pay - print ''; - print ''; - print ''; + print ''; + $resteapayeraffiche=0; } - else // Credit note + // Paye partiellement ou Abandon 'badcustomer' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer') { - // Total already paid back - print ''; - - // Billed - print ''; - - // Remainder to pay back - print ''; - print ''; - print ''; - - // Sold credit note - //print ''; - //print ''; + print ''; + //$resteapayeraffiche=0; + } + // Paye partiellement ou Abandon 'product_returned' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned') + { + print ''; + $resteapayeraffiche=0; + } + // Paye partiellement ou Abandon 'abandon' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon') + { + print ''; + $resteapayeraffiche=0; } - print '
'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).''.$langs->trans('Type').''.$langs->trans('BankAccount').''.$langs->trans('Amount').' 
'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).''.$langs->trans('Type').''.$langs->trans('BankAccount').''.$langs->trans('Amount').' 
'; + print ''.img_object($langs->trans('ShowPayment'),'payment').' '; + print dol_print_date($db->jdate($objp->dp),'day').''.$label.' '.$objp->num_paiement.''; + if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions'); + print ''.price($sign * $objp->amount).' 
'.$langs->trans("None").'
'; + if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits'); + else print $langs->trans('AlreadyPaid'); + print ' :'.price($totalpaye).' 
'; - print ''.img_object($langs->trans('ShowPayment'),'payment').' '; - print dol_print_date($db->jdate($objp->dp),'day').''.$label.' '.$objp->num_paiement.''; - if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions'); - print ''.price($sign * $objp->amount).' 
'; + if ($invoice->type == 2) print $langs->trans("CreditNote").' '; + if ($invoice->type == 3) print $langs->trans("Deposit").' '; + print $invoice->getNomUrl(0); + print ' :'.price($obj->amount_ttc).''; + print 'rowid.'">'.img_delete().''; + print '
'.$langs->trans("None").'
'; - if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits'); - else print $langs->trans('AlreadyPaid'); - print ' :'.price($totalpaye).' 
'; - if ($invoice->type == 2) print $langs->trans("CreditNote").' '; - if ($invoice->type == 3) print $langs->trans("Deposit").' '; - print $invoice->getNomUrl(0); - print ' :'.price($obj->amount_ttc).''; - print 'rowid.'">'.img_delete().''; - print '
'; - print $form->textwithpicto($langs->trans("Discount").':',$langs->trans("HelpEscompte"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - $text=$langs->trans("HelpAbandonOther"); - if ($object->close_note) $text.='

'.$langs->trans("Reason").':'.$object->close_note; - print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1); - print '
'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'.$langs->trans("Billed").' :'.price($object->total_ttc).' 
'; - if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay'); - else print $langs->trans('ExcessReceived'); - print ' :'.price($resteapayeraffiche).' 
'; + print $form->textwithpicto($langs->trans("Discount").':',$langs->trans("HelpEscompte"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - print $langs->trans('AlreadyPaidBack'); - print ' :'.price($sign * $totalpaye).' 
'.$langs->trans("Billed").' :'.price($sign * $object->total_ttc).' 
'; - if ($resteapayeraffiche <= 0) print $langs->trans('RemainderToPayBack'); - else print $langs->trans('ExcessPaydBack'); - print ' :'.price($sign * $resteapayeraffiche).' 
'.$langs->trans('TotalTTC').' :'.price($sign * $object->total_ttc).' 
'; + print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + $text=$langs->trans("HelpAbandonOther"); + if ($object->close_note) $text.='

'.$langs->trans("Reason").':'.$object->close_note; + print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1); + print '
'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + // Billed + print '
'.$langs->trans("Billed").' :'.price($object->total_ttc).' 
'; + if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay'); + else print $langs->trans('ExcessReceived'); + print ' :'.price($resteapayeraffiche).' 
'; + print $langs->trans('AlreadyPaidBack'); + print ' :'.price($sign * $totalpaye).' 
'.$langs->trans("Billed").' :'.price($sign * $object->total_ttc).' 
'; + if ($resteapayeraffiche <= 0) print $langs->trans('RemainderToPayBack'); + else print $langs->trans('ExcessPaydBack'); + print ' :'.price($sign * $resteapayeraffiche).' 
'.$langs->trans('TotalTTC').' :'.price($sign * $object->total_ttc).' 
'; + + // Margin Infos + if (! empty($conf->margin->enabled)) + { + print '
'; + $object->displayMarginInfos($object->statut > 0); + } + + print '
'; + print ''; + if ($object->type != 2 && $action != 'editconditions' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('PaymentConditionsShort'); + print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; + print '
'; + if ($object->type != 2) + { + if ($action == 'editconditions') { - print '
'; - $object->displayMarginInfos($object->statut > 0); - } - - print '
'; - print ''; - if ($object->type != 2 && $action != 'editconditions' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('PaymentConditionsShort'); - print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; - print '
'; - if ($object->type != 2) - { - if ($action == 'editconditions') - { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); - } - else - { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none'); - } + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); } else { - print ' '; + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none'); } - print '
'; - print ''; - if ($object->type != 2 && $action != 'editpaymentterm' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('DateMaxPayment'); - print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; - print '
'; - if ($object->type != 2) + // Date payment term + print '
'; + print ''; + if ($object->type != 2 && $action != 'editpaymentterm' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('DateMaxPayment'); + print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; + print '
'; + if ($object->type != 2) + { + if ($action == 'editpaymentterm') { - if ($action == 'editpaymentterm') - { - $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm'); - } - else - { - print dol_print_date($object->date_lim_reglement,'daytext'); - if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! isset($object->am)) print img_warning($langs->trans('Late')); - } + $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm'); } else { - print ' '; + print dol_print_date($object->date_lim_reglement,'daytext'); + if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! isset($object->am)) print img_warning($langs->trans('Late')); } - print '
'; + print ''; + if ($action != 'editmode' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('PaymentMode'); + print 'id.'">'.img_edit($langs->trans('SetMode'),1).'
'; + print '
'; + if ($action == 'editmode') + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); + } + else + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none'); + } + print '
'.$langs->trans('AmountHT').''.price($object->total_ht,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('AmountVAT').''.price($object->total_tva,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($object->total_localtax1,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($object->total_localtax2,1,'',1,-1,-1,$conf->currency).'
'; print ''; - if ($action != 'editmode' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; print '
'; - print $langs->trans('PaymentMode'); + print $langs->trans('RevenueStamp'); print 'id.'">'.img_edit($langs->trans('SetMode'),1).'id.'">'.img_edit($langs->trans('SetRevenuStamp'),1).'
'; - print '
'; - if ($action == 'editmode') + print ''; + if ($action == 'editrevenuestamp') { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); + print '
'; + print ''; + print ''; + print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code); + //print ''; + print ' '; + print '
'; } else { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none'); + print price($object->revenuestamp,1,'',1,-1,-1,$conf->currency); } print '
'.$langs->trans('AmountHT').''.price($object->total_ht,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('AmountVAT').''.price($object->total_tva,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('AmountTTC').''.price($object->total_ttc,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('Status').''.($object->getLibStatut(4,$totalpaye)).'
'; + + print ''; + if ($action != 'classify') + { + print ''; + } + print '
'; + print $langs->trans('Project'); + print 'id.'">'; + print img_edit($langs->trans('SetProject'),1); + print '
'; + + print '
'; + if ($action == 'classify') + { + $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid'); + } + else + { + $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none'); + } + print '
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($object->total_localtax1,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($object->total_localtax2,1,'',1,-1,-1,$conf->currency).'
'; - print ''; - if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('RevenueStamp'); - print 'id.'">'.img_edit($langs->trans('SetRevenuStamp'),1).'
'; - print '
'; - if ($action == 'editrevenuestamp') + $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); + if ($extrafields->attribute_type[$key] == 'separate') { - print ''; - print ''; - print ''; - print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code); - //print ''; - print ' '; - print ''; + print $extrafields->showSeparator($key); } else { - print price($object->revenuestamp,1,'',1,-1,-1,$conf->currency); - } - print '
'.$langs->trans('AmountTTC').''.price($object->total_ttc,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('Status').''.($object->getLibStatut(4,$totalpaye)).'
'; - - print ''; - if ($action != 'classify') - { - print ''; - } - print '
'; - print $langs->trans('Project'); - print 'id.'">'; - print img_edit($langs->trans('SetProject'),1); - print '
'; - - print '
'; - if ($action == 'classify') - { - $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid'); - } - else - { - $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none'); - } - print '
'; + // Convert date into timestamp format + if (in_array($extrafields->attribute_type[$key],array('date','datetime'))) { - print $extrafields->showSeparator($key); + $value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key]; } - else - { - print '
'; - // Convert date into timestamp format - if (in_array($extrafields->attribute_type[$key],array('date','datetime'))) - { - $value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key]; - } - - if ($action == 'edit_extras' && $user->rights->facture->creer) - { - print $extrafields->showInputField($key,$value); - } - else - { - print $extrafields->showOutputField($key,$value); - } - print '
'; - print ''; - print ''; - print '
'.img_picto('','edit').' '.$langs->trans('Modify').'

'; - - if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) - { - $blocname = 'contacts'; - $title = $langs->trans('ContactsAddresses'); - include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; - } - - if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) - { - $blocname = 'notes'; - $title = $langs->trans('Notes'); - include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; - } - - /* - * Lines - */ - $result = $object->getLinesArray(); - - if (! empty($conf->use_javascript_ajax) && $object->statut == 0) - { - include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; - } - - print ''; - - // Show object lines - if (! empty($object->lines)) - $ret=$object->printObjectLines($action,$mysoc,$soc,$lineid,1); - - /* - * Form to add new line - */ - if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline') - { - $var=true; - - if ($conf->global->MAIN_FEATURES_LEVEL > 1) - { - // Add free or predefined products/services - $object->formAddObjectLine(1,$mysoc,$soc); - } - else - { - // Add free products/services - $object->formAddFreeProduct(1,$mysoc,$soc); - - // Add predefined products/services - if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) + else { - $var=!$var; - $object->formAddPredefinedProduct(1,$mysoc,$soc); + print $extrafields->showOutputField($key,$value); } + print ''."\n"; } - - $parameters=array(); - $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action); // Note that $action and $object may have been modified by hook } - print "
\n"; + if(count($extrafields->attribute_label) > 0) { - print "\n"; - - - /* - * Boutons actions - */ - - if ($action != 'prerelance' && $action != 'presend') - { - if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline') + if ($action == 'edit_extras' && $user->rights->facture->creer) { - print '
'; + print ''; + print ''; + print ''; + print ''; - // Editer une facture deja validee, sans paiement effectue et pas exporte en compta - if ($object->statut == 1) + } + else { + if ($object->statut == 0 && $user->rights->facture->creer) { - // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees - $ventilExportCompta = $object->getVentilExportCompta(); + print ''.img_picto('','edit').' '.$langs->trans('Modify').''; + } + } + } + } - if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) + print '
'; + + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) + { + $blocname = 'contacts'; + $title = $langs->trans('ContactsAddresses'); + include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; + } + + if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) + { + $blocname = 'notes'; + $title = $langs->trans('Notes'); + include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; + } + + /* + * Lines + */ + $result = $object->getLinesArray(); + + if (! empty($conf->use_javascript_ajax) && $object->statut == 0) + { + include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; + } + + print ''; + + // Show object lines + if (! empty($object->lines)) + $ret=$object->printObjectLines($action,$mysoc,$soc,$lineid,1); + + /* + * Form to add new line + */ + if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline') + { + $var=true; + + if ($conf->global->MAIN_FEATURES_LEVEL > 1) + { + // Add free or predefined products/services + $object->formAddObjectLine(1,$mysoc,$soc); + } + else + { + // Add free products/services + $object->formAddFreeProduct(1,$mysoc,$soc); + + // Add predefined products/services + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) + { + $var=!$var; + $object->formAddPredefinedProduct(1,$mysoc,$soc); + } + } + + $parameters=array(); + $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + } + + print "
\n"; + + print "
\n"; + + + /* + * Boutons actions + */ + + if ($action != 'prerelance' && $action != 'presend') + { + if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline') + { + print '
'; + + // Editer une facture deja validee, sans paiement effectue et pas exporte en compta + if ($object->statut == 1) + { + // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees + $ventilExportCompta = $object->getVentilExportCompta(); + + if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) + { + if (! $objectidnext) { - if (! $objectidnext) + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) { - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) - { - print ''; - } - else - { - print '
'.$langs->trans('Modify').'
'; - } + print ''; } else { - print '
'.$langs->trans('Modify').'
'; + print '
'.$langs->trans('Modify').'
'; } } - } - - // Reopen a standard paid invoice - if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3)) // A paid invoice (partially or completely) - { - if (! $objectidnext && $object->close_code != 'replaced') // Not replaced by another invoice - { - print ''; - } else { - print '
'.$langs->trans('ReOpen').'
'; + print '
'.$langs->trans('Modify').'
'; } } + } - // Validate - if ($object->statut == 0 && count($object->lines) > 0 && - ( - (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) - || ($object->type == 2 && $object->total_ttc <= 0)) - ) + // Reopen a standard paid invoice + if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3)) // A paid invoice (partially or completely) + { + if (! $objectidnext && $object->close_code != 'replaced') // Not replaced by another invoice { - if ($user->rights->facture->valider) - { - print ''; - } + print ''; } + else + { + print '
'.$langs->trans('ReOpen').'
'; + } + } - // Send by mail - if (($object->statut == 1 || $object->statut == 2)) + // Validate + if ($object->statut == 0 && count($object->lines) > 0 && + ( + (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) + || ($object->type == 2 && $object->total_ttc <= 0)) + ) + { + if ($user->rights->facture->valider) + { + print ''; + } + } + + // Send by mail + if (($object->statut == 1 || $object->statut == 2)) + { + if ($objectidnext) + { + print '
'.$langs->trans('SendByMail').'
'; + } + else + { + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) + { + print ''; + } + else print ''; + } + } + + if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) // For backward compatibility + { + if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) { if ($objectidnext) { - print '
'.$langs->trans('SendByMail').'
'; + print '
'.$langs->trans('SendRemindByMail').'
'; } else { if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) { - print ''; + print ''; } - else print ''; + else print ''; } } + } - if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) // For backward compatibility + // Create payment + if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) + { + if ($objectidnext) { - if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) - { - if ($objectidnext) - { - print '
'.$langs->trans('SendRemindByMail').'
'; - } - else - { - if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) - { - print ''; - } - else print ''; - } - } - } - - // Create payment - if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) - { - if ($objectidnext) - { - print '
'.$langs->trans('DoPayment').'
'; - } - else - { - if ($resteapayer == 0) - { - print '
'.$langs->trans('DoPayment').'
'; - } - else - { - print ''; - } - } - } - - // Reverse back money or convert to reduction - if ($object->type == 2 || $object->type == 3) - { - // For credit note only - if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) - { - print ''; - } - // For credit note - if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0) - { - print ''; - } - // For deposit invoice - if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer) - { - print ''; - } - } - - // Classify paid (if not deposit and not credit note. Such invoice are "converted") - if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement && - (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) ) - { - print ''; - } - - // Classify 'closed not completely paid' (possible si validee et pas encore classee payee) - if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 - && $user->rights->facture->paiement) - { - if ($totalpaye > 0 || $totalcreditnotes > 0) - { - // If one payment or one credit note was linked to this invoice - print ''; - } - else - { - if ($objectidnext) - { - print '
'.$langs->trans('ClassifyCanceled').'
'; - } - else - { - print ''; - } - } - } - - // Clone - if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer) - { - print ''; - } - - // Clone as predefined - if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer) - { - if (! $objectidnext) - { - print ''; - } - } - - // Delete - if ($user->rights->facture->supprimer) - { - if (! $object->is_erasable()) - { - print ''; - } - else if ($objectidnext) - { - print ''; - } - elseif ($object->getSommePaiement()) - { - print ''; - } - else - { - print ''; - } + print '
'.$langs->trans('DoPayment').'
'; } else { - print ''; - } - - print '
'; - } - } - print '
'; - - if ($action != 'prerelance' && $action != 'presend') - { - print '
'; - //print '
'; - //print ''; // ancre - - /* - * Documents generes - */ - $filename=dol_sanitizeFileName($object->ref); - $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref); - $urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id; - $genallowed=$user->rights->facture->creer; - $delallowed=$user->rights->facture->supprimer; - - print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); - $somethingshown=$formfile->numoffiles; - - /* - * Linked object block - */ - $somethingshown=$object->showLinkedObjectBlock(); - - // Link for paypal payment - if (! empty($conf->paypal->enabled) && $object->statut != 0) - { - include_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; - print showPaypalPaymentUrl('invoice',$object->ref); - } - - print '
'; - //print '
'; - - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions=new FormActions($db); - $somethingshown=$formactions->showactions($object,'invoice',$socid); - - //print '
'; - print '
'; - } - else - { - /* - * Affiche formulaire mail - */ - - // By default if $action=='presend' - $titreform='SendBillByMail'; - $topicmail='SendBillRef'; - $action='send'; - $modelmail='facture_send'; - - if ($action == 'prerelance') // For backward compatibility - { - $titrefrom='SendReminderBillByMail'; - $topicmail='SendReminderBillRef'; - $action='relance'; - $modelmail='facture_relance'; - } - - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); - $file=$fileparams['fullname']; - - // Build document if it not exists - if (! $file || ! is_readable($file)) - { - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - - $result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); - $file=$fileparams['fullname']; - } - - print '
'; - print_titre($langs->trans($titreform)); - - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->fromtype = 'user'; - $formmail->fromid = $user->id; - $formmail->fromname = $user->getFullName($langs); - $formmail->frommail = $user->email; - $formmail->withfrom=1; - $liste=array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; - $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; - $formmail->withtocc=$liste; - $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; - $formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__'); - $formmail->withfile=2; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - $formmail->withcancel=1; - // Tableau des substitutions - $formmail->substit['__FACREF__']=$object->ref; - $formmail->substit['__SIGNATURE__']=$user->signature; - $formmail->substit['__PERSONALIZED__']=''; - $formmail->substit['__CONTACTCIVNAME__']=''; - - //Find the good contact adress - $custcontact=''; - $contactarr=array(); - $contactarr=$object->liste_contact(-1,'external'); - - if (is_array($contactarr) && count($contactarr)>0) { - foreach($contactarr as $contact) { - if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { - - require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; - - $contactstatic=new Contact($db); - $contactstatic->fetch($contact['id']); - $custcontact=$contactstatic->getFullName($langs,1); + if ($resteapayer == 0) + { + print '
'.$langs->trans('DoPayment').'
'; + } + else + { + print ''; } } + } - if (!empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__']=$custcontact; + // Reverse back money or convert to reduction + if ($object->type == 2 || $object->type == 3) + { + // For credit note only + if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) + { + print ''; + } + // For credit note + if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0) + { + print ''; + } + // For deposit invoice + if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer) + { + print ''; } } - - // Tableau des parametres complementaires du post - $formmail->param['action']=$action; - $formmail->param['models']=$modelmail; - $formmail->param['facid']=$object->id; - $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; - - // Init list of files - if (GETPOST("mode")=='init') + // Classify paid (if not deposit and not credit note. Such invoice are "converted") + if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement && + (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) ) { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); + print ''; } - $formmail->show_form(); + // Classify 'closed not completely paid' (possible si validee et pas encore classee payee) + if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 + && $user->rights->facture->paiement) + { + if ($totalpaye > 0 || $totalcreditnotes > 0) + { + // If one payment or one credit note was linked to this invoice + print ''; + } + else + { + if ($objectidnext) + { + print '
'.$langs->trans('ClassifyCanceled').'
'; + } + else + { + print ''; + } + } + } - print '
'; + // Clone + if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer) + { + print ''; + } + + // Clone as predefined + if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer) + { + if (! $objectidnext) + { + print ''; + } + } + + // Delete + if ($user->rights->facture->supprimer) + { + if (! $object->is_erasable()) + { + print ''; + } + else if ($objectidnext) + { + print ''; + } + elseif ($object->getSommePaiement()) + { + print ''; + } + else + { + print ''; + } + } + else + { + print ''; + } + + print ''; } - } - else - { - dol_print_error($db,$object->error); - } + } + print '
'; + + if ($action != 'prerelance' && $action != 'presend') + { + print '
'; + //print '
'; + //print ''; // ancre + + /* + * Documents generes + */ + $filename=dol_sanitizeFileName($object->ref); + $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref); + $urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id; + $genallowed=$user->rights->facture->creer; + $delallowed=$user->rights->facture->supprimer; + + print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); + $somethingshown=$formfile->numoffiles; + + /* + * Linked object block + */ + $somethingshown=$object->showLinkedObjectBlock(); + + // Link for paypal payment + if (! empty($conf->paypal->enabled) && $object->statut != 0) + { + include_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; + print showPaypalPaymentUrl('invoice',$object->ref); + } + + print '
'; + //print '
'; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + $formactions=new FormActions($db); + $somethingshown=$formactions->showactions($object,'invoice',$socid); + + //print '
'; + print '
'; + } + else + { + /* + * Affiche formulaire mail + */ + + // By default if $action=='presend' + $titreform='SendBillByMail'; + $topicmail='SendBillRef'; + $action='send'; + $modelmail='facture_send'; + + if ($action == 'prerelance') // For backward compatibility + { + $titrefrom='SendReminderBillByMail'; + $topicmail='SendReminderBillRef'; + $action='relance'; + $modelmail='facture_relance'; + } + + $ref = dol_sanitizeFileName($object->ref); + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); + $file=$fileparams['fullname']; + + // Build document if it not exists + if (! $file || ! is_readable($file)) + { + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + $result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); + $file=$fileparams['fullname']; + } + + print '
'; + print_titre($langs->trans($titreform)); + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->fromtype = 'user'; + $formmail->fromid = $user->id; + $formmail->fromname = $user->getFullName($langs); + $formmail->frommail = $user->email; + $formmail->withfrom=1; + $liste=array(); + foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; + $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; + $formmail->withtocc=$liste; + $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; + $formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__'); + $formmail->withfile=2; + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + $formmail->substit['__FACREF__']=$object->ref; + $formmail->substit['__SIGNATURE__']=$user->signature; + $formmail->substit['__PERSONALIZED__']=''; + $formmail->substit['__CONTACTCIVNAME__']=''; + + //Find the good contact adress + $custcontact=''; + $contactarr=array(); + $contactarr=$object->liste_contact(-1,'external'); + + if (is_array($contactarr) && count($contactarr)>0) { + foreach($contactarr as $contact) { + if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { + + require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; + + $contactstatic=new Contact($db); + $contactstatic->fetch($contact['id']); + $custcontact=$contactstatic->getFullName($langs,1); + } + } + + if (!empty($custcontact)) { + $formmail->substit['__CONTACTCIVNAME__']=$custcontact; + } + } + + + // Tableau des parametres complementaires du post + $formmail->param['action']=$action; + $formmail->param['models']=$modelmail; + $formmail->param['facid']=$object->id; + $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + + // Init list of files + if (GETPOST("mode")=='init') + { + $formmail->clear_attached_files(); + $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); + } + + $formmail->show_form(); + + print '
'; + } } + else + { + dol_print_error($db,$object->error); + } +} - dol_htmloutput_mesg('',$mesgs); +dol_htmloutput_mesg('',$mesgs); - llxFooter(); - $db->close(); - ?> +llxFooter(); +$db->close(); +?> diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 41b08dd399f..a76156142d6 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -311,6 +311,8 @@ PaymentConditionShortPT_ORDER=On order PaymentConditionPT_ORDER=On order PaymentConditionShortPT_5050=50-50 PaymentConditionPT_5050=50%% in advance, 50%% on delivery +FixAmount=Fix amount +VarAmount=Variable amount (%% tot.) # PaymentType PaymentTypeVIR=Bank deposit diff --git a/htdocs/langs/es_ES/bills.lang b/htdocs/langs/es_ES/bills.lang index ff1d75eb358..d4146ba2f4e 100644 --- a/htdocs/langs/es_ES/bills.lang +++ b/htdocs/langs/es_ES/bills.lang @@ -287,6 +287,8 @@ TotalOfTwoDiscountMustEqualsOriginal=La suma del importe de los 2 nuevos descuen ConfirmRemoveDiscount=¿Está seguro de querer eliminar este descuento? RelatedBill=Factura asociada RelatedBills=Facturas asociadas +FixAmount=Importe fijo +VarAmount=Importe variable (%% total) # PaymentConditions PaymentConditionShortRECEP=A la recepción diff --git a/htdocs/langs/fr_FR/bills.lang b/htdocs/langs/fr_FR/bills.lang index 0c87fb93f66..adfa9a34bdc 100644 --- a/htdocs/langs/fr_FR/bills.lang +++ b/htdocs/langs/fr_FR/bills.lang @@ -322,6 +322,8 @@ PaymentTypeVAD=Paiement en ligne PaymentTypeShortVAD=Paiement en ligne PaymentTypeTRA=Paiement par traite PaymentTypeShortTRA=Traite +FixAmount=Montant Fixe +VarAmount=Montant variable (%% tot.) BankDetails=Coordonnées bancaires BankCode=Code banque From 2008fd14196d47cd15bcf95e74eff1cf0ac529bf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 20 Apr 2013 17:49:24 +0200 Subject: [PATCH 63/97] Fix: Optimize for small screen --- htdocs/core/lib/functions.lib.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 46f65283a3e..b1b26518e95 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1072,9 +1072,11 @@ function dol_now($mode='gmt') */ function dol_print_size($size,$shortvalue=0,$shortunit=0) { - global $langs; + global $conf,$langs; $level=1024; - + + if (! empty($conf->dol_optimize_smallscreen)) $shortunit=1; + // Set value text if (empty($shortvalue) || $size < ($level*10)) { From 4202c8fc914aee06e4e5a03e58b06e2e16dd01ac Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 20 Apr 2013 17:56:39 +0200 Subject: [PATCH 64/97] required once instead of require --- htdocs/compta/facture.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 32505622a85..d5e24eb61f8 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -29,13 +29,13 @@ */ require '../main.inc.php'; -require DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; -require DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php'; -require DOL_DOCUMENT_ROOT . '/core/modules/facture/modules_facture.php'; -require DOL_DOCUMENT_ROOT . '/core/class/discount.class.php'; -require DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php'; -require DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; -require DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/modules/facture/modules_facture.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; From dd13c334c7d56260f58bd76e9e68cb5920d71841 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 20 Apr 2013 20:30:18 +0200 Subject: [PATCH 65/97] New: Compatibility with jmobile --- htdocs/comm/action/rapport/index.php | 2 +- htdocs/comm/propal/apercu.php | 2 +- htdocs/commande/apercu.php | 4 ++-- htdocs/compta/facture/apercu.php | 4 ++-- htdocs/compta/paiement/rapport.php | 2 +- htdocs/compta/prelevement/bon.php | 2 +- htdocs/compta/prelevement/factures.php | 2 +- htdocs/compta/prelevement/fiche-rejet.php | 2 +- htdocs/compta/prelevement/fiche-stat.php | 2 +- htdocs/compta/prelevement/fiche.php | 2 +- htdocs/compta/prelevement/lignes.php | 2 +- htdocs/core/class/html.formfile.class.php | 12 ++++++------ htdocs/fichinter/apercu.php | 4 ++-- htdocs/imports/import.php | 8 ++++---- 14 files changed, 25 insertions(+), 25 deletions(-) diff --git a/htdocs/comm/action/rapport/index.php b/htdocs/comm/action/rapport/index.php index 33a30e9c6b6..fa100e532f3 100644 --- a/htdocs/comm/action/rapport/index.php +++ b/htdocs/comm/action/rapport/index.php @@ -132,7 +132,7 @@ if ($resql) if (file_exists($file)) { - print ''.img_pdf().''; + print ''.img_pdf().''; print ''.dol_print_date(dol_filemtime($file),'dayhour').''; print ''.dol_print_size(dol_filesize($file)).''; } diff --git a/htdocs/comm/propal/apercu.php b/htdocs/comm/propal/apercu.php index fa01f818b16..8972baaac88 100644 --- a/htdocs/comm/propal/apercu.php +++ b/htdocs/comm/propal/apercu.php @@ -142,7 +142,7 @@ if ($id > 0 || ! empty($ref)) print "".$langs->trans("Propal")." PDF"; - print ''.$object->ref.'.pdf'; + print ''.$object->ref.'.pdf'; print ''.dol_print_size(dol_filesize($file)).''; print ''.dol_print_date(dol_filemtime($file),'dayhour').''; diff --git a/htdocs/commande/apercu.php b/htdocs/commande/apercu.php index 03957361ae2..f92a309a53c 100644 --- a/htdocs/commande/apercu.php +++ b/htdocs/commande/apercu.php @@ -128,7 +128,7 @@ if ($id > 0 || ! empty($ref)) print "".$langs->trans("Order")." PDF"; - print ''.$object->ref.'.pdf'; + print ''.$object->ref.'.pdf'; print ''.dol_print_size(dol_filesize($file)).''; print ''.dol_print_date(dol_filemtime($file),'dayhour').''; print ''; @@ -139,7 +139,7 @@ if ($id > 0 || ! empty($ref)) { print "Commande detaillee"; - print ''.$object->ref.'-detail.pdf'; + print ''.$object->ref.'-detail.pdf'; print ''.dol_print_size(dol_filesize($filedetail)).''; print ''.dol_print_date(dol_filemtime($filedetail),'dayhour').''; print ''; diff --git a/htdocs/compta/facture/apercu.php b/htdocs/compta/facture/apercu.php index 2db60bada79..f31f0a50f0f 100644 --- a/htdocs/compta/facture/apercu.php +++ b/htdocs/compta/facture/apercu.php @@ -318,7 +318,7 @@ if ($id > 0 || ! empty($ref)) print "".$langs->trans("Bill")." PDF"; - print ''.$object->ref.'.pdf'; + print ''.$object->ref.'.pdf'; print ''.dol_print_size(dol_filesize($file)). ''; print ''.dol_print_date(dol_filemtime($file),'dayhour').''; print ''; @@ -328,7 +328,7 @@ if ($id > 0 || ! empty($ref)) { print "Facture detaillee"; - print ''.$object->ref.'-detail.pdf'; + print ''.$object->ref.'-detail.pdf'; print ''.dol_print_size(dol_filesize($filedetail)).''; print ''.dol_print_date(dol_filemtime($filedetail),'dayhour').''; print ''; diff --git a/htdocs/compta/paiement/rapport.php b/htdocs/compta/paiement/rapport.php index 1bb4ad3a9ca..ce4a3b7cb7f 100644 --- a/htdocs/compta/paiement/rapport.php +++ b/htdocs/compta/paiement/rapport.php @@ -154,7 +154,7 @@ if ($year) $var=!$var; $tfile = $dir . '/'.$year.'/'.$file; $relativepath = $year.'/'.$file; - print "".''.img_pdf().' '.$file.''; + print "".''.img_pdf().' '.$file.''; print ''.dol_print_size(dol_filesize($tfile)).''; print ''.dol_print_date(dol_filemtime($tfile),"dayhour").''; } diff --git a/htdocs/compta/prelevement/bon.php b/htdocs/compta/prelevement/bon.php index 6448a5b3df5..89b40e095bc 100644 --- a/htdocs/compta/prelevement/bon.php +++ b/htdocs/compta/prelevement/bon.php @@ -63,7 +63,7 @@ if ($id > 0 || ! empty($ref)) $relativepath = 'bon/'.$object->ref; - print ''.$object->ref.''; + print ''.$object->ref.''; print ''; print '
'; diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 5271dbd03b4..ee5558b8ba2 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -94,7 +94,7 @@ if ($prev_id) print '
'; print $langs->trans("WithdrawalFile").''; $relativepath = 'receipts/'.$bon->ref; - print ''.$relativepath.''; + print ''.$relativepath.''; print '
'; dol_fiche_end(); diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index 3cc372094a3..335bfbc26c6 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -93,7 +93,7 @@ if ($prev_id) print '
'; print $langs->trans("WithdrawalFile").''; $relativepath = 'receipts/'.$bon->ref; - print ''.$relativepath.''; + print ''.$relativepath.''; print '
'; dol_fiche_end(); diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php index 20e9c09145f..ee03e0d18b2 100644 --- a/htdocs/compta/prelevement/fiche-stat.php +++ b/htdocs/compta/prelevement/fiche-stat.php @@ -92,7 +92,7 @@ if ($prev_id) print '
'; print $langs->trans("WithdrawalFile").''; $relativepath = 'receipts/'.$bon->ref; - print ''.$relativepath.''; + print ''.$relativepath.''; print '
'; dol_fiche_end(); diff --git a/htdocs/compta/prelevement/fiche.php b/htdocs/compta/prelevement/fiche.php index 283f0c24183..fee2f1ecc24 100644 --- a/htdocs/compta/prelevement/fiche.php +++ b/htdocs/compta/prelevement/fiche.php @@ -191,7 +191,7 @@ if ($id > 0) print '
'; print $langs->trans("WithdrawalFile").''; $relativepath = 'receipts/'.$bon->ref; - print ''.$relativepath.''; + print ''.$relativepath.''; print '
'; dol_fiche_end(); diff --git a/htdocs/compta/prelevement/lignes.php b/htdocs/compta/prelevement/lignes.php index 298effa2b15..5e186774abe 100644 --- a/htdocs/compta/prelevement/lignes.php +++ b/htdocs/compta/prelevement/lignes.php @@ -101,7 +101,7 @@ if ($prev_id) print '
'; print $langs->trans("WithdrawalFile").''; $relativepath = 'receipts/'.$bon->ref; - print ''.$relativepath.''; + print ''.$relativepath.''; print '
'; dol_fiche_end(); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 71541ab4a5d..699977c05ff 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -480,10 +480,10 @@ class FormFile // Show file name with link to download $out.= ''; - $out.= 'trans("File").': '.$file["name"]).' '.dol_trunc($file["name"],$maxfilenamelength); $out.= ''."\n"; $out.= ''; @@ -575,7 +575,7 @@ class FormFile } // Show file name with link to download - $out.= ''; print ''; //print "XX".$file['name']; //$file['name'] must be utf8 - print ''; @@ -855,7 +855,7 @@ class FormFile print ''; print ''; //print "XX".$file['name']; //$file['name'] must be utf8 - print ''; print img_mime($file['name'],$file['name'].' ('.dol_print_size($file['size'],0,0).')').' '; @@ -865,7 +865,7 @@ class FormFile print ''.dol_print_size($file['size'],1,1).''; print ''.dol_print_date($file['date'],"dayhour").''; print ''; - if (! empty($useinecm)) print ''; print img_view().'   '; diff --git a/htdocs/fichinter/apercu.php b/htdocs/fichinter/apercu.php index 2bac1eae624..507a48d2dee 100644 --- a/htdocs/fichinter/apercu.php +++ b/htdocs/fichinter/apercu.php @@ -100,7 +100,7 @@ if ($id > 0 || ! empty($ref)) print "".$langs->trans("Intervention")." PDF"; - print ''.$object->ref.'.pdf'; + print ''.$object->ref.'.pdf'; print ''.dol_print_size(dol_filesize($file)).''; print ''.dol_print_date(dol_filemtime($file),'dayhour').''; print ''; @@ -110,7 +110,7 @@ if ($id > 0 || ! empty($ref)) { print "Fiche d'intervention detaillee"; - print ''.$object->ref.'-detail.pdf'; + print ''.$object->ref.'-detail.pdf'; print ''.dol_print_size(dol_filesize($filedetail)).''; print ''.dol_print_date(dol_filemtime($filedetail),'dayhour').''; print ''; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 85c8410da7e..d6d35335bed 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -569,7 +569,7 @@ if ($step == 3 && $datatoimport) print ''; print ''.img_mime($file).''; print ''; - print ''; + print ''; print $file; print ''; print ''; @@ -742,7 +742,7 @@ if ($step == 4 && $datatoimport) print ''; $modulepart='import'; $relativepath=GETPOST('filetoimport'); - print ''; + print ''; print $filetoimport; print ''; print ''; @@ -1172,7 +1172,7 @@ if ($step == 5 && $datatoimport) print ''; $modulepart='import'; $relativepath=GETPOST('filetoimport'); - print ''; + print ''; print $filetoimport; print ''; print ''; @@ -1506,7 +1506,7 @@ if ($step == 6 && $datatoimport) print ''; $modulepart='import'; $relativepath=GETPOST('filetoimport'); - print ''; + print ''; print $filetoimport; print ''; print ''; From 7b0c7c1a55a4202b0eaa038e2a696c100e51bcf3 Mon Sep 17 00:00:00 2001 From: simnandez Date: Sat, 20 Apr 2013 22:42:06 +0200 Subject: [PATCH 66/97] Update ChangeLog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index bbfeb367955..2eca52d30a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -105,6 +105,7 @@ WARNING: If you used external modules, some of them may need to be upgraded due - Fix: [ bug #774 ] Bug on creating event with box "all day" crossed - Fix: [ bug #810 ] Cannot update ODT template path - Fix: [ bug #824 ] MAIN_DB_PREFIX not use into dictionnary +- Fix: [ bug #828 ] Error when code_region is not a number in llx_c_regions (with postgres) ***** ChangeLog for 3.3.1 compared to 3.3 ***** From c282ff91d65a2e90f55e155692dfc4cbc1b4765a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 20 Apr 2013 23:43:02 +0200 Subject: [PATCH 67/97] Fix: pgsql compatibility --- htdocs/core/modules/modBarcode.class.php | 12 ++++++------ test/phpunit/ModulesTest.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php index b4c933ccf69..856f4251e9c 100644 --- a/htdocs/core/modules/modBarcode.class.php +++ b/htdocs/core/modules/modBarcode.class.php @@ -111,12 +111,12 @@ class modBarcode extends DolibarrModules $this->remove($options); $sql = array( - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("EAN8", "EAN8", 0, "1234567", __ENTITY__)','ignoreerror'=>1), - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("EAN13", "EAN13", 0, "123456789012", __ENTITY__)','ignoreerror'=>1), - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("UPC", "UPC", 0, "123456789012", __ENTITY__)','ignoreerror'=>1), - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("ISBN", "ISBN", 0, "123456789", __ENTITY__)','ignoreerror'=>1), - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("C39", "Code 39", 0, "1234567890", __ENTITY__)','ignoreerror'=>1), - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("C128", "Code 128", 0, "ABCD1234567890", __ENTITY__)','ignoreerror'=>1) + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('EAN8', 'EAN8', 0, '1234567', __ENTITY__)",'ignoreerror'=>1), + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('EAN13', 'EAN13', 0, '123456789012', __ENTITY__)",'ignoreerror'=>1), + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('UPC', 'UPC', 0, '123456789012', __ENTITY__)",'ignoreerror'=>1), + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('ISBN', 'ISBN', 0, '123456789', __ENTITY__)",'ignoreerror'=>1), + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('C39', 'Code 39', 0, '1234567890', __ENTITY__)",'ignoreerror'=>1), + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('C128', 'Code 128', 0, 'ABCD1234567890', __ENTITY__)",'ignoreerror'=>1) ); return $this->_init($sql, $options); diff --git a/test/phpunit/ModulesTest.php b/test/phpunit/ModulesTest.php index 357413e3be9..8b2a0617275 100755 --- a/test/phpunit/ModulesTest.php +++ b/test/phpunit/ModulesTest.php @@ -138,7 +138,7 @@ class ModulesTest extends PHPUnit_Framework_TestCase $mod=new $class($db); $result=$mod->remove(); $result=$mod->init(); - $this->assertLessThan($result, 0); + $this->assertLessThan($result, 0, $modlabel); print __METHOD__." result=".$result."\n"; } From 50eb88db5df9d6b34998dbac7c63cb5563574621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Sun, 21 Apr 2013 10:11:19 +0200 Subject: [PATCH 68/97] Fixed turnover by user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mistakingly used distinct in SQL request --- htdocs/compta/stats/cabyuser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/stats/cabyuser.php b/htdocs/compta/stats/cabyuser.php index d4ef827ad0f..82bbff465eb 100644 --- a/htdocs/compta/stats/cabyuser.php +++ b/htdocs/compta/stats/cabyuser.php @@ -188,7 +188,7 @@ if ($modecompta == 'CREANCES-DETTES') { * Liste des paiements (les anciens paiements ne sont pas vus par cette requete car, sur les * vieilles versions, ils n'etaient pas lies via paiement_facture. On les ajoute plus loin) */ - $sql = "SELECT u.rowid as rowid, u.lastname as name, u.firstname as firstname, sum(DISTINCT pf.amount) as amount_ttc"; + $sql = "SELECT u.rowid as rowid, u.lastname as name, u.firstname as firstname, sum(pf.amount) as amount_ttc"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u" ; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.fk_user_author = u.rowid "; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_facture = f.rowid"; From 6cce2c0b10fd76428743ba0243051f50750e7ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Sun, 21 Apr 2013 10:19:07 +0200 Subject: [PATCH 69/97] Added forgotten file --- htdocs/compta/stats/cabyprodserv.php | 390 +++++++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 htdocs/compta/stats/cabyprodserv.php diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php new file mode 100644 index 00000000000..6adbd4ebf06 --- /dev/null +++ b/htdocs/compta/stats/cabyprodserv.php @@ -0,0 +1,390 @@ + + * + * 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 . + */ + +/** + * \file htdocs/compta/stats/cabyprodserv.php + * \brief Page reporting TO by Products & Services + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; + +$langs->load("products"); +$langs->load("categories"); +$langs->load("errors"); + +// Security pack (data & check) +$socid = GETPOST('socid','int'); + +if ($user->societe_id > 0) $socid = $user->societe_id; +if (! empty($conf->comptabilite->enabled)) $result=restrictedArea($user,'compta','','','resultat'); +if (! empty($conf->accounting->enabled)) $result=restrictedArea($user,'accounting','','','comptarapport'); + +// Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES') +$modecompta = $conf->global->COMPTA_MODE; +if (GETPOST("modecompta")) $modecompta=GETPOST("modecompta"); + +$sortorder=isset($_GET["sortorder"])?$_GET["sortorder"]:$_POST["sortorder"]; +$sortfield=isset($_GET["sortfield"])?$_GET["sortfield"]:$_POST["sortfield"]; +if (! $sortorder) $sortorder="asc"; +if (! $sortfield) $sortfield="name"; + +// Category +$selected_cat = (int)GETPOST('search_categ', 'int'); +$subcat = false; +if (GETPOST('subcat', 'alpha') === 'yes') { + $subcat = true; +} + +// Date range +$year=GETPOST("year"); +$month=GETPOST("month"); +$date_startyear = GETPOST("date_startyear"); +$date_startmonth = GETPOST("date_startmonth"); +$date_startday = GETPOST("date_startday"); +$date_endyear = GETPOST("date_endyear"); +$date_endmonth = GETPOST("date_endmonth"); +$date_endday = GETPOST("date_endday"); +if (empty($year)) +{ + $year_current = strftime("%Y",dol_now()); + $month_current = strftime("%m",dol_now()); + $year_start = $year_current; +} else { + $year_current = $year; + $month_current = strftime("%m",dol_now()); + $year_start = $year; +} +$date_start=dol_mktime(0,0,0,$_REQUEST["date_startmonth"],$_REQUEST["date_startday"],$_REQUEST["date_startyear"]); +$date_end=dol_mktime(23,59,59,$_REQUEST["date_endmonth"],$_REQUEST["date_endday"],$_REQUEST["date_endyear"]); +// Quarter +if (empty($date_start) || empty($date_end)) // We define date_start and date_end +{ + $q=GETPOST("q")?GETPOST("q"):0; + if ($q==0) + { + // We define date_start and date_end + $month_start=GETPOST("month")?GETPOST("month"):($conf->global->SOCIETE_FISCAL_MONTH_START?($conf->global->SOCIETE_FISCAL_MONTH_START):1); + $year_end=$year_start; + $month_end=$month_start; + if (! GETPOST("month")) // If month not forced + { + if (! GETPOST('year') && $month_start > $month_current) + { + $year_start--; + $year_end--; + } + $month_end=$month_start-1; + if ($month_end < 1) $month_end=12; + else $year_end++; + } + $date_start=dol_get_first_day($year_start,$month_start,false); $date_end=dol_get_last_day($year_end,$month_end,false); + } + if ($q==1) { $date_start=dol_get_first_day($year_start,1,false); $date_end=dol_get_last_day($year_start,3,false); } + if ($q==2) { $date_start=dol_get_first_day($year_start,4,false); $date_end=dol_get_last_day($year_start,6,false); } + if ($q==3) { $date_start=dol_get_first_day($year_start,7,false); $date_end=dol_get_last_day($year_start,9,false); } + if ($q==4) { $date_start=dol_get_first_day($year_start,10,false); $date_end=dol_get_last_day($year_start,12,false); } +} else { + // TODO We define q +} + +$commonparams=array(); +$commonparams['modecompta']=$modecompta; +$commonparams['sortorder'] = $sortorder; +$commonparams['sortfield'] = $sortfield; + +$headerparams = array(); +$headerparams['date_startyear'] = $date_startyear; +$headerparams['date_startmonth'] = $date_startmonth; +$headerparams['date_startday'] = $date_startday; +$headerparams['date_endyear'] = $date_endyear; +$headerparams['date_endmonth'] = $date_endmonth; +$headerparams['date_endday'] = $date_endday; +$headerparams['q'] = $q; + +$tableparams = array(); +$tableparams['search_categ'] = $selected_cat; +$tableparams['subcat'] = ($subcat === true)?'yes':''; + +// Adding common parameters +$allparams = array_merge($commonparams, $headerparams, $tableparams); +$headerparams = array_merge($commonparams, $headerparams); +$tableparams = array_merge($commonparams, $tableparams); + +foreach($allparams as $key => $value) { + $paramslink .= '&' . $key . '=' . $value; +} +/* + * View + */ +llxHeader(); +$form=new Form($db); +$formother = new FormOther($db); + +// Show report header +$nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByProductsAndServices"); + +if ($modecompta=="CREANCES-DETTES") { + $nom.='
('.$langs->trans("SeeReportInInputOutputMode",'','').')'; + + $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); + + $description=$langs->trans("RulesCADue"); + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $description.= $langs->trans("DepositsAreNotIncluded"); + } else { + $description.= $langs->trans("DepositsAreIncluded"); + } + + $builddate=time(); +} else { + $nom.='
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; + + $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); + + $description=$langs->trans("RulesCAIn"); + $description.= $langs->trans("DepositsAreIncluded"); + + $builddate=time(); +} + +report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$tableparams); + + +// SQL request +$catotal=0; + +if ($modecompta == 'CREANCES-DETTES') { + $sql = "SELECT DISTINCT p.rowid as rowid, p.ref as ref, p.label as label,"; + $sql.= " sum(DISTINCT l.total_ht) as amount, sum(DISTINCT l.total_ttc) as amount_ttc"; + $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; + $sql.= " JOIN ".MAIN_DB_PREFIX."facturedet as l"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON l.fk_facture = f.rowid"; + if ($selected_cat === -2) { + $sql.=" LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; + } + if ($selected_cat && $selected_cat !== -2) { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = " . $selected_cat; + if ($subcat) { + $sql.=" OR c.fk_parent = " . $selected_cat; + } + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON cp.fk_categorie = c.rowid"; + } + $sql.= " WHERE l.fk_product = p.rowid"; + $sql.= " AND f.fk_statut in (1,2)"; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql.= " AND f.type IN (0,1,2)"; + } else { + $sql.= " AND f.type IN (0,1,2,3)"; + } + if ($date_start && $date_end) { + $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; + } + if ($selected_cat === -2) { + $sql.=" AND cp.fk_product is null"; + } + if ($selected_cat && $selected_cat !== -2) { + $sql.= " AND cp.fk_product = p.rowid"; + } + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " GROUP BY p.rowid "; + $sql.= "ORDER BY p.ref "; + + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + $i=0; + while ($i < $num) { + $obj = $db->fetch_object($result); + $amount_ht[$obj->rowid] = $obj->amount; + $amount[$obj->rowid] = $obj->amount_ttc; + $name[$obj->rowid] = $obj->ref . ' - ' . $obj->label; + $catotal_ht+=$obj->amount; + $catotal+=$obj->amount_ttc; + $i++; + } + } else { + dol_print_error($db); + } + + // Show Array + $i=0; + print '
'; + // Extra parameters management + foreach($headerparams as $key => $value) + { + print ''; + } + + print ''; + // Category filter + print ''; + print ''; + print ''; + // Array header + print ""; + print_liste_field_titre( + $langs->trans("Product"), + $_SERVER["PHP_SELF"], + "name", + "", + $paramslink, + "", + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('AmountHT'), + $_SERVER["PHP_SELF"], + "amount_ht", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans("AmountTTC"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans("Percentage"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + // TODO: statistics? + print "\n"; + + // Array Data + $var=true; + + if (count($amount)) { + $arrayforsort=$name; + // defining arrayforsort + if ($sortfield == 'nom' && $sortorder == 'asc') { + asort($name); + $arrayforsort=$name; + } + if ($sortfield == 'nom' && $sortorder == 'desc') { + arsort($name); + $arrayforsort=$name; + } + if ($sortfield == 'amount_ht' && $sortorder == 'asc') { + asort($amount_ht); + $arrayforsort=$amount_ht; + } + if ($sortfield == 'amount_ht' && $sortorder == 'desc') { + arsort($amount_ht); + $arrayforsort=$amount_ht; + } + if ($sortfield == 'amount_ttc' && $sortorder == 'asc') { + asort($amount); + $arrayforsort=$amount; + } + if ($sortfield == 'amount_ttc' && $sortorder == 'desc') { + arsort($amount); + $arrayforsort=$amount; + } + foreach($arrayforsort as $key=>$value) { + $var=!$var; + print ""; + + // Third party + $fullname=$name[$key]; + if ($key >= 0) { + $linkname=''.img_object($langs->trans("ShowProduct"),'product').' '.$fullname.''; + } else { + $linkname=$langs->trans("PaymentsNotLinkedToProduct"); + } + + print "\n"; + + // Amount w/o VAT + print ''; + + // Amount with VAT + print ''; + + // Percent; + print ''; + + // TODO: statistics? + + print "\n"; + $i++; + } + + // Total + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $db->free($result); + } + print "
'; + print $langs->trans("Category") . ': ' . $formother->select_categories(0, $selected_cat, 'search_categ', true); + print ' '; + print $langs->trans("SubCats") . '? '; + print ''; + print ''; + print '
".$linkname."'; + if ($key > 0) { + print ''; + } else { + print ''; + } + print price($amount_ht[$key]); + print ''; + if ($key > 0) { + print ''; + } else { + print ''; + } + print price($amount[$key]); + print ''; + print ''.($catotal > 0 ? round(100 * $amount[$key] / $catotal, 2).'%' : ' ').'
'.$langs->trans("Total").''.price($catotal_ht).''.price($catotal).' 
"; + print '
'; +} else { + // $modecompta != 'CREANCES-DETTES' + // TODO: better message + print '
' . $langs->trans("WarningNotRelevant") . '
'; +} + +llxFooter(); +$db->close(); +?> From 52b4daf69670d59687de70f89d5060303b67a96d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sun, 21 Apr 2013 10:43:34 +0200 Subject: [PATCH 70/97] Refactor + replaced "OK" and "Error" status install messages with images --- htdocs/install/etape1.php | 42 ++++++++++++++++----------------------- htdocs/install/etape2.php | 20 +++++++++---------- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/htdocs/install/etape1.php b/htdocs/install/etape1.php index 24e56a7ecf0..53f1aba9e19 100644 --- a/htdocs/install/etape1.php +++ b/htdocs/install/etape1.php @@ -458,7 +458,7 @@ if (! $error && $db->connected && $action == "set") print ''; print $langs->trans("ConfFileReload"); print ''; - print ''.$langs->trans("OK").''; + print 'Ok'; $userroot=isset($_POST["db_user_root"])?$_POST["db_user_root"]:""; @@ -508,7 +508,7 @@ if (! $error && $db->connected && $action == "set") print $langs->trans("UserCreation").' : '; print $dolibarr_main_db_user; print ''; - print ''.$langs->trans("OK").''; + print 'Ok'; } else { @@ -542,7 +542,7 @@ if (! $error && $db->connected && $action == "set") print $langs->trans("UserCreation").' : '; print $dolibarr_main_db_user; print ''; - print ''.$langs->trans("Error").''; + print 'Error'; print ''; // Affiche aide diagnostique @@ -576,7 +576,7 @@ if (! $error && $db->connected && $action == "set") print $langs->trans("DatabaseCreation")." (".$langs->trans("User")." ".$userroot.") : "; print $dolibarr_main_db_name; print ''; - print "".$langs->trans("OK").""; + print 'Ok'; $check1=$newdb->getDefaultCharacterSetDatabase(); $check2=$newdb->getDefaultCollationDatabase(); @@ -606,7 +606,7 @@ if (! $error && $db->connected && $action == "set") print $langs->trans("DatabaseCreation")." (".$langs->trans("User")." ".$userroot.") : "; print $dolibarr_main_db_name; print ''; - print ''.$langs->trans("Error").''; + print 'Error'; print ''; // Affiche aide diagnostique @@ -632,43 +632,35 @@ if (! $error && $db->connected && $action == "set") if ($db->connected == 1) { + dolibarr_install_syslog("etape1: connexion to server by user ".$conf->db->user." is ok", LOG_DEBUG); + print ""; + print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; + print $dolibarr_main_db_host; + print ""; + print 'Ok'; + print ""; + // si acces serveur ok et acces base ok, tout est ok, on ne va pas plus loin, on a meme pas utilise le compte root. if ($db->database_selected == 1) { - dolibarr_install_syslog("etape1: connexion to server by user ".$conf->db->user." is ok", LOG_DEBUG); - print ""; - print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; - print $dolibarr_main_db_host; - print ""; - print $langs->trans("OK"); - print ""; - dolibarr_install_syslog("etape1: connexion to database : ".$conf->db->name.", by user : ".$conf->db->user." is ok", LOG_DEBUG); print ""; print $langs->trans("DatabaseConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; print $dolibarr_main_db_name; print ""; - print $langs->trans("OK"); + print 'Ok'; print ""; $error = 0; } else { - dolibarr_install_syslog("etape1: connexion to server by user ".$conf->db->user." is ok", LOG_DEBUG); - print ""; - print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; - print $dolibarr_main_db_host; - print ""; - print $langs->trans("OK"); - print ""; - dolibarr_install_syslog("etape1: connexion to database ".$conf->db->name.", by user : ".$conf->db->user." has failed", LOG_ERR); print ""; print $langs->trans("DatabaseConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; print $dolibarr_main_db_name; print ''; - print $langs->trans("Error"); + print 'Error'; print ""; // Affiche aide diagnostique @@ -688,7 +680,7 @@ if (! $error && $db->connected && $action == "set") print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; print $dolibarr_main_db_host; print ''; - print ''.$db->error.''; + print 'Error'; print ""; // Affiche aide diagnostique @@ -938,7 +930,7 @@ function write_conf_file($conffile) print $langs->trans("SaveConfigurationFile"); print ' '.$conffile.''; print ""; - print $langs->trans("OK"); + print 'Ok'; print ""; } else diff --git a/htdocs/install/etape2.php b/htdocs/install/etape2.php index 9ad310dec9d..92b5f2111b7 100644 --- a/htdocs/install/etape2.php +++ b/htdocs/install/etape2.php @@ -87,12 +87,12 @@ if ($action == "set") if ($db->connected == 1) { print ""; - print $langs->trans("ServerConnection")." : ".$conf->db->host."".$langs->trans("OK").""; + print $langs->trans("ServerConnection")." : ".$conf->db->host.'Ok'; $ok = 1 ; } else { - print "Failed to connect to server : ".$conf->db->host."".$langs->trans("Error").""; + print "Failed to connect to server : ".$conf->db->host.'Error'; } if ($ok) @@ -104,7 +104,7 @@ if ($action == "set") else { dolibarr_install_syslog("etape2: Connexion failed to database : ".$conf->db->name); - print "Failed to select database ".$conf->db->name."".$langs->trans("Error").""; + print "Failed to select database ".$conf->db->name.'Error'; $ok = 0 ; } } @@ -241,13 +241,13 @@ if ($action == "set") if ($error == 0) { print ''; - print $langs->trans("TablesAndPrimaryKeysCreation").''.$langs->trans("OK").''; + print $langs->trans("TablesAndPrimaryKeysCreation").'Ok'; $ok = 1; } } else { - print ''.$langs->trans("ErrorFailedToFindSomeFiles",$dir).''.$langs->trans("Error").''; + print ''.$langs->trans("ErrorFailedToFindSomeFiles",$dir).'Error'; dolibarr_install_syslog("Failed to find files to create database in directory ".$dir,LOG_ERR); } } @@ -388,7 +388,7 @@ if ($action == "set") if ($tablefound && $error == 0) { print ''; - print $langs->trans("OtherKeysCreation").''.$langs->trans("OK").''; + print $langs->trans("OtherKeysCreation").'Ok'; $okkeys = 1; } } @@ -466,11 +466,11 @@ if ($action == "set") print "".$langs->trans("FunctionsCreation").""; if ($ok) { - print "".$langs->trans("OK").""; + print 'Ok'; } else { - print ''.$langs->trans("Error").''; + print 'Error'; $ok = 1 ; } @@ -588,11 +588,11 @@ if ($action == "set") print "".$langs->trans("ReferenceDataLoading").""; if ($ok) { - print "".$langs->trans("OK").""; + print 'Ok'; } else { - print ''.$langs->trans("Error").''; + print 'Error'; $ok = 1; // Data loading are not blocking errors } } From 01ec3d79ca80c8bba58d8680965b13a45724eabb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 21 Apr 2013 11:59:15 +0200 Subject: [PATCH 71/97] Reduce default size of description --- htdocs/comm/action/fiche.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/action/fiche.php b/htdocs/comm/action/fiche.php index 37c5aaba693..b6357880dad 100644 --- a/htdocs/comm/action/fiche.php +++ b/htdocs/comm/action/fiche.php @@ -592,7 +592,7 @@ if ($action == 'create') // Description print ''.$langs->trans("Description").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('note',(GETPOST('note')?GETPOST('note'):$actioncomm->note),'',280,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_7,90); + $doleditor=new DolEditor('note',(GETPOST('note')?GETPOST('note'):$actioncomm->note),'',240,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_7,90); $doleditor->Create(); print ''; From ab2709f684e8a3ed95167ca1f3cc8552c343f0bc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 21 Apr 2013 12:26:44 +0200 Subject: [PATCH 72/97] Filter on agenda event are autoselected on "manual event". --- htdocs/comm/action/class/cactioncomm.class.php | 2 +- htdocs/comm/action/index.php | 6 +++--- htdocs/core/class/html.formactions.class.php | 9 ++++++--- htdocs/core/lib/agenda.lib.php | 6 +++--- htdocs/langs/en_US/agenda.lang | 1 + htdocs/langs/fr_FR/agenda.lang | 1 + 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/htdocs/comm/action/class/cactioncomm.class.php b/htdocs/comm/action/class/cactioncomm.class.php index c686db153c4..e9fe439e75c 100644 --- a/htdocs/comm/action/class/cactioncomm.class.php +++ b/htdocs/comm/action/class/cactioncomm.class.php @@ -132,7 +132,7 @@ class CActionComm $qualified=1; // $obj->type can be system, systemauto, module, moduleauto, xxx, xxxauto - if ($qualified && $onlyautoornot && preg_match('/^system/',$obj->type) && ! preg_match('/^AC_OTH/',$obj->code)) $qualified=0; // We discard detailed system events. We keep only the 2 generic lines (AC_OTH and AC_OTHER) + if ($qualified && $onlyautoornot && preg_match('/^system/',$obj->type) && ! preg_match('/^AC_OTH/',$obj->code)) $qualified=0; // We discard detailed system events. We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO) if ($qualified && $obj->module) { diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 49a84a28d22..813c2578374 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2003 Eric Seigne - * Copyright (C) 2004-2012 Laurent Destailleur + * Copyright (C) 2004-2013 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011 Juanjo Menent * @@ -72,11 +72,11 @@ $year=GETPOST("year","int")?GETPOST("year","int"):date("Y"); $month=GETPOST("month","int")?GETPOST("month","int"):date("m"); $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); $day=GETPOST("day","int")?GETPOST("day","int"):0; -$actioncode=GETPOST("actioncode","alpha",3); $pid=GETPOST("projectid","int",3); $status=GETPOST("status"); $type=GETPOST("type"); $maxprint=(isset($_GET["maxprint"])?GETPOST("maxprint"):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); +$actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=="0"?'':(empty($conf->global->AGENDA_USE_EVENT_TYPE)?'AC_OTH':'')); if (GETPOST('viewcal')) { $action='show_month'; $day=''; @@ -271,7 +271,7 @@ $param.='&year='.$year.'&month='.$month.($day?'&day='.$day:''); $head = calendars_prepare_head(''); dol_fiche_head($head, 'card', $langs->trans('Events'), 0, $picto); -print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$listofextcals); +print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$listofextcals,$actioncode); dol_fiche_end(); $link=''; diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index 827a65ed51f..b7477c203f5 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -209,10 +209,10 @@ class FormActions /** * Output list of type of event * - * @param string $selected Type pre-selectionne + * @param string $selected Type pre-selected (can be 'manual', 'auto' or 'AC_xxx' * @param string $htmlname Nom champ formulaire * @param string $excludetype Type to exclude - * @param string $onlyautoornot Group list by auto events or not + * @param string $onlyautoornot Group list by auto events or not: We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO) * @return void */ function select_type_actions($selected='',$htmlname='actioncode',$excludetype='',$onlyautoornot=0) @@ -224,11 +224,14 @@ class FormActions $caction=new CActionComm($this->db); $form=new Form($this->db); - // Suggest a list with manual event or all auto events + // Suggest a list with manual events or all auto events $arraylist=$caction->liste_array(1, 'code', $excludetype, $onlyautoornot); array_unshift($arraylist,' '); // Add empty line at start //asort($arraylist); + if ($selected == 'manual') $selected='AC_OTH'; + if ($selected == 'auto') $selected='AC_OTH_AUTO'; + print $form->selectarray($htmlname, $arraylist, $selected); if ($user->admin && empty($onlyautoornot)) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionnarySetup"),1); } diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 531ea49eb96..9b7f37b6fee 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -40,9 +40,10 @@ * @param int $pid Product id * @param int $socid Third party id * @param array $showextcals Array with list of external calendars, or -1 to show no legend + * @param string $actioncode Preselected value of actioncode for filter on type * @return void */ -function print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$showextcals=array()) +function print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$showextcals=array(),$actioncode='') { global $conf,$user,$langs,$db; @@ -94,8 +95,7 @@ function print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirt print $langs->trans("Type"); print '  '; - // print $formactions->select_type_actions(GETPOST('actioncode'), "actioncode"); - print $formactions->select_type_actions(GETPOST('actioncode')?GETPOST('actioncode'):'manual', "actioncode", '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0)); + print $formactions->select_type_actions($actioncode, "actioncode", '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0)); print ''; } diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 7bd84be4cd1..3d0aadefec2 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -67,6 +67,7 @@ AgendaUrlOptions4=logint=%s to restrict output to actions assigned to use AgendaUrlOptions5=logind=%s to restrict output to actions done by user %s. AgendaShowBirthdayEvents=Show birthday's contacts AgendaHideBirthdayEvents=Hide birthday's contacts +Busy=Busy # External Sites ical ExportCal=Export calendar diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index cf8216b617b..6c41e3e95c2 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -67,6 +67,7 @@ AgendaUrlOptions4=logint=%s pour limiter l'export aux actions affectées AgendaUrlOptions5=logind=%s pour limiter l'export aux actions réalisées par l'utilisateur %s. AgendaShowBirthdayEvents=Afficher anniversaires contacts AgendaHideBirthdayEvents=Cacher anniversaires contacts +Busy=Occupé # External Sites ical ExportCal=Export calendrier From 7befeae37124186e2fa797ab1efd17617d649474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sun, 21 Apr 2013 12:40:46 +0200 Subject: [PATCH 73/97] ECM Refactor --- htdocs/core/ajax/ajaxdirpreview.php | 139 +++++++++------------------- 1 file changed, 43 insertions(+), 96 deletions(-) diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php index ef4d976d4d7..b7ac13d3bd3 100644 --- a/htdocs/core/ajax/ajaxdirpreview.php +++ b/htdocs/core/ajax/ajaxdirpreview.php @@ -139,8 +139,7 @@ if (! dol_is_dir($upload_dir)) print ''."\n"; print ''."\n"; -$param=''; -$param.=($sortfield?'&sortfield='.$sortfield:'').($sortorder?'&sortorder='.$sortorder:''); +$param=($sortfield?'&sortfield='.$sortfield:'').($sortorder?'&sortorder='.$sortorder:''); $url=DOL_URL_ROOT.'/ecm/index.php'; // Dir scan @@ -149,126 +148,74 @@ if ($type == 'directory') $formfile=new FormFile($db); $maxlengthname=40; + $excludefiles = array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'); + $sorting = (strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC); // Right area. If module is defined, we are in automatic ecm. - if ($module == 'company') // Auto area for suppliers invoices - { - $upload_dir = $conf->societe->dir_output; // TODO change for multicompany sharing - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); + $automodules = array('company', 'invoice', 'invoice_supplier', 'propal', 'order', 'order_supplier', 'contract', 'product', 'tax', 'project'); - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'invoice') // Auto area for suppliers invoices - { - $upload_dir = $conf->facture->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'invoice_supplier') // Auto area for suppliers invoices + // TODO change for multicompany sharing + // Auto area for suppliers invoices + if ($module == 'company') $upload_dir = $conf->societe->dir_output; + // Auto area for suppliers invoices + else if ($module == 'invoice') $upload_dir = $conf->facture->dir_output; + // Auto area for suppliers invoices + else if ($module == 'invoice_supplier') { $relativepath='facture'; $upload_dir = $conf->fournisseur->dir_output.'/'.$relativepath; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); } - else if ($module == 'propal') // Auto area for customers orders - { - $upload_dir = $conf->propal->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'order') // Auto area for customers orders - { - $upload_dir = $conf->commande->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'order_supplier') // Auto area for suppliers orders + // Auto area for customers orders + else if ($module == 'propal') $upload_dir = $conf->propal->dir_output; + // Auto area for customers orders + else if ($module == 'order') $upload_dir = $conf->commande->dir_output; + // Auto area for suppliers orders + else if ($module == 'order_supplier') { $relativepath='commande'; $upload_dir = $conf->fournisseur->dir_output.'/'.$relativepath; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); + } + // Auto area for suppliers invoices + else if ($module == 'contract') $upload_dir = $conf->contrat->dir_output; + // Auto area for products + else if ($module == 'product') $upload_dir = $conf->product->dir_output; + // Auto area for suppliers invoices + else if ($module == 'tax') $upload_dir = $conf->tax->dir_output; + // Auto area for projects + else if ($module == 'project') $upload_dir = $conf->projet->dir_output; + if (in_array($module, $automodules)) + { $param.='&module='.$module; $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); + $filearray=dol_dir_list($upload_dir,"files",1,'', $excludefiles, $sortfield, $sorting,1); + var_dump($filearray); $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); } - else if ($module == 'contract') // Auto area for suppliers invoices - { - $upload_dir = $conf->contrat->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'product') // Auto area for products - { - $upload_dir = $conf->product->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'tax') // Auto area for suppliers invoices - { - $upload_dir = $conf->tax->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'project') // Auto area for projects - { - $upload_dir = $conf->projet->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else // Manual area + //Manual area + else { $relativepath=$ecmdir->getRelativePath(); $upload_dir = $conf->ecm->dir_output.'/'.$relativepath; - $filearray=dol_dir_list($upload_dir,"files",0,'',array('^\.','\.meta$','^temp$','^CVS$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - if ($section) $param.='§ion='.$section; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("ECMSelectASection"))); // If $section defined with value 0 if ($section === '0') { - $filearray=array(); - $textifempty='
'.$langs->trans("DirNotSynchronizedSyncFirst").'

'; + $filearray=array(); + $textifempty='
'.$langs->trans("DirNotSynchronizedSyncFirst").'

'; } + else $filearray=dol_dir_list($upload_dir,"files",0,'',array('^\.','\.meta$','^temp$','^CVS$'),$sortfield, $sorting,1); + + if ($section) + { + $param.='§ion='.$section; + $textifempty = $langs->trans('NoFileFound'); + } + else $textifempty=($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("ECMSelectASection")); + $formfile->list_of_documents($filearray,'','ecm',$param,1,$relativepath,$user->rights->ecm->upload,1,$textifempty,$maxlengthname,'',$url); } - } if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) From 17902a84557204c65730f690ccb83474bd38c636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sun, 21 Apr 2013 12:44:13 +0200 Subject: [PATCH 74/97] Removed var_dump --- htdocs/core/ajax/ajaxdirpreview.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php index b7ac13d3bd3..73147edeeb0 100644 --- a/htdocs/core/ajax/ajaxdirpreview.php +++ b/htdocs/core/ajax/ajaxdirpreview.php @@ -190,7 +190,6 @@ if ($type == 'directory') $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); $filearray=dol_dir_list($upload_dir,"files",1,'', $excludefiles, $sortfield, $sorting,1); - var_dump($filearray); $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); } //Manual area From 293fc89a9fb173692fd6d4de9a9b5c40fefd8d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sun, 21 Apr 2013 12:45:34 +0200 Subject: [PATCH 75/97] Missing copyright --- htdocs/core/ajax/ajaxdirpreview.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php index 73147edeeb0..2389a681000 100644 --- a/htdocs/core/ajax/ajaxdirpreview.php +++ b/htdocs/core/ajax/ajaxdirpreview.php @@ -4,6 +4,7 @@ * Copyright (C) 2005 Simon Tosser * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2010 Pierre Morin + * Copyright (C) 2013 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 From 82e3a8d0b9c16c744dde875a290d09f6d617f23a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sun, 21 Apr 2013 14:14:30 +0200 Subject: [PATCH 76/97] New: [ task #823 ] Shipping_validate email notification --- ChangeLog | 1 + ..._50_modNotification_Notification.class.php | 17 ++++++++++- htdocs/expedition/fiche.php | 30 +++++++++++++------ htdocs/langs/en_US/other.lang | 1 + htdocs/langs/es_ES/other.lang | 1 + htdocs/langs/fr_FR/other.lang | 1 + 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2eca52d30a7..22a4e6fde72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -50,6 +50,7 @@ For users: - New: [ task #770 ] Add ODT document generation for Projects module - New: [ task #741 ] Add intervention box - New: [ task #826 ] Optionnal increase stock when deleting an invoice already validated +- New: [ task #823 ] Shipping_validate email notification For translators: - Update language files. diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php index c2785445800..f3b10e7f1f8 100755 --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php @@ -1,6 +1,7 @@ * Copyright (C) 2011 Regis Houssin + * Copyright (C) 2013 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 @@ -35,7 +36,8 @@ class InterfaceNotification 'PROPAL_VALIDATE', 'FICHINTER_VALIDATE', 'ORDER_SUPPLIER_APPROVE', - 'ORDER_SUPPLIER_REFUSE' + 'ORDER_SUPPLIER_REFUSE', + 'SHIPPING_VALIDATE' ); /** @@ -196,6 +198,19 @@ class InterfaceNotification $notify = new Notify($this->db); $notify->send($action, $object->socid, $mesg, 'order_supplier', $object->id, $filepdf); } + elseif ($action == 'SHIPPING_VALIDATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + + $ref = dol_sanitizeFileName($object->ref); + $filepdf = $conf->expedition->dir_output . '/sending/' . $ref . '/' . $ref . '.pdf'; + if (! file_exists($filepdf)) $filepdf=''; + $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$object->ref); + + + $notify = new Notify($this->db); + $notify->send($action, $object->socid, $mesg, 'expedition', $object->id, $filepdf); + } // If not found /* diff --git a/htdocs/expedition/fiche.php b/htdocs/expedition/fiche.php index de3107b663f..996e41a649a 100644 --- a/htdocs/expedition/fiche.php +++ b/htdocs/expedition/fiche.php @@ -5,6 +5,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011-2012 Juanjo Menent * Copyright (C) 2013 Florian Henry + * Copyright (C) 2013 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 @@ -698,16 +699,16 @@ if ($action == 'create') //$lines = $object->fetch_lines(1); $numAsked = count($object->lines); - print ''; + }); + '; print '
'; @@ -904,7 +905,7 @@ if ($action == 'create') print '
'; - print ''; + print ''; print '
'; } @@ -974,7 +975,18 @@ else { $numref = $object->ref; } - $ret=$form->form_confirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('ValidateSending'),$langs->trans("ConfirmValidateSending",$numref),'confirm_valid','',0,1); + + $text = $langs->trans("ConfirmValidateSending",$numref); + + if (! empty($conf->notification->enabled)) + { + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage('SHIPPING_VALIDATE',$object->socid); + } + + $ret=$form->form_confirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('ValidateSending'),$text,'confirm_valid','',0,1); if ($ret == 'html') print '
'; } /* diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 6a350078731..bb6c4873c93 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -152,6 +152,7 @@ EMailTextOrderApproved=The order %s has been approved. EMailTextOrderApprovedBy=The order %s has been approved by %s. EMailTextOrderRefused=The order %s has been refused. EMailTextOrderRefusedBy=The order %s has been refused by %s. +EMailTextExpeditionValidated=The shipping %s has been validated. ImportedWithSet=Importation data set DolibarrNotification=Automatic notification ResizeDesc=Enter new width OR new height. Ratio will be kept during resizing... diff --git a/htdocs/langs/es_ES/other.lang b/htdocs/langs/es_ES/other.lang index 60af821e8c1..6d53b9de9cb 100644 --- a/htdocs/langs/es_ES/other.lang +++ b/htdocs/langs/es_ES/other.lang @@ -151,6 +151,7 @@ EMailTextOrderApproved=Pedido %s aprobado EMailTextOrderApprovedBy=Pedido %s aprobado por %s EMailTextOrderRefused=Pedido %s rechazado EMailTextOrderRefusedBy=Pedido %s rechazado por %s +EMailTextExpeditionValidated=El envío %s ha sido validado. ImportedWithSet=Lote de importación (import key) DolibarrNotification=Notificación automática ResizeDesc=Introduzca el nuevo ancho O la nueva altura. La relación se conserva al cambiar el tamaño ... diff --git a/htdocs/langs/fr_FR/other.lang b/htdocs/langs/fr_FR/other.lang index de941e850a6..86218e219be 100644 --- a/htdocs/langs/fr_FR/other.lang +++ b/htdocs/langs/fr_FR/other.lang @@ -151,6 +151,7 @@ EMailTextOrderApproved=La commande %s a été approuvée. EMailTextOrderApprovedBy=La commande %s a été approuvée par %s. EMailTextOrderRefused=La commande %s a été refusée. EMailTextOrderRefusedBy=La commande %s a été refusée par %s. +EMailTextExpeditionValidated= ImportedWithSet=Lot d'importation (Import key) DolibarrNotification=Notification automatique ResizeDesc=Entrer la nouvelle largeur OU la nouvelle hauteur. Le ratio est conservé lors du redimensionnement... From 5b248805c26bd0e793e54c45304d9bf146016bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sun, 21 Apr 2013 14:24:19 +0200 Subject: [PATCH 77/97] Notifications popup messages were not showing real notifications that were going to be sent --- htdocs/comm/propal.php | 4 ++-- htdocs/commande/fiche.php | 28 ++++++++++++++-------------- htdocs/compta/facture.php | 6 +++--- htdocs/fourn/commande/fiche.php | 6 +++--- htdocs/fourn/facture/fiche.php | 14 +++++++------- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index c178c37078b..2a7c92dce56 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -1534,7 +1534,7 @@ else require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; $notify=new Notify($db); $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_PROPAL',$object->socid); + $text.=$notify->confirmMessage('PROPAL_VALIDATE',$object->socid); } if (! $error) $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProp'), $text, 'confirm_validate','',0,1); @@ -2171,7 +2171,7 @@ else //print ''; - print ''; + print ''; } diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php index 9cc8da95d51..4801305a091 100644 --- a/htdocs/commande/fiche.php +++ b/htdocs/commande/fiche.php @@ -1784,7 +1784,7 @@ else require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; $notify=new Notify($db); $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_ORDER',$object->socid); + $text.=$notify->confirmMessage('ORDER_VALIDATE',$object->socid); } $formquestion=array(); if (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $object->hasProductsOrServices(1)) @@ -1935,15 +1935,15 @@ else print ''.$soc->getNomUrl(1).''; print ''; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) - { - $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - } - else - { - $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; - $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) + { + $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + } + else + { + $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; + $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; } // Relative and absolute discounts @@ -2170,9 +2170,9 @@ else } } - $rowspan=4; - if ($mysoc->localtax1_assuj=="1") $rowspan++; - if ($mysoc->localtax2_assuj=="1") $rowspan++; + $rowspan=4; + if ($mysoc->localtax1_assuj=="1") $rowspan++; + if ($mysoc->localtax2_assuj=="1") $rowspan++; // Total HT print ''.$langs->trans('AmountHT').''; @@ -2411,7 +2411,7 @@ else print ''; } } - print '
'; + print '
'; if ($action != 'presend') diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 2a02522bbcc..6c190bac20b 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -2523,7 +2523,7 @@ else if ($id > 0 || ! empty($ref)) require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; $notify=new Notify($db); $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_FAC',$object->socid); + $text.=$notify->confirmMessage('BILL_VALIDATE',$object->socid); } $formquestion=array(); @@ -3618,7 +3618,7 @@ else if ($id > 0 || ! empty($ref)) print ''; } } - print '
'; + print '
'; if ($action != 'prerelance' && $action != 'presend') { @@ -3659,7 +3659,7 @@ else if ($id > 0 || ! empty($ref)) $somethingshown=$formactions->showactions($object,'invoice',$socid); //print ''; - print ''; + print ''; } else { diff --git a/htdocs/fourn/commande/fiche.php b/htdocs/fourn/commande/fiche.php index 653397cfaf5..cad571686e8 100644 --- a/htdocs/fourn/commande/fiche.php +++ b/htdocs/fourn/commande/fiche.php @@ -1077,7 +1077,7 @@ elseif (! empty($object->id)) require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; $notify=new Notify($db); $text.='
'; - $text.=$notify->confirmMessage(3,$object->socid); + $text.=$notify->confirmMessage('ORDER_SUPPLIER_APPROVE', $object->socid); } $ret=$form->form_confirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_valid', '', 0, 1); @@ -1762,10 +1762,10 @@ elseif (! empty($object->id)) print ""; } - print "
"; + print "
"; - print '
'; + print '
'; //print ''; - return $out; - } - - /** - * Fill array_options array for object by extrafields value (using for data send by forms) - * - * @param array $extralabels $array of extrafields - * @param object &$object object - * @return int 1 if array_options set / 0 if no value - */ - function setOptionalsFromPost($extralabels,&$object) - { - global $_POST; - - if (is_array($extralabels)) - { - // Get extra fields - foreach ($extralabels as $key => $value) - { - $key_type = $this->attribute_type[$key]; - - if (in_array($key_type,array('date','datetime'))) - { - // Clean parameters - $value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]); - } - else if (in_array($key_type,array('checkbox'))) - { - $value_arr=GETPOST("options_".$key); - $value_key=implode($value_arr,','); - } - else - { - $value_key=GETPOST("options_".$key); - } - $object->array_options["options_".$key]=$value_key; - } - - return 1; - } - else { - return 0; - } - } + $sql = 'SELECT '.$InfoFieldList[1]; + $sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0]; + $sql.= ' where '.$keyList.'="'.$value.'"'; + + $resql = $this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + $value=$obj->$InfoFieldList[1]; + } + } + elseif ($type == 'radio') + { + $value=$params['options'][$value]; + } + elseif ($type == 'checkbox') + { + $value_arr=explode(',',$value); + $value=''; + if (is_array($value_arr)) + { + foreach ($value_arr as $keyval=>$valueval) { + $value.=$params['options'][$valueval].'
'; + } + } + } + else + { + $showsize=round($size); + if ($showsize > 48) $showsize=48; + } + //print $type.'-'.$size; + $out=$value; + return $out; + } + + /** + * Return HTML string to print separator extrafield + * + * @param string $key Key of attribute + * @return string + */ + function showSeparator($key) + { + $out = ''; + return $out; + } + + /** + * Fill array_options array for object by extrafields value (using for data send by forms) + * + * @param array $extralabels $array of extrafields + * @param object &$object object + * @return int 1 if array_options set / 0 if no value + */ + function setOptionalsFromPost($extralabels,&$object) + { + global $_POST; + + if (is_array($extralabels)) + { + // Get extra fields + foreach ($extralabels as $key => $value) + { + $key_type = $this->attribute_type[$key]; + + if (in_array($key_type,array('date','datetime'))) + { + // Clean parameters + $value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]); + } + else if (in_array($key_type,array('checkbox'))) + { + $value_arr=GETPOST("options_".$key); + $value_key=implode($value_arr,','); + } + else + { + $value_key=GETPOST("options_".$key); + } + $object->array_options["options_".$key]=$value_key; + } + + return 1; + } + else { + return 0; + } + } } ?> diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php index 5272c06b31f..44cc7a78bc0 100644 --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php @@ -27,7 +27,7 @@ var required = jQuery("#required"); var default_value = jQuery("#default_value"); " method="post"> +
'; //print ''; // ancre diff --git a/htdocs/fourn/facture/fiche.php b/htdocs/fourn/facture/fiche.php index 23ed291c681..1ea01631f79 100644 --- a/htdocs/fourn/facture/fiche.php +++ b/htdocs/fourn/facture/fiche.php @@ -1342,12 +1342,12 @@ else } $text=$langs->trans('ConfirmValidateBill',$numref); - /*if (! empty($conf->notification->enabled)) - { - require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; - $notify=new Notify($db); - $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_FAC_SUP',$object->socid); + /*if (! empty($conf->notification->enabled)) + { + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage('BILL_SUPPLIER_VALIDATE',$object->socid); }*/ $formquestion=array(); @@ -2066,7 +2066,7 @@ else print ''.$langs->trans('Delete').''; } print ''; - print '
'; + print '
'; if ($action != 'edit') { From fcf1eeba203bdefeaff9619fe8e126402e034d4c Mon Sep 17 00:00:00 2001 From: JF FERRY Date: Sun, 21 Apr 2013 14:55:32 +0200 Subject: [PATCH 78/97] Task #838 - change regex to look at ods document too --- htdocs/core/lib/functions2.lib.php | 2 +- htdocs/core/modules/societe/doc/doc_generic_odt.modules.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 059400d7399..dc6c57002c9 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -1283,7 +1283,7 @@ function getListOfModels($db,$type,$maxfilenamelength=0) if (! $tmpdir) { unset($listofdir[$key]); continue; } if (is_dir($tmpdir)) { - $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt','','name',SORT_ASC,0,true); // Disable hook for the moment + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.od(s|t)$','','name',SORT_ASC,0,true); // Disable hook for the moment if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); } } diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php index ca93ab1880e..fe40e5c0ad4 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -109,7 +109,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); else { - $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt','','name',SORT_ASC,0,true); // Disable hook for the moment + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.od(s|t)$','','name',SORT_ASC,0,true); // Disable hook for the moment if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); } } From 83028b958a4532457717ca27e93357d38271125b Mon Sep 17 00:00:00 2001 From: JF FERRY Date: Sun, 21 Apr 2013 15:12:48 +0200 Subject: [PATCH 79/97] Task #838 : retieve extension to work with ods document --- .../core/modules/societe/doc/doc_generic_odt.modules.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php index fe40e5c0ad4..22835fec8e8 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -210,16 +210,20 @@ class doc_generic_odt extends ModeleThirdPartyDoc { //print "srctemplatepath=".$srctemplatepath; // Src filename $newfile=basename($srctemplatepath); - $newfiletmp=preg_replace('/\.odt/i','',$newfile); + $newfiletmp=preg_replace('/\.od(s|t)/i','',$newfile); $newfiletmp=preg_replace('/template_/i','',$newfiletmp); $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); - $filename=$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; + // Get extension (ods or odt) + $newfileformat=substr($newfile, strrpos($newfile, '.')+1); + $filename=$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.'.$newfileformat; $file=$dir.'/'.$filename; $object->builddoc_filename=$filename; // For triggers + //print "newfileformat=".$newfileformat; //print "newdir=".$dir; //print "newfile=".$newfile; //print "file=".$file; //print "conf->societe->dir_temp=".$conf->societe->dir_temp; + //exit; dol_mkdir($conf->societe->multidir_temp[$object->entity]); From 0a853c9c7cc58e5c3b4cac4464f1a298529be565 Mon Sep 17 00:00:00 2001 From: BENKE Charles Date: Sun, 21 Apr 2013 16:14:40 +0300 Subject: [PATCH 80/97] Update products.lang --- htdocs/langs/fr_FR/products.lang | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 3d27fdd9d6d..4a805a5c2dc 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -184,4 +184,12 @@ AlwaysUseNewPrice=Toujours utiliser le prix du jour AlwaysUseFixedPrice=Utiliser le prix fixé PriceByQuantity=Prix par quantité PriceByQuantityRange=Grille de quantités -ProductsDashboard=Synthèse produits/services \ No newline at end of file +ProductsDashboard=Synthèse produits/services +### composition fabrication +Building=Fabrication +Build=Fabriquer +BuildIt=Lancer la fabrication +BuildindListInfo=Nombre de produit fabricable par entrepot, si saisie à zéro on ne fabrique pas +QtyNeed=Affectée +UnitPmp=Prix Achat Unitaire +CostPmpHT=Cout à l'achat HT From 72e571fcd5aad0b05cafbe12accf5b314a1d1950 Mon Sep 17 00:00:00 2001 From: BENKE Charles Date: Sun, 21 Apr 2013 16:16:13 +0300 Subject: [PATCH 81/97] Update products.lang Add Fabrication Feature --- htdocs/langs/en_US/products.lang | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index b58dec53dcb..deb19df8e12 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -184,4 +184,14 @@ AlwaysUseNewPrice=Always use current price of product/service AlwaysUseFixedPrice=Use the fixed price PriceByQuantity=Price by quantity PriceByQuantityRange=Quantity range -ProductsDashboard=Products/Services summary \ No newline at end of file +ProductsDashboard=Products/Services summary +### composition fabrication +Building=Production and items dispatchment +Build=Produce +BuildIt=Produce & Dispatch +BuildindListInfo=Available quantity for production per warehouse (set it to 0 for no further action) +QtyNeed=Qty +UnitPmp=Net unit VWAP +CostPmpHT=Net total VWAP +ProductUsedForBuild=Auto consumed by production +ProductBuilded=Production completed From f4513d1beb526534c5321127cf5c8adcb592289b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 21 Apr 2013 16:01:36 +0200 Subject: [PATCH 82/97] Move option ate better place --- htdocs/admin/agenda.php | 49 +----------- htdocs/admin/agenda_other.php | 135 +++++++++++++++++++++++++++++++++ htdocs/core/lib/agenda.lib.php | 5 ++ 3 files changed, 144 insertions(+), 45 deletions(-) create mode 100644 htdocs/admin/agenda_other.php diff --git a/htdocs/admin/agenda.php b/htdocs/admin/agenda.php index 7eb659bde97..4e53a709d20 100644 --- a/htdocs/admin/agenda.php +++ b/htdocs/admin/agenda.php @@ -65,8 +65,8 @@ else /* -* Actions -*/ + * Actions + */ if ($action == "save" && empty($cancel)) { $i=0; @@ -125,7 +125,7 @@ if (preg_match('/del_(.*)/',$action,$reg)) /** - * Affichage du formulaire de saisie + * View */ llxHeader(); @@ -184,48 +184,7 @@ print ""; print "\n"; -print ''; - -/* - * Other options -*/ - -print_titre($langs->trans("OtherOptions")); - -$var=true; - -print ''."\n"; -print ''."\n"; -print ''."\n"; -print ''."\n"; -print ''."\n"; -print ''."\n"; - -// Manual or automatic -$var=!$var; -print ''."\n"; -print ''."\n"; -print ''."\n"; - -print ''."\n"; - -print '
'.$langs->trans("Parameters").' '.$langs->trans("Value").'
'.$langs->trans("AGENDA_USE_EVENT_TYPE").' '."\n"; -if ($conf->use_javascript_ajax) -{ - print ajax_constantonoff('AGENDA_USE_EVENT_TYPE'); -} -else -{ - if($conf->global->AGENDA_USE_EVENT_TYPE == 0) - { - print ''.img_picto($langs->trans("Disabled"),'off').''; - } - else if($conf->global->BUSINESS_VISIBLE_TO_ALL_BY_DEFAULT == 1) - { - print ''.img_picto($langs->trans("Enabled"),'on').''; - } -} -print '
'; +dol_fiche_end(); print "
"; diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php new file mode 100644 index 00000000000..cffbed706ce --- /dev/null +++ b/htdocs/admin/agenda_other.php @@ -0,0 +1,135 @@ + + * Copyright (C) 2011 Regis Houssin + * Copyright (C) 2011-2012 Juanjo Menent + * + * 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 . + */ + +/** + * \file htdocs/admin/agenda.php + * \ingroup agenda + * \brief Autocreate actions for agenda module setup page + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; + +if (!$user->admin) + accessforbidden(); + +$langs->load("admin"); +$langs->load("other"); + +$action = GETPOST('action','alpha'); +$cancel = GETPOST('cancel','alpha'); + + +/* + * Actions + */ + +if (preg_match('/set_(.*)/',$action,$reg)) +{ + $code=$reg[1]; + $value=(GETPOST($code) ? GETPOST($code) : 1); + if (dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity) > 0) + { + Header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } + else + { + dol_print_error($db); + } +} + +if (preg_match('/del_(.*)/',$action,$reg)) +{ + $code=$reg[1]; + if (dolibarr_del_const($db, $code, $conf->entity) > 0) + { + Header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } + else + { + dol_print_error($db); + } +} + + +/** + * View + */ + +llxHeader(); + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans("AgendaSetup"),$linkback,'setup'); +print "
\n"; + + +$head=agenda_prepare_head(); + +dol_fiche_head($head, 'other', $langs->trans("Agenda")); + +print_titre($langs->trans("OtherOptions")); + +$var=true; + +print ''."\n"; +print ''."\n"; +print ''."\n"; +print ''."\n"; +print ''."\n"; +print ''."\n"; + +// Manual or automatic +$var=!$var; +print ''."\n"; +print ''."\n"; +print ''."\n"; + +print ''."\n"; + +print '
'.$langs->trans("Parameters").' '.$langs->trans("Value").'
'.$langs->trans("AGENDA_USE_EVENT_TYPE").' '."\n"; +if ($conf->use_javascript_ajax) +{ + print ajax_constantonoff('AGENDA_USE_EVENT_TYPE'); +} +else +{ + if($conf->global->AGENDA_USE_EVENT_TYPE == 0) + { + print ''.img_picto($langs->trans("Disabled"),'off').''; + } + else if($conf->global->BUSINESS_VISIBLE_TO_ALL_BY_DEFAULT == 1) + { + print ''.img_picto($langs->trans("Enabled"),'on').''; + } +} +print '
'; + +dol_fiche_end(); + +print "
"; + +dol_htmloutput_mesg($mesg); + +llxFooter(); + +$db->close(); +?> diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 9b7f37b6fee..a11fdac4dda 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -384,6 +384,11 @@ function agenda_prepare_head() $head[$h][2] = 'extsites'; $h++; + $head[$h][0] = DOL_URL_ROOT."/admin/agenda_other.php"; + $head[$h][1] = $langs->trans("Other"); + $head[$h][2] = 'other'; + $h++; + complete_head_from_modules($conf,$langs,$object,$head,$h,'agenda_admin'); $head[$h][0] = DOL_URL_ROOT."/admin/agenda_extrafields.php"; From 642ba10d84f038aca41bfdfc9b4f26d25292a587 Mon Sep 17 00:00:00 2001 From: JF FERRY Date: Sun, 21 Apr 2013 17:04:54 +0200 Subject: [PATCH 83/97] New hidden option to introduce timing value into odt document nam --- .../core/modules/societe/doc/doc_generic_odt.modules.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php index 22835fec8e8..e748e45a498 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -215,7 +215,14 @@ class doc_generic_odt extends ModeleThirdPartyDoc $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); // Get extension (ods or odt) $newfileformat=substr($newfile, strrpos($newfile, '.')+1); - $filename=$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.'.$newfileformat; + if ( ! empty($conf->global->MAIN_ODT_USE_TIMING)) + { + $filename=$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.'.$newfileformat; + } + else + { + $filename=$newfiletmp.'.'.$newfileformat; + } $file=$dir.'/'.$filename; $object->builddoc_filename=$filename; // For triggers //print "newfileformat=".$newfileformat; From 8cb7770a6a3ef3b19c6e1158ca95baaba2747015 Mon Sep 17 00:00:00 2001 From: JF FERRY Date: Sun, 21 Apr 2013 17:06:25 +0200 Subject: [PATCH 84/97] Add ODS document for example --- .../thirdparties/template_thirdparty.ods | Bin 0 -> 14558 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 htdocs/install/doctemplates/thirdparties/template_thirdparty.ods diff --git a/htdocs/install/doctemplates/thirdparties/template_thirdparty.ods b/htdocs/install/doctemplates/thirdparties/template_thirdparty.ods new file mode 100644 index 0000000000000000000000000000000000000000..ad50961b562d95810ea98e692c74827e9ece247d GIT binary patch literal 14558 zcmeHuWmr|)7AQ(fgLHRyNSAbXH*8?jus0wr9ZE?fA>Ab0%9&E=K!2$&Z^>9I|pzMM60I-J> zz|_gf4rp!)20A*hx;a>|IGTchAQnd_fP;mjxvM?E0n7q&asilHfUE%ku*yGZTAYr- z_z*!sJzRJYni|%w_GS*IKsyjC_~$K)lY>>bijp+S6M`oY5ENM%2{p+79w?|sPzaA9 zcOGZuxlm9<60#Cv8ZXlJ(mg~q#!0#lN(Z2z5fHN9y?Yt(F$RguhCnwFn7F29vUJ>1 zxeG`Uvd8MrQ&4?a;Kj_o-a9e&~<3QkS zd9=})85FK2uAR7{`_f)0slMO*+Lqx)n~y(;&cWd3a`@n;Wp$w&Iv_&bFsVzsOz}-i z+}ZQ5B7qBQDCK3o+uu{L_l-paOozi=l6nbQeK^6+JvJ5ZMvy+C8Tg%lE0Oijq>cPy z&`NimFpm^kiFmk_3^iYkuOI52BgEh>$ZC8P^R@8s6{~i+_eD5LiZCmwNSkZ10M__; zwuIY(+2zNr=A!{*`jR4z^}V56PUSTL8P%CZo(}0m?R89o5o6Euqj58buP?F;_t#$2 zWES>hm5%5)lwFsEUKaJ25bWgc=j1$2*VIgDv*LOYg~R`JU4AOnCqxoy@0H^mCLsZl zN%vQ`^2EfszVUs|i2@2m&{%Szs2Hfqc}1cp=wo8(0*E(DRqQqdwRA3(Rg$2z%T|{D zbNBgb#Z?ue?$r_Z`NGYi@pVCKMm|FNZF_Mut$PEBJ}Li>iV>(%u08$zmhtsQdCSQV zF-sKDVEeMM(kfS5d15VscG-ZB+wIz^u@bJM0^>$TQF`6f+pAUp8_H0|{e}Fz>J}~{ z1=rk%!(vrqhn8;==$!vARSwdt$b&4X>@nS>u!AJ*r{k^1uq4!Jr2#q+9n6QfT}=W3tNRAV+iP{ z9dq~;isG`!3vY7=C@dsSw!;Z*H{rxNd=4K(wbLpr0KBm)xT5q>Y7b0nz74&vQ)Cx{rPL^zq$y2}a$D)LG-A7)=wWu?_B?|!&gxGWJN;_+Ee zEF33w5fPlue=$y*|TT$*{g?sgWR5W)98Sf-@Qs(Jn4PhF?7q^ z{Pr+JahQZVLZ-?0F7)b|ex}Q79S&pe@ysUR{vFb_IsEATb2-A~FP{Q6y!zkfxnU>d zN#+HwQK+i2SEx}{Mu)q;SZa34f{tT%6aTcHz7Qr24uSW0OC)mz47t`EmEcsZU0zPXa5s4y-9usy0lAG1WRjga+SFMaX z686ni3dchOGbxRJJ5e-Mw?@KA{G%z}F4JpQfU$eV({9ykqRj0k(bJ{NP{Y#&g)f}y zD9qMu0(}=nid*j$d&=KGt31ZxH~OOe#n?+w?|3{uXVo0Otu(Ihj_CgAm6%&<#be_; zvyxKTcIQP!B~MWr&B2V`;j!Kq_s`)SeBNKEO|4#7Wv<$^a=Y*QYIIiV7f#bJ;SW}0 zpP1-yx&dC9C+)b}Mr zGfDL$ZqzzClXQU}?J?%Sd^|KtMZ=vTy-+AmpH}u=f#bW29y+ggqOgy)32tAXjk^~JZK-4_RZki> zwEJ$@9b)385Ei-9afjT!SbzhgUnS-(S_wtD)&%riK-1xqAX5yes0E=oHu$eY(UbfuA(PE2MN*kum^foH(bmscNINu|t(%6jWGL z_I1>t!qm$5bP&mJjuHFP##cm3W4kV4WO=|lfm7XPvf|P~n3jt{G##|%x%aWh`R=i$ zykebcQvqxxfetJXZF{TagE<{d|Fq4r#<9Msm(syV!|1b%S8)a7b4BWnfKp#pD^vY~ z^O?aZ`p}{IRCA^iI_`pVS6fifn^JcBAd;-aNn7_jAdjuzT|jPCV3an7Vv=@iO4j^D z+IRzZX4Bx|%~tNY03vLEoMCc;SU4g__#5=Gbi;>Zm6tg(o=`Ou6s6k= z?ejD~fj`tyfXl+%!1)k0<`Bn>5F#bjKsxOe4fb65Bse0XU)5(noEV$&CDyss)^(Oh zV);YKB2Mmnxs{7}+5vx#+50jorQZ4uhF3}l{u3nEpLwYt?wrh$u$23IWc{yI{UD0A0vH~@&)S6ggS6OAL#-X_-qHLp^$j`8Ti)3 zRkr<D!#>DOmwk{i?1PKav39}=ySZnsdo zT?q}&O6TWzL8kKY=UO+Kd*(Sk565%ILbWz`fZTr|wmOQc9_@!N zENqM2WKU0!!QL)uQ@bnq*LahD(rkT`ll98)cPZ*7%pIoI;BcCA*d)YTgE(QO(qz*Cxr!y zzH0f@;O{!=+3o{4G|_p976nuphlcOzQs3rq^SAaj*UXOicd$7Mlhc3cDYkIdadV4r z_W1Y-$C7Y49dSO-^DJb#W34Kl+x=BT?A(s+xBkgz0{h!%SXev}?&UVV)U9VERuY%e z*RDtF)zWF`i60pj&vXonHxk7*2O$hQ7pIOd9{V@HtJOU{9;IEQCarO2ZmT*-D#%C~ zx*sNUj4^CE{kU7zs54~5rk^Z`(_Z85@ZrdI8fhiLs&??pVs$#nt0IG)!*zLpd_|PE z;rvX%hhV4t%MF}4k`mj~c>e5X`WJ!|JMcUVI)eLC!y%U8Vpa6|cy<%<71>;*2nh3I z-#*c?E<`}YN-r;X&$7aJVu`dPDpKxIt-#YDtJQw?@t}%dcjz0tKG%00A3VHGc&G{3 z006U{RE(RbaWbMJU8nniT^4B$+i`14oAl|tO+{t9V!i9R@M~1}0YzCs&egoF{Xqj- zS+|UiQNP?^IQBpf8nD$4{i#bs1M|3hZ?>$1rtT$!zpjwIFHOyADy;qma4LKdclnv; zfh>dG?E!fs&bK7T=^om>%%+>&eu4Sr4i~q~MJCg29@9niDna=-1Le9+7g}K z;iqwug?NeEz!lD{6bBr;C1n48d)@8&ZmD=Jk1#^mGI3?@v4*9-23rR}c1MRNMOQZY zXJkvUnPAU}u?Cll+;6FeX~vq8vz}-EDPM8ymjdF6T>_fG!X7kT0UB2KG)j~xSp&Ki zL|ZVBBs1-qkyfVF!_{fQo-;`l$x~)Unu4gPQyI)u-WeTX(!5=>8#`d*p zNXDrtMuGT^+uFP0^W>?!Y>jVum@t`)B7yhf%BquB!litLmL5aCWSLEWK#e*|>fAF` zza)vLQ>|q7jyA5gfr+nxswDwrl86XuP?ap`Otz++0X53XRR#O@GAv7&;j8Vn7aGT&3T8E{R%EnuS?Y!&Qm)oLS&GEnGKwsH-W zao@dSyR|#~eBI-nKiDcKDQ<|k+|(lGv~?`8Wusa2 z7(Wmmgeu_Y(L1J&+sf8XZK;F^r5&@K=rnxEpJRRshn6=~!w*S#Yo2x6U%%-C(<+6; zZ1lex$4~^GwK+VhlQl-fxufp0hcw^_p3~i8ty*re2#;iI_^BAOJtLu}d`)}#7&8)@ znMXX-GELe;V`=PW zszG3t=U}4~R$CcY4L5nef`D(#lr&;}CKER%I_O>-yqeWPYdX!Rx1hIi*Y;y>Clg93 zLAMuebc`RSfzTv-)4DTd+QHf%2^0^e3JbuajYl8rhqg=V7~;d!HN3RO_Ea;f{}0lG3&z zaZ`C#L*CO1;e3{oJb0n%If*`7p|d^nO5hy8CnPB1MnyWwr-RLpa>7ZHKbb%t<72{{ zo_I9I>Kos3QDnY<35v|f`2>5;Dfc4KkeVXjFS#Nok8~dle=I5zoON-tJz?q@LhdC8 zbhd2mOQEmbne={^iA8|@?h83QoK)1Y=G?Hu1yVAOV`k*>)Ra=p)zfILZjeD`X(Y-xs0kEAwPM-TIc3USW2&3D-*wf z7ScxSiu3Wh&Vk8Z9QobaK}d7Zw|eeT(d@{hoFwn-*XgEJUmF1;4{b+Kku|Qid9J?b z@#COXX?{mLG2e3I!Oypki&-=FEW>;6=azYZ4p1R82beAcAMmi2B!Xf|QE`Fx zG~r7!?nkqF{EhT=jHs`lC@2z}Zr-jWp08iVMdnfq*LX?SIvFanRwhA-*}&0=*>H7g zsW^2Oo(t9c3Tkp`2v9d#X-_mkh(O1Y0eH7))}=o5-?MESg75W!<}tQ~@5{-~GYUKI z?tD@T=d#}G?paG8r1?X@Gs(D-`CkbNPk+7k8@e&1o@5*iMvFxwzRT~%oo0NHs)VeT zcXL21fgV8(OEe}M28JF=2R9W~UejZ{C3>u%M`&N}U}zf$BG_XZvEtHx*(PRUI^^SZ ztT)TAce~mt4PTY7If(~5ypBLh8sbBX4m-k~8na@Cn8pM%m&vPZe2G*m zeXD{uS548uo_&A$2aqlve^v>~4>2bgqvH_(GpYK10W|o76yoJYksFNcp z(6^M`nEDK>K`5|DFh%rJmg3bu{}_+ zP$CqkJ4~wcy|Fu&EA?o%q;^q~WX6?625YOL4DvCZbU$3>25B7(1u+yGqFR1V6@uor;ya(E%-qk_=Nb#Lj66H;m0Vc& z0er+z0b?)_UAXZitox2_0ukptKH5i3Hn;|0&njLk>KMF3Ri2A*Z%;#g@OPcQB&I@Z zlTuIwNMG@tiS=i^4N^Zsvk6DhttIG3RUdE%wxG~+Ef+C!ky(`8q#4Dn2oy}(GxM@L z%#?0|LM*C%IkOj{8E;U}|KN=59dI(=(hi3)A>Q~6L>5I+=55#nFHgixU5V8yx4_p~Y{Re4aG=c}&KJ+YY7myQuFz9~BhB8P(t zx2lbursAReAwiAYRtLV5FNj@~^_1%&v!BOx^k-Lqa!2h6mlNs8VOG>?Cg#`9_1ifc z3X|l@xrc_+51x>XAxLaMMV4KNwFAd1p_Mb5RzeqQc1KQ-;UU2 zFW1Wx5=tzx8R0up_0iw`q*fKq_uK7)V47gjmG08 zGFhU!ASbtDPY^fW6_0rmpZ5?E)H2u{ZZTh58Wz`uy!@iK1v=$$W_uIpu`fURcC1r}^eItpfc53^Q2y3CjY+6PBk9FPTmQ&jO{00=a2o_a+>SyG6=c-s{ zO&)vc@gO}oB8hD6dvWVGErRbhGwVo)ge~U|gJ8$z1Kj&ns{2QI`o=Gc_)HgAHB6Z>AHDPDWMiO{N0FX!U%*MfuC z@j@y_jqM~l_KIbD3Eqd-HD!4&Kn$)-nr)`G2xf^0f1@ce-it6lwMZjGt6Z(^`3~D| zDX0I$g9|Qj2n#&j58veZdf7?Hs%9k5S5z8t541MRtO+fCX^qbji=SX@V=Z2!|J3!& z?pa-tp6+&XCjEGy5dOlnOx~OF1Ym^+)u~c4?YJ*6A@lhqWU7=-| zW;t_vj+46^gEg0Tj6%yLxOB1yV^g_lCbt7ibe-Y-p$wvF5r+)z`G6(^`*+uEjB?d$ zqzwWEvd54pdMO=K7gnCu{Qcw&JTdpI0a7N`tc}p8lw>#47%zLx;(d&qv&g?d-wRP# zec8672g8dKx;F7Arf>W+vy3aqF{< zCR;RQ-MRRMF1=5H$7EcpxVua_M*iD1GT!2I1RcMVlQ*%D1OaKL@m!f@aM5B@Tb=K` ziQ>|%4_vOYE6TeQt$L^ruK5=IqJg*&n?drZ4Lv|ulib`!jV@5TYlUaK(_|dcCEI5} zVvXEBnv-`~9gx@Ako{!8cDJJmHHG4Sm;{^(qxh1{9=a7H7g6uHL0X2OS$De2Or_xH zwdWX%hcfzc-3?bo_vCB1hfd6>)5!MwSme67^z2S-E5r`|B$P7O-=hbH>$v-m z1a&sxbf*7*{l991dua24 z;Qi-qj*D#R5-*Zm#aBpA3@)3Wr=R-XOv09HjX`%yvp#uQQVx@M zf<8Sw+5mpPAB&B+PZq1ep9VulyvB$3c&LCcG$(ybXToKOu8mNaFi*U@ZiQDkTv=JA zbnou+vLXF!{khO8V`I531EG)g6AV9mIT{NKHS<8DgUECt{dA#T=t<;K=l#%|({5ZZ z=xOC71_aCn@Yx_@ZET(*zy6a$)(Ty~G0B&Pyf-ZP3NSISAzI&x+_Ls_4Rlw&1>fSW zN`A~V$r~WMm-eZp4;1zj5ELS~eX{AP-gjf?#8Zm2fFd)MHy7&l{Z&30i*XJ(DvG75 z7Qim?fO!q-P8k#SC&ZDGL2dW#KYGvq@UKD?dtP=&sc7jLD+vp-15CZOIs0=|%N z>Gy>8EcC}La6fMq7xSag4r(CJ+2*`b0pG)QVmv|>R~>rl>F=}uj_27XxgYcemhv!j z?k1>X5_=zr$HTXfD9IR_t}WXa`(ZD_J<2m&&h#tAceKwYS*m)Gn=mJdm4#ucn0x1` zS1(J+hbL%w%-TzJq1@Q zUJ$ti@JohdLk+S`i{G|?2eZA<7YOt=Gemi@79pc3^yGqQg^{e4Md3A`Y_J4lPIULQ%bfexZvql3N^{Sy7>unZkZ z>x-K)7DswE zskk2!w$01e@tI1EmwMpU0Pm(AZFH~iV{Gi5chCu%vv4ykp*(+Z<VViC+iFlXV%ib2HsN@-=MJ+1bKZ##zTBw*Az=8j4p|six9s6D3Upiboiu< z11G<_vR%`+JK}rd(_emd^z4pQMIIhOh36!%1sV!U0J0z9-hTL%WE{_)T`AF|c%t=gc`Zs>`M-eij0njh=L)?)D=J=oNb& zALsVTW_1MNJ`tuhG3*IWUF< zNuIt*ot-ng;XaY~s%~XfqO}!O6R>KA$MM$$j#NnMsHGd!YGAa^km2P|96j+2xT+eH zr!^VM4LZ`*{r&wtG6ElE3$(QY@R`#jf-r~`q^h@=Y+OOvF|5L6JK_w*-jYGjxMi{e zHJM>!-#s2358vA8soh$e9Gnqoa+sjxqQ%Gj=3yCsUBuCS2f51aqcnKlx3XqWl5zPN zwau(0^!S(q=Seif-{qZimDSk}@g2Ogf!5!JbMSU^Bbh#ka`Vw>!O_52Dx{Sj$NKyx z$~glq7S6L8flJ&aN4=GiLNSPlJ&clZKc1Sz_4a&6+cEC-s&#>aNEy+HID^J+GKMFH zl$9q2qMAz#Rrm^JxM$b6EPVZ$yZeL9 z=N)G#7A_h_b-SD!51cEOG3hsK!lv9EDVUK?GhhuH!dG|4ot@?#2I|lOV<@?mVxjbM zGGVeEtEUO}mGj>}`%ZpHYVS9B>{Efg9&eu{#(%qraWg1lX*|p2~ znsEz2|E&xDJ#Z^QzI7=)*Gi#UB}oKL*5N2O{BixWz@VW<6BN7A%B8T+#mxwM^6qR* zS(6x9bn#MsxQt?7L!Bhw?fE|^ZakeToP4^oGT6x##rkG$(S4EV6V3v5-SL*UuLnWh zrJ?Dog2T>N>XqSD+}O?Epy4Q47#K$a@w0Z2dCID{E-#hQZ+I8w-ozwDtcL}c*J5Jx z!JhYc`jPBkYzTZ3dV`c1dQH(vIrju*LslU9Q+i}rrGzbJoe-}iwz^lG3ylTq*W|u8 zS@wYihxuq%PC}@lsCF!@EWLCU2a8fgj4nOd@F3p?Hsda+PqI5skGRsET)RK!ZWXHd z8Jr9gJ~yKOU>i95lzkd^>re#{puNLnXC&~%D8`7El+Wv<8evr~shFSuV*x9s0%>VEFrqytWW5Yq|E#o4Oj*^U~X5dbQTYn0$6 zB35NfKH-F>e2bxx4u;aEB@|ol>8^|{#M_oNvh2y96@wDPquvso0hjQ{eDev;_jRiU z%VkCHT}D@YMXQh=O7IoWYx8C~a;)p=MjeW-=*e_H-XQSn<0gp|=Hm*$?w*}zv_y0# zVB!=XJ56X|N^TqMY)>51XAU`TB?b|`Y^^%kO?`X%ve;wFx}37kK6!s+hxV!x!{hpu zNH^)+7r3-7!Yd<#@7(XE+?x08@v5Hm+35!;Fg!Y^-;-_&O`2TK)a!K1X0FJ#{LU~F zy^K9MS1)LG_tx=k<-PT%`>3wSv#>*RhBNa%+(T5h4jpv*1OH;0qx33QOlDG`2LW}# zAn}~YfCr-yZats#-o5FU=IIg#(2-)8*B;t2*7fs1eBndw%>v(HGF-Mb~{5hTjF&2kyXyd_Y;={6v_TMF4uHjB!eP`>B}Q*i(Cl>bJt1$I!hPfH+!# z+tkvG-8pTUP2VFhu80`5W|+|QWm^SICzqIlBg=TWc8Oyce1v@a=rmTQ-wo8pK~xRi zNwc#I&sBHlRg(M2Ww7Ewdogj1vff_(ZRUXSJ=#M*^YT#egcS}lcx3%w{mjF5HxSsv z4)9}eIj=h(HOBL_^*~)h7tvpWCPnw%KqaS_YLFhHmbJXsfnwV0S6I?@oFWEi9#odHmCbnAbn-AI9}S6|~u$zVv59p#aB z5x`v7SRzaw^K0?&>0``LHk3EjSL;lRkE;iMRrKmg&M8J7Fr5VBs-94B4WXReF?kP# ze{OyhJ=9??VP3%7A1VPoCkP|)(w$+AIkiMF+S8Z7#ejo_I2P<#1?`HnU+4f(>W(f> zt^N9%wwLVbra_34-O^VWfq-+|GCen=dqANWOP*M{`r&E{;{kn1#AhPPYCdl|c3PV! zs`hm@9@gntr#&9EfZH8@B;}k4={#gBYOy_uK4Tr!t&wWlYg)4Nht*vKXJzpubL3dfX;EIH#UMHbGUgu4W8b&NfLK{wP#L74*?Ul1!&_TqxyDperh?93DOU5-%>9aYUhY z4ME^JtBkKp4TdawdVLVuAI9Bt0ZNW2u@HxDwkJ|P;ArJa0(<6aCXb<;@UK}^~ z#%O(WdUNzvrH>lH3lm~tmLetPa%hwp?Z}-)1deD&1oI><=4!>yu6t@Nmw0nh`|gJ@ zXL=q**z=pR!eN=!U-+99SnlH~k0o_1Uqk6+bzJ95y z95x|WM(z{DU-FzVSXzK#bCihgD~e!RskJY@gmM7vs>;*gE9Ix-Oi!JTr>cYeeV&$` zkV<>f`OMt3>MD7dVihiU^7I3+th-v(_Jcna2oc@2bq@MH^f3a^D9TKbKIZLTbD5tz zxzlg<8Mq*`oQLbjPHq6$^kE_+C<6H*a|5`5AbYumDA-xpD98W~=8hJS^$j5kO${k# zUJ4Q6CxVWamOyg=|Ih8+%#eNHreqLQ2N3@suY@RET^#s-Yy{_bFtrDO_`&A*=K>rdDR3IA_}dVu}ANREzb&nT?B?gI$B2ou8YVpZ%F2>u=x$EzJ4<3xS89o1LExg7EX@9~=M{z=uUF zW(!xBADo0$G`M8AxfHoM)&HdZUl9L9H1{xv3{!-;{sa2Y>OWwu01f~Mc}Evv1)!M= zK>0@$v2wETP$>W%TwfT!;N>Cv+Z$si7e^a_Ihd7`hs~ayO57D_XTi+zCxc(K{-FI= zEP}ug1wde+IoS`BfKAQp0L-!us!6q`$!e+M8Md zK&;|Gu)V1h=zky+{07;{(aF{6f$#sogJg*R5*1>7D;EF=^uNXZoswWjN4x)x^*cEq zu$)XC0CxXF&fjsfv~z^Cik~L^-6}2ZZ?rQthXlbN(a37<>f-X}QVuj^)d&6|B|<$M zEO{vZ?y27?@eqBke>2(d#KDG8Rg}~aW0qBtVzoDQ09pb-Kh}}T)Y~0Cks-I7Gg9pP zmlYs#?`4g&zPpB!N_&ck+>vi{?<wVNyAmdq)~Fnhs7?_BfOi6`S9Emq-x|QB;P_-*@j>(LpV#SZqTbDdsc2U z2j#sFzk4@5ni5P0lU9LzdM9DCYB?qXLdhd_r{5eO9A9QmkUmR%5`|;oJn{u!>M-)^ zP_f?l!5i-SK1W!OprDo@y_JgmqsLF7{{2kS510M*^Yet#e`5XTsiVITpfn)2|8@rH zCzYQ*{rg(s!-s%h1)lhyp9TIC^Y632hqc6C<&NwhD~tb$`1daTVRHDZSVDsQ*HrN* z-oJJDzwr8)AqTl2Jic&(56SOW8TuWaf26{Hr}U7XeicNH|2ERE)cEgI{;8M9zfk#^ zD*v6%Kc#X14V_=9^A9RNBl|&zpZV`0dHyP8zoGIksq}wE(?3;&;rwqy{XLQXQ@FpU jgNIc5s|Z5q{5G+w$iqU$!B9}>kUt(6D5y7F4^RIGT@Nx0 literal 0 HcmV?d00001 From d6514e1cd66af2cb9d58444f768eb65990f23c2e Mon Sep 17 00:00:00 2001 From: fhenry Date: Sun, 21 Apr 2013 17:36:23 +0200 Subject: [PATCH 85/97] Add extrafield select from table --- htdocs/core/class/extrafields.class.php | 880 ++++++++++-------- htdocs/core/tpl/admin_extrafields_add.tpl.php | 6 +- .../core/tpl/admin_extrafields_edit.tpl.php | 7 +- htdocs/langs/ca_ES/admin.lang | 5 +- htdocs/langs/en_US/admin.lang | 5 +- htdocs/langs/es_ES/admin.lang | 5 +- htdocs/langs/fr_FR/admin.lang | 5 +- 7 files changed, 499 insertions(+), 414 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index aae14dba217..e2986615dde 100755 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1,34 +1,34 @@ * Copyright (C) 2002-2003 Jean-Louis Bergamo - * Copyright (C) 2004 Sebastien Di Cintio - * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2009-2012 Laurent Destailleur - * Copyright (C) 2009-2012 Regis Houssin - * - * 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 . - */ +* Copyright (C) 2004 Sebastien Di Cintio +* Copyright (C) 2004 Benoit Mortier +* Copyright (C) 2009-2012 Laurent Destailleur +* Copyright (C) 2009-2012 Regis Houssin +* +* 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 . +*/ /** * \file htdocs/core/class/extrafields.class.php - * \ingroup core - * \brief File of class to manage extra fields - */ +* \ingroup core +* \brief File of class to manage extra fields +*/ /** * Class to manage standard extra fields - */ +*/ class ExtraFields { var $db; @@ -53,27 +53,29 @@ class ExtraFields var $errno; static $type2label=array( - 'varchar'=>'String', - 'text'=>'TextLong', - 'int'=>'Int', - 'double'=>'Float', - 'date'=>'Date', - 'datetime'=>'DateAndTime', - 'boolean'=>'Boolean', - 'price'=>'ExtrafieldPrice', - 'phone'=>'ExtrafieldPhone', - 'mail'=>'ExtrafieldMail', - 'select' => 'ExtrafieldSelect', - 'separate' => 'ExtrafieldSeparator', - 'checkbox' => 'ExtrafieldCheckBox', - 'radio' => 'ExtrafieldRadio', + 'varchar'=>'String', + 'text'=>'TextLong', + 'int'=>'Int', + 'double'=>'Float', + 'date'=>'Date', + 'datetime'=>'DateAndTime', + 'boolean'=>'Boolean', + 'price'=>'ExtrafieldPrice', + 'phone'=>'ExtrafieldPhone', + 'mail'=>'ExtrafieldMail', + 'select' => 'ExtrafieldSelect', + 'sellist' => 'ExtrafieldSelectList', + 'separate' => 'ExtrafieldSeparator', + 'checkbox' => 'ExtrafieldCheckBox', + 'radio' => 'ExtrafieldRadio', + ); /** * Constructor * * @param DoliDB $db Database handler - */ + */ function __construct($db) { $this->db = $db; @@ -86,49 +88,49 @@ class ExtraFields $this->attribute_required = array(); } - /** - * Add a new extra field parameter - * - * @param string $attrname Code of attribute - * @param string $label label of attribute - * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') - * @param int $pos Position of attribute - * @param int $size Size/length of attribute - * @param string $elementtype Element type ('member', 'product', 'company', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param string $default_value Defaulted value - * @param array $param Params for field - * @return int <=0 if KO, >0 if OK - */ - function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0,$default_value='', $param=0) + /** + * Add a new extra field parameter + * + * @param string $attrname Code of attribute + * @param string $label label of attribute + * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') + * @param int $pos Position of attribute + * @param int $size Size/length of attribute + * @param string $elementtype Element type ('member', 'product', 'company', ...) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param string $default_value Defaulted value + * @param array $param Params for field + * @return int <=0 if KO, >0 if OK + */ + function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0,$default_value='', $param=0) { - if (empty($attrname)) return -1; - if (empty($label)) return -1; + if (empty($attrname)) return -1; + if (empty($label)) return -1; - // Create field into database except for separator type which is not stored in database - if ($type != 'separate') - { - $result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value,$param); - } - $err1=$this->errno; - if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') - { - // Add declaration of field into table - $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param); - $err2=$this->errno; - if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) - { - $this->error=''; - $this->errno=0; - return 1; - } - else return -2; - } - else - { - return -1; - } + // Create field into database except for separator type which is not stored in database + if ($type != 'separate') + { + $result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value,$param); + } + $err1=$this->errno; + if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') + { + // Add declaration of field into table + $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param); + $err2=$this->errno; + if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) + { + $this->error=''; + $this->errno=0; + return 1; + } + else return -2; + } + else + { + return -1; + } } /** @@ -138,22 +140,22 @@ class ExtraFields * @param string $attrname code of attribute * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') * @param int $length Size/length of attribute - * @param string $elementtype Element type ('member', 'product', 'company', 'contact', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param string $default_value Default value for field - * @param array $param Params for field (ex for select list : array('options'=>array('value'=>'label of option')) - * - * @return int <=0 if KO, >0 if OK + * @param string $elementtype Element type ('member', 'product', 'company', 'contact', ...) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param string $default_value Default value for field + * @param array $param Params for field (ex for select list : array('options'=>array('value'=>'label of option')) + * + * @return int <=0 if KO, >0 if OK */ private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='') { - $table=$elementtype.'_extrafields'; - - // Special case for not normalized table names - if ($elementtype == 'member') $table='adherent_extrafields'; - elseif ($elementtype == 'company') $table='societe_extrafields'; - elseif ($elementtype == 'contact') $table='socpeople_extrafields'; + $table=$elementtype.'_extrafields'; + + // Special case for not normalized table names + if ($elementtype == 'member') $table='adherent_extrafields'; + elseif ($elementtype == 'company') $table='societe_extrafields'; + elseif ($elementtype == 'contact') $table='socpeople_extrafields'; if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { @@ -169,7 +171,7 @@ class ExtraFields }elseif($type=='mail') { $typedb='varchar'; $lengthdb='128'; - } elseif (($type=='select') || ($type=='radio') ||($type=='checkbox')){ + } elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox')){ $typedb='text'; $lengthdb=''; } else { @@ -177,12 +179,12 @@ class ExtraFields $lengthdb=$length; } $field_desc = array( - 'type'=>$typedb, - 'value'=>$lengthdb, - 'null'=>($required?'NOT NULL':'NULL'), - 'default' => $default_value + 'type'=>$typedb, + 'value'=>$lengthdb, + 'null'=>($required?'NOT NULL':'NULL'), + 'default' => $default_value ); - + $result=$this->db->DDLAddField(MAIN_DB_PREFIX.$table, $attrname, $field_desc); if ($result > 0) { @@ -215,9 +217,9 @@ class ExtraFields * @param int $pos Position of attribute * @param int $size Size/length of attribute * @param string $elementtype Element type ('member', 'product', 'company', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @return int <=0 if KO, >0 if OK */ private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='') @@ -227,7 +229,7 @@ class ExtraFields // Clean parameters if (empty($pos)) $pos=0; - + if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { if(is_array($param) and count($param) > 0) @@ -242,7 +244,7 @@ class ExtraFields { $params=''; } - + $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param)"; $sql.= " VALUES('".$attrname."',"; $sql.= " '".$this->db->escape($label)."',"; @@ -250,11 +252,11 @@ class ExtraFields $sql.= " '".$pos."',"; $sql.= " '".$size."',"; $sql.= " ".$conf->entity.","; - $sql.= " '".$elementtype."',"; - $sql.= " '".$unique."',"; - $sql.= " '".$required."',"; - $sql.= " '".$params."'"; - $sql.=')'; + $sql.= " '".$elementtype."',"; + $sql.= " '".$unique."',"; + $sql.= " '".$required."',"; + $sql.= " '".$params."'"; + $sql.=')'; dol_syslog(get_class($this)."::create_label sql=".$sql); if ($this->db->query($sql)) @@ -279,16 +281,16 @@ class ExtraFields */ function delete($attrname, $elementtype='member') { - $table=$elementtype.'_extrafields'; + $table=$elementtype.'_extrafields'; - // Special case for not normalized table names - if ($elementtype == 'member') $table='adherent_extrafields'; - elseif ($elementtype == 'company') $table='societe_extrafields'; - elseif ($elementtype == 'contact') $table='socpeople_extrafields'; + // Special case for not normalized table names + if ($elementtype == 'member') $table='adherent_extrafields'; + elseif ($elementtype == 'company') $table='societe_extrafields'; + elseif ($elementtype == 'contact') $table='socpeople_extrafields'; if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { - $result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname); // This also drop the unique key + $result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname); // This also drop the unique key if ($result < 0) { $this->error=$this->db->lasterror(); @@ -310,8 +312,8 @@ class ExtraFields * Delete description of an optionnal attribute * * @param string $attrname Code of attribute to delete - * @param string $elementtype Element type ('member', 'product', 'company', ...) - * @return int < 0 if KO, 0 if nothing is done, 1 if OK + * @param string $elementtype Element type ('member', 'product', 'company', ...) + * @return int < 0 if KO, 0 if nothing is done, 1 if OK */ private function delete_label($attrname, $elementtype='member') { @@ -322,7 +324,7 @@ class ExtraFields $sql = "DELETE FROM ".MAIN_DB_PREFIX."extrafields"; $sql.= " WHERE name = '".$attrname."'"; $sql.= " AND entity = ".$conf->entity; - $sql.= " AND elementtype = '".$elementtype."'"; + $sql.= " AND elementtype = '".$elementtype."'"; dol_syslog(get_class($this)."::delete_label sql=".$sql); $resql=$this->db->query($sql); @@ -350,22 +352,22 @@ class ExtraFields * @param string $label Label of attribute * @param string $type Type of attribute * @param int $length Length of attribute - * @param string $elementtype Element type ('member', 'product', 'company', 'contact', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param int $pos Position of attribute - * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) + * @param string $elementtype Element type ('member', 'product', 'company', 'contact', ...) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param int $pos Position of attribute + * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @return int >0 if OK, <=0 if KO */ function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='') { - $table=$elementtype.'_extrafields'; - // Special case for not normalized table names - if ($elementtype == 'member') $table='adherent_extrafields'; - elseif ($elementtype == 'company') $table='societe_extrafields'; - elseif ($elementtype == 'contact') $table='socpeople_extrafields'; + $table=$elementtype.'_extrafields'; + // Special case for not normalized table names + if ($elementtype == 'member') $table='adherent_extrafields'; + elseif ($elementtype == 'company') $table='societe_extrafields'; + elseif ($elementtype == 'contact') $table='socpeople_extrafields'; - if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) + if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { if ($type=='boolean') { $typedb='int'; @@ -379,7 +381,7 @@ class ExtraFields }elseif($type=='mail') { $typedb='varchar'; $lengthdb='128'; - } elseif (($type=='select') || ($type=='radio') ||($type=='checkbox')) { + } elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox')) { $typedb='text'; $lengthdb=''; } else { @@ -387,7 +389,7 @@ class ExtraFields $lengthdb=$length; } $field_desc = array('type'=>$typedb, 'value'=>$lengthdb, 'null'=>($required?'NOT NULL':'NULL')); - + if ($type != 'separate') // No table update when separate type { $result=$this->db->DDLUpdateField(MAIN_DB_PREFIX.$table, $attrname, $field_desc); @@ -437,15 +439,15 @@ class ExtraFields * * @param string $attrname Name of attribute * @param string $label Label of attribute - * @param string $type Type of attribute - * @param int $size Length of attribute - * @param string $elementtype Element type ('member', 'product', 'company', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param int $pos Position of attribute - * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) - * @return int <=0 if KO, >0 if OK - */ + * @param string $type Type of attribute + * @param int $size Length of attribute + * @param string $elementtype Element type ('member', 'product', 'company', ...) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param int $pos Position of attribute + * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) + * @return int <=0 if KO, >0 if OK + */ private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='') { global $conf; @@ -454,12 +456,12 @@ class ExtraFields if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { $this->db->begin(); - + if(is_array($param) && count($param) > 0) { $param = serialize($param); } - + $sql_del = "DELETE FROM ".MAIN_DB_PREFIX."extrafields"; $sql_del.= " WHERE name = '".$attrname."'"; $sql_del.= " AND entity = ".$conf->entity; @@ -484,12 +486,12 @@ class ExtraFields $sql.= " '".$this->db->escape($label)."',"; $sql.= " '".$type."',"; $sql.= " '".$size."',"; - $sql.= " '".$elementtype."',"; - $sql.= " '".$unique."',"; - $sql.= " '".$required."',"; - $sql.= " '".$pos."',"; - $sql.= " '".$param."'"; - $sql.= ")"; + $sql.= " '".$elementtype."',"; + $sql.= " '".$unique."',"; + $sql.= " '".$required."',"; + $sql.= " '".$pos."',"; + $sql.= " '".$param."'"; + $sql.= ")"; dol_syslog(get_class($this)."::update_label sql=".$sql); $resql2=$this->db->query($sql); @@ -555,7 +557,7 @@ class ExtraFields { while ($tab = $this->db->fetch_object($resql)) { - + // we can add this attribute to adherent object if ($tab->type != 'separate') { @@ -565,11 +567,11 @@ class ExtraFields $this->attribute_type[$tab->name]=$tab->type; $this->attribute_label[$tab->name]=$tab->label; $this->attribute_size[$tab->name]=$tab->size; - $this->attribute_elementtype[$tab->name]=$tab->elementtype; - $this->attribute_unique[$tab->name]=$tab->fieldunique; - $this->attribute_required[$tab->name]=$tab->fieldrequired; - $this->attribute_param[$tab->name]=unserialize($tab->param); - $this->attribute_pos[$tab->name]=$tab->pos; + $this->attribute_elementtype[$tab->name]=$tab->elementtype; + $this->attribute_unique[$tab->name]=$tab->fieldunique; + $this->attribute_required[$tab->name]=$tab->fieldrequired; + $this->attribute_param[$tab->name]=unserialize($tab->param); + $this->attribute_pos[$tab->name]=$tab->pos; } } return $array_name_label; @@ -593,268 +595,332 @@ class ExtraFields { global $conf,$langs; - $label=$this->attribute_label[$key]; - $type =$this->attribute_type[$key]; - $size =$this->attribute_size[$key]; - $elementtype=$this->attribute_elementtype[$key]; - $unique=$this->attribute_unique[$key]; - $required=$this->attribute_required[$key]; - $param=$this->attribute_param[$key]; - if ($type == 'date') - { - $showsize=10; - } - elseif ($type == 'datetime') - { - $showsize=19; - } - elseif (in_array($type,array('int','double'))) - { - $showsize=10; - } - else - { - $showsize=round($size); - if ($showsize > 48) $showsize=48; - } + $label=$this->attribute_label[$key]; + $type =$this->attribute_type[$key]; + $size =$this->attribute_size[$key]; + $elementtype=$this->attribute_elementtype[$key]; + $unique=$this->attribute_unique[$key]; + $required=$this->attribute_required[$key]; + $param=$this->attribute_param[$key]; + if ($type == 'date') + { + $showsize=10; + } + elseif ($type == 'datetime') + { + $showsize=19; + } + elseif (in_array($type,array('int','double'))) + { + $showsize=10; + } + else + { + $showsize=round($size); + if ($showsize > 48) $showsize=48; + } if (in_array($type,array('date','datetime'))) - { - $tmp=explode(',',$size); - $newsize=$tmp[0]; - if(!class_exists('Form')) - require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; - $formstat = new Form($db); - - $showtime = in_array($type,array('datetime')) ? 1 : 0; - // Do not show current date when field not required (see select_date() method) - if(!$required && $value == '') - $value = '-1'; - - $out = $formstat->select_date($value, 'options_'.$key, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1); - //$out=''; - } - elseif (in_array($type,array('int','double'))) - { - $tmp=explode(',',$size); - $newsize=$tmp[0]; - $out=''; - } - elseif ($type == 'varchar') - { - $out=''; - } - elseif ($type == 'text') - { - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('options_'.$key,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100); - $out=$doleditor->Create(1); - } - elseif ($type == 'boolean') - { - $checked=''; - if (!empty($value)) { - $checked=' checked="checked" value="1" '; - } else { - $checked=' value="1" '; - } - $out=''; - } - elseif ($type == 'mail') - { - $out=''; - } - elseif ($type == 'phone') - { - $out=''; - } - elseif ($type == 'price') - { - $out=' '.$langs->getCurrencySymbol($conf->currency); - } - elseif ($type == 'select') - { - $out=''; - } - elseif ($type == 'checkbox') - { - $out=''; - $value_arr=explode(',',$value); + { + $tmp=explode(',',$size); + $newsize=$tmp[0]; + if(!class_exists('Form')) + require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + $formstat = new Form($db); - foreach ($param['options'] as $keyopt=>$val ) - { - - $out.=''; - } - } - elseif ($type == 'radio') - { - $out=''; - foreach ($param['options'] as $keyopt=>$val ) - { - $out.=''; - } - } - /* Add comments - if ($type == 'date') $out.=' (YYYY-MM-DD)'; - elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)'; - */ - return $out; + $showtime = in_array($type,array('datetime')) ? 1 : 0; + // Do not show current date when field not required (see select_date() method) + if(!$required && $value == '') + $value = '-1'; + + $out = $formstat->select_date($value, 'options_'.$key, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1); + //$out=''; + } + elseif (in_array($type,array('int','double'))) + { + $tmp=explode(',',$size); + $newsize=$tmp[0]; + $out=''; + } + elseif ($type == 'varchar') + { + $out=''; + } + elseif ($type == 'text') + { + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor('options_'.$key,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100); + $out=$doleditor->Create(1); + } + elseif ($type == 'boolean') + { + $checked=''; + if (!empty($value)) { + $checked=' checked="checked" value="1" '; + } else { + $checked=' value="1" '; + } + $out=''; + } + elseif ($type == 'mail') + { + $out=''; + } + elseif ($type == 'phone') + { + $out=''; + } + elseif ($type == 'price') + { + $out=' '.$langs->getCurrencySymbol($conf->currency); + } + elseif ($type == 'select') + { + $out=''; + } + elseif ($type == 'sellist') + { + $out=''; + } + elseif ($type == 'checkbox') + { + $out=''; + $value_arr=explode(',',$value); + + foreach ($param['options'] as $keyopt=>$val ) + { + + $out.=''; + } + } + elseif ($type == 'radio') + { + $out=''; + foreach ($param['options'] as $keyopt=>$val ) + { + $out.=''; + } + } + /* Add comments + if ($type == 'date') $out.=' (YYYY-MM-DD)'; + elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)'; + */ + return $out; } - /** - * Return HTML string to put an output field into a page - * - * @param string $key Key of attribute - * @param string $value Value to show - * @param string $moreparam More param - * @return string Formated value - */ - function showOutputField($key,$value,$moreparam='') - { + /** + * Return HTML string to put an output field into a page + * + * @param string $key Key of attribute + * @param string $value Value to show + * @param string $moreparam More param + * @return string Formated value + */ + function showOutputField($key,$value,$moreparam='') + { global $conf,$langs; - $label=$this->attribute_label[$key]; - $type=$this->attribute_type[$key]; - $size=$this->attribute_size[$key]; - $elementtype=$this->attribute_elementtype[$key]; - $unique=$this->attribute_unique[$key]; - $required=$this->attribute_required[$key]; - $params=$this->attribute_param[$key]; - if ($type == 'date') - { - $showsize=10; - $value=dol_print_date($value,'day'); - } - elseif ($type == 'datetime') - { - $showsize=19; - $value=dol_print_date($value,'dayhour'); - } - elseif ($type == 'int') - { - $showsize=10; - } - elseif ($type == 'boolean') - { - $checked=''; - if (!empty($value)) { - $checked=' checked="checked" '; - } - $value=''; - } - elseif ($type == 'mail') - { - $value=dol_print_email($value); - } - elseif ($type == 'phone') - { - $value=dol_print_phone($value); - } - elseif ($type == 'price') - { - $value=price($value).' '.$langs->getCurrencySymbol($conf->currency); - } - elseif ($type == 'select') - { - $value=$params['options'][$value]; - } - elseif ($type == 'radio') - { - $value=$params['options'][$value]; - } - elseif ($type == 'checkbox') - { - $value_arr=explode(',',$value); - $value=''; - if (is_array($value_arr)) - { - foreach ($value_arr as $keyval=>$valueval) { - $value.=$params['options'][$valueval].'
'; - } - } - } - else - { - $showsize=round($size); - if ($showsize > 48) $showsize=48; - } - //print $type.'-'.$size; - $out=$value; - return $out; - } + $label=$this->attribute_label[$key]; + $type=$this->attribute_type[$key]; + $size=$this->attribute_size[$key]; + $elementtype=$this->attribute_elementtype[$key]; + $unique=$this->attribute_unique[$key]; + $required=$this->attribute_required[$key]; + $params=$this->attribute_param[$key]; + if ($type == 'date') + { + $showsize=10; + $value=dol_print_date($value,'day'); + } + elseif ($type == 'datetime') + { + $showsize=19; + $value=dol_print_date($value,'dayhour'); + } + elseif ($type == 'int') + { + $showsize=10; + } + elseif ($type == 'boolean') + { + $checked=''; + if (!empty($value)) { + $checked=' checked="checked" '; + } + $value=''; + } + elseif ($type == 'mail') + { + $value=dol_print_email($value); + } + elseif ($type == 'phone') + { + $value=dol_print_phone($value); + } + elseif ($type == 'price') + { + $value=price($value).' '.$langs->getCurrencySymbol($conf->currency); + } + elseif ($type == 'select') + { + $value=$params['options'][$value]; + } + elseif ($type == 'sellist') + { + $InfoFieldList = explode(":", $params); + $keyList='rowid'; + if (count($InfoFieldList)==3) + $keyList=$InfoFieldList[2]; - /** - * Return HTML string to print separator extrafield - * - * @param string $key Key of attribute - * @return string - */ - function showSeparator($key) - { - $out = '
'.$this->attribute_label[$key].'
'.$this->attribute_label[$key].'
@@ -85,7 +87,7 @@
+
-textwithpicto('', $langs->trans("ExtrafieldParamHelp"),1,0)?>
textwithpicto('', $langs->trans("ExtrafieldParamHelp".$type),1,0)?>
diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 181fcd55bbc..d3b06545fa2 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -44,6 +44,7 @@ + @@ -80,7 +81,7 @@ if((($type == 'select') || ($type == 'checkbox') ||(($type == 'radio'))) && is_a @@ -88,7 +89,11 @@ if(($type == 'select') || ($type == 'checkbox') ||(($type == 'radio'))) trans("Value"); ?>
per exemple :
1,text1
2,text2
3,text3
... +ExtrafieldParamHelpselect=La llista ha de ser en forma clau, valor

per exemple :
1,text1
2,text2
3,text3
... +ExtrafieldParamHelpcheckbox=La llista ha de ser en forma clau, valor

per exemple :
1,text1
2,text2
3,text3
... +ExtrafieldParamHelpradio=La llista ha de ser en forma clau, valor

per exemple :
1,text1
2,text2
3,text3
... +ExtrafieldParamHelpsellist=La llista ha de ser del table

per exemple :
table:label:(code)
LibraryToBuildPDF=Llibreria usada per a la creació d'arxius PDF WarningUsingFPDF=Atenció: El seu arxiu conf.php conté la directiva dolibarr_pdf_force_fpdf=1. Això fa que s'usi la llibreria FPDF per generar els seus arxius PDF. Aquesta llibreria és antiga i no cobreix algunes funcionalitats (Unicode, transparència d'imatges, idiomes ciríl · lics, àrabs o asiàtics, etc.), Pel que pot tenir problemes en la generació dels PDF.
Per resoldre-ho, i disposar d'un suport complet de PDF, pot descarregar la llibreria TCPDF , i a continuació comentar o eliminar la línia $dolibarr_pdf_force_fpdf=1, i afegir al seu lloc $dolibarr_lib_TCPDF_PATH='ruta_a_TCPDF' LocalTaxDesc=Alguns països apliquen 2 o 3 taxes a cada línia de factura. Si és el cas, escolliu el tipus de la segona i tercera taxa i el seu valor. Els possibles tipus són:
1: taxa local aplicable a productes i serveis sense IVA (IVA no s'aplica a la taxa local)
2: taxa local s'aplica a productes i serveis abans de l'IVA (IVA es calcula sobre import + taxa local)
3: taxa local s'aplica a productes sense IVA (IVA no s'aplica a la taxa local)
4: taxa local s'aplica a productes abans de l'IVA (IVA es calcula sobre l'import + taxa local)
5: taxa local s'aplica a serveis sense IVA (IVA no s'aplica a la taxa local)
6: taxa local s'aplica a serveis abans de l'IVA (IVA es calcula sobre import + taxa local) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index e73e752fb21..46d893c3984 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -360,7 +360,10 @@ ExtrafieldSelect = Select list ExtrafieldSeparator=Separator ExtrafieldCheckBox=Checkbox ExtrafieldRadio=Radio button -ExtrafieldParamHelp=Parameters list have to be like key,value

for exemple :
1,value1
2,value2
3,value3
... +ExtrafieldParamHelpselect=Parameters list have to be like key,value

for exemple :
1,value1
2,value2
3,value3
... +ExtrafieldParamHelpcheckbox=Parameters list have to be like key,value

for exemple :
1,value1
2,value2
3,value3
... +ExtrafieldParamHelpradio=Parameters list have to be like key,value

for exemple :
1,value1
2,value2
3,value3
... +ExtrafieldParamHelpsellist=Parameters list have come from table

for exemple :
c_typent:libelle:id
LibraryToBuildPDF=Library used to build PDF WarningUsingFPDF=Warning: Your conf.php contains directive dolibarr_pdf_force_fpdf=1. This means you use the FPDF library to generate PDF files. This library is old and does not support a lot of features (Unicode, image transparency, cyrillic, arab and asiatic languages, ...), so you may experience errors during PDF generation.
To solve this and have a full support of PDF generation, please download TCPDF library, then comment or remove the line $dolibarr_pdf_force_fpdf=1, and add instead $dolibarr_lib_TCPDF_PATH='path_to_TCPDF_dir' LocalTaxDesc=Some countries apply 2 or 3 taxes on each invoice line. If this is the case, choose type for second and third tax and its rate. Possible type are:
1 : local tax apply on products and services without vat (vat is not applied on local tax)
2 : local tax apply on products and services before vat (vat is calculated on amount + localtax)
3 : local tax apply on products without vat (vat is not applied on local tax)
4 : local tax apply on products before vat (vat is calculated on amount + localtax)
5 : local tax apply on services without vat (vat is not applied on local tax)
6 : local tax apply on services before vat (vat is calculated on amount + localtax) diff --git a/htdocs/langs/es_ES/admin.lang b/htdocs/langs/es_ES/admin.lang index ec45e7eb6a9..0f2083af780 100644 --- a/htdocs/langs/es_ES/admin.lang +++ b/htdocs/langs/es_ES/admin.lang @@ -357,7 +357,10 @@ ExtrafieldSelect=Lista de selección ExtrafieldSeparator=Separador ExtrafieldCheckBox=Casilla de verificación ExtrafieldRadio=Botón de selección excluyente -ExtrafieldParamHelp=La lista debe ser en forma llave,valor

por ejemplo :
1,texto1
2,texto2
3,texto3
... +ExtrafieldParamHelpselect=La llista ha de ser en forma clau, valor

per exemple :
1,text1
2,text2
3,text3
... +ExtrafieldParamHelpcheckbox=La llista ha de ser en forma clau, valor

per exemple :
1,text1
2,text2
3,text3
... +ExtrafieldParamHelpradio=La llista ha de ser en forma clau, valor

per exemple :
1,text1
2,text2
3,text3
... +ExtrafieldParamHelpsellist=La llista ha de ser del table

per exemple :
table:label:(code)
LibraryToBuildPDF=Librería usada para la creación de archivos PDF WarningUsingFPDF=Atención: Su archivo conf.php contiene la directiva dolibarr_pdf_force_fpdf=1. Esto hace que se use la librería FPDF para generar sus archivos PDF. Esta librería es antigua y no cubre algunas funcionalidades (Unicode, transparencia de imágenes, idiomas cirílicos, árabes o asiáticos, etc.), por lo que puede tener problemas en la generación de los PDF.
Para resolverlo, y disponer de un soporte completo de PDF, puede descargar la librería TCPDF , y a continuación comentar o eliminar la línea $dolibarr_pdf_force_fpdf=1, y añadir en su lugar $dolibarr_lib_TCPDF_PATH='ruta_a_TCPDF' LocalTaxDesc=Algunos países aplican 2 o 3 tasas a cada línea de factura. Si es el caso, escoja el tipo de la segunda y tercera tasa y su valor. Los posibles tipos son:
1 : tasa local aplicable a productos y servicios sin IVA (IVA no se aplica en la tasa local)
2 : tasa local se aplica a productos y servicios antes del IVA (IVA se calcula sobre importe+tasa local)
3 : tasa local se aplica a productos sin IVA (IVA no se aplica en la tasa local)
4 : tasa local se aplica a productos antes del IVA (IVA se calcula sobre el importe+tasa local)
5 : tasa local se aplica a servicios sin IVA (IVA no se aplica a la tasa local)
6 : tasa local se aplica a servicios antes del IVA (IVA se calcula sobre importe + tasa local) diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index d1bc47fb624..669ff93ae83 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -357,7 +357,10 @@ ExtrafieldSelect = Liste de sélection ExtrafieldSeparator = Séparateur de champ ExtrafieldCheckBox=Case à cocher ExtrafieldRadio=Case d'option -ExtrafieldParamHelp=La liste doit être de la forme clef,valeur

par exemple :
1,valeur1
2,valeur2
3,valeur3
... +ExtrafieldParamHelpselect=La liste doit être de la forme clef,valeur

par exemple :
1,valeur1
2,valeur2
3,valeur3
... +ExtrafieldParamHelpcheckbox=La liste doit être de la forme clef,valeur

par exemple :
1,valeur1
2,valeur2
3,valeur3
... +ExtrafieldParamHelpradio=La liste doit être de la forme clef,valeur

par exemple :
1,valeur1
2,valeur2
3,valeur3
... +ExtrafieldParamHelpsellist=La liste vient d'une table

par exemple :
c_typent:libelle:id
LibraryToBuildPDF=Bibliothèque utilisée pour la génération des PDF WarningUsingFPDF=Attention: Votre fichier conf.php contient la directive dolibarr_pdf_force_fpdf=1. Cela signifie que vous utilisez la librairie FPDF pour générer vos fichiers PDF. Cette librairie est ancienne et ne couvre pas de nombreuses fonctionnalitée (Unicode, transparence des images, langues cyrillic, arabes ou asiatiques...), aussi vous pouvez rencontrez des problèmes durant la génération des PDF.
Pour résoudre cela et avoir un support complet de PDF, vous pouvez télécharger la librairie TCPDF puis commenter ou supprimer la ligne $dolibarr_pdf_force_fpdf=1, et ajouter à la place $dolibarr_lib_TCPDF_PATH='chemin_vers_TCPDF' LocalTaxDesc=Certains pays appliquent 2 voir 3 taux sur chaque ligne de facture. Si c'est le cas, choisissez le type du deuxième et troisième taux et sa valeur. Les types possibles sont:
1 : taxe locale sur les produits et services hors tva (la tva n'est pas appliquée sur la taxe locale)
2 : taxe locale sur les produits et services avant tva (la tva est appliquée sur le montant + la taxe locale)
3 : taxe locale uniquement sur les produits hors tva (la tva n'est pas appliquée sur la taxe locale)
4 : taxe locale uniquement sur les produits avant tva (la tva est appliquée sur le montant + la taxe locale)
5 : taxe locale uniquement sur les services hors tva (la tva n'est pas appliquée sur la taxe locale)
6 : taxe locale uniquement sur les service avant tva (la tva est appliquée sur le montant + la taxe locale) From 5893fadb585373bdbe2adc419abe52c99e1d0081 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 21 Apr 2013 17:56:29 +0200 Subject: [PATCH 86/97] Look: Minor style enhancement --- htdocs/comm/action/fiche.php | 16 +- htdocs/core/lib/functions.lib.php | 23 +- htdocs/fourn/fiche.php | 20 +- htdocs/holiday/index.php | 13 +- htdocs/langs/en_US/agenda.lang | 2 +- htdocs/langs/fr_FR/agenda.lang | 2 +- htdocs/langs/fr_FR/main.lang | 4 +- htdocs/theme/amarok/graph-color.php | 10 +- htdocs/theme/amarok/style.css.php | 360 +++++++++++++++------------- htdocs/theme/eldy/style.css.php | 24 +- 10 files changed, 264 insertions(+), 210 deletions(-) diff --git a/htdocs/comm/action/fiche.php b/htdocs/comm/action/fiche.php index b6357880dad..4b4917715b5 100644 --- a/htdocs/comm/action/fiche.php +++ b/htdocs/comm/action/fiche.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2012 Laurent Destailleur + * Copyright (C) 2004-2013 Laurent Destailleur * Copyright (C) 2005 Simon TOSSER * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2010 Juanjo Menent @@ -663,7 +663,6 @@ if ($id > 0) */ $head=actions_prepare_head($act); - dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action'); $now=dol_now(); $delay_warning=$conf->global->MAIN_DELAY_ACTIONS_TODO*24*60*60; @@ -711,6 +710,8 @@ if ($id > 0) print ''; if ($backtopage) print ''; + dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action'); + print '
+ + +
+textwithpicto('', $langs->trans("ExtrafieldParamHelp".$type),1,0)?>
'; // Ref @@ -836,7 +837,9 @@ if ($id > 0) print '
'; - print '

'; + dol_fiche_end(); + + print '
'; print '     '; print '
'; @@ -844,6 +847,8 @@ if ($id > 0) } else { + dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action'); + // Affichage fiche action en mode visu print ''; @@ -1021,14 +1026,13 @@ if ($id > 0) } print '


'; } - } - print "
\n"; + dol_fiche_end(); + } /* * Barre d'actions - * */ print '
'; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 45683412037..b2c2998a462 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -814,13 +814,14 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e } if (! is_object($outputlangs)) $outputlangs=$langs; if (! $format) $format='daytextshort'; - + $reduceformat=(! empty($conf->dol_optimize_smallscreen) && in_array($format,array('day','hour')))?1:0; + // Change predefined format into computer format. If found translation in lang file we use it, otherwise we use default. - if ($format == 'day') $format=($outputlangs->trans("FormatDateShort")!="FormatDateShort"?$outputlangs->trans("FormatDateShort"):$conf->format_date_short); - else if ($format == 'hour') $format=($outputlangs->trans("FormatHourShort")!="FormatHourShort"?$outputlangs->trans("FormatHourShort"):$conf->format_hour_short); - else if ($format == 'hourduration') $format=($outputlangs->trans("FormatHourShortDuration")!="FormatHourShortDuration"?$outputlangs->trans("FormatHourShortDuration"):$conf->format_hour_short_duration); + if ($format == 'day') $format=($outputlangs->trans("FormatDateShort")!="FormatDateShort"?$outputlangs->trans("FormatDateShort"):$conf->format_date_short); + else if ($format == 'hour') $format=($outputlangs->trans("FormatHourShort")!="FormatHourShort"?$outputlangs->trans("FormatHourShort"):$conf->format_hour_short); + else if ($format == 'hourduration') $format=($outputlangs->trans("FormatHourShortDuration")!="FormatHourShortDuration"?$outputlangs->trans("FormatHourShortDuration"):$conf->format_hour_short_duration); else if ($format == 'daytext') $format=($outputlangs->trans("FormatDateText")!="FormatDateText"?$outputlangs->trans("FormatDateText"):$conf->format_date_text); - else if ($format == 'daytextshort') $format=($outputlangs->trans("FormatDateTextShort")!="FormatDateTextShort"?$outputlangs->trans("FormatDateTextShort"):$conf->format_date_text_short); + else if ($format == 'daytextshort') $format=($outputlangs->trans("FormatDateTextShort")!="FormatDateTextShort"?$outputlangs->trans("FormatDateTextShort"):$conf->format_date_text_short); else if ($format == 'dayhour') $format=($outputlangs->trans("FormatDateHourShort")!="FormatDateHourShort"?$outputlangs->trans("FormatDateHourShort"):$conf->format_date_hour_short); else if ($format == 'dayhoursec') $format=($outputlangs->trans("FormatDateHourSecShort")!="FormatDateHourSecShort"?$outputlangs->trans("FormatDateHourSecShort"):$conf->format_date_hour_sec_short); else if ($format == 'dayhourtext') $format=($outputlangs->trans("FormatDateHourText")!="FormatDateHourText"?$outputlangs->trans("FormatDateHourText"):$conf->format_date_hour_text); @@ -828,12 +829,18 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e // Format not sensitive to language else if ($format == 'dayhourlog') $format='%Y%m%d%H%M%S'; else if ($format == 'dayhourldap') $format='%Y%m%d%H%M%SZ'; - else if ($format == 'dayhourxcard') $format='%Y%m%dT%H%M%SZ'; - else if ($format == 'dayxcard') $format='%Y%m%d'; + else if ($format == 'dayhourxcard') $format='%Y%m%dT%H%M%SZ'; + else if ($format == 'dayxcard') $format='%Y%m%d'; else if ($format == 'dayrfc') $format='%Y-%m-%d'; // DATE_RFC3339 else if ($format == 'dayhourrfc') $format='%Y-%m-%dT%H:%M:%SZ'; // DATETIME RFC3339 - else if ($format == 'standard') $format='%Y-%m-%d %H:%M:%S'; + else if ($format == 'standard') $format='%Y-%m-%d %H:%M:%S'; + if ($reduceformat) + { + $format=str_replace('%Y','%y',$format); + $format=str_replace('yyyy','yy',$format); + } + // If date undefined or "", we return "" if (dol_strlen($time) == 0) return ''; // $time=0 allowed (it means 01/01/1970 00:00:00) diff --git a/htdocs/fourn/fiche.php b/htdocs/fourn/fiche.php index 2d9a7a151b3..13ef8ea8523 100644 --- a/htdocs/fourn/fiche.php +++ b/htdocs/fourn/fiche.php @@ -85,8 +85,9 @@ if ($object->fetch($id)) dol_fiche_head($head, 'supplier', $langs->trans("ThirdParty"),0,'company'); - print ''; - print ''; + //print '
'; + print '
'; + //print ''; + //print ''; - print '
'; print ''; print '
'.$langs->trans("ThirdPartyName").''; @@ -216,7 +217,11 @@ if ($object->fetch($id)) print '
'; - print '
'; + + print '
'; + //print '
'; + + $var=true; $MAXLIST=5; @@ -367,9 +372,12 @@ if ($object->fetch($id)) } } - print '
' . "\n"; - print '
'; + print '
'; + print '
'; + //print '
' . "\n"; + + dol_fiche_end(); /* diff --git a/htdocs/holiday/index.php b/htdocs/holiday/index.php index c269a148615..06c75411453 100644 --- a/htdocs/holiday/index.php +++ b/htdocs/holiday/index.php @@ -1,6 +1,6 @@ - * Copyright (C) 2012 Laurent Destailleur + * Copyright (C) 2013 Laurent Destailleur * Copyright (C) 2012 Regis Houssin * * This program is free software; you can redistribute it and/or modify @@ -228,7 +228,6 @@ if ($id > 0) print "\n"; print '
'; - } else { @@ -242,7 +241,15 @@ $nbaquis=$holiday->getCPforUser($user_id); $nbdeduced=$holiday->getConfCP('nbHolidayDeducted'); $nb_holiday = $nbaquis / $nbdeduced; print $langs->trans('SoldeCPUser',round($nb_holiday,2)).($nbdeduced != 1 ? ' ('.$nbaquis.' / '.$nbdeduced.')' : ''); -print '
'; + +if ($id > 0) +{ + dol_fiche_end(); + print '
'; +} +else { + print '
'; +} print '
'."\n"; print ''; diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 3d0aadefec2..33d52b04c94 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -32,7 +32,7 @@ ViewCal=Month view ViewDay=Day view ViewWeek=Week view ViewWithPredefinedFilters= View with predefined filters -AutoActions= Automatic filling of agenda +AutoActions= Automatic filling AgendaAutoActionDesc= Define here events for which you want Dolibarr to create automatically an event in agenda. If nothing is checked (by default), only manual actions will be included in agenda. AgendaSetupOtherDesc= This page provides options to allow export of your Dolibarr events into an external calendar (thunderbird, google calendar, ...) AgendaExtSitesDesc=This page allows to declare external sources of calendars to see their events into Dolibarr agenda. diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index 6c41e3e95c2..62b09ec39d1 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -32,7 +32,7 @@ ViewCal=Vue mois ViewDay=Vue jour ViewWeek=Vue semaine ViewWithPredefinedFilters=Vues avec filtres prédéfinis -AutoActions=Alimentation automatique de l'agenda +AutoActions=Alimentation automatique AgendaAutoActionDesc=Définissez dans cet onglet les événements pour lesquels dolibarr créera automatiquement une action dans l'agenda. Si aucune case n'est cochée (par défaut), seules les actions manuelles seront incluses dans l'agenda. AgendaSetupOtherDesc=Cette page permet de configurer quelques options permettant d'exporter une vue de votre agenda Dolibarr vers un calendrier externe (thunderbird, google calendar, ...) AgendaExtSitesDesc=Cette page permet d'ajouter des sources de calendriers externes pour les visualiser au sein de l'agenda Dolibarr. diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index 1173c74e14f..bad84a57548 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -3,9 +3,9 @@ CHARSET=UTF-8 DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= -FormatDateShort=%d/%m/%y +FormatDateShort=%d/%m/%Y FormatDateShortInput=%d/%m/%Y -FormatDateShortJava=dd/MM/yy +FormatDateShortJava=dd/MM/yyyy FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy FormatDateShortJQueryInput=dd/mm/yy diff --git a/htdocs/theme/amarok/graph-color.php b/htdocs/theme/amarok/graph-color.php index 96e9894c7fa..1a0d2253a2a 100755 --- a/htdocs/theme/amarok/graph-color.php +++ b/htdocs/theme/amarok/graph-color.php @@ -22,10 +22,10 @@ * \ingroup core */ -global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet; -$theme_bordercolor = array(235,235,224); -$theme_datacolor = array(array(125,135,150), array(200,160,180), array(190,190,220), array(170,140,190), array(190,190,170)); -$theme_bgcolor = array(hexdec('F4'),hexdec('F4'),hexdec('F4')); -$theme_bgcoloronglet = array(hexdec('DE'),hexdec('E7'),hexdec('EC')); +global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet; +$theme_bordercolor = array(235,235,224); +$theme_datacolor = array(array(190,190,220), array(200,160,180), array(125,135,150), array(170,140,190), array(190,190,170)); +$theme_bgcolor = array(hexdec('F4'),hexdec('F4'),hexdec('F4')); +$theme_bgcoloronglet = array(hexdec('DE'),hexdec('E7'),hexdec('EC')); ?> diff --git a/htdocs/theme/amarok/style.css.php b/htdocs/theme/amarok/style.css.php index 6bf44532621..c5e92cdcb1b 100755 --- a/htdocs/theme/amarok/style.css.php +++ b/htdocs/theme/amarok/style.css.php @@ -21,25 +21,28 @@ /** * \file htdocs/theme/amarok/style.css.php - * \brief Fichier de style CSS du theme amarok + * \brief File for CSS style sheet Amarok */ -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled because need to load personalized language //if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Not disabled to increase speed. Language code is found on url. if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Not disabled cause need to do translations +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Not disabled because need to do translations if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK',1); if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); -if (! defined('NOLOGIN')) define('NOLOGIN',1); +if (! defined('NOLOGIN')) define('NOLOGIN',1); // File must be accessed by logon page so without login if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU',1); if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML',1); if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); session_cache_limiter(FALSE); -require_once("../../main.inc.php"); +require_once '../../main.inc.php'; + +// Load user to have $user->conf loaded (not done into main because of NOLOGIN constant defined) +if (empty($user->id) && ! empty($_SESSION['dol_login'])) $user->fetch('',$_SESSION['dol_login']); // Define css type header('Content-type: text/css'); @@ -69,12 +72,55 @@ $fontlist='helvetica,arial,tahoma,verdana'; //$fontlist='Verdana,Helvetica,Ar $img_liste_titre=dol_buildpath($path.'/theme/'.$theme.'/img/menus/trtitle.png',1); $img_head=dol_buildpath($path.'/theme/'.$theme.'/img/headbg2.jpg',1); $img_button=dol_buildpath($path.'/theme/'.$theme.'/img/button_bg.png',1); +$dol_hide_topmenu=$conf->dol_hide_topmenu; +$dol_hide_leftmenu=$conf->dol_hide_leftmenu; +$dol_optimize_smallscreen=$conf->dol_optimize_smallscreen; +$dol_no_mouse_hover=$conf->dol_no_mouse_hover; +$dol_use_jmobile=$conf->dol_use_jmobile; + + +// Define reference colors +// Example: Light grey: $colred=235;$colgreen=235;$colblue=235; +// Example: Pink: $colred=230;$colgreen=210;$colblue=230; +// Example: Green: $colred=210;$colgreen=230;$colblue=210; +// Example: Ocean: $colred=220;$colgreen=220;$colblue=240; +//$conf->global->THEME_ELDY_ENABLE_PERSONALIZED=0; +//$user->conf->THEME_ELDY_ENABLE_PERSONALIZED=0; +//var_dump($user->conf->THEME_ELDY_RGB); +$colred =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_RGB)?235:hexdec(substr($conf->global->THEME_ELDY_RGB,0,2))):(empty($user->conf->THEME_ELDY_RGB)?235:hexdec(substr($user->conf->THEME_ELDY_RGB,0,2))); +$colgreen=empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_RGB)?235:hexdec(substr($conf->global->THEME_ELDY_RGB,2,2))):(empty($user->conf->THEME_ELDY_RGB)?235:hexdec(substr($user->conf->THEME_ELDY_RGB,2,2))); +$colblue =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_RGB)?235:hexdec(substr($conf->global->THEME_ELDY_RGB,4,2))):(empty($user->conf->THEME_ELDY_RGB)?235:hexdec(substr($user->conf->THEME_ELDY_RGB,4,2))); + +// Colors +$isred=max(0,(2*$colred-$colgreen-$colblue)/2); // 0 - 255 +$isgreen=max(0,(2*$colgreen-$colred-$colblue)/2); // 0 - 255 +$isblue=max(0,(2*$colblue-$colred-$colgreen)/2); // 0 - 255 +$colorback1=($colred-3).','.($colgreen-3).','.($colblue-3); // topmenu +$colorback2=($colred+5).','.($colgreen+5).','.($colblue+5); +$colorbacktab1=($colred+15).','.($colgreen+16).','.($colblue+17); // vmenu +$colorbacktab1b=($colred+5).','.($colgreen+6).','.($colblue+7); // vmenu (not menu) +$colorbacktab2=($colred-15).','.($colgreen-15).','.($colblue-15); +$colorbacktitle1=($colred-5).','.($colgreen-5).','.($colblue-5); // title of array +$colorbacktitle2=($colred-15).','.($colgreen-15).','.($colblue-15); +$colorbacktabcard1=($colred+15).','.($colgreen+16).','.($colblue+17); // card +$colorbacktabcard2=($colred-15).','.($colgreen-15).','.($colblue-15); +$colorbacktabactive=($colred-15).','.($colgreen-15).','.($colblue-15); +$colorbacklineimpair1=(244+round($isred/3)).','.(244+round($isgreen/3)).','.(244+round($isblue/3)); // line impair +$colorbacklineimpair2=(250+round($isred/3)).','.(250+round($isgreen/3)).','.(250+round($isblue/3)); // line impair +$colorbacklineimpairhover=(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9)); // line impair +$colorbacklinepair1='255,255,255'; // line pair +$colorbacklinepair2='255,255,255'; // line pair +$colorbacklinepairhover=(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9)); +$colorbackbody='#f5f5f5'; +$colortext='40,40,40'; +$fontsize=empty($conf->dol_optimize_smallscreen)?'12':'14'; +$fontsizesmaller=empty($conf->dol_optimize_smallscreen)?'11':'14'; ?> /* ============================================================================== */ -/* Styles par défaut */ +/* Default styles */ /* ============================================================================== */ *, html { @@ -84,31 +130,17 @@ font-size:100%; } body { - background-color:#f5f5f5; - - - background-image:url(); - background-repeat:repeat-y; - margin:0px; - - - background-image:url(); - margin:100px; - +dol_optimize_smallscreen)) { ?> + background-color: #FFFFFF; + + background-color: ; + color:#232323; font-size:px; font-family:; - trans("DIRECTION").";\n"; ?> } -.checkVatPopup { - background-color:#f5f5f5; - background-image:none; - margin:10px; - line-height:16px; -} - a { font-family:; font-weight:bold; @@ -194,6 +226,15 @@ div.inline-block display:inline-block; } +th .button { + -moz-box-shadow: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + -moz-border-radius:0px !important; + -webkit-border-radius:0px !important; + border-radius:0px !important; +} + .valignmiddle { vertical-align: middle; } @@ -211,11 +252,102 @@ div.inline-block } +.blockvmenubookmarks .menu_contenu { + background-color: transparent; +} + +/* ! Message d'erreur lors du login : */ +center .error { padding:8px !important; padding-left:26px !important; padding-right:20px; width:inherit; max-width:450px;color:#552323 !important; font-size:14px; border-radius:8px; text-align: left;} + + + /* ============================================================================== */ -/* Login */ +/* Styles to hide objects */ /* ============================================================================== */ -body.body center{color:white;} +.hideobject { display:none; } + +.hideonsmartphone { display: none; } +.noenlargeonsmartphone { width : 50px !important; display: inline !important; } + +.linkobject { cursor:pointer; } + + +/* ============================================================================== */ +/* Styles for dragging lines */ +/* ============================================================================== */ + +.dragClass { + color: #333333; +} +td.showDragHandle { + cursor: move; +} +.tdlineupdown { + white-space: nowrap; +} + +/* ============================================================================== */ +/* Menu top et 1ere ligne tableau */ +/* ============================================================================== */ + +div.tmenu { + + display:none; + + position:relative; + display:block; + margin:0; + padding:0; + padding-left:1em; + top:0; + left:0; + right:0; + white-space:nowrap; + height:36px; + browser->name != 'ie') echo "line-height:36px; /* disabled for ie9 */ \n"; ?> + background:#333333; + background-image:linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); + background-image:-o-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); + background-image:-moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); + background-image:-webkit-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); + background-image:-ms-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); + background-image:-webkit-gradient( + linear, + left top, + left bottom, + color-stop(0, rgba(255,255,255,.3)), + color-stop(1, rgba(0,0,0,.3)) + ); + border-bottom:solid 1px rgba(0,0,0,.8); + box-shadow:0 0 6px rgba(0,0,0,.4) !important; + z-index:100; + +} + +div.tmenu a { + font-weight:normal; +} + +div.tmenu li { + display:inline-table; + margin-right:1em; + text-transform:uppercase; +} + +div.tmenu li a {color:#cccccc;} +div.tmenu li a:hover { color:rgba(255,255,255,1);} + +div.tmenu ul li a.tmenusel {/* texte du menu principal sélectionné */ + color:#ffffff; + font-weight:bold; +} + +.tmenudisabled { color:#808080 !important; cursor: not-allowed; } + + + +/* Login */ form#login { display:block; @@ -329,96 +461,6 @@ table.login_table .vmenu { font-size:120%; } -.blockvmenubookmarks .menu_contenu { - background-color: transparent; -} - -/* ! Message d'erreur lors du login : */ -center .error { padding:8px !important; padding-left:26px !important; padding-right:20px; width:inherit; max-width:450px;color:#552323 !important; font-size:14px; border-radius:8px; text-align: left;} - - - -/* ============================================================================== */ -/* Styles to hide objects */ -/* ============================================================================== */ - -.hideobject { display:none; } - -.hideonsmartphone { display: none; } -.noenlargeonsmartphone { width : 50px !important; display: inline !important; } - -.linkobject { cursor:pointer; } - - -/* For dragging lines */ - -.dragClass {color:#333333;} -td.showDragHandle {cursor:move;} -.tdlineupdown {white-space:nowrap;} - - -/* ============================================================================== */ -/* Menu top et 1ère ligne tableau */ -/* ============================================================================== */ - -div.tmenu { - - display:none; - - position:relative; - display:block; - margin:0; - padding:0; - padding-left:1em; - top:0; - left:0; - right:0; - white-space:nowrap; - height:36px; - browser->name != 'ie') echo "line-height:36px; /* disabled for ie9 */ \n"; ?> - background:#333333; - background-image:linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); - background-image:-o-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); - background-image:-moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); - background-image:-webkit-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); - background-image:-ms-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); - background-image:-webkit-gradient( - linear, - left top, - left bottom, - color-stop(0, rgba(255,255,255,.3)), - color-stop(1, rgba(0,0,0,.3)) - ); - border-bottom:solid 1px rgba(0,0,0,.8); - box-shadow:0 0 6px rgba(0,0,0,.4) !important; - z-index:100; - -} - -div.tmenu a { - font-weight:normal; -} - -div.tmenu li { - display:inline-table; - margin-right:1em; - text-transform:uppercase; -} - -div.tmenu li a {color:#cccccc;} -div.tmenu li a:hover {color:rgba(255,255,255,.2);} - -div.tmenu ul li a.tmenusel {/* texte du menu principal sélectionné */ - color:#ffffff; - font-weight:bold; -} - -.tmenudisabled { color:#808080 !important; cursor: not-allowed; } - -/* --- end nav --- */ - -/* Login */ - div.login_block { position:absolute; top:5px; @@ -438,16 +480,16 @@ div.login_block table { div.login { white-space:nowrap; - padding:8px 0px 0px 0px; + padding: dol_optimize_smallscreen?'0':'8')?>px 0px 0px 0px; margin:0px 0px 0px 8px; font-weight:bold; } img.login, img.printer, img.entity { - padding:8px 0px 0px 0px; + padding: dol_optimize_smallscreen?'0':'8')?>px 0px 0px 0px; margin:0px 0px 0px 8px; text-decoration:none; - color:#ffffff; + color: white; font-weight:bold; } @@ -461,6 +503,9 @@ div.vmenu { display:none; width:170px; + -moz-box-shadow: 4px 4px 4px #CCC; + -webkit-box-shadow: 4px 4px 4px #CCC; + box-shadow: 4px 4px 4px #CCC; } @@ -773,8 +818,11 @@ div.tabs { div.tabBar { background-color:#ffffff; padding:6px; - margin:3px 0px 5px; + margin:3px 0px 14px 0px; border:1px solid #bbbbbb; + -moz-box-shadow: 4px 4px 4px #DDD; + -webkit-box-shadow: 4px 4px 4px #DDD; + box-shadow: 4px 4px 4px #DDD; } div.tabBar table.notopnoleftnoright { @@ -1066,7 +1114,7 @@ table.liste { table.liste td {padding:1px 2px 1px 0px;} -tr.liste_titre, tr.box_titre { +div.liste_titre, tr.liste_titre, tr.box_titre { padding:4px; background-color:rgba(0,0,0,.2); background-image:linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); @@ -1116,13 +1164,13 @@ tr.impair td, tr.pair td {padding:1px 1px 1px 2px;} tr.impair table.nobordernopadding td, tr.pair table.nobordernopadding td {padding:1px 0px;} .impair { - background:#f4f4f4; + background:#fdfdfd; font-family:; border:0px; } .pair { - background:#eaeaea; + background:#f4f4f4; font-family:; border:0px; } @@ -1147,12 +1195,12 @@ tr.impair table.nobordernopadding td, tr.pair table.nobordernopadding td {paddin } tr.box_impair { - background:#f4f4f4; + background:#fdfdfd; font-family:; } tr.box_pair { - background:#eaeaea; + background:#f4f4f4; font-family:; } @@ -1423,7 +1471,7 @@ td.dpHead { /* Jour courant */ .dpSelected { - background-color:#a61111; + background-color:#0B63A2; color:#ffffff; font-weight:bold; } @@ -1468,7 +1516,7 @@ td.dpHead { padding:0px 2px; font-size:9px; border-width:0px; - color:#a61111; + color:#0B63A2; vertical-align:middle; cursor:pointer; } @@ -1499,17 +1547,9 @@ table.cal_month { border-spacing: 0px; } .cal_current_month_right { border-right: solid 1px #E0E0E0; } .cal_other_month_right { border-right: solid 1px #C0C0C0; } -.cal_other_month { - background:#dddddd; -} - -.cal_past_month { - background:#eeeeee; -} - -.cal_current_month { - background:#ffffff; -} +.cal_other_month { opacity: 0.6; background: #EAEAEA; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } +.cal_past_month { opacity: 0.6; background: #EEEEEE; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } +.cal_current_month { background: #FFFFFF; border-left: solid 1px #E0E0E0; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } .cal_today { background:#ffffff; @@ -1518,37 +1558,19 @@ table.cal_month { border-spacing: 0px; } div.dayevent table.nobordernopadding tr td {padding:1px;} -table.cal_event { - border-collapse:collapse; - margin-bottom:1px; -} - -ul.cal_event { padding-right: 2px; padding-top: 1px; border: none; list-style-type: none; margin: 0 auto; padding-left: 0px; padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; -webkit-padding-start: 0px; -webkit-padding-start: 0px; } +table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 6px; border-radius: 6px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); + moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); + background: -webkit-gradient(linear, left top, left bottom, from(#006aac), to(#00438d)); + } +table.cal_event td { border: none; padding-: 2px; padding-: 2px; padding-top: 0px; padding-bottom: 0px; } +ul.cal_event { padding-right: 2px; padding-top: 1px; border: none; list-style-type: none; margin: 0 auto; padding-left: 0px; padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; -moz-padding-start: 0px; -webkit-padding-start: 0px; } li.cal_event { border: none; list-style-type: none; } - -.cal_event a:link { - color:#232323; - font-size:11px; - font-weight:normal !important; -} - -.cal_event a:visited { - color:#232323; - font-size:11px; - font-weight:normal !important; -} - -.cal_event a:active { - color:#232323; - font-size:11px; - font-weight:normal !important; -} - -.cal_event a:hover { - color:rgba(255,255,255,.75); - font-size:11px; - font-weight:normal !important; -} +.cal_event a:link { color: #111111; font-size: 11px; font-weight: normal !important; } +.cal_event a:visited { color: #111111; font-size: 11px; font-weight: normal !important; } +.cal_event a:active { color: #111111; font-size: 11px; font-weight: normal !important; } +.cal_event a:hover { color: #111111; font-size: 11px; font-weight: normal !important; color:rgba(255,255,255,.75); } /* ============================================================================== */ diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 47e27f3f968..43af5fc2482 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -58,6 +58,8 @@ if (GETPOST('theme')) $conf->theme=GETPOST('theme'); // If theme was forced on $langs->load("main",0,1); $right=($langs->trans("DIRECTION")=='rtl'?'left':'right'); $left=($langs->trans("DIRECTION")=='rtl'?'right':'left'); +$fontsize=empty($conf->dol_optimize_smallscreen)?'12':'12'; +$fontsizesmaller=empty($conf->dol_optimize_smallscreen)?'11':'11'; $path=''; // This value may be used in future for external module to overwrite theme $theme='eldy'; // Value of theme @@ -198,7 +200,7 @@ if (! empty($conf->dol_optimize_smallscreen)) $fontsize=11; ?> /* ============================================================================== */ -/* Styles par defaut */ +/* Default styles */ /* ============================================================================== */ body { @@ -304,8 +306,8 @@ input[type=image] { background-color: transparent; border: none; box-shadow: non box-shadow: 4px 4px 4px #CCC; } form { - padding: 0em 0em 0em 0em; - margin: 0em 0em 0em 0em; + padding:0px; + margin:0px; } div.float { @@ -852,9 +854,9 @@ td.vmenu { .vmenu { margin-left: 4px; - + display: none; - + } .menu_contenu { padding-top: 1px; } @@ -1317,11 +1319,14 @@ div.tabsAction { a.tabTitle { - background: #657090; - color: white; +/* background: #657090; + color: white;*/ + color:rgba(0,0,0,.5); + margin-right:10px; + text-shadow:1px 1px 1px #ffffff; font-family: ; font-weight: normal; - padding: 0px 6px 2px 6px; + padding: 5px 6px 2px 6px; margin: 0px 6px; text-decoration: none; white-space: nowrap; @@ -1329,7 +1334,7 @@ a.tabTitle { a.tab:link, a.tab:visited, a.tab:hover, a.tab#active { font-family: ; - padding: 2px 6px 2px 6px; + padding: 5px 6px 2px 6px; margin: 0em 0.2em; text-decoration: none; white-space: nowrap; @@ -1364,6 +1369,7 @@ a.tab#active { a.tab:link, a.tab:visited, a.tab:hover, a.tab#active { color: #; + font-weight: normal !important; } a.tabimage { From 1f0adfaff57b7fd578567160a7f20fd27364b501 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 21 Apr 2013 23:44:33 +0200 Subject: [PATCH 87/97] Can remove an element from category when on category view. --- htdocs/adherents/class/adherent.class.php | 7 +- htdocs/categories/categorie.php | 7 +- htdocs/categories/class/categorie.class.php | 1 + htdocs/categories/viewcat.php | 121 +++++++++++++++++--- htdocs/product/class/product.class.php | 4 + htdocs/societe/class/societe.class.php | 11 +- 6 files changed, 133 insertions(+), 18 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 87a9b14877e..13a6bdea810 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1520,7 +1520,12 @@ class Adherent extends CommonObject $lien = ''; $lienfin=''; } - + if ($option == 'category') + { + $lien = ''; + $lienfin=''; + } + $picto='user'; $label=$langs->trans("ShowMember"); diff --git a/htdocs/categories/categorie.php b/htdocs/categories/categorie.php index ddc7079c786..ec2a2b49d63 100644 --- a/htdocs/categories/categorie.php +++ b/htdocs/categories/categorie.php @@ -99,7 +99,7 @@ $error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->e if (empty($reshook)) { - //Suppression d'un objet d'une categorie + // Remove element from category if ($removecat > 0) { if ($type==0 && ($user->rights->produit->creer || $user->rights->service->creer)) @@ -113,17 +113,20 @@ if (empty($reshook)) { $object = new Societe($db); $result = $object->fetch($objectid); + $elementtype = 'fournisseur'; } if ($type==2 && $user->rights->societe->creer) { $object = new Societe($db); $result = $object->fetch($objectid); + $elementtype = 'societe'; } if ($type == 3 && $user->rights->adherent->creer) { require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; $object = new Adherent($db); $result = $object->fetch($objectid); + $elementtype = 'member'; } $cat = new Categorie($db); $result=$cat->fetch($removecat); @@ -507,7 +510,7 @@ function formCategory($db,$object,$typeid,$socid=0) //print $c->getNomUrl(1); print img_object('','category').' '.$way.""; - // Lien supprimer + // Link to delete from category print ''; + $nbofsubproducts=count($product->get_arbo_each_prod()); + print ''; dol_fiche_end(); - // List of subproducts + // List of products into this virtual product $prods_arbo = $product->get_arbo_each_prod(); if (count($prods_arbo) > 0) { @@ -231,8 +234,10 @@ if ($id || $ref) print ''; } - // Number of parent products - print ''; + // Number of parent virtual products + print ''; if (count($prodsfather) > 0) { From 5b4b0583998752ac9993d1e1745d58475ba5c2ae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Apr 2013 12:30:52 +0200 Subject: [PATCH 93/97] Perf: Minor perf enhancement --- htdocs/product/composition/fiche.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/product/composition/fiche.php b/htdocs/product/composition/fiche.php index 206dd87ceae..d02253b4d24 100644 --- a/htdocs/product/composition/fiche.php +++ b/htdocs/product/composition/fiche.php @@ -198,9 +198,10 @@ if ($id || $ref) print ''; // Number of subproducts - $prodsfather = $product->getFather(); //Parent Products + $prodsfather = $product->getFather(); // Parent Products $product->get_sousproduits_arbo(); - $nbofsubproducts=count($product->get_arbo_each_prod()); + $prods_arbo=$product->get_arbo_each_prod(); + $nbofsubproducts=count($prods_arbo); print ''; @@ -209,7 +210,6 @@ if ($id || $ref) // List of products into this virtual product - $prods_arbo = $product->get_arbo_each_prod(); if (count($prods_arbo) > 0) { print ''; - print ''; + //print ''; + print ''; if (! empty($conf->stock->enabled)) print ''; print ''; } From 54040bed1d4b5280cd76eb4c751335f439c29941 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Apr 2013 12:48:56 +0200 Subject: [PATCH 94/97] Fix: No slash alone --- htdocs/core/lib/company.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index d01c0456250..695b6deb2c1 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -47,7 +47,7 @@ function societe_prepare_head($object) { $head[$h][0] = DOL_URL_ROOT.'/comm/fiche.php?socid='.$object->id; if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && ($object->client==2 || $object->client==3)) $head[$h][1] = $langs->trans("Prospect"); - if ($object->client==3) $head[$h][1] .= '/'; + if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && $object->client==3) $head[$h][1] .= '/'; if (empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && ($object->client==1 || $object->client==3)) $head[$h][1] .= $langs->trans("Customer"); $head[$h][2] = 'customer'; $h++; From c87c7703cd4a50b78fd4f3ad4882b5cde4d83d4d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Apr 2013 13:01:22 +0200 Subject: [PATCH 95/97] Qual: Make code simpler. --- htdocs/product/class/product.class.php | 95 +++++++++----------------- htdocs/product/composition/fiche.php | 16 +++-- 2 files changed, 43 insertions(+), 68 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 9422eed8250..8cac5ebe573 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1803,7 +1803,7 @@ class Product extends CommonObject $result=$this->del_sousproduit($id_pere, $id_fils); if ($result < 0) return $result; - + // Check not already father of id_pere (to avoid father -> child -> father links) $sql = 'SELECT fk_product_pere from '.MAIN_DB_PREFIX.'product_association'; $sql .= ' WHERE fk_product_pere = '.$id_fils.' AND fk_product_fils = '.$id_pere; @@ -1852,11 +1852,11 @@ class Product extends CommonObject { if (! is_numeric($fk_parent)) $fk_parent=0; if (! is_numeric($fk_child)) $fk_child=0; - + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_association"; $sql.= " WHERE fk_product_pere = ".$fk_parent; $sql.= " AND fk_product_fils = ".$fk_child; - + dol_syslog(get_class($this).'::del_sousproduit sql='.$sql); if (! $this->db->query($sql)) { @@ -2122,7 +2122,7 @@ class Product extends CommonObject * Define value of this->res * * @param array $prod Products array - * @param string $compl_path Directory path + * @param string $compl_path Directory path of parents to add before * @param int $multiply Because each sublevel must be multiplicated by parent nb * @param int $level Init level * @return void @@ -2132,7 +2132,8 @@ class Product extends CommonObject global $conf,$langs; $product = new Product($this->db); - foreach($prod as $nom_pere => $desc_pere) + //var_dump($prod); + foreach($prod as $id_product => $desc_pere) // nom_pere is 0 or id of sub_product { if (is_array($desc_pere)) // If this parent desc is an array, this is an array of childs { @@ -2140,58 +2141,27 @@ class Product extends CommonObject $nb=(! empty($desc_pere[1]) ? $desc_pere[1] :''); $type=(! empty($desc_pere[2]) ? $desc_pere[2] :''); $label=(! empty($desc_pere[3]) ? $desc_pere[3] :''); + if ($multiply < 1) $multiply=1; - if ($multiply) - { - //print "XXX ".$desc_pere[1]." multiply=".$multiply; - $img=""; - $this->fetch($id); - $this->load_stock(); - if ($this->stock_warehouse[1]->real < $this->seuil_stock_alerte) - { - $img=img_warning($langs->trans("StockTooLow")); - } - $this->res[]= array( -/* " - ", - $desc_pere[0], // Id product -*/ 'id'=>$id, // Id product - 'nb'=>$nb, // Nb of units that compose parent product - 'nb_total'=>$nb*$multiply, // Nb of units for all nb of product - 'stock'=>$this->stock_warehouse[1]->real, // Stock - 'stock_alert'=>$this->seuil_stock_alerte, // Stock alert - 'fullpath' => $compl_path.$label, // Label - 'type'=>$type // Nb of units that compose parent product - ); - } - else - { - $this->fetch($desc_pere[0]); - $this->load_stock(); - $this->res[]= array( -/* $compl_path.$nom_pere." (".$desc_pere[1].")", - $desc_pere[0], // Id product -*/ 'id'=>$id, // Id product + //print "XXX We add id=".$id." - label=".$label." - nb=".$nb." - multiply=".$multiply." fullpath=".$compl_path.$label."\n"; + $this->fetch($id); + $this->load_stock(); + $this->res[]= array( + 'id'=>$id, // Id product 'nb'=>$nb, // Nb of units that compose parent product - 'nb_total'=>$nb, // Nb of units for all nb of product - 'stock'=>$this->stock_warehouse[1]->real, // Stock + 'nb_total'=>$nb*$multiply, // Nb of units for all nb of product + 'stock'=>$this->stock_warehouse[1]->real, // Stock 'stock_alert'=>$this->seuil_stock_alerte, // Stock alert - 'fullpath' => $compl_path.$nom_pere, // Label - 'type'=>$type // Nb of units that compose parent product - ); - } - } - else if($nom_pere != "0" && $nom_pere != "1") - { - $this->res[]= array($compl_path.$nom_pere,$desc_pere); + 'fullpath' => $compl_path.$label, // Label + 'type'=>$type // Nb of units that compose parent product + ); } // Recursive call if child is an array - if (is_array($desc_pere[0])) + if (is_array($desc_pere['childs'])) { - $this ->fetch_prod_arbo($desc_pere[0], $nom_pere." -> ", $desc_pere[1]*$multiply, $level+1); + //print 'YYY We go down for '.$desc_pere[3]." -> \n"; + $this ->fetch_prod_arbo($desc_pere['childs'], $compl_path.$desc_pere[3]." -> ", $desc_pere[1]*$multiply, $level+1); } } } @@ -2228,11 +2198,12 @@ class Product extends CommonObject $this->res = array(); if (isset($this->sousprods) && is_array($this->sousprods)) { - foreach($this->sousprods as $nom_pere => $desc_pere) + foreach($this->sousprods as $prod_name => $desc_product) { - if (is_array($desc_pere)) $this->fetch_prod_arbo($desc_pere,"",$multiply); + if (is_array($desc_product)) $this->fetch_prod_arbo($desc_product,"",$multiply); } } + //var_dump($this->res); return $this->res; } @@ -2293,7 +2264,7 @@ class Product extends CommonObject /** - * Return all parent products fo current product + * Return all direct parent products fo current product * * @return array prod */ @@ -2324,19 +2295,19 @@ class Product extends CommonObject } /** - * Return childs of product with if fk_parent + * Return childs of product $id * - * @param int $fk_parent Id of product to search childs of + * @param int $id Id of product to search childs of * @return array Prod */ - function getChildsArbo($fk_parent) + function getChildsArbo($id) { $sql = "SELECT p.rowid, p.label as label, pa.qty as qty, pa.fk_product_fils as id, p.fk_product_type"; $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; $sql.= ", ".MAIN_DB_PREFIX."product_association as pa"; $sql.= " WHERE p.rowid = pa.fk_product_fils"; - $sql.= " AND pa.fk_product_pere = ".$fk_parent; - $sql.= " AND pa.fk_product_fils != ".$fk_parent; // This should not happens, it is to avoid invinite loop if it happens + $sql.= " AND pa.fk_product_pere = ".$id; + $sql.= " AND pa.fk_product_fils != ".$id; // This should not happens, it is to avoid infinite loop if it happens dol_syslog(get_class($this).'::getChildsArbo sql='.$sql); $res = $this->db->query($sql); @@ -2351,7 +2322,7 @@ class Product extends CommonObject $listofchilds=$this->getChildsArbo($rec['id']); foreach($listofchilds as $keyChild => $valueChild) { - $prods[$rec['rowid']][$keyChild] = $valueChild; + $prods[$rec['rowid']]['childs'][$keyChild] = $valueChild; } } @@ -2373,14 +2344,14 @@ class Product extends CommonObject function get_sousproduits_arbo() { $parent = $this->getParent(); - foreach($parent as $key => $value) + foreach($parent as $key => $value) // key=label, value[0]=id { foreach($this->getChildsArbo($value[0]) as $keyChild => $valueChild) { $parent[$key][$keyChild] = $valueChild; } } - foreach($parent as $key => $value) + foreach($parent as $key => $value) // key=label, value is array of childs { $this->sousprods[$key] = $value; } @@ -2418,7 +2389,7 @@ class Product extends CommonObject else if ($option == 'category') { $lien = ''; - } + } else { $lien = ''; diff --git a/htdocs/product/composition/fiche.php b/htdocs/product/composition/fiche.php index d02253b4d24..71ce35c76e1 100644 --- a/htdocs/product/composition/fiche.php +++ b/htdocs/product/composition/fiche.php @@ -227,7 +227,7 @@ if ($id || $ref) //print $value[0]; // This contains a tr line. print ''; //print ''; - print ''; + print ''; if (! empty($conf->stock->enabled)) print ''; print ''; } @@ -292,12 +292,14 @@ if ($id || $ref) // Number of subproducts $prodsfather = $product->getFather(); //Parent Products $product->get_sousproduits_arbo(); - print ''; + $prods_arbo=$product->get_arbo_each_prod(); + $nbofsubproducts=count($prods_arbo); + print ''; print ''; // List of subproducts - $prods_arbo = $product->get_arbo_each_prod(); - //var_dump($prods_arbo); if(count($prods_arbo) > 0) { print ''; } - // Number of parent products - print ''; + // Number of parent virtual products + print ''; if (count($prodsfather) > 0) { From 335c8cd5112df9a55c0e456d85729547213743fb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Apr 2013 13:01:38 +0200 Subject: [PATCH 96/97] Look: Minor change --- htdocs/theme/eldy/style.css.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 43af5fc2482..bcfb9a051bd 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1326,7 +1326,7 @@ a.tabTitle { text-shadow:1px 1px 1px #ffffff; font-family: ; font-weight: normal; - padding: 5px 6px 2px 6px; + padding: 4px 6px 2px 6px; margin: 0px 6px; text-decoration: none; white-space: nowrap; @@ -1334,7 +1334,7 @@ a.tabTitle { a.tab:link, a.tab:visited, a.tab:hover, a.tab#active { font-family: ; - padding: 5px 6px 2px 6px; + padding: 4px 6px 2px 6px; margin: 0em 0.2em; text-decoration: none; white-space: nowrap; From ed4c18b9d36fdb83c4d0fee00bd339879c61c0e5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Apr 2013 13:15:33 +0200 Subject: [PATCH 97/97] Update changelog. Fix: Fix template ODS. --- ChangeLog | 69 +++++++++--------- .../thirdparties/template_thirdparty.ods | Bin 14558 -> 13595 bytes 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index c4b8ccf1e55..a70c0f58da2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ English Dolibarr ChangeLog ***** ChangeLog for 3.4 compared to 3.3.2 ***** For users: +- New: Can use ODS templates as document templates. - New: Add link to autofill/reset with quantity to ship when creating a delivery receipt. - New: Event into calendar use different colors for different users. @@ -11,46 +12,48 @@ For users: - New: Add a tab "consumption" on thirdparties to list products bought/sells. - New: Some performance enhancements. - New: Can attach files onto trip and expenses modules. -- New: Add option MAIN_PDF_TITLE_BACKGROUND_COLOR. +- New: Add hidden option MAIN_PDF_TITLE_BACKGROUND_COLOR. - New: Merge tab customer and prospect. - New: Add ES formated address country rule. -- New: Can define a hierarchical responsible on user. -- New: Add a hierarchical view for users. +- New: Can define a hierarchical responsible on user and add a tree view to + see hierarchy of users. - New: Can expand/collapse menus, categories and users list. -- New: extra parameters are supported into ODT templates. -- New: total per vat rate are available as tags for ODT templates. -- New: Add more types for extra parameters (lists, phone, emails, checkbox, prices). +- New: extra parameters are supported into ODT/ODS templates. +- New: total per vat rate are available as tags for ODT/ODS templates. - New: Some part of interface use more CSS3 (ie: agenda) -- New: [ task #707 ] Create option ProfIdx are mandatory to validate a invoice. +- New: [ task #707 ] Create option "ProfIdx is mandatory to validate a invoice". - New: Can define if we want to use VAT or not for subscriptions (foundation module). -- New: Can define a default choice for choice "More action when recording - a subscription" (foundation module). -- New: Add link to check professional id for india. +- New: Can define a default choice for "More action when recording a + subscription" (foundation module). +- New: Add link to check professional id for India. - New: [ task #731 ] Uniformize ref generation - New: [ task #748 ] Add a link "Dolibarr" into left menu -- New: Script email_unpaid_invoices_to_representative accepts now a parameter test - and a delay. -- New: Can define a different clicktodial setup per user. -- New: Add option INVOICE_CAN_NEVER_BE_REMOVED. -- New: Enhance agenda module to reach RFC2445 (add busy information). +- New: Script email_unpaid_invoices_to_representative accepts now a parameter "test" + and a "late delay". +- New: Can define different clicktodial setups for each user. +- New: Add hidden option INVOICE_CAN_NEVER_BE_REMOVED. +- New: Enhance agenda module to reach RFC2445 ("type" not enabled by default and add + "busy" information). - New: Add module Opensurvey. -- New: Default aprrover for holidays i sby default hierchical parent. +- New: Default approver for holidays is set by default to hierchical parent. - First change to prepare feature "click to print" (IPP) for PDF. -- New: [ task #350 ] Merge tab customer and prospect -- New: [ task #710 ] Add substitution into mailing send (and HTML is now valid) -- New: [ task #711 ] Add combobox for contact as done for product/thirdparty -- New: [ task #714 ] In Emailing module admin autogenerate security key of READRECIEPT -- New: [ task #743 ] GED : Add aministration option to disabled autotree to display -- New: [ task #767 ] Customer Address fallback when a contact doesn't have an address -- New: [ task #768 ] WYSIWYG for all mail -- New: [ task #773 ] Add Project document in GED(ECM) modules -- New: [ task #783 ] Add checkbox and radio into extrafield feature -- New: [ task #798 ] Add range limit date on product/services as it is done on order and invoice -- New: [ task #814 ] Add extrafield feature into Project/project tasks module -- New: [ task #770 ] Add ODT document generation for Projects module -- New: [ task #741 ] Add intervention box -- New: [ task #826 ] Optionnal increase stock when deleting an invoice already validated -- New: [ task #823 ] Shipping_validate email notification +- New: [ task #350 ] Merge tab customer and prospect. +- New: [ task #710 ] Add substitution into mailing send (and HTML is now valid). +- New: [ task #711 ] Add combobox for contact, as done for product/thirdparty. +- New: [ task #714 ] In Emailing module admin autogenerate security key of READRECEIPT. +- New: [ task #743 ] GED : Add aministration option to disable autotree display. +- New: [ task #767 ] Customer Address fallback when a contact doesn't have an address. +- New: [ task #768 ] WYSIWYG for all mails. +- New: [ task #773 ] Add Project document in GED(ECM) modules. +- New: [ task #783 ] Add more types for extra parameters (lists, phone, emails, checkbox, + prices, radio). +- New: [ task #798 ] Add range limit date on product/services as it is done on order + and invoice. +- New: [ task #814 ] Add extrafield feature for projects ands tasks. +- New: [ task #770 ] Add ODT document generation for Projects module. +- New: [ task #741 ] Add intervention box. +- New: [ task #826 ] Optionnal increase stock when deleting an invoice already validated. +- New: [ task #823 ] Shipping_validate email notification. For translators: - Update language files. @@ -60,8 +63,8 @@ For developers: - An external module can force its theme. - Add function dol_set_focus('#xxx'). - A mymodule can bring its own core/modules/mymodule/modules_mymodule.php file. -- Removed not used libraries. -- More web services. +- Removed some not used libraries. +- More web services. - Renamed some database fields, code variables and parameters from french to english. - First change to manage margins on contracts. - Add hook getFormMail. diff --git a/htdocs/install/doctemplates/thirdparties/template_thirdparty.ods b/htdocs/install/doctemplates/thirdparties/template_thirdparty.ods index ad50961b562d95810ea98e692c74827e9ece247d..c715d7fb80f94399f3a39710b5d67c73a91db913 100644 GIT binary patch literal 13595 zcmeHuWmsIx(k>b_2~L1OaCdhN7Th&Ra2uS#Ww0Q@B{&54V8J~=AXtFGCAb9$?r>+a zcTTeR+2_0G`*(lbhK99zRlQwZU0q%MtXj%)@CZ0CFvu`4-r7mx!M1$i%rG!8&bMbI6Gj?#WwK6ewv9brSxB*O=?TwwSoSE$%%mAkLCa!j702gLw2PZRQQ)f#v zGZ*E*V7iDK0JY&^V4(E}rkRT|v%8(Gpa|p-shgRTGXzzLoQ;{4oYV|pVsB~%un;2G zP?uujB^MD!6|^@uw=yx~|Je}}L?UBS2rIyu|BpvPIgc9KZf|DJ9bu9PL@CJfA(bI zWNK>rFZ$mG0HNhzv0yPZb}?phvoZrxkdywY$KMprPA>dYyHGKN1%C)*0+~nXL^DB{ z&4k%m**KV3Ihokm)Y;hhxw!b*cm!GgflkoWg#WJ$?CNYB{Hz@OTo8tz5C7=F%+$&S zGRaJ)u1-IC5>{5{l;Pr3;NnpG6Z_vN{>o_LVPb3MEX?&c>OY(RptUdqm_gv}orLAB zUOAa5{jeey4rVS&c`JacyP-BOw;?wt>2D7W9h~f~%}iWaIJj8t*eJzat!z!1*#GR~ z7aVk?KXe3zHgq=3@NH){M!--WA{iF?#Yp z8cob>ZGX0LaQ@k7{|YM2&t_I~7Gc3Zr=S0i>H2y1udaSH|FQazk&%C_XviY|S3!qd zIh(mab?*#afqN-SYAdW5eM<+GMpsdY>Vg8GK;F!Gj~(R`-i$ zj0s0f&)eSPMFsck!?SzkPK)cWVr3NQ|5lsU;9sktYu>K+ZQ)qK$w zXv9p7`l7TN<9mD8KP!4vD2wZ^VoSK&7i%LVkye|8)3sSd;Bjm)+*lZ=NPvzIgK{Os zU!>ValBZ8_I~jHR< zlg#&|athoYHgiv6_@1v^NqYk28d^KP$7ky-WRkO!&TlbbiVE{>E^j!ha6aAjoGHg; z@a>F^ler!qTSYdteerx5bCK^V>y<#Ew&_>-WcJ7PaPM@pX&20c`a#|dCL1)!k+;eA zBb)3uHtMc9^>aa$u@pNP1mWnZ#7>RP^b-Mw5eNPPF99=C` zBVx5>YR4u-pY^ASZUY{DOXQKHw);fVnE0fM?~sOMUoxvWkhzq@W{#ZPAMD}~uogsPz8ota z;U&h}hw-Y%x+I}8!k~SMwSjP&r`S?G>!B?6fh8RaWg(DbAWWNJLxibA>d4zC+M4Ax z?PNPKd)}hB3Gs%_Em`|Zddww;foE7;bZt8`N9@j&?fzfkWl`E6Hsr#^Ib*BIVv8m@ zWa%3(eJ7L9F|1Ry5aRsq^Pwr8bU2J0Z1MS;x&H2j%1fZLn&D@j2~?@4tuPWN-mvVm zXo-dr>RP->qeBbL9bG$PH+x9THCu)4cPz?sNXQROt9ff6o2lSa7?}UO*wG-1-NYW? z0^OUTYh70^dX5{T?OY3)c~s5p@(ZN_u(c6K@^KnTT`c zx;dvU%In3?gc~hwm%JS0b#30Q{o3!TRaH9i0}mZIk&&Yj3%u)|+??K>J8--EoOb8S zU=hai;W@@)R&;ASJj{aCcIK+gix4Bb)F+h$r{_i%HAZcc)3j8jHqSZ}mFlW^er_2m zueK@gm%1h-T8LuOy^{VgP{EZ{bi&2mBwAvViEOy~=9MwI|0$z%>VD2N>wpOJgW}0c z!SI3Vr%B^EF{PH?j*gf*R%pC{(<5>A(%{wCtgk@DmV!^E-vFdIk9sUzUdpt5N_y_8 z7Rbpz4c5m(q>rhflNXV$P$+DhWH{K-t@N~vQlo6$9i#`!nT6j%>dQIw?OF>zi!VeN zvm*8tKvyb`C2gsC2@OW8{S5Q`y;(Fe-J;%XYd16?JK-&s#uD+~QJyDVG4+^Av{Fgm z>mH_6asesAtv3{-$o;bk-gD1GkijObVf2orWe%0QevA6;5o&Qc8SJ;!PBM*SuMghF znqzx%_+ZM$p%v@B!n$8ZYv!`5%I7z^&Fz*U0w;dFD5CF3kz$p~4(sNkT93|{@oXYt zCNG`9W2P$Gj?=7H47GJ4FYZTRQ$sc`@aLp`6gxt^yYHPi(>szuha3>^6YVvG$-o8f z<8{C1X0ILo<%oCN@;ozMSvC~TuRjtmfJoLqI^h0Y$3>R`D`{i(l z_aPPWQkA)}YQ)|8x)ic|)KZ192f^PEeUV1>D=@SS(m|O>oEob6ZDCvqs2p;SFzP@= z=yyby{&&oZ&MR9N->WoIO_yr5$n*Ix0-fZq&#elN7g!~I7IZ6f#k+ki2}389=6cWU zX#%w)=Zv^)1rV3#JHsO%6UqVE294=4i|J~m$T#Fm88)X&|6sQtroYYU~|q3bjurk|7cp2Y{B_-n@A(5N-B=R z$^d1W#m9eH-=zUIM6m(e#Ar-WV@s5*d8<5!mQ(*#ryc0+PWYf_ks4jN2H|8SX2aJ! zjv=q%XYaw9Wm_~D(bA0{Y|sxiVCPvLWN{NUV?}^$8tnw@-4u9HPK}b8C=NmmQVC;=+suIR^F!Ky?CKW{gH|FdYi;ix6S&d z#hEjW$em)8ry9(>8R&m^eO{Gfv!|!?5!JH5?h$)F z)%=^tXUBe>Hv@N@q4w}59t7Zs^>R1 zR5l4wx*^^uHaw9Su)RR)NgI<{LNw;y?>5<~*s;OC@m0(h3^v(T7^Wop>bsGdJ)~gn zTRHNKQX&CSiTgH=G0S#ej&exQvnlOaZo2iyOxwF>sIqKtFgYFrtju#& z$p23;Ft9MlaF8pHvx+A%UC3nL$b?ZWF_)|2joHEtcD zk~W2~q$9j38tgMvGe2*;nwhJ=Z{T~WDU$qcx1h%FW?m_?&FH)CqVoM%`^UXm4g6GX zjRY6HYCg;Jtv9`x!Yryby(}N*-OMkP3|#~T?2H#?GgP7k-yQXCQm98OUK$(p6!i4b zGlEBEDUqj&+bvREu6M8{rScm;VAnIF)GaRq6wr#VY{o5kx{{TU->(lmwrM>%TU?j* zwGnxY!)};vD?S5Wi0<{R0n#2aE(OgG6E@r3zwfGSX&o!P^V(mt;aSzUVB|Dl-}5b= z9|^ZGr3uftPgy^wpegid-J?%fyjlkYf11weyOq)Ce#nM_fL*`p|-U?s%Oi0Oh*4g$jWVNXWID&I?vhEnqoUhb0sDm{hd{5aP zLOO~d$6Q)jNwL)VnSQ{AvEOgC-}BEhO7D=Ax3_%4yU zE!@2ow3P!%HpS#SJ;nI)SA(SO5`xYa_!c9utDr3X&(TkoPG6<>OLN#)$jgvi41ZKy z5BvN=!Y%R})1cg2_r@vUflEos#Sr|R`qf<=e@;zA+S2GWtMAFX3B@nu@o}MubuAU9 zGt53x*N|h+gpTy!TdPJHopFf;`b_0!2|GK1u))EuytOZK&47~?uCbdXk|zpV+W=j4 zO_q~=i@HYnLxyCFCxUWeu9eZv z3TYe^;JhxAVL!YFPU{C@s1%!{!eB$;qNl6YDjM3P{X_kqG3Ab&4c^L9YIeb@wJ6Oa zpR#R!ZaS}AxLbNgwIKQO8f`d}_ipNzC-e;|YW&u9djj7?@_f7dk(v4CFdzPb$Hiwk zLz&%@a8%Tul`cV9WcDn2aRSCRiHq6Wq^2oFxSX651;YC3SQ;p(DE<}2?R7p`og(2c%N7;p#%h-y||DA~yiNoG0g zQ_$(vOhB?Z=e6fe>j64QiPp?6w*9?JsTiK9YgAK-BnLXvG-pV@m}eiD%XdX5OnX`Q zp4)wvt7Lp5G)C5Swd@lCvouCCOm<`AAq)!$fVX{Y+y9-Khn#{xt@Z=bpub*>bsE9p zsd$z}35lk9FN^kS!Q7yX$`aeVTGtoS*3%;a@^oq@Qo)O%bL^j+5|phg=7;NLa|*LH zUwE_(wzDKooz8JhU%08Z$;Y{Awhm$Q*8$I-K3R9)w{>f01&+TUQi@nhuyH!*Y-_^{ z9gZRDMh4+_cCpBC4N(G<_)0w8Z8m#rT%DtLI61t+Rt$f4sk$7M=QOoPBh_`LCXxF(a`;(LCNVw31Tfl^le#|jw zDa*;zn7p$!b+n@-P3O`>m8Yk7l|7}Bj}UX5U7J(}4DI{;(L2w#Y6ssmy!Go-_}1B# zY}%!+>4r^ZQV2O%PFyDDpMaQ8KBXoq#l^d%XS!_`OMFUG>SeI@JeV$;F-R=p)fA~4 zM>|5NehtLcGav^)kTVJ(1#`zcWaW=bfEMLJ-%}Q~MLx3>u;$7?d>5v@h1oS+?&!%F z;su((c#ue^C*0}qY#&8c;)!|z1|tj#v@)V3wOkBDsSU>qe}5G$;7+AYB}24DGj{kc zy5 z6^ZYts&ehi`$!g#XO1%bu8${s1sC`=jL9CNbDAVptL>T~j-3);hMUy=2#-Uz}jYO$+mSM7(_2z0HFpo4k;6ViEIZ{DamNiJ|?M*#}U&M`?qHJSovR29w4%Tpl+f6fXi6< zR5+jF_So7$EE71dtIN@kDzJ%fubcU_N?4F-zdkDVoiK%9w7fe0O%SGIxJJwX>bNgg z*+_&V>u22Qrsjs_z$v`L`Zgpnge13r#ql7pq8}$7)w3sq$7c% zK=^7%pSGCC{@~jV(c1WSu@j)SP;^pJZS+GV3KaTikElpwY-~T^+e#;87XGWbcTP5m z;|w0#lRnv9Z|paJh$*Y33&sq@ zMp4`23`9)I=aXv8OcbYRR)OTh)Xr``Iul2sjP)A5 zNEe5=cBp%Ipw=$O&HGd-G$VyzRbyF{;%Q#@24yS+mD%8{o9ztQkSi_FMl%k@*~n>B zCJi%B0k6eX@2fVm`>(gQhC_8U>tlMeiKfU80>L2&R`H0XA0jk8 zN!sR&IIRAlYsgNE--#i`eAfG&VKb%UR zy<{i@9$p~j*cz<}Y*cM9+thH?W|zi?A2#?L)>o{=dV{MGsGa?)qSa=P_;ifl+rHxAvYETg5hHiASb{KX&*n2ZmqD?lk4rxRfWbj-ALcLG&zTgzhO*Cs*dZiqojTC zP0N6i&}~_vlU0W2IurtvnL{x^FQ!)!nesJIM7=c?b9Pfvli6cY=*dh9$3rv(I>}B>RRgt*VR;tQXo)^{-bL?g z?uSzd+oh*9h`Nbrpak!MVzjNYsg4*ZKMR8uZWRuKGD92G(Wk{m$IlaSBcp4C{Cm8)vFD-w{iyl<;6hUc)vc+oD4nKQ z$;*cV=4T$`omIK;_w}Uh)mx5E<>pPd>Tht%Vud@6h0{=c#aoJ+K|7sI3MogrBA#gNwuYt|4#J1Nz~kh(X%d$4RU z(>BfV4{DGAih_P>b#$E=&D}Cad+rJNI47AZt68zluZUD?hI(*jxg` z_Ad`qd#J@;uNA^?cc*o8s8DD5<92qqr+wt>q^>-xf z^v?3RA^wZAjfb`i^SKaw!JL(&@@4FI%?VEM4o zY86xCvyy#wRX4Ubb9|5D25WN(KE4~F*DT|!ckbzM`!=5aCeScuKn}cWZz!|g8dyY@ z&38I%&{HB8f+v&FGl45zeoMc$7AxxG zk3-^P%L8woUUf3b^qX4?C^hUpf(6@_y-;U1SGusAu#B;IZ#`O^EK{Z8%N9(a7Oofb zffy2^={*cANMOn`YIq!qSp49D0v&YyTnAFIv{kPrsJS@o)H0C>wC#l+q0*JZ3F19$ zA(0dMd{&iPBzRXAT4283KmeGTNr>B~9})z%@tbRVG2~8WGOBi%eCgP!;;gY9q7T|= z;u7&o*nK5IN6^@G4o`?Am_!2E+Lb8OJ>OF8Pfap@YI@&3LBsBU#FIEeg;>DH zVvR&UndfpLbcXH4Q9V5>Z5&?U2=q&~& zn9L9myDAvvG?3CvnHt^C-dEcXrT4;!l^_Ac`2G6y);1cdN|Gh|g$7nnO*T{c-ay4f zRxN-LdlC4jJRzdB{?~@9_Oh@@mQgmeJ-u>efzO(`;1h^>TAZUN}cW0slB1< z_N>?u)Ubh<_syPSZ+X~9GAf^1`z5rwoQaDdaVyp%iM@a?B?Xtc*r^dU#*7(# zrg^dt4;kOjJ!ZowacSOTn(?fg=X7#RrTEL^7Ws*!gKJ;E(t|JE9m$&J`P--(t$yUt z*?~BM3eIEk@YC!^hlXo|`b-y2`M33YjP0uE&s@C|PF%L8vm20ah z>UC|kjCQx4!7FH6Lvwi)>RBgG&Rl$~Kc+5j*5i$+lB_K0*?q8A9_aY=dKmo*6=E6R zqe!_vxP8E!Kqe+0bVB^V>_*K+AI3vfaC}O|E}LrJLQAHsA2y*}WbIQt`ZE8b3(hsz zdQwggUu%gpD+)N2H$hhG^@sww7kaXIJRkAq*jFGI4PAiNN+4vx+P~S=X)2k3N%NldgHbdy98VN`b?Fatlc9vSUpnN(U#xS zp+4rau$JL~Djii-4NYtvKF6}btnc*&@fxvnZemX&R;5V36p;4Oi~iR8-2EIhjZ~IX zD)kB_r6NU5!1mL3$3ddtOmsNN9Jq<`H<|UlVu4uC`*m#eb6ALBKzCl7PEb!jAKao5 zLHMX&jQhmOTAJNG(BX^LOnh6`RH6{P1!N{W7-bS?)ue+4A=x z6kI>sjY?5b`?l#ti$~KQD@4lpsrw|QrH*EV7HX%sc?o9|m^p$9#cyXe%aKBrUi;>< z8ow;x8BICj?O9nPThzRfE*EkPfrYFPO)>gPtlcnWSy%i-BFM%&qC6{jy>AS94#x2^ z**>`R;M0i{k7$lQ%H$QMJ=!rJ0bQOVAgjW^k0#BJP?q44X$z6v#kYP`uA83zdiKOd zy;La^;w;8Gm}T^|!&@PqtTRc8bsh;~Tos6Df_Tzj-}R-k?~eE&vCAK1VMQt z>*h(^>0I939kWQGmp9I<(Ceez7tlv4(O{rV=}5X2#KXcw_uxP<{!o6jBvkp((C7cx z|95q;d=Hydia-2J+))J~)%|3I{wMqgW(Ru*R|iNQnd|?O&&A%}*1;HHX8XV7gQg_8 zI=?b@`XBfp$p!y5NJxT|g_D`{|AiC!`snZKflB&6_xDd+P?h}exy)_tA(?AG$M#Q& zP&EG_p|J@h3G0uHF%}b7Cumw1G;abP@}3L{nzjf7eZd7S|2gFX`cll<#RHO>2IXAP zSpdv&Wdq2jp87mqSrkJtqof)Jg*#5{?NmlW)0|2 zu#wyctDC&Bn^|ezrXX?{=f}HX1#6p#jTd-y6%sDV;ZX{{cGonL6kyyZ7+SKw$x!Vf z%;{cc6=1Z`&$DdPEsxnQN0H{Lphe^;;uR0V6ngvoc;+detrSk?fRagC!V!Bj#j9#g z?PUXXG%-q1qb7cqLO$!++9R7R#o-Dcesbs9?pIEk1P%fkNrxxuI=u>W=%ouX-dVXk zqgKAH9zFvMu?oa;CVHxpAiVfOt1k*(!yXD6MAJQhE#|K8STmast{m`uG1M`?_)A+X zW16d!^Nxf(ho656OHS&QarB7kBu`pML;{4PUz94t?o$Krig&8IP#pP&MPp$%yZH60 z811MIx%P+mmLMUj(1=L`H-mdz_H6$AeEpIfw#5bV1^lf&EbbudK0rDan%{0zP*AsH z%-7clY+-Nb4QBH7dA!baB5Dr})u!>`T(06(?QMNpAu z5PvnOSJMUz*yZaJqDEoX(OBmj!IiEFM8Gs21b&A@OGnlJ1`_Wmpuh>HGHQl-XyA_d zQJp@0m!2*CWd)vdYF6IZocz*+GI9U+ph|+_aje48G~{uNLv}5=Cv8oq&CGDqMUIOK zD1nZ?PuIGKPt_m2>>J_nsc%v@TDxmmC9KVTIpsQ4$wU1D{>Z-4mP-Ryqx`M5D?q#* z{-~rdaszeFWYDU%flj*7@ukWH8&aA<{A=^j;wY&)GR%q`NTe z+HkR!A_Ad&s zcIHhEU}|S4a@)bq#Uz||df0$XK#P=KG{_l@b<2o2F@8v9WnVfKW|8pnB*8UNv?Q8S zVT+>Yj6^T}T{sun*`=(~>q(h%>Y8x=TnS@IDI3P3d23~(7oOU>%iaV*$(?ZKgdv}9 zf{c5_;p>%zq@PTOF3;Xf2B8TRhP@>eT1?e zHw^{vjAP};$CrYxz@BS<0%1<^p#b?2SX~QiVH(RI*?s{VcS|*C+jYtJEmL%KW~@xa zFxo{_s&MaPyOTI3&}lSHJTPftkBtz8h^M9292YEB_a9Sv=Qw8K7)qqP&mwc|Jjw38 zB2PMhov|y|#w%-MR)+Xkg0QBVYO|f^`q@-qp(LU-N;R+50Vdwnh{faRrgoKf$RU{s zs#VJeh&I@;FfhxIoJeIkSU4P*|NKD%bOZlYetzEYcdoyGvha&T9dZfHvW9N(Ke>KJ z7{BLbLQ}1Ol`)89zb9V*o%8p!9BAI=uhNe6mn_boj6c8E_*5~l>ajlH0u3T_-OxK-M=E|{}#pmA5eZp(*G?={y(7nimd-Y`Dyvk z5&R5~A4t(e~7eyTIEmB-<>5ivi?=r>3)y1|IYWjJAk^Kg$@BR-DqdA)Z literal 14558 zcmeHuWmr|)7AQ(fgLHRyNSAbXH*8?jus0wr9ZE?fA>Ab0%9&E=K!2$&Z^>9I|pzMM60I-J> zz|_gf4rp!)20A*hx;a>|IGTchAQnd_fP;mjxvM?E0n7q&asilHfUE%ku*yGZTAYr- z_z*!sJzRJYni|%w_GS*IKsyjC_~$K)lY>>bijp+S6M`oY5ENM%2{p+79w?|sPzaA9 zcOGZuxlm9<60#Cv8ZXlJ(mg~q#!0#lN(Z2z5fHN9y?Yt(F$RguhCnwFn7F29vUJ>1 zxeG`Uvd8MrQ&4?a;Kj_o-a9e&~<3QkS zd9=})85FK2uAR7{`_f)0slMO*+Lqx)n~y(;&cWd3a`@n;Wp$w&Iv_&bFsVzsOz}-i z+}ZQ5B7qBQDCK3o+uu{L_l-paOozi=l6nbQeK^6+JvJ5ZMvy+C8Tg%lE0Oijq>cPy z&`NimFpm^kiFmk_3^iYkuOI52BgEh>$ZC8P^R@8s6{~i+_eD5LiZCmwNSkZ10M__; zwuIY(+2zNr=A!{*`jR4z^}V56PUSTL8P%CZo(}0m?R89o5o6Euqj58buP?F;_t#$2 zWES>hm5%5)lwFsEUKaJ25bWgc=j1$2*VIgDv*LOYg~R`JU4AOnCqxoy@0H^mCLsZl zN%vQ`^2EfszVUs|i2@2m&{%Szs2Hfqc}1cp=wo8(0*E(DRqQqdwRA3(Rg$2z%T|{D zbNBgb#Z?ue?$r_Z`NGYi@pVCKMm|FNZF_Mut$PEBJ}Li>iV>(%u08$zmhtsQdCSQV zF-sKDVEeMM(kfS5d15VscG-ZB+wIz^u@bJM0^>$TQF`6f+pAUp8_H0|{e}Fz>J}~{ z1=rk%!(vrqhn8;==$!vARSwdt$b&4X>@nS>u!AJ*r{k^1uq4!Jr2#q+9n6QfT}=W3tNRAV+iP{ z9dq~;isG`!3vY7=C@dsSw!;Z*H{rxNd=4K(wbLpr0KBm)xT5q>Y7b0nz74&vQ)Cx{rPL^zq$y2}a$D)LG-A7)=wWu?_B?|!&gxGWJN;_+Ee zEF33w5fPlue=$y*|TT$*{g?sgWR5W)98Sf-@Qs(Jn4PhF?7q^ z{Pr+JahQZVLZ-?0F7)b|ex}Q79S&pe@ysUR{vFb_IsEATb2-A~FP{Q6y!zkfxnU>d zN#+HwQK+i2SEx}{Mu)q;SZa34f{tT%6aTcHz7Qr24uSW0OC)mz47t`EmEcsZU0zPXa5s4y-9usy0lAG1WRjga+SFMaX z686ni3dchOGbxRJJ5e-Mw?@KA{G%z}F4JpQfU$eV({9ykqRj0k(bJ{NP{Y#&g)f}y zD9qMu0(}=nid*j$d&=KGt31ZxH~OOe#n?+w?|3{uXVo0Otu(Ihj_CgAm6%&<#be_; zvyxKTcIQP!B~MWr&B2V`;j!Kq_s`)SeBNKEO|4#7Wv<$^a=Y*QYIIiV7f#bJ;SW}0 zpP1-yx&dC9C+)b}Mr zGfDL$ZqzzClXQU}?J?%Sd^|KtMZ=vTy-+AmpH}u=f#bW29y+ggqOgy)32tAXjk^~JZK-4_RZki> zwEJ$@9b)385Ei-9afjT!SbzhgUnS-(S_wtD)&%riK-1xqAX5yes0E=oHu$eY(UbfuA(PE2MN*kum^foH(bmscNINu|t(%6jWGL z_I1>t!qm$5bP&mJjuHFP##cm3W4kV4WO=|lfm7XPvf|P~n3jt{G##|%x%aWh`R=i$ zykebcQvqxxfetJXZF{TagE<{d|Fq4r#<9Msm(syV!|1b%S8)a7b4BWnfKp#pD^vY~ z^O?aZ`p}{IRCA^iI_`pVS6fifn^JcBAd;-aNn7_jAdjuzT|jPCV3an7Vv=@iO4j^D z+IRzZX4Bx|%~tNY03vLEoMCc;SU4g__#5=Gbi;>Zm6tg(o=`Ou6s6k= z?ejD~fj`tyfXl+%!1)k0<`Bn>5F#bjKsxOe4fb65Bse0XU)5(noEV$&CDyss)^(Oh zV);YKB2Mmnxs{7}+5vx#+50jorQZ4uhF3}l{u3nEpLwYt?wrh$u$23IWc{yI{UD0A0vH~@&)S6ggS6OAL#-X_-qHLp^$j`8Ti)3 zRkr<D!#>DOmwk{i?1PKav39}=ySZnsdo zT?q}&O6TWzL8kKY=UO+Kd*(Sk565%ILbWz`fZTr|wmOQc9_@!N zENqM2WKU0!!QL)uQ@bnq*LahD(rkT`ll98)cPZ*7%pIoI;BcCA*d)YTgE(QO(qz*Cxr!y zzH0f@;O{!=+3o{4G|_p976nuphlcOzQs3rq^SAaj*UXOicd$7Mlhc3cDYkIdadV4r z_W1Y-$C7Y49dSO-^DJb#W34Kl+x=BT?A(s+xBkgz0{h!%SXev}?&UVV)U9VERuY%e z*RDtF)zWF`i60pj&vXonHxk7*2O$hQ7pIOd9{V@HtJOU{9;IEQCarO2ZmT*-D#%C~ zx*sNUj4^CE{kU7zs54~5rk^Z`(_Z85@ZrdI8fhiLs&??pVs$#nt0IG)!*zLpd_|PE z;rvX%hhV4t%MF}4k`mj~c>e5X`WJ!|JMcUVI)eLC!y%U8Vpa6|cy<%<71>;*2nh3I z-#*c?E<`}YN-r;X&$7aJVu`dPDpKxIt-#YDtJQw?@t}%dcjz0tKG%00A3VHGc&G{3 z006U{RE(RbaWbMJU8nniT^4B$+i`14oAl|tO+{t9V!i9R@M~1}0YzCs&egoF{Xqj- zS+|UiQNP?^IQBpf8nD$4{i#bs1M|3hZ?>$1rtT$!zpjwIFHOyADy;qma4LKdclnv; zfh>dG?E!fs&bK7T=^om>%%+>&eu4Sr4i~q~MJCg29@9niDna=-1Le9+7g}K z;iqwug?NeEz!lD{6bBr;C1n48d)@8&ZmD=Jk1#^mGI3?@v4*9-23rR}c1MRNMOQZY zXJkvUnPAU}u?Cll+;6FeX~vq8vz}-EDPM8ymjdF6T>_fG!X7kT0UB2KG)j~xSp&Ki zL|ZVBBs1-qkyfVF!_{fQo-;`l$x~)Unu4gPQyI)u-WeTX(!5=>8#`d*p zNXDrtMuGT^+uFP0^W>?!Y>jVum@t`)B7yhf%BquB!litLmL5aCWSLEWK#e*|>fAF` zza)vLQ>|q7jyA5gfr+nxswDwrl86XuP?ap`Otz++0X53XRR#O@GAv7&;j8Vn7aGT&3T8E{R%EnuS?Y!&Qm)oLS&GEnGKwsH-W zao@dSyR|#~eBI-nKiDcKDQ<|k+|(lGv~?`8Wusa2 z7(Wmmgeu_Y(L1J&+sf8XZK;F^r5&@K=rnxEpJRRshn6=~!w*S#Yo2x6U%%-C(<+6; zZ1lex$4~^GwK+VhlQl-fxufp0hcw^_p3~i8ty*re2#;iI_^BAOJtLu}d`)}#7&8)@ znMXX-GELe;V`=PW zszG3t=U}4~R$CcY4L5nef`D(#lr&;}CKER%I_O>-yqeWPYdX!Rx1hIi*Y;y>Clg93 zLAMuebc`RSfzTv-)4DTd+QHf%2^0^e3JbuajYl8rhqg=V7~;d!HN3RO_Ea;f{}0lG3&z zaZ`C#L*CO1;e3{oJb0n%If*`7p|d^nO5hy8CnPB1MnyWwr-RLpa>7ZHKbb%t<72{{ zo_I9I>Kos3QDnY<35v|f`2>5;Dfc4KkeVXjFS#Nok8~dle=I5zoON-tJz?q@LhdC8 zbhd2mOQEmbne={^iA8|@?h83QoK)1Y=G?Hu1yVAOV`k*>)Ra=p)zfILZjeD`X(Y-xs0kEAwPM-TIc3USW2&3D-*wf z7ScxSiu3Wh&Vk8Z9QobaK}d7Zw|eeT(d@{hoFwn-*XgEJUmF1;4{b+Kku|Qid9J?b z@#COXX?{mLG2e3I!Oypki&-=FEW>;6=azYZ4p1R82beAcAMmi2B!Xf|QE`Fx zG~r7!?nkqF{EhT=jHs`lC@2z}Zr-jWp08iVMdnfq*LX?SIvFanRwhA-*}&0=*>H7g zsW^2Oo(t9c3Tkp`2v9d#X-_mkh(O1Y0eH7))}=o5-?MESg75W!<}tQ~@5{-~GYUKI z?tD@T=d#}G?paG8r1?X@Gs(D-`CkbNPk+7k8@e&1o@5*iMvFxwzRT~%oo0NHs)VeT zcXL21fgV8(OEe}M28JF=2R9W~UejZ{C3>u%M`&N}U}zf$BG_XZvEtHx*(PRUI^^SZ ztT)TAce~mt4PTY7If(~5ypBLh8sbBX4m-k~8na@Cn8pM%m&vPZe2G*m zeXD{uS548uo_&A$2aqlve^v>~4>2bgqvH_(GpYK10W|o76yoJYksFNcp z(6^M`nEDK>K`5|DFh%rJmg3bu{}_+ zP$CqkJ4~wcy|Fu&EA?o%q;^q~WX6?625YOL4DvCZbU$3>25B7(1u+yGqFR1V6@uor;ya(E%-qk_=Nb#Lj66H;m0Vc& z0er+z0b?)_UAXZitox2_0ukptKH5i3Hn;|0&njLk>KMF3Ri2A*Z%;#g@OPcQB&I@Z zlTuIwNMG@tiS=i^4N^Zsvk6DhttIG3RUdE%wxG~+Ef+C!ky(`8q#4Dn2oy}(GxM@L z%#?0|LM*C%IkOj{8E;U}|KN=59dI(=(hi3)A>Q~6L>5I+=55#nFHgixU5V8yx4_p~Y{Re4aG=c}&KJ+YY7myQuFz9~BhB8P(t zx2lbursAReAwiAYRtLV5FNj@~^_1%&v!BOx^k-Lqa!2h6mlNs8VOG>?Cg#`9_1ifc z3X|l@xrc_+51x>XAxLaMMV4KNwFAd1p_Mb5RzeqQc1KQ-;UU2 zFW1Wx5=tzx8R0up_0iw`q*fKq_uK7)V47gjmG08 zGFhU!ASbtDPY^fW6_0rmpZ5?E)H2u{ZZTh58Wz`uy!@iK1v=$$W_uIpu`fURcC1r}^eItpfc53^Q2y3CjY+6PBk9FPTmQ&jO{00=a2o_a+>SyG6=c-s{ zO&)vc@gO}oB8hD6dvWVGErRbhGwVo)ge~U|gJ8$z1Kj&ns{2QI`o=Gc_)HgAHB6Z>AHDPDWMiO{N0FX!U%*MfuC z@j@y_jqM~l_KIbD3Eqd-HD!4&Kn$)-nr)`G2xf^0f1@ce-it6lwMZjGt6Z(^`3~D| zDX0I$g9|Qj2n#&j58veZdf7?Hs%9k5S5z8t541MRtO+fCX^qbji=SX@V=Z2!|J3!& z?pa-tp6+&XCjEGy5dOlnOx~OF1Ym^+)u~c4?YJ*6A@lhqWU7=-| zW;t_vj+46^gEg0Tj6%yLxOB1yV^g_lCbt7ibe-Y-p$wvF5r+)z`G6(^`*+uEjB?d$ zqzwWEvd54pdMO=K7gnCu{Qcw&JTdpI0a7N`tc}p8lw>#47%zLx;(d&qv&g?d-wRP# zec8672g8dKx;F7Arf>W+vy3aqF{< zCR;RQ-MRRMF1=5H$7EcpxVua_M*iD1GT!2I1RcMVlQ*%D1OaKL@m!f@aM5B@Tb=K` ziQ>|%4_vOYE6TeQt$L^ruK5=IqJg*&n?drZ4Lv|ulib`!jV@5TYlUaK(_|dcCEI5} zVvXEBnv-`~9gx@Ako{!8cDJJmHHG4Sm;{^(qxh1{9=a7H7g6uHL0X2OS$De2Or_xH zwdWX%hcfzc-3?bo_vCB1hfd6>)5!MwSme67^z2S-E5r`|B$P7O-=hbH>$v-m z1a&sxbf*7*{l991dua24 z;Qi-qj*D#R5-*Zm#aBpA3@)3Wr=R-XOv09HjX`%yvp#uQQVx@M zf<8Sw+5mpPAB&B+PZq1ep9VulyvB$3c&LCcG$(ybXToKOu8mNaFi*U@ZiQDkTv=JA zbnou+vLXF!{khO8V`I531EG)g6AV9mIT{NKHS<8DgUECt{dA#T=t<;K=l#%|({5ZZ z=xOC71_aCn@Yx_@ZET(*zy6a$)(Ty~G0B&Pyf-ZP3NSISAzI&x+_Ls_4Rlw&1>fSW zN`A~V$r~WMm-eZp4;1zj5ELS~eX{AP-gjf?#8Zm2fFd)MHy7&l{Z&30i*XJ(DvG75 z7Qim?fO!q-P8k#SC&ZDGL2dW#KYGvq@UKD?dtP=&sc7jLD+vp-15CZOIs0=|%N z>Gy>8EcC}La6fMq7xSag4r(CJ+2*`b0pG)QVmv|>R~>rl>F=}uj_27XxgYcemhv!j z?k1>X5_=zr$HTXfD9IR_t}WXa`(ZD_J<2m&&h#tAceKwYS*m)Gn=mJdm4#ucn0x1` zS1(J+hbL%w%-TzJq1@Q zUJ$ti@JohdLk+S`i{G|?2eZA<7YOt=Gemi@79pc3^yGqQg^{e4Md3A`Y_J4lPIULQ%bfexZvql3N^{Sy7>unZkZ z>x-K)7DswE zskk2!w$01e@tI1EmwMpU0Pm(AZFH~iV{Gi5chCu%vv4ykp*(+Z<VViC+iFlXV%ib2HsN@-=MJ+1bKZ##zTBw*Az=8j4p|six9s6D3Upiboiu< z11G<_vR%`+JK}rd(_emd^z4pQMIIhOh36!%1sV!U0J0z9-hTL%WE{_)T`AF|c%t=gc`Zs>`M-eij0njh=L)?)D=J=oNb& zALsVTW_1MNJ`tuhG3*IWUF< zNuIt*ot-ng;XaY~s%~XfqO}!O6R>KA$MM$$j#NnMsHGd!YGAa^km2P|96j+2xT+eH zr!^VM4LZ`*{r&wtG6ElE3$(QY@R`#jf-r~`q^h@=Y+OOvF|5L6JK_w*-jYGjxMi{e zHJM>!-#s2358vA8soh$e9Gnqoa+sjxqQ%Gj=3yCsUBuCS2f51aqcnKlx3XqWl5zPN zwau(0^!S(q=Seif-{qZimDSk}@g2Ogf!5!JbMSU^Bbh#ka`Vw>!O_52Dx{Sj$NKyx z$~glq7S6L8flJ&aN4=GiLNSPlJ&clZKc1Sz_4a&6+cEC-s&#>aNEy+HID^J+GKMFH zl$9q2qMAz#Rrm^JxM$b6EPVZ$yZeL9 z=N)G#7A_h_b-SD!51cEOG3hsK!lv9EDVUK?GhhuH!dG|4ot@?#2I|lOV<@?mVxjbM zGGVeEtEUO}mGj>}`%ZpHYVS9B>{Efg9&eu{#(%qraWg1lX*|p2~ znsEz2|E&xDJ#Z^QzI7=)*Gi#UB}oKL*5N2O{BixWz@VW<6BN7A%B8T+#mxwM^6qR* zS(6x9bn#MsxQt?7L!Bhw?fE|^ZakeToP4^oGT6x##rkG$(S4EV6V3v5-SL*UuLnWh zrJ?Dog2T>N>XqSD+}O?Epy4Q47#K$a@w0Z2dCID{E-#hQZ+I8w-ozwDtcL}c*J5Jx z!JhYc`jPBkYzTZ3dV`c1dQH(vIrju*LslU9Q+i}rrGzbJoe-}iwz^lG3ylTq*W|u8 zS@wYihxuq%PC}@lsCF!@EWLCU2a8fgj4nOd@F3p?Hsda+PqI5skGRsET)RK!ZWXHd z8Jr9gJ~yKOU>i95lzkd^>re#{puNLnXC&~%D8`7El+Wv<8evr~shFSuV*x9s0%>VEFrqytWW5Yq|E#o4Oj*^U~X5dbQTYn0$6 zB35NfKH-F>e2bxx4u;aEB@|ol>8^|{#M_oNvh2y96@wDPquvso0hjQ{eDev;_jRiU z%VkCHT}D@YMXQh=O7IoWYx8C~a;)p=MjeW-=*e_H-XQSn<0gp|=Hm*$?w*}zv_y0# zVB!=XJ56X|N^TqMY)>51XAU`TB?b|`Y^^%kO?`X%ve;wFx}37kK6!s+hxV!x!{hpu zNH^)+7r3-7!Yd<#@7(XE+?x08@v5Hm+35!;Fg!Y^-;-_&O`2TK)a!K1X0FJ#{LU~F zy^K9MS1)LG_tx=k<-PT%`>3wSv#>*RhBNa%+(T5h4jpv*1OH;0qx33QOlDG`2LW}# zAn}~YfCr-yZats#-o5FU=IIg#(2-)8*B;t2*7fs1eBndw%>v(HGF-Mb~{5hTjF&2kyXyd_Y;={6v_TMF4uHjB!eP`>B}Q*i(Cl>bJt1$I!hPfH+!# z+tkvG-8pTUP2VFhu80`5W|+|QWm^SICzqIlBg=TWc8Oyce1v@a=rmTQ-wo8pK~xRi zNwc#I&sBHlRg(M2Ww7Ewdogj1vff_(ZRUXSJ=#M*^YT#egcS}lcx3%w{mjF5HxSsv z4)9}eIj=h(HOBL_^*~)h7tvpWCPnw%KqaS_YLFhHmbJXsfnwV0S6I?@oFWEi9#odHmCbnAbn-AI9}S6|~u$zVv59p#aB z5x`v7SRzaw^K0?&>0``LHk3EjSL;lRkE;iMRrKmg&M8J7Fr5VBs-94B4WXReF?kP# ze{OyhJ=9??VP3%7A1VPoCkP|)(w$+AIkiMF+S8Z7#ejo_I2P<#1?`HnU+4f(>W(f> zt^N9%wwLVbra_34-O^VWfq-+|GCen=dqANWOP*M{`r&E{;{kn1#AhPPYCdl|c3PV! zs`hm@9@gntr#&9EfZH8@B;}k4={#gBYOy_uK4Tr!t&wWlYg)4Nht*vKXJzpubL3dfX;EIH#UMHbGUgu4W8b&NfLK{wP#L74*?Ul1!&_TqxyDperh?93DOU5-%>9aYUhY z4ME^JtBkKp4TdawdVLVuAI9Bt0ZNW2u@HxDwkJ|P;ArJa0(<6aCXb<;@UK}^~ z#%O(WdUNzvrH>lH3lm~tmLetPa%hwp?Z}-)1deD&1oI><=4!>yu6t@Nmw0nh`|gJ@ zXL=q**z=pR!eN=!U-+99SnlH~k0o_1Uqk6+bzJ95y z95x|WM(z{DU-FzVSXzK#bCihgD~e!RskJY@gmM7vs>;*gE9Ix-Oi!JTr>cYeeV&$` zkV<>f`OMt3>MD7dVihiU^7I3+th-v(_Jcna2oc@2bq@MH^f3a^D9TKbKIZLTbD5tz zxzlg<8Mq*`oQLbjPHq6$^kE_+C<6H*a|5`5AbYumDA-xpD98W~=8hJS^$j5kO${k# zUJ4Q6CxVWamOyg=|Ih8+%#eNHreqLQ2N3@suY@RET^#s-Yy{_bFtrDO_`&A*=K>rdDR3IA_}dVu}ANREzb&nT?B?gI$B2ou8YVpZ%F2>u=x$EzJ4<3xS89o1LExg7EX@9~=M{z=uUF zW(!xBADo0$G`M8AxfHoM)&HdZUl9L9H1{xv3{!-;{sa2Y>OWwu01f~Mc}Evv1)!M= zK>0@$v2wETP$>W%TwfT!;N>Cv+Z$si7e^a_Ihd7`hs~ayO57D_XTi+zCxc(K{-FI= zEP}ug1wde+IoS`BfKAQp0L-!us!6q`$!e+M8Md zK&;|Gu)V1h=zky+{07;{(aF{6f$#sogJg*R5*1>7D;EF=^uNXZoswWjN4x)x^*cEq zu$)XC0CxXF&fjsfv~z^Cik~L^-6}2ZZ?rQthXlbN(a37<>f-X}QVuj^)d&6|B|<$M zEO{vZ?y27?@eqBke>2(d#KDG8Rg}~aW0qBtVzoDQ09pb-Kh}}T)Y~0Cks-I7Gg9pP zmlYs#?`4g&zPpB!N_&ck+>vi{?<wVNyAmdq)~Fnhs7?_BfOi6`S9Emq-x|QB;P_-*@j>(LpV#SZqTbDdsc2U z2j#sFzk4@5ni5P0lU9LzdM9DCYB?qXLdhd_r{5eO9A9QmkUmR%5`|;oJn{u!>M-)^ zP_f?l!5i-SK1W!OprDo@y_JgmqsLF7{{2kS510M*^Yet#e`5XTsiVITpfn)2|8@rH zCzYQ*{rg(s!-s%h1)lhyp9TIC^Y632hqc6C<&NwhD~tb$`1daTVRHDZSVDsQ*HrN* z-oJJDzwr8)AqTl2Jic&(56SOW8TuWaf26{Hr}U7XeicNH|2ERE)cEgI{;8M9zfk#^ zD*v6%Kc#X14V_=9^A9RNBl|&zpZV`0dHyP8zoGIksq}wE(?3;&;rwqy{XLQXQ@FpU jgNIc5s|Z5q{5G+w$iqU$!B9}>kUt(6D5y7F4^RIGT@Nx0
'; $permission=0; if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer); diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 96c111f2dc0..377c06fd8d8 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -420,6 +420,7 @@ class Categorie $sql .= " WHERE fk_categorie = ".$this->id; $sql .= " AND fk_".($type=='fournisseur'?'societe':$type)." = ".$obj->id; + dol_syslog(get_class($this).'::del_type sql='.$sql); if ($this->db->query($sql)) { return 1; diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index f174f5f4a60..57cffd387de 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -36,6 +36,7 @@ $ref=GETPOST('ref'); $type=GETPOST('type'); $action=GETPOST('action'); $confirm=GETPOST('confirm'); +$removeelem = GETPOST('removeelem','int'); if ($id == "") { @@ -61,6 +62,40 @@ $type=$object->type; * Actions */ +// Remove element from category +if ($id > 0 && $removeelem > 0) +{ + if ($type==0 && ($user->rights->produit->creer || $user->rights->service->creer)) + { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + $tmpobject = new Product($db); + $result = $tmpobject->fetch($removeelem); + $elementtype = 'product'; + } + if ($type==1 && $user->rights->societe->creer) + { + $tmpobject = new Societe($db); + $result = $tmpobject->fetch($removeelem); + $elementtype = 'fournisseur'; + } + if ($type==2 && $user->rights->societe->creer) + { + $tmpobject = new Societe($db); + $result = $tmpobject->fetch($removeelem); + $elementtype = 'societe'; + } + if ($type == 3 && $user->rights->adherent->creer) + { + require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; + $tmpobject = new Adherent($db); + $result = $tmpobject->fetch($removeelem); + $elementtype = 'member'; + } + + $result=$object->del_type($tmpobject,$elementtype); + if ($result < 0) dol_print_error('',$object->error); +} + if ($user->rights->categorie->supprimer && $action == 'confirm_delete' && $confirm == 'yes') { if ($object->delete($user) >= 0) @@ -214,7 +249,7 @@ if ($object->type == 0) { print "
"; print "\n"; - print '\n"; + print '\n"; if (count($prods) > 0) { @@ -224,10 +259,24 @@ if ($object->type == 0) $var=!$var; print "\t\n"; print '\n"; + print $prod->getNomUrl(1,'category'); + print "\n"; print '\n"; + // Link to delete from category + print ''; print "\n"; } } @@ -249,8 +298,8 @@ if ($object->type == 1) else { print "
"; - print "
'.$langs->trans("ProductsAndServices")."
'.$langs->trans("ProductsAndServices")."
'; - if ($prod->type == 1) print img_object($langs->trans("ShowService"),"service"); - else print img_object($langs->trans("ShowProduct"),"product"); - print " ".$prod->ref."'.$prod->libelle."'; + $typeid=$object->type; + $permission=0; + if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer); + if ($typeid == 1) $permission=$user->rights->societe->creer; + if ($typeid == 2) $permission=$user->rights->societe->creer; + if ($typeid == 3) $permission=$user->rights->adherent->creer; + if ($permission) + { + print ""; + print img_delete($langs->trans("DeleteFromCat")).' '; + print $langs->trans("DeleteFromCat").""; + } + print '
\n"; - print "\n"; + print '
".$langs->trans("Suppliers")."
'."\n"; + print '\n"; if (count($socs) > 0) { @@ -261,9 +310,24 @@ if ($object->type == 1) print "\t\n"; print '\n"; - + // Link to delete from category + print ''; + print "\n"; } } @@ -285,8 +349,8 @@ if($object->type == 2) else { print "
"; - print "
'.$langs->trans("Suppliers")."
'; - print $soc->getNomUrl(1); + print $soc->getNomUrl(1,'category_supplier'); print "'; + $typeid=$object->type; + $permission=0; + if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer); + if ($typeid == 1) $permission=$user->rights->societe->creer; + if ($typeid == 2) $permission=$user->rights->societe->creer; + if ($typeid == 3) $permission=$user->rights->adherent->creer; + if ($permission) + { + print ""; + print img_delete($langs->trans("DeleteFromCat")).' '; + print $langs->trans("DeleteFromCat").""; + } + print '
\n"; - print "\n"; + print '
".$langs->trans("Customers")."
'."\n"; + print '\n"; if (count($socs) > 0) { @@ -298,9 +362,23 @@ if($object->type == 2) $var=!$var; print "\t\n"; print '\n"; - + // Link to delete from category + print ''; print "\n"; } } @@ -326,7 +404,7 @@ if ($object->type == 3) { print "
"; print "
'.$langs->trans("Customers")."
'; - print $soc->getNomUrl(1); + print $soc->getNomUrl(1,'category'); print "'; + $typeid=$object->type; + $permission=0; + if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer); + if ($typeid == 1) $permission=$user->rights->societe->creer; + if ($typeid == 2) $permission=$user->rights->societe->creer; + if ($typeid == 3) $permission=$user->rights->adherent->creer; + if ($permission) + { + print ""; + print img_delete($langs->trans("DeleteFromCat")).' '; + print $langs->trans("DeleteFromCat").""; + } + print '
\n"; - print '\n"; + print '\n"; if (count($prods) > 0) { @@ -336,10 +414,25 @@ if ($object->type == 3) $var=!$var; print "\t\n"; print '\n"; print '\n"; print '\n"; + // Link to delete from category + print '\n"; } } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index a8803d6e5e8..3d5749169ad 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2412,6 +2412,10 @@ class Product extends CommonObject $lien = ''; $lienfin=''; } + else if ($option == 'category') + { + $lien = ''; + } else { $lien = ''; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index d6666495a14..0c1b8016938 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1455,6 +1455,15 @@ class Societe extends CommonObject { $lien = 'canvas)?'&canvas='.$this->canvas:'').'">'; + $lien.=(!empty($this->canvas)?'&canvas='.$this->canvas:'').'">'; $lienfin=''; if ($withpicto) $result.=($lien.img_object($langs->trans("ShowCompany").': '.$name,'company').$lienfin); From ecb19e2225906ddda9ae6179b7840ff8fbbbdc66 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Apr 2013 00:28:12 +0200 Subject: [PATCH 88/97] Fix: Removed warning --- dev/skeletons/modMyModule.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dev/skeletons/modMyModule.class.php b/dev/skeletons/modMyModule.class.php index 2f203cbfeb2..5711b61c4ac 100644 --- a/dev/skeletons/modMyModule.class.php +++ b/dev/skeletons/modMyModule.class.php @@ -133,7 +133,11 @@ class modMyModule extends DolibarrModules $this->tabs = array(); // Dictionnaries - if (! isset($conf->mymodule->enabled)) $conf->mymodule->enabled=0; + if (! isset($conf->mymodule->enabled)) + { + $conf->mymodule=new stdClass(); + $conf->mymodule->enabled=0; + } $this->dictionnaries=array(); /* Example: if (! isset($conf->mymodule->enabled)) $conf->mymodule->enabled=0; // This is to avoid warnings From e19e0ff55742d4f6e6fcc8cbb7ec50a20ec0d549 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Apr 2013 00:57:56 +0200 Subject: [PATCH 89/97] Fix: Error management --- htdocs/core/ajax/ajaxdirtree.php | 2 +- htdocs/ecm/class/ecmdirectory.class.php | 3 ++- htdocs/ecm/docdir.php | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php index ded1a4a30c4..db8af5ba265 100644 --- a/htdocs/core/ajax/ajaxdirtree.php +++ b/htdocs/core/ajax/ajaxdirtree.php @@ -117,7 +117,7 @@ if (file_exists($fullpathselecteddir)) // Loop on all database entries (sqltree) to find the one matching the subdir found into dir to scan foreach($sqltree as $key => $tmpval) { - //print "-- key=".$key." - ".$val['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file).'
'; + //print "-- key=".$key." - ".$tmpval['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file)."
\n"; if ($tmpval['fullrelativename'] == (($selecteddir != '/'?$selecteddir.'/':'').$file)) // We found equivalent record into database { $val=$tmpval; diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php index bdb8dd0f366..3c12fe066e9 100644 --- a/htdocs/ecm/class/ecmdirectory.class.php +++ b/htdocs/ecm/class/ecmdirectory.class.php @@ -142,7 +142,8 @@ class EcmDirectory // extends CommonObject $dir=$conf->ecm->dir_output.'/'.$this->getRelativePath(); $result=dol_mkdir($dir); - + if ($result < 0) { $error++; $this->error="ErrorFailedToCreateDir"; } + // Appel des triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; $interface=new Interfaces($this->db); diff --git a/htdocs/ecm/docdir.php b/htdocs/ecm/docdir.php index 8f71bf4ed97..5ab21beed0d 100644 --- a/htdocs/ecm/docdir.php +++ b/htdocs/ecm/docdir.php @@ -118,6 +118,7 @@ if ($action == 'add' && $user->rights->ecm->setup) { $langs->load("errors"); setEventMessage($langs->trans($ecmdir->error), 'errors'); + setEventMessage($ecmdir->errors, 'errors'); $action = 'create'; } } From 7ff2e559aa0538e75622a1ac7a6ff100885c566c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Apr 2013 01:59:52 +0200 Subject: [PATCH 90/97] Fix: PGsql compatibility --- htdocs/product/class/product.class.php | 62 +++++++++++++------------- htdocs/product/composition/fiche.php | 4 +- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 3d5749169ad..396695aa98d 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1797,8 +1797,16 @@ class Product extends CommonObject */ function add_sousproduit($id_pere, $id_fils,$qty) { - $sql = 'DELETE from '.MAIN_DB_PREFIX.'product_association'; - $sql .= ' WHERE fk_product_pere = "'.$id_pere.'" AND fk_product_fils = "'.$id_fils.'"'; + // Clean parameters + if (! is_numeric($id_pere)) $id_pere=0; + if (! is_numeric($id_fils)) $id_fils=0; + + $result=$this->del_sousproduit($id_pere, $id_fils); + if ($result < 0) return $result; + + // Check not already father of id_pere (to avoid father -> child -> father links) + $sql = 'SELECT fk_product_pere from '.MAIN_DB_PREFIX.'product_association'; + $sql .= ' WHERE fk_product_pere = '.$id_fils.' AND fk_product_fils = '.$id_pere; if (! $this->db->query($sql)) { dol_print_error($this->db); @@ -1806,37 +1814,27 @@ class Product extends CommonObject } else { - $sql = 'SELECT fk_product_pere from '.MAIN_DB_PREFIX.'product_association'; - $sql .= ' WHERE fk_product_pere = "'.$id_fils.'" AND fk_product_fils = "'.$id_pere.'"'; - if (! $this->db->query($sql)) + $result = $this->db->query($sql); + if ($result) { - dol_print_error($this->db); - return -1; - } - else - { - $result = $this->db->query($sql); - if ($result) + $num = $this->db->num_rows($result); + if($num > 0) { - $num = $this->db->num_rows($result); - if($num > 0) + $this->error="isFatherOfThis"; + return -1; + } + else + { + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_association(fk_product_pere,fk_product_fils,qty)'; + $sql .= ' VALUES ('.$id_pere.', '.$id_fils.', '.$qty.')'; + if (! $this->db->query($sql)) { - $this->error="isFatherOfThis"; + dol_print_error($this->db); return -1; } else { - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_association(fk_product_pere,fk_product_fils,qty)'; - $sql .= ' VALUES ("'.$id_pere.'","'.$id_fils.'","'.$qty.'")'; - if (! $this->db->query($sql)) - { - dol_print_error($this->db); - return -1; - } - else - { - return 1; - } + return 1; } } } @@ -1848,14 +1846,18 @@ class Product extends CommonObject * * @param int $fk_parent Id du produit auquel ne sera plus lie le produit lie * @param int $fk_child Id du produit a ne plus lie - * @return int < 0 si erreur, > 0 si ok + * @return int < 0 if KO, > 0 if OK */ function del_sousproduit($fk_parent, $fk_child) { + if (! is_numeric($fk_parent)) $fk_parent=0; + if (! is_numeric($fk_child)) $fk_child=0; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_association"; - $sql.= " WHERE fk_product_pere = '".$fk_parent."'"; - $sql.= " AND fk_product_fils = '".$fk_child."'"; - + $sql.= " WHERE fk_product_pere = ".$fk_parent; + $sql.= " AND fk_product_fils = ".$fk_child; + + dol_syslog(get_class($this).'::del_sousproduit sql='.$sql); if (! $this->db->query($sql)) { dol_print_error($this->db); diff --git a/htdocs/product/composition/fiche.php b/htdocs/product/composition/fiche.php index 804759afe3a..395275a9911 100644 --- a/htdocs/product/composition/fiche.php +++ b/htdocs/product/composition/fiche.php @@ -72,8 +72,8 @@ $cancel <> $langs->trans("Cancel") && $error=0; for($i=0;$i<$_POST["max_prod"];$i++) { - // print "
: ".$_POST["prod_id_chk".$i]; - if($_POST["prod_id_chk".$i] != "") + print "
: ".$_POST["prod_id_chk".$i]; + if ($_POST["prod_id_chk".$i] > 0) { if($product->add_sousproduit($id, $_POST["prod_id_".$i],$_POST["prod_qty_".$i]) > 0) { From ab4a3dcaa7793e0a51c6acbf80bd0bc95c90e4eb Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 22 Apr 2013 10:18:03 +0200 Subject: [PATCH 91/97] Fix: missing rename field --- htdocs/core/modules/modFacture.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index 666bcb9a22a..4d18c3d8757 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -198,10 +198,10 @@ class modFacture extends DolibarrModules $this->export_label[$r]='CustomersInvoicesAndPayments'; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_icon[$r]='bill'; $this->export_permission[$r]=array(array("facture","facture","export")); - $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','c.code'=>'CountryCode','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode','s.code_compta_fournisseur'=>'SupplierAccountancyCode','s.tva_intra'=>'VATIntra','f.rowid'=>"InvoiceId",'f.facnumber'=>"InvoiceRef",'f.datec'=>"InvoiceDateCreation",'f.datef'=>"DateInvoice",'f.date_lim_reglement'=>"DateDue",'f.total'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",'f.fk_statut'=>'InvoiceStatus','f.note'=>"NotePrivate",'f.note_public'=>"NotePublic",'p.rowid'=>'PaymentId','pf.amount'=>'AmountPayment','p.datep'=>'DatePayment','p.num_paiement'=>'PaymentNumber'); - //$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number'); - $this->export_TypeFields_array[$r]=array('s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number'); - $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','c.code'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company','s.tva_intra'=>'company','f.rowid'=>"invoice",'f.facnumber'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.date_lim_reglement'=>"invoice",'f.total'=>"invoice",'f.total_ttc'=>"invoice",'f.tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note'=>"invoice",'f.note_public'=>"invoice",'p.rowid'=>'payment','pf.amount'=>'payment','p.datep'=>'payment','p.num_paiement'=>'payment'); + $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','c.code'=>'CountryCode','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode','s.code_compta_fournisseur'=>'SupplierAccountancyCode','s.tva_intra'=>'VATIntra','f.rowid'=>"InvoiceId",'f.facnumber'=>"InvoiceRef",'f.datec'=>"InvoiceDateCreation",'f.datef'=>"DateInvoice",'f.date_lim_reglement'=>"DateDue",'f.total'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",'f.fk_statut'=>'InvoiceStatus','f.note_private'=>"NotePrivate",'f.note_public'=>"NotePublic",'p.rowid'=>'PaymentId','pf.amount'=>'AmountPayment','p.datep'=>'DatePayment','p.num_paiement'=>'PaymentNumber'); + //$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_private'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number'); + $this->export_TypeFields_array[$r]=array('s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_private'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number'); + $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','c.code'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company','s.tva_intra'=>'company','f.rowid'=>"invoice",'f.facnumber'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.date_lim_reglement'=>"invoice",'f.total'=>"invoice",'f.total_ttc'=>"invoice",'f.tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note_private'=>"invoice",'f.note_public'=>"invoice",'p.rowid'=>'payment','pf.amount'=>'payment','p.datep'=>'payment','p.num_paiement'=>'payment'); $this->export_dependencies_array[$r]=array('payment'=>'p.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them $this->export_sql_start[$r]='SELECT DISTINCT '; From ee843924dd56d1d5b47346a99125bb3f2e8f91c4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Apr 2013 10:33:06 +0200 Subject: [PATCH 92/97] Fix: Some translation change to have things more clear. --- htdocs/core/class/html.form.class.php | 4 ++-- htdocs/langs/en_US/products.lang | 12 +++++++----- htdocs/langs/fr_FR/products.lang | 16 +++++++++------- htdocs/product/class/product.class.php | 7 ++++--- htdocs/product/composition/fiche.php | 15 ++++++++++----- 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 944f364ee4b..97658572831 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -344,7 +344,7 @@ class Form * Show a text and picto with tooltip on text or picto * * @param string $text Text to show - * @param string $htmltext Content html of tooltip. Must be HTML/UTF8 encoded. + * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. * @param int $tooltipon 1=tooltip sur texte, 2=tooltip sur picto, 3=tooltip sur les 2 * @param int $direction -1=Le picto est avant, 0=pas de picto, 1=le picto est apres * @param string $img Code img du picto (use img_xxx() function to get it) @@ -383,7 +383,7 @@ class Form //if ($text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.(($direction < 0)?' ':'').$text.(($direction > 0)?' ':'').''; $paramfortooltiptd.= (($direction < 0)?' style="padding-left: 3px !important;"':''); $paramfortooltiptd.= (($direction > 0)?' style="padding-right: 3px !important;"':''); - if ($text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.$text.''; + if ((string) $text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.$text.''; if ($direction > 0) $s.='<'.$tag.$paramfortooltipimg.' valign="top" width="14">'.$img.''; if (empty($notabs)) $s.='
'.$langs->trans("Member")."
'.$langs->trans("Member")."
'; - print $member->getNomUrl(1); + $member->ref=$member->login; + print $member->getNomUrl(1,0,'category'); print "'.$member->lastname."'.$member->firstname."'; + $typeid=$object->type; + $permission=0; + if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer); + if ($typeid == 1) $permission=$user->rights->societe->creer; + if ($typeid == 2) $permission=$user->rights->societe->creer; + if ($typeid == 3) $permission=$user->rights->adherent->creer; + if ($permission) + { + print ""; + print img_delete($langs->trans("DeleteFromCat")).' '; + print $langs->trans("DeleteFromCat").""; + } print "
'; diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index b58dec53dcb..6ba653600e4 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -111,10 +111,12 @@ ServiceLimitedDuration=If product is a service with limited duration: MultiPricesAbility=Activate the multi-prices MultiPricesNumPrices=Number of price MultiPriceLevelsName=Price categories -AssociatedProductsAbility=Activate the sub-products -AssociatedProducts=Sub-products -AssociatedProductsNumber=Number of products composing this product -ParentProductsNumber=Number of parent product +AssociatedProductsAbility=Activate the virtual products feature +AssociatedProducts=Virtual product +AssociatedProductsNumber=Number of products composing this virtual product +ParentProductsNumber=Number of parent virtual product +IfZeroItIsNotAVirtualProduct=If 0, this product is not a virtual product +IfZeroItIsNotUsedByVirtualProduct=If 0, this product is not used by any virtual product EditAssociate=Associate Translation=Translation KeywordFilter=Keyword filter @@ -124,7 +126,7 @@ AddDel=Add/Delete Quantity=Quantity NoMatchFound=No match found ProductAssociationList=List of related products/services: name of product/service (quantity affected) -ProductParentList=List of products/services with this product as a component +ProductParentList=List of virtual products/services with this product as a component ErrorAssociationIsFatherOfThis=One of selected product is parent with current product DeleteProduct=Delete a product/service ConfirmDeleteProduct=Are you sure you want to delete this product/service? diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 3d27fdd9d6d..f5ce6482353 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -111,11 +111,13 @@ ServiceLimitedDuration=Si produit de type service à durée limitée : MultiPricesAbility=Prise en charge de prix multiples MultiPricesNumPrices=Nombre de prix MultiPriceLevelsName=Catégorie de prix -AssociatedProductsAbility=Prise en charge des produits composés -AssociatedProducts=Composition -AssociatedProductsNumber=Nbre de sous-produits composant ce produit -ParentProductsNumber=Nbre de produits parent -EditAssociate=Composer +AssociatedProductsAbility=Prise en charge des produits virtuels +AssociatedProducts=Produit virtuel +AssociatedProductsNumber=Nbre de sous-produits constituant ce produit virtuel +ParentProductsNumber=Nbre de produits virtuels parent +IfZeroItIsNotAVirtualProduct=Si 0, ce produit n'est pas un produit virtuel +IfZeroItIsNotUsedByVirtualProduct=Si 0, ce produit n'est pas utilisé par un produit virtuel +EditAssociate=Composer comme produit virtuel Translation=Traduction KeywordFilter=Filtre par mot-clé CategoryFilter=Filtre par catégorie @@ -123,8 +125,8 @@ ProductToAddSearch=Recherche des produits à ajouter AddDel=Ajouter/Retirer Quantity=Quantité NoMatchFound=Aucun résultat n'a été trouvé -ProductAssociationList=Liste des produits/services composant ce produit: Le nombre entre parenthèse est la quantité affectée dans cette composition. -ProductParentList=Liste des produits/services avec ce produit comme composante +ProductAssociationList=Liste des produits/services composant ce produit virtuel: Le nombre entre parenthèse est la quantité affectée dans cette composition. +ProductParentList=Liste des produits/services virtuels avec ce produit comme composante ErrorAssociationIsFatherOfThis=L'un des produits sélectionnés est parent du produit en cours DeleteProduct=Supprimer un produit/service ConfirmDeleteProduct=Êtes-vous sûr de vouloir supprimer ce produit/service ? diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index a8803d6e5e8..f6219d5acd4 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2137,6 +2137,7 @@ class Product extends CommonObject $id=(! empty($desc_pere[0]) ? $desc_pere[0] :''); $nb=(! empty($desc_pere[1]) ? $desc_pere[1] :''); $type=(! empty($desc_pere[2]) ? $desc_pere[2] :''); + $label=(! empty($desc_pere[3]) ? $desc_pere[3] :''); if ($multiply) { @@ -2157,10 +2158,10 @@ class Product extends CommonObject */ 'id'=>$id, // Id product 'nb'=>$nb, // Nb of units that compose parent product 'nb_total'=>$nb*$multiply, // Nb of units for all nb of product - 'stock'=>$this->stock_warehouse[1]->real, // Stock + 'stock'=>$this->stock_warehouse[1]->real, // Stock 'stock_alert'=>$this->seuil_stock_alerte, // Stock alert - 'fullpath' => $compl_path.$nom_pere, // Label - 'type'=>$type // Nb of units that compose parent product + 'fullpath' => $compl_path.$label, // Label + 'type'=>$type // Nb of units that compose parent product ); } else diff --git a/htdocs/product/composition/fiche.php b/htdocs/product/composition/fiche.php index 804759afe3a..471631cc464 100644 --- a/htdocs/product/composition/fiche.php +++ b/htdocs/product/composition/fiche.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2004-2013 Laurent Destailleur * Copyright (C) 2005 Eric Seigne * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2006 Andre Cianfarani @@ -200,12 +200,15 @@ if ($id || $ref) // Number of subproducts $prodsfather = $product->getFather(); //Parent Products $product->get_sousproduits_arbo(); - print '
'.$langs->trans("AssociatedProductsNumber").''.count($product->get_arbo_each_prod()).'
'.$langs->trans("AssociatedProductsNumber").''; + print $form->textwithpicto($nbofsubproducts, $langs->trans('IfZeroItIsNotAVirtualProduct')); + print '
'.$langs->trans("ParentProductsNumber").''.count($prodsfather).'
'.$langs->trans("ParentProductsNumber").''; + print $form->textwithpicto(count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct')); + print '
'.$langs->trans("AssociatedProductsNumber").''; print $form->textwithpicto($nbofsubproducts, $langs->trans('IfZeroItIsNotAVirtualProduct')); print '
'; @@ -226,7 +226,8 @@ if ($id || $ref) //print $productstatic->getNomUrl(1).'
'; //print $value[0]; // This contains a tr line. print '
'.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].')    '.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].($value['nb_total'] > $value['nb']?'->'.$value['nb_total']:'').')    '.$productstatic->getNomUrl(1,'composition').' ('.$value['nb_total'].')    '.$langs->trans("Stock").' : '.$productstatic->stock_reel.'
      -> - ".$compl_path.stripslashes($nom_pere)." - (".$desc_pere[1].") ".($desc_pere[1]*$multiply)."  ".$this->stock_entrepot[1]." ".$img."
'.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].($value['nb_total'] > $value['nb']?'->'.$value['nb_total']:'').')    '.$productstatic->getNomUrl(1,'composition').' ('.$value['nb_total'].')    '.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].')    '.$langs->trans("Stock").' : '.$productstatic->stock_reel.'
'.$langs->trans("AssociatedProductsNumber").''.count($product->get_arbo_each_prod()).'
'.$langs->trans("AssociatedProductsNumber").''; + print $form->textwithpicto($nbofsubproducts, $langs->trans('IfZeroItIsNotAVirtualProduct')); + print '
'; @@ -322,8 +324,10 @@ if ($id || $ref) print '
'.$langs->trans("ParentProductsNumber").''.count($prodsfather).'
'.$langs->trans("ParentProductsNumber").''; + print $form->textwithpicto(count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct')); + print '