From b4c84fac9deac7820af9c20c3fe5ae82d3b727ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Thu, 26 Feb 2015 14:15:33 +0100 Subject: [PATCH] NEW: [ task #977 ] New option to manage product unit Migrated code from GPCSolutions/dolibarr:3.2-units branch and adapted for 3.8 with some improvements --- htdocs/admin/dict.php | 22 ++++- htdocs/comm/propal.php | 14 ++- htdocs/comm/propal/class/propal.class.php | 25 ++++- htdocs/commande/card.php | 14 ++- htdocs/commande/class/commande.class.php | 31 ++++-- htdocs/compta/facture.php | 20 +++- .../facture/class/facture-rec.class.php | 14 ++- htdocs/compta/facture/class/facture.class.php | 34 +++++-- htdocs/compta/facture/fiche-rec.php | 22 ++++- htdocs/contrat/card.php | 38 ++++++- htdocs/contrat/class/contrat.class.php | 26 +++-- htdocs/core/class/commonobject.class.php | 15 ++- htdocs/core/class/commonobjectline.class.php | 50 ++++++++++ htdocs/core/class/commonorder.class.php | 3 +- htdocs/core/class/html.form.class.php | 48 +++++++++ htdocs/core/lib/pdf.lib.php | 37 +++++++ .../commande/doc/pdf_einstein.modules.php | 69 ++++++++++--- .../modules/facture/doc/pdf_crabe.modules.php | 54 ++++++++-- .../modules/propale/doc/pdf_azur.modules.php | 56 +++++++++-- htdocs/core/tpl/objectline_create.tpl.php | 23 +++++ htdocs/core/tpl/objectline_edit.tpl.php | 9 ++ htdocs/core/tpl/objectline_view.tpl.php | 12 +++ htdocs/core/tpl/originproductline.tpl.php | 5 +- htdocs/install/mysql/data/llx_c_units.sql | 31 ++++++ .../install/mysql/migration/3.7.0-3.8.0.sql | 43 +++++++- .../install/mysql/tables/llx_c_units.key.sql | 21 ++++ htdocs/install/mysql/tables/llx_c_units.sql | 27 +++++ .../mysql/tables/llx_commandedet.key.sql | 2 + .../install/mysql/tables/llx_commandedet.sql | 2 + .../mysql/tables/llx_contratdet.key.sql | 2 + .../install/mysql/tables/llx_contratdet.sql | 3 +- .../mysql/tables/llx_facturedet.key.sql | 2 + .../install/mysql/tables/llx_facturedet.sql | 3 +- .../mysql/tables/llx_facturedet_rec.key.sql | 21 ++++ .../mysql/tables/llx_facturedet_rec.sql | 4 +- .../install/mysql/tables/llx_product.key.sql | 3 +- htdocs/install/mysql/tables/llx_product.sql | 7 +- .../mysql/tables/llx_propaldet.key.sql | 2 + htdocs/install/mysql/tables/llx_propaldet.sql | 4 +- htdocs/langs/en_US/admin.lang | 1 + htdocs/langs/en_US/products.lang | 26 +++++ htdocs/product/admin/product.php | 24 ++++- htdocs/product/card.php | 99 +++++++++++++++++-- htdocs/product/class/product.class.php | 55 ++++++++++- 44 files changed, 931 insertions(+), 92 deletions(-) create mode 100644 htdocs/install/mysql/data/llx_c_units.sql create mode 100644 htdocs/install/mysql/tables/llx_c_units.key.sql create mode 100644 htdocs/install/mysql/tables/llx_c_units.sql create mode 100644 htdocs/install/mysql/tables/llx_facturedet_rec.key.sql diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 05402898ee6..4f193ed76f2 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -70,7 +70,7 @@ $hookmanager->initHooks(array('admin')); // Put here declaration of dictionaries properties // Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder=array(9,0,4,3,2,0,1,8,19,16,0,5,11,0,6,0,10,23,12,13,0,14,0,7,17,0,22,20,18,21,0,15,0,24,0,25); +$taborder=array(9,0,4,3,2,0,1,8,19,16,0,5,11,0,6,0,10,23,12,13,0,14,0,7,17,0,22,20,18,21,0,15,0,24,0,25,0,26); // Name of SQL tables of dictionaries $tabname=array(); @@ -99,6 +99,7 @@ $tabname[22]= MAIN_DB_PREFIX."c_input_reason"; $tabname[23]= MAIN_DB_PREFIX."c_revenuestamp"; $tabname[24]= MAIN_DB_PREFIX."c_type_resource"; $tabname[25]= MAIN_DB_PREFIX."c_email_templates"; +$tabname[26]= MAIN_DB_PREFIX."c_units"; // Dictionary labels $tablib=array(); @@ -127,6 +128,7 @@ $tablib[22]= "DictionarySource"; $tablib[23]= "DictionaryRevenueStamp"; $tablib[24]= "DictionaryResourceType"; $tablib[25]= "DictionaryEMailTemplates"; +$tablib[26]= "DictionnaryUnits"; // Requests to extract data $tabsql=array(); @@ -155,6 +157,7 @@ $tabsql[22]= "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX $tabsql[23]= "SELECT t.rowid, t.taux, c.label as country, c.code as country_code, t.fk_pays as country_id, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_revenuestamp as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; $tabsql[24]= "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_type_resource"; $tabsql[25]= "SELECT rowid as rowid, label, type_template, private, position, topic, content, active FROM ".MAIN_DB_PREFIX."c_email_templates"; +$tabsql[26]= "SELECT rowid as rowid, code, label, short_label, active FROM ".MAIN_DB_PREFIX."c_units"; // Criteria to sort dictionaries $tabsqlsort=array(); @@ -183,6 +186,7 @@ $tabsqlsort[22]="code ASC, label ASC"; $tabsqlsort[23]="country ASC, taux ASC"; $tabsqlsort[24]="code ASC,label ASC"; $tabsqlsort[25]="label ASC"; +$tabsqlsort[26]="code ASC"; // Nom des champs en resultat de select pour affichage du dictionnaire $tabfield=array(); @@ -211,6 +215,7 @@ $tabfield[22]= "code,label"; $tabfield[23]= "country_id,country,taux,accountancy_code_sell,accountancy_code_buy,note"; $tabfield[24]= "code,label"; $tabfield[25]= "label,type_template,private,position,topic,content"; +$tabfield[26]= "code,label,short_label"; // Nom des champs d'edition pour modification d'un enregistrement $tabfieldvalue=array(); @@ -239,6 +244,7 @@ $tabfieldvalue[22]= "code,label"; $tabfieldvalue[23]= "country,taux,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldvalue[24]= "code,label"; $tabfieldvalue[25]= "label,type_template,private,position,topic,content"; +$tabfieldvalue[26]= "code,label,short_label"; // Nom des champs dans la table pour insertion d'un enregistrement $tabfieldinsert=array(); @@ -267,6 +273,7 @@ $tabfieldinsert[22]= "code,label"; $tabfieldinsert[23]= "fk_pays,taux,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldinsert[24]= "code,label"; $tabfieldinsert[25]= "label,type_template,private,position,topic,content"; +$tabfieldinsert[26]= "code,label,short_label"; // Nom du rowid si le champ n'est pas de type autoincrement // Example: "" if id field is "rowid" and has autoincrement on @@ -297,6 +304,7 @@ $tabrowid[22]= "rowid"; $tabrowid[23]= ""; $tabrowid[24]= ""; $tabrowid[25]= ""; +$tabrowid[26]= ""; // Condition to show dictionary in setup page $tabcond=array(); @@ -325,6 +333,7 @@ $tabcond[22]= (! empty($conf->commande->enabled) || ! empty($conf->propal->enabl $tabcond[23]= true; $tabcond[24]= ! empty($conf->resource->enabled); $tabcond[25]= true; // && ! empty($conf->global->MAIN_EMAIL_EDIT_TEMPLATE_FROM_DIC); +$tabcond[26]= $conf->product->enabled; // List of help for fields $tabhelp=array(); @@ -858,6 +867,7 @@ if ($id) if ($fieldlist[$field]=='pcg_type') { $valuetoshow=$langs->trans("Pcg_type"); } if ($fieldlist[$field]=='pcg_subtype') { $valuetoshow=$langs->trans("Pcg_subtype"); } if ($fieldlist[$field]=='sortorder') { $valuetoshow=$langs->trans("SortOrder"); } + if ($fieldlist[$field]=='short_label') { $valuetoshow=$langs->trans("ShortLabel"); } if ($id == 2) // Special cas for state page { @@ -995,6 +1005,7 @@ if ($id) if ($fieldlist[$field]=='pcg_type') { $valuetoshow=$langs->trans("Pcg_type"); } if ($fieldlist[$field]=='pcg_subtype') { $valuetoshow=$langs->trans("Pcg_subtype"); } if ($fieldlist[$field]=='sortorder') { $valuetoshow=$langs->trans("SortOrder"); } + if ($fieldlist[$field]=='short_label') { $valuetoshow=$langs->trans("ShortLabel"); } // Affiche nom du champ if ($showfield) @@ -1159,7 +1170,14 @@ if ($id) else if ($fieldlist[$field]=='unicode') { $valuetoshow = $langs->getCurrencySymbol($obj->code,1); } - + else if ($fieldlist[$field]=='label' && $tabname[$_GET["id"]]==MAIN_DB_PREFIX.'c_units') { + $langs->load("products"); + $valuetoshow=$langs->trans($obj->$fieldlist[$field]); + } + else if ($fieldlist[$field]=='short_label' && $tabname[$_GET["id"]]==MAIN_DB_PREFIX.'c_units') { + $langs->load("products"); + $valuetoshow = $langs->trans($obj->$fieldlist[$field]); + } else if (($fieldlist[$field] == 'unit') && ($tabname[$id] == MAIN_DB_PREFIX.'c_paper_format')) { $key = $langs->trans('SizeUnit'.strtolower($obj->unit)); diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index 302b49fbdb7..a2c578fcaa9 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -8,6 +8,7 @@ * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2010-2011 Philippe Grand * Copyright (C) 2012-2013 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2014 Ferran Marcet * @@ -687,6 +688,7 @@ if (empty($reshook)) // Ecrase $pu par celui du produit // Ecrase $desc par celui du produit // Ecrase $txtva par celui du produit + // Replaces $fk_unit with the product unit if (! empty($idprod)) { $prod = new Product($db); $prod->fetch($idprod); @@ -782,6 +784,7 @@ if (empty($reshook)) } $type = $prod->type; + $fk_unit = $prod->fk_unit; } else { $pu_ht = price2num($price_ht, 'MU'); $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); @@ -790,6 +793,12 @@ if (empty($reshook)) $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); $desc = $product_desc; $type = GETPOST('type'); + + $fk_unit = GETPOST('units', 'int'); + + if ($fk_unit <= 0) { + $fk_unit = null; + } } // Margin @@ -812,7 +821,7 @@ if (empty($reshook)) setEventMessage($mesg, 'errors'); } else { // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_option); + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_option, $fk_unit); if ($result > 0) { $db->commit(); @@ -846,6 +855,7 @@ if (empty($reshook)) unset($_POST['np_markRate']); unset($_POST['dp_desc']); unset($_POST['idprod']); + unset($_POST['units']); unset($_POST['date_starthour']); unset($_POST['date_startmin']); @@ -940,7 +950,7 @@ if (empty($reshook)) if (! $error) { $db->begin(); - $result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_option); + $result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_option, $_POST["units"]); if ($result >= 0) { $db->commit(); diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index dc1184b7490..306df930523 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -9,6 +9,7 @@ * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2010-2011 Philippe Grand * Copyright (C) 2012-2014 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013 Florian Henry * Copyright (C) 2014-2015 Marcos García * @@ -32,6 +33,7 @@ */ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT ."/core/class/commonobjectline.class.php"; require_once DOL_DOCUMENT_ROOT .'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT .'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT .'/margin/lib/margins.lib.php'; @@ -203,6 +205,7 @@ class Propal extends CommonObject $line->subprice=$price; $line->remise_percent=$remise_percent; $line->tva_tx=$tva_tx; + $line->fk_unit=$prod->fk_unit; $this->lines[]=$line; } @@ -315,11 +318,12 @@ class Propal extends CommonObject * @param int $date_start Start date of the line * @param int $date_end End date of the line * @param array $array_option extrafields array + * @param int $fk_unit Id of the unit to use. Null to use the default one * @return int >0 if OK, <0 if KO * * @see add_product */ - function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='',$date_start='', $date_end='',$array_option=0) + function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='',$date_start='', $date_end='',$array_option=0, $fk_unit = null) { global $mysoc; @@ -416,6 +420,7 @@ class Propal extends CommonObject $this->line->product_type=$type; $this->line->special_code=$special_code; $this->line->fk_parent_line=$fk_parent_line; + $this->line->fk_unit=$fk_unit; $this->line->date_start=$date_start; $this->line->date_end=$date_end; @@ -497,9 +502,10 @@ class Propal extends CommonObject * @param int $date_start Start date of the line * @param int $date_end End date of the line * @param array $array_option extrafields array + * @param int $fk_unit Id of the unit to use. Null to use the default one * @return int 0 if OK, <0 if KO */ - function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=0, $pa_ht=0, $label='', $type=0, $date_start='', $date_end='', $array_option=0) + function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=0, $pa_ht=0, $label='', $type=0, $date_start='', $date_end='', $array_option=0, $fk_unit = null) { global $mysoc; @@ -581,6 +587,7 @@ class Propal extends CommonObject $this->line->special_code = $special_code; $this->line->fk_parent_line = $fk_parent_line; $this->line->skip_update_total = $skip_update_total; + $this->line->fk_unit = $fk_unit; // infos marge if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { @@ -829,7 +836,8 @@ class Propal extends CommonObject $this->lines[$i]->label, $this->lines[$i]->date_start, $this->lines[$i]->date_end, - $this->lines[$i]->array_options + $this->lines[$i]->array_options, + $this->lines[$i]->fk_unit ); if ($result < 0) @@ -1193,6 +1201,7 @@ class Propal extends CommonObject */ $sql = "SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,"; $sql.= " d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,"; + $sql.= " d.fk_unit,"; $sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,'; $sql.= ' d.date_start, d.date_end'; $sql.= " FROM ".MAIN_DB_PREFIX."propaldet as d"; @@ -1249,6 +1258,7 @@ class Propal extends CommonObject $line->product_label = $objp->product_label; $line->product_desc = $objp->product_desc; // Description produit $line->fk_product_type = $objp->fk_product_type; + $line->fk_unit = $objp->fk_unit; $line->date_start = $objp->date_start; $line->date_end = $objp->date_end; @@ -2674,6 +2684,7 @@ class Propal extends CommonObject $sql.= ' pt.qty, pt.tva_tx, pt.remise_percent, pt.subprice, pt.info_bits,'; $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code, pt.localtax1_tx, pt.localtax2_tx,'; $sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,'; + $sql.= ' pt.fk_unit,'; $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid,'; $sql.= ' p.description as product_desc,'; $sql.= ' p.entity'; @@ -2724,6 +2735,7 @@ class Propal extends CommonObject $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_unit = $obj->fk_unit; $i++; } @@ -2780,7 +2792,7 @@ class Propal extends CommonObject * \class PropaleLigne * \brief Class to manage commercial proposal lines */ -class PropaleLigne extends CommonObject +class PropaleLigne extends CommonObjectLine { var $db; var $error; @@ -2866,6 +2878,7 @@ class PropaleLigne extends CommonObject $sql = 'SELECT pd.rowid, pd.fk_propal, pd.fk_parent_line, pd.fk_product, pd.label as custom_label, pd.description, pd.price, pd.qty, pd.tva_tx,'; $sql.= ' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,'; $sql.= ' pd.info_bits, pd.total_ht, pd.total_tva, pd.total_ttc, pd.fk_product_fournisseur_price as fk_fournprice, pd.buy_price_ht as pa_ht, pd.special_code, pd.rang,'; + $sql.= ' pd.fk_unit,'; $sql.= ' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,'; $sql.= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,'; $sql.= ' pd.date_start, pd.date_end, pd.product_type'; @@ -2913,6 +2926,7 @@ class PropaleLigne extends CommonObject $this->libelle = $objp->product_label; // deprecated $this->product_label = $objp->product_label; $this->product_desc = $objp->product_desc; + $this->fk_unit = $objp->fk_unit; $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); @@ -2975,6 +2989,7 @@ class PropaleLigne extends CommonObject $sql.= ' subprice, remise_percent, '; $sql.= ' info_bits, '; $sql.= ' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,'; + $sql.= ' fk_unit,'; $sql.= ' date_start, date_end)'; $sql.= " VALUES (".$this->fk_propal.","; $sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").","; @@ -3001,6 +3016,7 @@ class PropaleLigne extends CommonObject $sql.= " ".(isset($this->pa_ht)?"'".price2num($this->pa_ht)."'":"null").","; $sql.= ' '.$this->special_code.','; $sql.= ' '.$this->rang.','; + $sql.= ' '.(!$this->fk_unit ? 'NULL' : $this->fk_unit).','; $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.= ')'; @@ -3166,6 +3182,7 @@ class PropaleLigne extends CommonObject if (! empty($this->rang)) $sql.= ", rang=".$this->rang; $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.= " , fk_unit=".(!$this->fk_unit ? 'NULL' : $this->fk_unit); $sql.= " WHERE rowid = ".$this->rowid; dol_syslog(get_class($this)."::update", LOG_DEBUG); diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index bda67f809fa..a11ea9cf154 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -8,6 +8,7 @@ * Copyright (C) 2011 Philippe Grand * Copyright (C) 2012-2013 Christophe Battarel * Copyright (C) 2012 Marcos García + * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013 Florian Henry * Copyright (C) 2014 Ferran Marcet * @@ -341,7 +342,7 @@ if (empty($reshook)) $array_option = $lines[$i]->array_options; } - $result = $object->addline($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, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $date_start, $date_end, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_option); + $result = $object->addline($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, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $date_start, $date_end, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_option, $lines[$i]->fk_unit); if ($result < 0) { $error ++; @@ -700,6 +701,7 @@ if (empty($reshook)) } $type = $prod->type; + $fk_unit = $prod->fk_unit; } else { $pu_ht = price2num($price_ht, 'MU'); $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); @@ -708,6 +710,11 @@ if (empty($reshook)) $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); $desc = $product_desc; $type = GETPOST('type'); + $fk_unit=GETPOST('units', 'int'); + + if ($fk_unit <= 0) { + $fk_unit = null; + } } // Margin @@ -729,7 +736,7 @@ if (empty($reshook)) setEventMessage($mesg, 'errors'); } else { // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option); + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option, $fk_unit); if ($result > 0) { $ret = $object->fetch($object->id); // Reload to get new records @@ -765,6 +772,7 @@ if (empty($reshook)) unset($_POST['np_markRate']); unset($_POST['dp_desc']); unset($_POST['idprod']); + unset($_POST['units']); unset($_POST['date_starthour']); unset($_POST['date_startmin']); @@ -853,7 +861,7 @@ if (empty($reshook)) } if (! $error) { - $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option); + $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option, GETPOST('units')); if ($result >= 0) { if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index dd0d3163bba..d0c7e14fc9c 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -6,6 +6,7 @@ * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2011 Jean Heimburger * Copyright (C) 2012-2014 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013 Florian Henry * Copyright (C) 2014-2015 Marcos García * @@ -29,6 +30,7 @@ * \brief Fichier des classes de commandes */ include_once DOL_DOCUMENT_ROOT.'/core/class/commonorder.class.php'; +require_once DOL_DOCUMENT_ROOT ."/core/class/commonobjectline.class.php"; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT .'/margin/lib/margins.lib.php'; @@ -740,7 +742,8 @@ class Commande extends CommonOrder $this->lines[$i]->fk_fournprice, $this->lines[$i]->pa_ht, $this->lines[$i]->label, - $this->lines[$i]->array_options + $this->lines[$i]->array_options, + $this->lines[$i]->fk_unit ); if ($result < 0) { @@ -999,6 +1002,7 @@ class Commande extends CommonOrder $line->rang = $object->lines[$i]->rang; $line->special_code = $object->lines[$i]->special_code; $line->fk_parent_line = $object->lines[$i]->fk_parent_line; + $line->fk_unit = $object->lines[$i]->fk_unit; $line->date_start = $object->lines[$i]->date_start; $line->date_end = $object->lines[$i]->date_end; @@ -1102,6 +1106,7 @@ class Commande extends CommonOrder * @param int $pa_ht Buying price (without tax) * @param string $label Label * @param array $array_option extrafields array + * @param int $fk_unit Id of the unit to use. Null to use the default one * @return int >0 if OK, <0 if KO * * @see add_product @@ -1111,11 +1116,11 @@ class Commande extends CommonOrder * 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) */ - function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $info_bits=0, $fk_remise_except=0, $price_base_type='HT', $pu_ttc=0, $date_start='', $date_end='', $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='',$array_option=0) + function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $info_bits=0, $fk_remise_except=0, $price_base_type='HT', $pu_ttc=0, $date_start='', $date_end='', $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='',$array_option=0, $fk_unit = null) { global $mysoc, $conf, $langs; - dol_syslog(get_class($this)."::addline commandeid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_percent=$remise_percent, info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, date_start=$date_start, date_end=$date_end, type=$type", LOG_DEBUG); + dol_syslog(get_class($this)."::addline commandeid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_percent=$remise_percent, info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, date_start=$date_start, date_end=$date_end, type=$type, fk_unit=$fk_unit", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; @@ -1230,6 +1235,7 @@ class Commande extends CommonOrder $this->line->product_type=$type; $this->line->special_code=$special_code; $this->line->fk_parent_line=$fk_parent_line; + $this->line->fk_unit=$fk_unit; $this->line->date_start=$date_start; $this->line->date_end=$date_end; @@ -1333,6 +1339,7 @@ class Commande extends CommonOrder $line->ref=$prod->ref; $line->libelle=$prod->libelle; $line->product_desc=$prod->description; + $line->fk_unit=$prod->fk_unit; // Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html) // Save the start and end date of the line in the object @@ -1581,6 +1588,7 @@ class Commande extends CommonOrder $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.product_type, l.fk_commande, l.label as custom_label, l.description, l.price, l.qty, l.tva_tx,'; $sql.= ' l.localtax1_tx, l.localtax2_tx, l.fk_remise_except, l.remise_percent, l.subprice, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht, l.rang, l.info_bits, l.special_code,'; $sql.= ' l.total_ht, l.total_ttc, l.total_tva, l.total_localtax1, l.total_localtax2, l.date_start, l.date_end,'; + $sql.= ' l.fk_unit,'; $sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label'; $sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as l'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON (p.rowid = l.fk_product)'; @@ -1638,6 +1646,7 @@ class Commande extends CommonOrder $line->product_label = $objp->product_label; $line->product_desc = $objp->product_desc; // Description produit $line->fk_product_type = $objp->fk_product_type; // Produit ou service + $line->fk_unit = $objp->fk_unit; $line->date_start = $this->db->jdate($objp->date_start); $line->date_end = $this->db->jdate($objp->date_end); @@ -2347,9 +2356,10 @@ class Commande extends CommonOrder * @param string $label Label * @param int $special_code Special code (also used by externals modules!) * @param array $array_option extrafields array + * @param int $fk_unit Id of the unit to use. Null to use the default one * @return int < 0 if KO, > 0 if OK */ - function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0,$txlocaltax2=0.0, $price_base_type='HT', $info_bits=0, $date_start='', $date_end='', $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_option=0) + function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0,$txlocaltax2=0.0, $price_base_type='HT', $info_bits=0, $date_start='', $date_end='', $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_option=0, $fk_unit = null) { global $conf, $mysoc; @@ -2369,6 +2379,7 @@ class Commande extends CommonOrder if (empty($remise)) $remise=0; if (empty($remise_percent)) $remise_percent=0; if (empty($special_code) || $special_code == 3) $special_code=0; + $remise_percent=price2num($remise_percent); $qty=price2num($qty); $pu = price2num($pu); @@ -2441,6 +2452,7 @@ class Commande extends CommonOrder $this->line->product_type=$type; $this->line->fk_parent_line=$fk_parent_line; $this->line->skip_update_total=$skip_update_total; + $this->line->fk_unit=$fk_unit; // infos marge if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { @@ -3121,6 +3133,7 @@ class Commande extends CommonOrder $sql.= ' l.fk_remise_except, 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, l.localtax1_tx, l.localtax2_tx,'; $sql.= ' l.date_start, l.date_end,'; + $sql.= ' l.fk_unit,'; $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, '; $sql.= ' p.description as product_desc, p.stock as stock_reel,'; $sql.= ' p.entity'; @@ -3170,6 +3183,7 @@ class Commande extends CommonOrder $this->lines[$i]->pa_ht = $marginInfos[0]; $this->lines[$i]->marge_tx = $marginInfos[1]; $this->lines[$i]->marque_tx = $marginInfos[2]; + $this->lines[$i]->fk_unit = $obj->fk_unit; $i++; } @@ -3307,6 +3321,7 @@ class OrderLine extends CommonOrderLine $sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_parent_line, cd.fk_product, cd.product_type, cd.label as custom_label, cd.description, cd.price, cd.qty, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx,'; $sql.= ' cd.remise, cd.remise_percent, cd.fk_remise_except, cd.subprice,'; $sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.fk_product_fournisseur_price as fk_fournprice, cd.buy_price_ht as pa_ht, cd.rang, cd.special_code,'; + $sql.= ' cd.fk_unit,'; $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc,'; $sql.= ' cd.date_start, cd.date_end'; $sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as cd'; @@ -3352,6 +3367,7 @@ class OrderLine extends CommonOrderLine $this->libelle = $objp->product_libelle; // deprecated $this->product_label = $objp->product_libelle; $this->product_desc = $objp->product_desc; + $this->fk_unit = $objp->fk_unit; $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); @@ -3468,7 +3484,8 @@ class OrderLine extends CommonOrderLine $sql.= ' tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,'; $sql.= ' fk_product, product_type, remise_percent, subprice, price, remise, fk_remise_except,'; $sql.= ' special_code, rang, fk_product_fournisseur_price, buy_price_ht,'; - $sql.= ' info_bits, total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, date_start, date_end)'; + $sql.= ' info_bits, total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, date_start, date_end,'; + $sql.= ' fk_unit)'; $sql.= " VALUES (".$this->fk_commande.","; $sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").","; $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").","; @@ -3497,7 +3514,8 @@ class OrderLine extends CommonOrderLine $sql.= " '".price2num($this->total_localtax2)."',"; $sql.= " '".price2num($this->total_ttc)."',"; $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.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null").','; + $sql.= ' '.(!$this->fk_unit ? 'NULL' : $this->fk_unit); $sql.= ')'; dol_syslog(get_class($this)."::insert", LOG_DEBUG); @@ -3615,6 +3633,7 @@ class OrderLine extends CommonOrderLine $sql.= " , product_type=".$this->product_type; $sql.= " , fk_parent_line=".(! empty($this->fk_parent_line)?$this->fk_parent_line:"null"); if (! empty($this->rang)) $sql.= ", rang=".$this->rang; + $sql.= " , fk_unit=".(!$this->fk_unit ? 'NULL' : $this->fk_unit); $sql.= " WHERE rowid = ".$this->rowid; dol_syslog(get_class($this)."::update", LOG_DEBUG); diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 3c194a522d3..1804763760d 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1064,7 +1064,7 @@ if (empty($reshook)) $array_option = $lines[$i]->array_options; } - $result = $object->addline($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, $array_option, $lines[$i]->situation_percent, $lines[$i]->fk_prev_id); + $result = $object->addline($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, $array_option, $lines[$i]->situation_percent, $lines[$i]->fk_prev_id, $lines[$i]->fk_unit); if ($result > 0) { $lineid = $result; @@ -1106,7 +1106,7 @@ if (empty($reshook)) $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($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); + $result = $object->addline($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, -1, 0, '', 0, 0, null, 0, '', 0, 100, '', $product->fk_unit); } } } @@ -1252,6 +1252,7 @@ if (empty($reshook)) // Ecrase $desc par celui du produit // Ecrase $txtva par celui du produit // Ecrase $base_price_type par celui du produit + // Replaces $fk_unit with the product's if (! empty($idprod)) { $prod = new Product($db); $prod->fetch($idprod); @@ -1347,6 +1348,7 @@ if (empty($reshook)) } $type = $prod->type; + $fk_unit = $prod->fk_unit; } else { $pu_ht = price2num($price_ht, 'MU'); $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); @@ -1355,6 +1357,11 @@ if (empty($reshook)) $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); $desc = $product_desc; $type = GETPOST('type'); + $fk_unit= GETPOST('units', 'int'); + + if ($fk_unit <= 0) { + $fk_unit = null; + } } // Margin @@ -1374,7 +1381,7 @@ if (empty($reshook)) setEventMessage($mesg, 'errors'); } else { // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $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, $array_option, $_POST['progress']); + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $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, $array_option, $_POST['progress'], '', $fk_unit); if ($result > 0) { @@ -1412,6 +1419,7 @@ if (empty($reshook)) unset($_POST['np_markRate']); unset($_POST['dp_desc']); unset($_POST['idprod']); + unset($_POST['units']); unset($_POST['date_starthour']); unset($_POST['date_startmin']); @@ -1528,7 +1536,10 @@ if (empty($reshook)) // Update line if (! $error) { - $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $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, 0, $array_option, GETPOST('progress')); + $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $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, 0, $array_option, GETPOST('progress'), + $_POST['units']); if ($result >= 0) { if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { @@ -1565,6 +1576,7 @@ if (empty($reshook)) unset($_POST['dp_desc']); unset($_POST['idprod']); + unset($_POST['units']); unset($_POST['date_starthour']); unset($_POST['date_startmin']); diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 40ab9119998..111fcf2b684 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2009-2012 Regis Houssin * Copyright (C) 2010-2011 Juanjo Menent + * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013 Florian Henry * * This program is free software; you can redistribute it and/or modify @@ -161,7 +162,8 @@ class FactureRec extends Facture $facsrc->lines[$i]->product_type, $facsrc->lines[$i]->rang, $facsrc->lines[$i]->special_code, - $facsrc->lines[$i]->label + $facsrc->lines[$i]->label, + $facsrc->lines[$i]->fk_unit ); if ($result_insert < 0) @@ -299,6 +301,7 @@ class FactureRec extends Facture $sql.= ' l.remise, l.remise_percent, l.subprice,'; $sql.= ' l.total_ht, l.total_tva, l.total_ttc,'; $sql.= ' l.rang, l.special_code,'; + $sql.= ' l.fk_unit,'; $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_rec as l'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; @@ -341,6 +344,7 @@ class FactureRec extends Facture $line->code_ventilation = $objp->fk_code_ventilation; $line->rang = $objp->rang; $line->special_code = $objp->special_code; + $line->fk_unit = $objp->fk_unit; // Ne plus utiliser $line->price = $objp->price; @@ -412,11 +416,11 @@ class FactureRec extends Facture * @param string $label Label of the line * @return int <0 if KO, Id of line if OK */ - function addline($desc, $pu_ht, $qty, $txtva, $fk_product=0, $remise_percent=0, $price_base_type='HT', $info_bits=0, $fk_remise_except='', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $label='') + function addline($desc, $pu_ht, $qty, $txtva, $fk_product=0, $remise_percent=0, $price_base_type='HT', $info_bits=0, $fk_remise_except='', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $label='', $fk_unit= null) { $facid=$this->id; - dol_syslog("FactureRec::addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,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); + dol_syslog("FactureRec::addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,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,fk_unit=$fk_unit", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; // Check parameters @@ -476,6 +480,7 @@ class FactureRec extends Facture $sql.= ", total_ttc"; $sql.= ", rang"; $sql.= ", special_code"; + $sql.= ", fk_unit"; $sql.= ") VALUES ("; $sql.= "'".$facid."'"; $sql.= ", ".(! empty($label)?"'".$this->db->escape($label)."'":"null"); @@ -492,7 +497,8 @@ class FactureRec extends Facture $sql.= ", '".price2num($total_tva)."'"; $sql.= ", '".price2num($total_ttc)."'"; $sql.= ", ".$rang; - $sql.= ", ".$special_code.")"; + $sql.= ", ".$special_code; + $sql.= ", ".$fk_unit.")"; dol_syslog(get_class($this)."::addline", LOG_DEBUG); if ($this->db->query($sql)) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 0c277014a64..25c70392647 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -36,6 +36,7 @@ */ include_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php'; +require_once DOL_DOCUMENT_ROOT ."/core/class/commonobjectline.class.php"; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php'; require_once DOL_DOCUMENT_ROOT.'/margin/lib/margins.lib.php'; @@ -436,7 +437,8 @@ class Facture extends CommonInvoice $this->lines[$i]->label, $this->lines[$i]->array_options, $this->lines[$i]->situation_percent, - $this->lines[$i]->fk_prev_id + $this->lines[$i]->fk_prev_id, + $this->lines[$i]->fk_unit ); if ($result < 0) { @@ -490,7 +492,9 @@ class Facture extends CommonInvoice 0, $_facrec->lines[$i]->label, null, - $_facrec->lines[$i]->situation_percent + $_facrec->lines[$i]->situation_percent, + '', + $_facrec->lines[$i]->fk_unit ); if ( $result_insert < 0) @@ -782,6 +786,7 @@ class Facture extends CommonInvoice $line->rang = $object->lines[$i]->rang; $line->special_code = $object->lines[$i]->special_code; $line->fk_parent_line = $object->lines[$i]->fk_parent_line; + $line->fk_unit = $object->lines[$i]->fk_unit; $line->fk_fournprice = $object->lines[$i]->fk_fournprice; $marginInfos = getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht); @@ -1040,6 +1045,7 @@ class Facture extends CommonInvoice $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.= ' l.fk_unit,'; $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'; @@ -1097,6 +1103,7 @@ class Facture extends CommonInvoice $line->fk_parent_line = $objp->fk_parent_line; $line->situation_percent= $objp->situation_percent; $line->fk_prev_id = $objp->fk_prev_id; + $line->fk_unit = $objp->fk_unit; $this->lines[$i] = $line; @@ -2037,13 +2044,14 @@ class Facture extends CommonInvoice * @param array $array_option extrafields array * @param int $situation_percent Situation advance percentage * @param int $fk_prev_id Previous situation line id reference + * @param int $fk_unit Id of the unit to use. Null to use the default one * @return int <0 if KO, Id of line if OK */ - function addline($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=self::TYPE_STANDARD, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='', $array_option=0, $situation_percent=100, $fk_prev_id='') + function addline($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=self::TYPE_STANDARD, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='', $array_option=0, $situation_percent=100, $fk_prev_id='', $fk_unit = null) { global $mysoc, $conf, $langs; - dol_syslog(get_class($this)."::addline facid=$this->id,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); + dol_syslog(get_class($this)."::addline facid=$this->id,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, fk_unit=$fk_unit", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; // Clean parameters @@ -2157,6 +2165,7 @@ class Facture extends CommonInvoice $this->line->origin_id=$origin_id; $this->line->situation_percent = $situation_percent; $this->line->fk_prev_id = $fk_prev_id; + $this->line->fk_unit=$fk_unit; // infos marge $this->line->fk_fournprice = $fk_fournprice; @@ -2219,15 +2228,16 @@ class Facture extends CommonInvoice * @param int $special_code Special code (also used by externals modules!) * @param array $array_option extrafields array * @param int $situation_percent Situation advance percentage + * @param int $fk_unit Id of the unit to use. Null to use the default one * @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= self::TYPE_STANDARD, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_option=0, $situation_percent=0) + 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= self::TYPE_STANDARD, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_option=0, $situation_percent=0, $fk_unit = null) { include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; global $mysoc; - 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, $fk_unit", LOG_DEBUG); if ($this->brouillon) { @@ -2239,7 +2249,6 @@ class Facture extends CommonInvoice if (empty($special_code) || $special_code == 3) $special_code=0; if ($situation_percent > 100 || is_null($situation_percent) || $situation_percent == "") $situation_percent = 100; - $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); @@ -2308,7 +2317,7 @@ class Facture extends CommonInvoice $this->line->fk_parent_line = $fk_parent_line; $this->line->skip_update_total = $skip_update_total; $this->line->situation_percent = $situation_percent; - + $this->line->fk_unit = $fk_unit; // infos marge if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { @@ -3367,6 +3376,7 @@ class Facture extends CommonInvoice $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.= ' l.fk_unit,'; $sql.= ' p.ref as product_ref, p.fk_product_type, p.label as product_label,'; $sql.= ' p.description as product_desc,'; $sql.= ' p.entity'; @@ -3418,6 +3428,7 @@ class Facture extends CommonInvoice $this->lines[$i]->pa_ht = $marginInfos[0]; $this->lines[$i]->marge_tx = $marginInfos[1]; $this->lines[$i]->marque_tx = $marginInfos[2]; + $this->lines[$i]->fk_unit = $obj->fk_unit; $i++; } @@ -3694,6 +3705,7 @@ class FactureLigne extends CommonInvoiceLine $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.special_code, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,'; $sql.= ' fd.fk_code_ventilation,'; + $sql.= ' fd.fk_unit,'; $sql.= ' fd.situation_percent, fd.fk_prev_id,'; $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd'; @@ -3741,6 +3753,7 @@ class FactureLigne extends CommonInvoiceLine $this->libelle = $objp->product_libelle; // deprecated $this->product_label = $objp->product_libelle; $this->product_desc = $objp->product_desc; + $this->fk_unit = $objp->fk_unit; $this->situation_percent = $objp->situation_percent; $this->fk_prev_id = $objp->fk_prev_id; @@ -3828,7 +3841,8 @@ class FactureLigne extends CommonInvoiceLine $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.= ' situation_percent, fk_prev_id)'; + $sql.= ' situation_percent, fk_prev_id,'; + $sql.= ' fk_unit)'; $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").","; @@ -3859,6 +3873,7 @@ class FactureLigne extends CommonInvoiceLine $sql.= " ".price2num($this->total_localtax2); $sql .= ", " . $this->situation_percent; $sql .= ", " . $this->fk_prev_id; + $sql .= ", ".(!$this->fk_unit ? 'NULL' : $this->fk_unit); $sql.= ')'; dol_syslog(get_class($this)."::insert", LOG_DEBUG); @@ -4023,6 +4038,7 @@ class FactureLigne extends CommonInvoiceLine $sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null"); if (! empty($this->rang)) $sql.= ", rang=".$this->rang; $sql .= ", situation_percent=" . $this->situation_percent; + $sql .= ", fk_unit=".(!$this->fk_unit ? 'NULL' : $this->fk_unit); $sql.= " WHERE rowid = ".$this->rowid; dol_syslog(get_class($this)."::update", LOG_DEBUG); diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 1fd4d2c80fc..95fd7121998 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -2,6 +2,7 @@ /* Copyright (C) 2002-2003 Rodolphe Quiedeville * Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013 Florian Henry * Copyright (C) 2013 Juanjo Menent * @@ -201,6 +202,7 @@ if ($action == 'create') $sql.= ' l.date_start,'; $sql.= ' l.date_end,'; $sql.= ' l.product_type,'; + $sql.= ' l.fk_unit,'; $sql.= ' p.ref, p.fk_product_type, p.label as product_label,'; $sql.= ' p.description as product_desc'; $sql.= " FROM ".MAIN_DB_PREFIX."facturedet as l"; @@ -221,6 +223,9 @@ if ($action == 'create') print ''.$langs->trans("Description").''; print ''.$langs->trans("VAT").''; print ''.$langs->trans("Qty").''; + if ($conf->global->PRODUCT_USE_UNITS) { + print ''.$langs->trans("Unit").''; + } print ''.$langs->trans("ReductionShort").''; print ''.$langs->trans("TotalHT").''; print ''.$langs->trans("TotalVAT").''; @@ -245,6 +250,7 @@ if ($action == 'create') // Show product and description $type=(isset($objp->product_type)?$objp->product_type:$objp->fk_product_type); + $product_static->fk_unit=$objp->fk_unit; if ($objp->fk_product > 0) { @@ -298,6 +304,10 @@ if ($action == 'create') // Qty print ''.$objp->qty.''; + if ($conf->global->PRODUCT_USE_UNITS) { + print ''.$product_static->get_unit_label().''; + } + // Percent if ($objp->remise_percent > 0) { @@ -444,7 +454,11 @@ else print ''.$langs->trans("Description").''; print ''.$langs->trans("Price").''; print ''.$langs->trans("ReductionShort").''; - print ''.$langs->trans("Qty").''; + print ''.$langs->trans("Qty").''; + if ($conf->global->PRODUCT_USE_UNITS) { + print ''.$langs->trans("Unit").''; + } + print ''; $num = count($object->lines); $i = 0; @@ -511,7 +525,11 @@ else } print ''.price($object->lines[$i]->price).''; print ''.$object->lines[$i]->remise_percent.' %'; - print ''.$object->lines[$i]->qty.''."\n"; + print ''.$object->lines[$i]->qty.''; + if ($conf->global->PRODUCT_USE_UNITS) { + print "".$object->lines[$i]->get_unit_label().""; + } + print "\n"; $i++; } print ''; diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 731ad1c6cc1..3a38c8e4ffb 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -490,6 +490,7 @@ else if ($action == 'addline' && $user->rights->contrat->creer) $desc=$prod->description; $desc=dol_concatdesc($desc,$product_desc); + $fk_unit = $prod->fk_unit; } else { @@ -498,6 +499,11 @@ else if ($action == 'addline' && $user->rights->contrat->creer) $tva_tx=GETPOST('tva_tx')?str_replace('*','',GETPOST('tva_tx')):0; // tva_tx field may be disabled, so we use vat rate 0 $tva_npr=preg_match('/\*/',GETPOST('tva_tx'))?1:0; $desc=$product_desc; + $fk_unit= GETPOST('units', 'int'); + + if ($fk_unit <= 0) { + $fk_unit = null; + } } $localtax1_tx=get_localtax($tva_tx,1,$object->thirdparty); @@ -537,7 +543,8 @@ else if ($action == 'addline' && $user->rights->contrat->creer) $info_bits, $fk_fournprice, $pa_ht, - $array_option + $array_option, + $fk_unit ); } @@ -618,6 +625,8 @@ else if ($action == 'updateligne' && $user->rights->contrat->creer && ! GETPOST( else $pa_ht = null; + $fk_unit = GETPOST('unit', 'int'); + $objectline->description=GETPOST('product_desc'); $objectline->price_ht=GETPOST('elprice'); $objectline->subprice=GETPOST('elprice'); @@ -634,6 +643,12 @@ else if ($action == 'updateligne' && $user->rights->contrat->creer && ! GETPOST( $objectline->fk_fournprice=$fk_fournprice; $objectline->pa_ht=$pa_ht; + if ($fk_unit > 0) { + $objectline->fk_unit = $_POST['unit']; + } else { + $objectline->fk_unit = null; + } + // Extrafields $extrafieldsline = new ExtraFields($db); $extralabelsline = $extrafieldsline->fetch_name_optionals_label($objectline->table_element); @@ -1286,6 +1301,7 @@ else $sql.= " cd.date_ouverture_prevue as date_debut, cd.date_ouverture as date_debut_reelle,"; $sql.= " cd.date_fin_validite as date_fin, cd.date_cloture as date_fin_reelle,"; $sql.= " cd.commentaire as comment, cd.fk_product_fournisseur_price as fk_fournprice, cd.buy_price_ht as pa_ht,"; + $sql.= " cd.fk_unit,"; $sql.= " p.rowid as pid, p.ref as pref, p.label as label, p.fk_product_type as ptype"; $sql.= " FROM ".MAIN_DB_PREFIX."contratdet as cd"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid"; @@ -1301,6 +1317,7 @@ else print ''.$langs->trans("VAT").''; print ''.$langs->trans("PriceUHT").''; print ''.$langs->trans("Qty").''; + if($conf->global->PRODUCT_USE_UNITS) print ''.$langs->trans("Unit").''; print ''.$langs->trans("ReductionShort").''; if (! empty($conf->margin->enabled) && ! empty($conf->global->MARGIN_SHOW_ON_CONTRACT)) print ''.$langs->trans("BuyingPrice").''; print ' '; @@ -1343,6 +1360,8 @@ else print ''.price($objp->subprice)."\n"; // Quantite print ''.$objp->qty.''; + //Unit + if($conf->global->PRODUCT_USE_UNITS) print ''.$langs->trans($object->lines[$cursorline-1]->get_unit_label()).''; // Remise if ($objp->remise_percent > 0) { @@ -1390,8 +1409,16 @@ else // Dates de en service prevues et effectives if ($objp->subprice >= 0) { + $colspan = 6; + + if ($conf->margin->enabled && $conf->global->PRODUCT_USE_UNITS) { + $colspan = 8; + } elseif ($conf->margin->enabled || $conf->global->PRODUCT_USE_UNITS) { + $colspan = 7; + } + print ''; - print ''; + print ''; // Date planned print $langs->trans("DateStartPlanned").': '; @@ -1459,6 +1486,12 @@ else print ''; print ''; print ''; + if($conf->global->PRODUCT_USE_UNITS) + { + print ''; + $form->select_units($objp->fk_unit, "unit"); + print ''; + } print '%'; if (! empty($usemargins)) { @@ -1472,6 +1505,7 @@ else $colspan=5; if (! empty($conf->margin->enabled) && ! empty($conf->global->MARGIN_SHOW_ON_CONTRACT)) $colspan++; + if($conf->global->PRODUCT_USE_UNITS) $colspan++; // Ligne dates prevues print ""; diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index bb00a5d9838..8031ca85ebe 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -30,6 +30,7 @@ */ require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT."/core/class/commonobjectline.class.php"; require_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; require_once DOL_DOCUMENT_ROOT . '/margin/lib/margins.lib.php'; @@ -655,7 +656,8 @@ class Contrat extends CommonObject $sql.= " d.date_fin_validite, d.date_cloture,"; $sql.= " d.fk_user_author,"; $sql.= " d.fk_user_ouverture,"; - $sql.= " d.fk_user_cloture"; + $sql.= " d.fk_user_cloture,"; + $sql.= " d.fk_unit"; $sql.= " FROM ".MAIN_DB_PREFIX."contratdet as d, ".MAIN_DB_PREFIX."product as p"; $sql.= " WHERE d.fk_contrat = ".$this->id ." AND d.fk_product = p.rowid"; $sql.= " ORDER by d.rowid ASC"; @@ -700,6 +702,7 @@ class Contrat extends CommonObject $line->fk_user_author = $objp->fk_user_author; $line->fk_user_ouverture= $objp->fk_user_ouverture; $line->fk_user_cloture = $objp->fk_user_cloture; + $line->fk_unit = $objp->fk_unit; $line->ref = $objp->ref; $line->libelle = $objp->label; // Label produit @@ -754,7 +757,8 @@ class Contrat extends CommonObject $sql.= " d.date_fin_validite, d.date_cloture,"; $sql.= " d.fk_user_author,"; $sql.= " d.fk_user_ouverture,"; - $sql.= " d.fk_user_cloture"; + $sql.= " d.fk_user_cloture,"; + $sql.= " d.fk_unit"; $sql.= " FROM ".MAIN_DB_PREFIX."contratdet as d"; $sql.= " WHERE d.fk_contrat = ".$this->id; $sql.= " AND (d.fk_product IS NULL OR d.fk_product = 0)"; // fk_product = 0 gardee pour compatibilitee @@ -807,6 +811,7 @@ class Contrat extends CommonObject $line->date_debut_reel = $this->db->jdate($objp->date_ouverture); $line->date_fin_prevue = $this->db->jdate($objp->date_fin_validite); $line->date_fin_reel = $this->db->jdate($objp->date_cloture); + $line->fk_unit = $objp->fk_unit; if ($line->statut == 0) $this->nbofserviceswait++; if ($line->statut == 4 && (empty($line->date_fin_prevue) || $line->date_fin_prevue >= $now)) $this->nbofservicesopened++; @@ -1240,9 +1245,10 @@ class Contrat extends CommonObject * @param int $fk_fournprice Fourn price id * @param int $pa_ht Buying price HT * @param array $array_option extrafields array + * @param int $fk_unit Id of the unit to use. Null to use the default one * @return int <0 si erreur, >0 si ok */ - function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $date_start, $date_end, $price_base_type='HT', $pu_ttc=0.0, $info_bits=0, $fk_fournprice=null, $pa_ht = 0,$array_option=0) + function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $date_start, $date_end, $price_base_type='HT', $pu_ttc=0.0, $info_bits=0, $fk_fournprice=null, $pa_ht = 0,$array_option=0, $fk_unit = null) { global $user, $langs, $conf, $mysoc; @@ -1259,6 +1265,7 @@ class Contrat extends CommonObject if (! $info_bits) $info_bits=0; if (! $pu_ht) $pu_ht=0; if (! $pu_ttc) $pu_ttc=0; + $pu_ht=price2num($pu_ht); $pu_ttc=price2num($pu_ttc); $pa_ht=price2num($pa_ht); @@ -1322,6 +1329,7 @@ class Contrat extends CommonObject $sql.= " price_ht, remise, fk_product_fournisseur_price, buy_price_ht"; if ($date_start > 0) { $sql.= ",date_ouverture_prevue"; } if ($date_end > 0) { $sql.= ",date_fin_validite"; } + $sql.= ", fk_unit"; $sql.= ") VALUES ($this->id, '', '" . $this->db->escape($desc) . "',"; $sql.= ($fk_product>0 ? $fk_product : "null").","; $sql.= " '".$qty."',"; @@ -1340,6 +1348,7 @@ class Contrat extends CommonObject else $sql.= ' null'; if ($date_start > 0) { $sql.= ",'".$this->db->idate($date_start)."'"; } if ($date_end > 0) { $sql.= ",'".$this->db->idate($date_end)."'"; } + $sql.= ", ".$fk_unit; $sql.= ")"; dol_syslog(get_class($this)."::addline", LOG_DEBUG); @@ -1418,9 +1427,10 @@ class Contrat extends CommonObject * @param int $fk_fournprice Fourn price id * @param int $pa_ht Buying price HT * @param array $array_option extrafields array + * @param int $fk_unit Id of the unit to use. Null to use the default one * @return int < 0 si erreur, > 0 si ok */ - function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $tvatx, $localtax1tx=0.0, $localtax2tx=0.0, $date_debut_reel='', $date_fin_reel='', $price_base_type='HT', $info_bits=0, $fk_fournprice=null, $pa_ht = 0,$array_option=0) + function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $tvatx, $localtax1tx=0.0, $localtax2tx=0.0, $date_debut_reel='', $date_fin_reel='', $price_base_type='HT', $info_bits=0, $fk_fournprice=null, $pa_ht = 0,$array_option=0, $fk_unit = null) { global $user, $conf, $langs, $mysoc; @@ -1511,6 +1521,7 @@ class Contrat extends CommonObject else { $sql.=",date_ouverture=null"; } if ($date_fin_reel > 0) { $sql.= ",date_cloture='".$this->db->idate($date_fin_reel)."'"; } else { $sql.=",date_cloture=null"; } + $sql .= ", fk_unit=".$fk_unit; $sql .= " WHERE rowid = ".$rowid; dol_syslog(get_class($this)."::updateline", LOG_DEBUG); @@ -2127,7 +2138,7 @@ class Contrat extends CommonObject /** * Classe permettant la gestion des lignes de contrats */ -class ContratLigne extends CommonObject +class ContratLigne extends CommonObjectLine { var $id; @@ -2347,7 +2358,8 @@ class ContratLigne extends CommonObject $sql.= " t.fk_user_author,"; $sql.= " t.fk_user_ouverture,"; $sql.= " t.fk_user_cloture,"; - $sql.= " t.commentaire"; + $sql.= " t.commentaire,"; + $sql.= " t.fk_unit"; $sql.= " FROM ".MAIN_DB_PREFIX."contratdet as t"; if ($id) $sql.= " WHERE t.rowid = ".$id; if ($ref) $sql.= " WHERE t.rowid = '".$this->db->escape($ref)."'"; @@ -2396,6 +2408,7 @@ class ContratLigne extends CommonObject $this->fk_fournprice = $obj->fk_fournprice; $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->fk_fournprice, $obj->pa_ht); $this->pa_ht = $marginInfos[0]; + $this->fk_unit = $obj->fk_unit; } $this->db->free($resql); @@ -2506,6 +2519,7 @@ class ContratLigne extends CommonObject $sql.= " fk_user_ouverture=".($this->fk_user_ouverture > 0?$this->fk_user_ouverture:"NULL").","; $sql.= " fk_user_cloture=".($this->fk_user_cloture > 0?$this->fk_user_cloture:"NULL").","; $sql.= " commentaire='".$this->db->escape($this->commentaire)."'"; + $sql.= ", fk_unit=".(!$this->fk_unit ? 'NULL' : $this->fk_unit); $sql.= " WHERE rowid=".$this->id; dol_syslog(get_class($this)."::update", LOG_DEBUG); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index da9971b1b4e..51dbbbe9c6e 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -8,6 +8,7 @@ * Copyright (C) 2011-2014 Philippe Grand * Copyright (C) 2012-2014 Marcos García * Copyright (C) 2012-2014 Raphaël Doursenaud + * Copyright (C) 2012 Cedric Salvador * * 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 @@ -2592,6 +2593,11 @@ abstract class CommonObject // Qty print ''; + if($conf->global->PRODUCT_USE_UNITS) + { + print ''.$langs->trans('Unit').''; + } + // Reduction short print ''; @@ -2794,7 +2800,7 @@ abstract class CommonObject */ function printOriginLinesList() { - global $langs, $hookmanager; + global $langs, $hookmanager, $conf; print ''; print ''.$langs->trans('Ref').''; @@ -2802,6 +2808,10 @@ abstract class CommonObject print ''.$langs->trans('VAT').''; print ''.$langs->trans('PriceUHT').''; print ''.$langs->trans('Qty').''; + if($conf->global->PRODUCT_USE_UNITS) + { + print ''.$langs->trans('Unit').''; + } print ''.$langs->trans('ReductionShort').''; $num = count($this->lines); @@ -2842,7 +2852,7 @@ abstract class CommonObject */ function printOriginLine($line,$var) { - global $conf,$langs,$bc; + global $conf,$langs,$bc, $conf; //var_dump($line); if (!empty($line->date_start)) @@ -2929,6 +2939,7 @@ abstract class CommonObject $this->tpl['vat_rate'] = vatrate($line->tva_tx, true); $this->tpl['price'] = price($line->subprice); $this->tpl['qty'] = (($line->info_bits & 2) != 2) ? $line->qty : ' '; + if($conf->global->PRODUCT_USE_UNITS) $this->tpl['unit'] = $line->get_unit_label('long'); $this->tpl['remise_percent'] = (($line->info_bits & 2) != 2) ? vatrate($line->remise_percent, true) : ' '; // Output template part (modules that overwrite templates must declare this into descriptor) diff --git a/htdocs/core/class/commonobjectline.class.php b/htdocs/core/class/commonobjectline.class.php index c3c8d823a34..b72a2d28681 100644 --- a/htdocs/core/class/commonobjectline.class.php +++ b/htdocs/core/class/commonobjectline.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2012 Cedric Salvador * * 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 @@ -28,8 +29,57 @@ */ abstract class CommonObjectLine extends CommonObject { + //! Database handler + public $db; + + /** + * Product/service unit + * @var int + */ + public $fk_unit; // TODO + /** + * Returns the text label from units dictionnary + * + * @param string $type Label type (long or short) + * @return string|int <0 if ko, label if ok + */ + public function get_unit_label($type='long') + { + global $langs; + + if (!$this->fk_unit) { + return ''; + } + + $langs->load('products'); + + $this->db->begin(); + + $label_type = 'label'; + + if ($type == 'short') + { + $label_type = 'short_label'; + } + + $sql = 'select '.$label_type.' from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; + $resql = $this->db->query($sql); + if($resql && $this->db->num_rows($resql) > 0) + { + $res = $this->db->fetch_array($resql); + $label = $res[$label_type]; + $this->db->free($resql); + return $label; + } + else + { + $this->error=$this->db->error().' sql='.$sql; + dol_syslog(get_class($this)."::get_unit_label Error ".$this->error, LOG_ERR); + return -1; + } + } // Currently we need function at end of file CommonObject for all object lines. Should find a way to avoid duplicate code. // For the moment we use the extends on CommonObject until PHP min is 5.4 so use Traits. diff --git a/htdocs/core/class/commonorder.class.php b/htdocs/core/class/commonorder.class.php index 469e1676a53..3e30b0a9ca6 100644 --- a/htdocs/core/class/commonorder.class.php +++ b/htdocs/core/class/commonorder.class.php @@ -22,6 +22,7 @@ */ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT .'/core/class/commonobjectline.class.php'; /** * \class CommonOrder @@ -36,7 +37,7 @@ abstract class CommonOrder extends CommonObject * \class CommonOrderLine * \brief Superclass for orders classes */ -abstract class CommonOrderLine extends CommonObject +abstract class CommonOrderLine extends CommonObjectLine { } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 6a6474c8306..13035b145e8 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2728,6 +2728,54 @@ class Form return $opt; } + /** + * Prints units selector + * + * @param string $selected Preselected ID + * @param string $htmlname Select name + * @return void + */ + function select_units($selected = '', $htmlname = 'units') + { + print $this->load_units($selected, $htmlname); + } + + /** + * Creates HTML units selector + * + * @param string $selected Preselected ID + * @param string $htmlname Select name + * @return string HTML select + */ + function load_units($selected = '', $htmlname = 'units') + { + global $langs; + + $langs->load('products'); + + $return= ''; + } + return $return; + } + /** * Return a HTML select list of bank accounts * diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 1c5ae62d014..ca1be2c7604 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1420,6 +1420,43 @@ function pdf_getlineqty_keeptoship($object,$i,$outputlangs,$hidedetails=0) } } +/** + * Return line unit + * + * @param Object $object Object + * @param int $i Current line number + * @param Translate $outputlangs Object langs for output + * @param int $hidedetails Hide details (0=no, 1=yes, 2=just special lines) + * @param HookManager $hookmanager Hook manager instance + * @return void + */ +function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = false) +{ + global $langs; + if ($object->lines[$i]->special_code != 3) { + if (is_object($hookmanager) && (($object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line))) { + $special_code = $object->lines[$i]->special_code; + if (!empty($object->lines[$i]->fk_parent_line)) { + $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line); + } + $parameters = array( + 'i' => $i, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails, + 'special_code' => $special_code + ); + $action = ''; + return $hookmanager->executeHooks('pdf_getlineunit', $parameters, $object, + $action); // Note that $action and $object may have been modified by some hooks + } else { + if (empty($hidedetails) || $hidedetails > 1) { + return $langs->transnoentitiesnoconv($object->lines[$i]->get_unit_label('short')); + } + } + } +} + + /** * Return line remise percent * diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php index f6d28a4f135..70b8c8f2dfe 100644 --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php @@ -4,6 +4,7 @@ * Copyright (C) 2008 Raphael Bertrand * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador * * 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 @@ -68,6 +69,7 @@ class pdf_einstein extends ModelePDFCommandes $langs->load("main"); $langs->load("bills"); + $langs->load("products"); $this->db = $db; $this->name = "einstein"; @@ -103,9 +105,19 @@ class pdf_einstein extends ModelePDFCommandes // Define position of columns $this->posxdesc=$this->marge_gauche+1; - $this->posxtva=112; - $this->posxup=126; - $this->posxqty=145; + if($conf->global->PRODUCT_USE_UNITS) + { + $this->posxtva=99; + $this->posxup=114; + $this->posxqty=133; + $this->posxunit=150; + } + else + { + $this->posxtva=112; + $this->posxup=126; + $this->posxqty=145; + } $this->posxdiscount=162; $this->postotalht=174; if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) $this->posxtva=$this->posxup; @@ -239,7 +251,7 @@ class pdf_einstein extends ModelePDFCommandes $this->atleastonediscount++; } } - if (empty($this->atleastonediscount)) + if (empty($this->atleastonediscount) && empty($conf->global->PRODUCT_USE_UNITS)) { $this->posxpicture+=($this->postotalht - $this->posxdiscount); $this->posxtva+=($this->postotalht - $this->posxdiscount); @@ -380,9 +392,26 @@ class pdf_einstein extends ModelePDFCommandes // Quantity $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxqty, $curY); - $pdf->MultiCell($this->posxdiscount-$this->posxqty-0.8, 3, $qty, 0, 'R'); // Enough for 6 chars + // Enough for 6 chars + if($conf->global->PRODUCT_USE_UNITS) + { + $pdf->MultiCell($this->posxunit-$this->posxqty-0.8, 4, $qty, 0, 'R'); + } + else + { + $pdf->MultiCell($this->posxdiscount-$this->posxqty-0.8, 4, $qty, 0, 'R'); + } + + // Unit + if($conf->global->PRODUCT_USE_UNITS) + { + $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); + $pdf->SetXY($this->posxunit, $curY); + $pdf->MultiCell($this->posxdiscount-$this->posxunit-0.8, 4, $unit, 0, 'L'); + } // Discount on line + $pdf->SetXY($this->posxdiscount, $curY); if ($object->lines[$i]->remise_percent) { $pdf->SetXY($this->posxdiscount-2, $curY); @@ -540,7 +569,7 @@ class pdf_einstein extends ModelePDFCommandes /** * Show payments table * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object order * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output @@ -555,7 +584,7 @@ class pdf_einstein extends ModelePDFCommandes /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -739,7 +768,7 @@ class pdf_einstein extends ModelePDFCommandes /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Montant deja regle * @param int $posy Position depart @@ -996,7 +1025,7 @@ class pdf_einstein extends ModelePDFCommandes /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1064,7 +1093,23 @@ class pdf_einstein extends ModelePDFCommandes if (empty($hidetop)) { $pdf->SetXY($this->posxqty-1, $tab_top+1); - $pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C'); + if($conf->global->PRODUCT_USE_UNITS) + { + $pdf->MultiCell($this->posxunit-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C'); + } + else + { + $pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C'); + } + } + + if($conf->global->PRODUCT_USE_UNITS) { + $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height); + if (empty($hidetop)) { + $pdf->SetXY($this->posxunit - 1, $tab_top + 1); + $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("Unit"), '', + 'C'); + } } $pdf->line($this->posxdiscount-1, $tab_top, $this->posxdiscount-1, $tab_top + $tab_height); @@ -1091,7 +1136,7 @@ class pdf_einstein extends ModelePDFCommandes /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1270,7 +1315,7 @@ class pdf_einstein extends ModelePDFCommandes /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 4c340a12cfa..1c0fa822bb9 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -115,9 +115,19 @@ class pdf_crabe extends ModelePDFFactures // Define position of columns $this->posxdesc=$this->marge_gauche+1; - $this->posxtva=112; - $this->posxup=126; - $this->posxqty=145; + if($conf->global->PRODUCT_USE_UNITS) + { + $this->posxtva=99; + $this->posxup=114; + $this->posxqty=133; + $this->posxunit=150; + } + else + { + $this->posxtva=112; + $this->posxup=126; + $this->posxqty=145; + } $this->posxdiscount=162; $this->posxprogress=174; // Only displayed for situation invoices $this->postotalht=174; @@ -282,7 +292,7 @@ class pdf_crabe extends ModelePDFFactures $this->atleastonediscount++; } } - if (empty($this->atleastonediscount)) + if (empty($this->atleastonediscount) && empty($conf->global->PRODUCT_USE_UNITS)) { $this->posxpicture+=($this->postotalht - $this->posxdiscount); $this->posxtva+=($this->postotalht - $this->posxdiscount); @@ -463,7 +473,23 @@ class pdf_crabe extends ModelePDFFactures // Quantity $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxqty, $curY); - $pdf->MultiCell($this->posxdiscount-$this->posxqty-0.8, 3, $qty, 0, 'R'); // Enough for 6 chars + // Enough for 6 chars + if($conf->global->PRODUCT_USE_UNITS) + { + $pdf->MultiCell($this->posxunit-$this->posxqty-0.8, 4, $qty, 0, 'R'); + } + else + { + $pdf->MultiCell($this->posxdiscount-$this->posxqty-0.8, 4, $qty, 0, 'R'); + } + + // Unit + if($conf->global->PRODUCT_USE_UNITS) + { + $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); + $pdf->SetXY($this->posxunit, $curY); + $pdf->MultiCell($this->posxdiscount-$this->posxunit-0.8, 4, $unit, 0, 'L'); + } // Discount on line if ($object->lines[$i]->remise_percent) @@ -1303,7 +1329,23 @@ class pdf_crabe extends ModelePDFFactures if (empty($hidetop)) { $pdf->SetXY($this->posxqty-1, $tab_top+1); - $pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C'); + if($conf->global->PRODUCT_USE_UNITS) + { + $pdf->MultiCell($this->posxunit-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C'); + } + else + { + $pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C'); + } + } + + if($conf->global->PRODUCT_USE_UNITS) { + $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height); + if (empty($hidetop)) { + $pdf->SetXY($this->posxunit - 1, $tab_top + 1); + $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("Unit"), '', + 'C'); + } } $pdf->line($this->posxdiscount-1, $tab_top, $this->posxdiscount-1, $tab_top + $tab_height); diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index 35953b8521f..402cfcae8fc 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -4,6 +4,7 @@ * Copyright (C) 2008 Raphael Bertrand * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador * * 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 @@ -102,9 +103,19 @@ class pdf_azur extends ModelePDFPropales // Define position of columns $this->posxdesc=$this->marge_gauche+1; - $this->posxtva=112; - $this->posxup=126; - $this->posxqty=145; + if($conf->global->PRODUCT_USE_UNITS) + { + $this->posxtva=99; + $this->posxup=114; + $this->posxqty=133; + $this->posxunit=150; + } + else + { + $this->posxtva=112; + $this->posxup=126; + $this->posxqty=145; + } $this->posxdiscount=162; $this->postotalht=174; if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) $this->posxtva=$this->posxup; @@ -265,7 +276,7 @@ class pdf_azur extends ModelePDFPropales $this->atleastonediscount++; } } - if (empty($this->atleastonediscount)) + if (empty($this->atleastonediscount) && empty($conf->global->PRODUCT_USE_UNITS)) { $this->posxpicture+=($this->postotalht - $this->posxdiscount); $this->posxtva+=($this->postotalht - $this->posxdiscount); @@ -436,9 +447,26 @@ class pdf_azur extends ModelePDFPropales // Quantity $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxqty, $curY); - $pdf->MultiCell($this->posxdiscount-$this->posxqty-0.8, 3, $qty, 0, 'R'); // Enough for 6 chars + // Enough for 6 chars + if($conf->global->PRODUCT_USE_UNITS) + { + $pdf->MultiCell($this->posxunit-$this->posxqty-0.8, 4, $qty, 0, 'R'); + } + else + { + $pdf->MultiCell($this->posxdiscount-$this->posxqty-0.8, 4, $qty, 0, 'R'); + } + + // Unit + if($conf->global->PRODUCT_USE_UNITS) + { + $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); + $pdf->SetXY($this->posxunit, $curY); + $pdf->MultiCell($this->posxdiscount-$this->posxunit-0.8, 4, $unit, 0, 'L'); + } // Discount on line + $pdf->SetXY($this->posxdiscount, $curY); if ($object->lines[$i]->remise_percent) { $pdf->SetXY($this->posxdiscount-2, $curY); @@ -1143,7 +1171,23 @@ class pdf_azur extends ModelePDFPropales if (empty($hidetop)) { $pdf->SetXY($this->posxqty-1, $tab_top+1); - $pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C'); + if($conf->global->PRODUCT_USE_UNITS) + { + $pdf->MultiCell($this->posxunit-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C'); + } + else + { + $pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C'); + } + } + + if($conf->global->PRODUCT_USE_UNITS) { + $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height); + if (empty($hidetop)) { + $pdf->SetXY($this->posxunit - 1, $tab_top + 1); + $pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("Unit"), '', + 'C'); + } } $pdf->line($this->posxdiscount-1, $tab_top, $this->posxdiscount-1, $tab_top + $tab_height); diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index bce94c70a57..ede2b522ecd 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -58,6 +58,15 @@ if (in_array($object->element,array('propal','facture','invoice','commande','ord trans('PriceUTTC'); ?> trans('Qty'); ?> + global->PRODUCT_USE_UNITS) + { + print ''; + print ''; + print $langs->trans('Unit'); + print ''; + } + ?> trans('ReductionShort'); ?> situation_cycle_ref) { @@ -218,6 +227,14 @@ else { "> + global->PRODUCT_USE_UNITS) + { + print ''; + print $form->select_units($line->fk_unit, "units"); + print ''; + } + ?> remise_percent); ?>">% situation_cycle_ref) { @@ -291,6 +308,9 @@ if (! empty($conf->service->enabled) && $dateSelector && GETPOST('type') != '0') if($this->situation_cycle_ref) $colspan++; if (! empty($inputalsopricewithtax)) $colspan++; // We add 1 if col total ttc if (in_array($object->element,array('propal','facture','invoice','commande','order'))) $colspan++; // With this, there is a column move button + if ($conf->global->PRODUCT_USE_UNITS) { + $colspan++; + } if (! empty($usemargins)) { @@ -560,6 +580,7 @@ function setforfree() { jQuery("#np_markRate").show(); // May no exists jQuery(".np_marginRate").show(); // May no exists jQuery(".np_markRate").show(); // May no exists + jQuery("#units, #title_units").show(); } function setforpredef() { jQuery("#select_type").val(-1); @@ -576,6 +597,8 @@ function setforpredef() { jQuery("#np_markRate").hide(); // May no exists jQuery(".np_marginRate").hide(); // May no exists jQuery(".np_markRate").hide(); // May no exists + jQuery(".np_markRate").hide(); // May no exists + jQuery("#units, #title_units").hide(); } diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index ae2238e06f2..81af7385efc 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -140,6 +140,15 @@ $coldisplay=-1; // We remove first td + global->PRODUCT_USE_UNITS) + { + print ''; + $form->select_units($line->fk_unit, "units"); + print ''; + } + ?> + info_bits & 2) != 2) { print ' + global->PRODUCT_USE_UNITS) + { + print ''; + $label = $line->get_unit_label('short'); + if ($label !== '') { + print $langs->trans($label); + } + print ''; + } + ?> + remise_percent) && $line->special_code != 3) { ?> remise_percent,$langs); ?> diff --git a/htdocs/core/tpl/originproductline.tpl.php b/htdocs/core/tpl/originproductline.tpl.php index 878166bb40d..7919668ae53 100644 --- a/htdocs/core/tpl/originproductline.tpl.php +++ b/htdocs/core/tpl/originproductline.tpl.php @@ -24,6 +24,9 @@ tpl['vat_rate']; ?> tpl['price']; ?> tpl['qty']; ?> + global->PRODUCT_USE_UNITS) echo ''.$langs->trans($this->tpl['unit']).''; + ?> tpl['remise_percent']; ?> - \ No newline at end of file + diff --git a/htdocs/install/mysql/data/llx_c_units.sql b/htdocs/install/mysql/data/llx_c_units.sql new file mode 100644 index 00000000000..835c0ab06eb --- /dev/null +++ b/htdocs/install/mysql/data/llx_c_units.sql @@ -0,0 +1,31 @@ +-- ======================================================================== +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville +-- Copyright (C) 2004 Laurent Destailleur +-- Copyright (C) 2012 Cédric Salvador +-- 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 2 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 . +-- +-- ======================================================================== + +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('P','piece','p', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('SET','set','se', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('S','second','s', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('H','hour','h', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('D','day','d', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('KG','kilogram','kg', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('G','gram','g', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('M','meter','m', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('LM','linear meter','lm', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('M2','square meter','m2', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('M3','cubic meter','m3', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('L','liter','l', 1); diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index c09c434d27e..e8d4f77d5f8 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -1,4 +1,4 @@ --- +NULL- -- Be carefull to requests order. -- This file must be loaded by calling /install/index.php page -- when current version is 3.8.0 or higher. @@ -209,3 +209,44 @@ create table llx_commande_fournisseurdet_extrafields ALTER TABLE llx_commande_fournisseurdet_extrafields ADD INDEX idx_commande_fournisseurdet_extrafields (fk_object); +-- Units +create table llx_c_units( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(3), + label varchar(50), + short_label varchar(5), + active tinyint DEFAULT 1 NOT NULL +)ENGINE=innodb; +ALTER TABLE llx_c_units ADD UNIQUE uk_c_units_code(code); + +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('NA','aucune','', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('P','piece','p', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('SET','set','se', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('S','second','s', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('H','hour','h', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('D','day','d', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('KG','kilogram','kg', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('G','gram','g', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('M','meter','m', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('LM','linear meter','lm', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('M2','square meter','m2', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('M3','cubic meter','m3', 1); +INSERT INTO llx_c_units ( code, label, short_label, active) VALUES ('L','liter','l', 1); + +alter table llx_product add fk_unit integer default NULL; +ALTER TABLE llx_product ADD CONSTRAINT fk_product_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); + +alter table llx_facturedet_rec add fk_unit integer default NULL; +ALTER TABLE llx_facturedet_rec ADD CONSTRAINT fk_facturedet_rec_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); + +alter table llx_facturedet add fk_unit integer default NULL; +ALTER TABLE llx_facturedet ADD CONSTRAINT fk_facturedet_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); + +alter table llx_propaldet add fk_unit integer default NULL; +ALTER TABLE llx_propaldet ADD CONSTRAINT fk_propaldet_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); + +alter table llx_commandedet add fk_unit integer default NULL; +ALTER TABLE llx_commandedet ADD CONSTRAINT fk_commandedet_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); + +alter table llx_contratdet add fk_unit integer default NULL; +ALTER TABLE llx_contratdet ADD CONSTRAINT fk_contratdet_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_c_units.key.sql b/htdocs/install/mysql/tables/llx_c_units.key.sql new file mode 100644 index 00000000000..f97ea9f709f --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_units.key.sql @@ -0,0 +1,21 @@ +-- ======================================================================== +-- Copyright (C) 2005 Laurent Destailleur +-- Copyright (C) 2012 Cédric Salvador +-- +-- 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 2 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_c_units ADD UNIQUE uk_c_units_code(code); diff --git a/htdocs/install/mysql/tables/llx_c_units.sql b/htdocs/install/mysql/tables/llx_c_units.sql new file mode 100644 index 00000000000..44c5b812483 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_units.sql @@ -0,0 +1,27 @@ +-- ======================================================================== +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville +-- Copyright (C) 2004 Laurent Destailleur +-- Copyright (C) 2012 Cédric Salvador +-- +-- 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 2 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_c_units( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(3), + label varchar(50), + short_label varchar(5), + active tinyint DEFAULT 1 NOT NULL +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_commandedet.key.sql b/htdocs/install/mysql/tables/llx_commandedet.key.sql index 4d3f8223f79..21765a6ad1b 100644 --- a/htdocs/install/mysql/tables/llx_commandedet.key.sql +++ b/htdocs/install/mysql/tables/llx_commandedet.key.sql @@ -1,6 +1,7 @@ -- =================================================================== -- Copyright (C) 2006 Laurent Destailleur -- Copyright (C) 2011 Regis Houssin +-- Copyright (C) 2012 Cédric Salvador -- -- 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 @@ -22,4 +23,5 @@ ALTER TABLE llx_commandedet ADD INDEX idx_commandedet_fk_commande (fk_commande); ALTER TABLE llx_commandedet ADD INDEX idx_commandedet_fk_product (fk_product); +ALTER TABLE llx_commandedet ADD CONSTRAINT fk_commandedet_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); ALTER TABLE llx_commandedet ADD CONSTRAINT fk_commandedet_fk_commande FOREIGN KEY (fk_commande) REFERENCES llx_commande (rowid); diff --git a/htdocs/install/mysql/tables/llx_commandedet.sql b/htdocs/install/mysql/tables/llx_commandedet.sql index 7562b694b99..76bd75f17c8 100644 --- a/htdocs/install/mysql/tables/llx_commandedet.sql +++ b/htdocs/install/mysql/tables/llx_commandedet.sql @@ -3,6 +3,7 @@ -- Copyright (C) 2005-2012 Regis Houssin -- Copyright (C) 2006-2009 Laurent Destailleur -- Copyright (C) 2010 Juanjo Menent +-- Copyright (C) 2012 Cédric Salvador -- -- 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 @@ -53,6 +54,7 @@ create table llx_commandedet special_code integer UNSIGNED DEFAULT 0, -- code pour les lignes speciales rang integer DEFAULT 0, + fk_unit integer DEFAULT NULL, -- lien vers table des unités import_key varchar(14) )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_contratdet.key.sql b/htdocs/install/mysql/tables/llx_contratdet.key.sql index e749c09df51..6f65271ebb7 100644 --- a/htdocs/install/mysql/tables/llx_contratdet.key.sql +++ b/htdocs/install/mysql/tables/llx_contratdet.key.sql @@ -27,3 +27,5 @@ ALTER TABLE llx_contratdet ADD INDEX idx_contratdet_date_fin_validite (date_fin_ ALTER TABLE llx_contratdet ADD CONSTRAINT fk_contratdet_fk_contrat FOREIGN KEY (fk_contrat) REFERENCES llx_contrat (rowid); ALTER TABLE llx_contratdet ADD CONSTRAINT fk_contratdet_fk_product FOREIGN KEY (fk_product) REFERENCES llx_product (rowid); + +ALTER TABLE llx_contratdet ADD CONSTRAINT fk_contratdet_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); diff --git a/htdocs/install/mysql/tables/llx_contratdet.sql b/htdocs/install/mysql/tables/llx_contratdet.sql index 78091d3a3d9..b4e13fb99c2 100644 --- a/htdocs/install/mysql/tables/llx_contratdet.sql +++ b/htdocs/install/mysql/tables/llx_contratdet.sql @@ -61,6 +61,7 @@ create table llx_contratdet fk_user_author integer NOT NULL DEFAULT 0, fk_user_ouverture integer, fk_user_cloture integer, - commentaire text + commentaire text, + fk_unit integer DEFAULT NULL )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_facturedet.key.sql b/htdocs/install/mysql/tables/llx_facturedet.key.sql index 52c7ec7668d..8a8ecf1da9c 100644 --- a/htdocs/install/mysql/tables/llx_facturedet.key.sql +++ b/htdocs/install/mysql/tables/llx_facturedet.key.sql @@ -1,6 +1,7 @@ -- =================================================================== -- Copyright (C) 2005 Laurent Destailleur -- Copyright (C) 2011 Regis Houssin +-- Copyright (C) 2012 Cédric Salvador -- -- 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 @@ -25,3 +26,4 @@ ALTER TABLE llx_facturedet ADD INDEX idx_facturedet_fk_facture (fk_facture); ALTER TABLE llx_facturedet ADD INDEX idx_facturedet_fk_product (fk_product); ALTER TABLE llx_facturedet ADD UNIQUE INDEX uk_fk_remise_except (fk_remise_except, fk_facture); ALTER TABLE llx_facturedet ADD CONSTRAINT fk_facturedet_fk_facture FOREIGN KEY (fk_facture) REFERENCES llx_facture (rowid); +ALTER TABLE llx_facturedet ADD CONSTRAINT fk_facturedet_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); diff --git a/htdocs/install/mysql/tables/llx_facturedet.sql b/htdocs/install/mysql/tables/llx_facturedet.sql index d663adf4e1c..63cd9ab3bc1 100644 --- a/htdocs/install/mysql/tables/llx_facturedet.sql +++ b/htdocs/install/mysql/tables/llx_facturedet.sql @@ -60,7 +60,8 @@ create table llx_facturedet import_key varchar(14), situation_percent real, -- % progression of lines invoicing - fk_prev_id integer -- id of the line in the previous situation + fk_prev_id integer, -- id of the line in the previous situation, + fk_unit integer DEFAULT NULL -- id of the unit code¡ )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_facturedet_rec.key.sql b/htdocs/install/mysql/tables/llx_facturedet_rec.key.sql new file mode 100644 index 00000000000..45619e94727 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_facturedet_rec.key.sql @@ -0,0 +1,21 @@ +-- =================================================================== +-- Copyright (C) 2005 Laurent Destailleur +-- Copyright (C) 2011 Regis Houssin +-- Copyright (C) 2012 Cedric Salvador +-- +-- 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 2 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_facturedet_rec ADD CONSTRAINT fk_facturedet_rec_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); diff --git a/htdocs/install/mysql/tables/llx_facturedet_rec.sql b/htdocs/install/mysql/tables/llx_facturedet_rec.sql index 05bfa71ec2e..164dc2f94d5 100644 --- a/htdocs/install/mysql/tables/llx_facturedet_rec.sql +++ b/htdocs/install/mysql/tables/llx_facturedet_rec.sql @@ -3,6 +3,7 @@ -- Copyright (C) 2009-2014 Laurent Destailleur -- Copyright (C) 2010 Juanjo Menent -- Copyright (C) 2010-2012 Regis Houssin +-- Copyright (C) 2012 Cédric Salvador -- -- 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,5 +47,6 @@ create table llx_facturedet_rec info_bits integer DEFAULT 0, -- TVA NPR ou non special_code integer UNSIGNED DEFAULT 0, -- code pour les lignes speciales rang integer DEFAULT 0, -- ordre d'affichage - fk_contract_line integer NULL -- id of contract line when predefined invoice comes from contract lines + fk_contract_line integer NULL, -- id of contract line when predefined invoice comes from contract lines + fk_unit integer DEFAULT NULL )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product.key.sql b/htdocs/install/mysql/tables/llx_product.key.sql index fb471910230..5157861ba4b 100644 --- a/htdocs/install/mysql/tables/llx_product.key.sql +++ b/htdocs/install/mysql/tables/llx_product.key.sql @@ -2,6 +2,7 @@ -- Copyright (C) 2002-2004 Rodolphe Quiedeville -- Copyright (C) 2004-2013 Laurent Destailleur -- Copyright (C) 2005-2009 Regis Houssin +-- Copyright (C) 2012 Cédric Salvador -- Copyright (C) 2014 Marcos García -- -- This program is free software; you can redistribute it and/or modify @@ -30,7 +31,7 @@ ALTER TABLE llx_product ADD INDEX idx_product_fk_country (fk_country); ALTER TABLE llx_product ADD INDEX idx_product_fk_user_author (fk_user_author); ALTER TABLE llx_product ADD INDEX idx_product_fk_barcode_type (fk_barcode_type); ALTER TABLE llx_product ADD UNIQUE INDEX uk_product_barcode (barcode, fk_barcode_type, entity); - +ALTER TABLE llx_product ADD CONSTRAINT fk_product_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); ALTER TABLE llx_product ADD CONSTRAINT fk_product_fk_country FOREIGN KEY (fk_country) REFERENCES llx_c_country (rowid); ALTER TABLE llx_product ADD CONSTRAINT fk_product_barcode_type FOREIGN KEY (fk_barcode_type) REFERENCES llx_c_barcode_type (rowid); diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql index 03c5c5edd3c..5abbdcdde97 100755 --- a/htdocs/install/mysql/tables/llx_product.sql +++ b/htdocs/install/mysql/tables/llx_product.sql @@ -2,8 +2,8 @@ -- Copyright (C) 2002-2006 Rodolphe Quiedeville -- Copyright (C) 2008-2010 Laurent Destailleur -- Copyright (C) 2005-2010 Regis Houssin --- Copyright (C) 2010 juanjo Menent --- Copyright (C) 2013 Cédric Salvador +-- Copyright (C) 2010 Juanjo Menent +-- Copyright (C) 2012-2013 Cédric Salvador -- Copyright (C) 2014 Marcos García -- -- This program is free software; you can redistribute it and/or modify @@ -77,5 +77,6 @@ create table llx_product hidden tinyint DEFAULT 0, -- Not used. Deprecated. import_key varchar(14), -- Import key fk_price_expression integer, -- Link to the rule for dynamic price calculation - desiredstock integer DEFAULT 0 + desiredstock integer DEFAULT 0, + fk_unit integer DEFAULT NULL )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_propaldet.key.sql b/htdocs/install/mysql/tables/llx_propaldet.key.sql index eb56554a60f..3d3467ea888 100644 --- a/htdocs/install/mysql/tables/llx_propaldet.key.sql +++ b/htdocs/install/mysql/tables/llx_propaldet.key.sql @@ -1,5 +1,6 @@ -- =================================================================== -- Copyright (C) 2009-2011 Regis Houssin +-- Copyright (C) 2012 Cédric Salvador -- -- 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 @@ -21,4 +22,5 @@ ALTER TABLE llx_propaldet ADD INDEX idx_propaldet_fk_propal (fk_propal); ALTER TABLE llx_propaldet ADD INDEX idx_propaldet_fk_product (fk_product); +ALTER TABLE llx_propaldet ADD CONSTRAINT fk_propaldet_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); ALTER TABLE llx_propaldet ADD CONSTRAINT fk_propaldet_fk_propal FOREIGN KEY (fk_propal) REFERENCES llx_propal (rowid); diff --git a/htdocs/install/mysql/tables/llx_propaldet.sql b/htdocs/install/mysql/tables/llx_propaldet.sql index 624292decd6..299767ae2ed 100644 --- a/htdocs/install/mysql/tables/llx_propaldet.sql +++ b/htdocs/install/mysql/tables/llx_propaldet.sql @@ -2,6 +2,7 @@ -- Copyright (C) 2002-2003 Rodolphe Quiedeville -- Copyright (C) 2005-2012 Regis Houssin -- Copyright (C) 2010 Juanjo Menent +-- Copyright (C) 2012 Cédric Salvador -- -- 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 @@ -51,7 +52,8 @@ create table llx_propaldet fk_product_fournisseur_price integer DEFAULT NULL, -- reference of supplier price when line was added (may be used to update buy_price_ht current price when future invoice will be created) special_code integer DEFAULT 0, -- code pour les lignes speciales - rang integer DEFAULT 0 -- ordre affichage sur la propal + rang integer DEFAULT 0, -- ordre affichage sur la propal + fk_unit integer DEFAULT NULL -- lien vers table des unités )ENGINE=innodb; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 017c819d85e..33842e1ed8e 100755 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1371,6 +1371,7 @@ UseSearchToSelectProduct=Use a search form to choose a product (rather than a dr UseEcoTaxeAbility=Support Eco-Taxe (WEEE) SetDefaultBarcodeTypeProducts=Default barcode type to use for products SetDefaultBarcodeTypeThirdParties=Default barcode type to use for third parties +UseUnits=Support units ProductCodeChecker= Module for product code generation and checking (product or service) ProductOtherConf= Product / Service configuration ##### Syslog ##### diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index eb7261ab613..793fd40a2ce 100755 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -189,6 +189,32 @@ CustomCode=Customs code CountryOrigin=Origin country HiddenIntoCombo=Hidden into select lists Nature=Nature +DictionnaryUnits=Units +ShortLabel=Short label +Unit=Unit +p=u. +set=set +se=set +second=second +s=s +hour=hour +h=h +day=day +d=d +kilogram=kilogram +kg=Kg +gram=gram +g=g +meter=meter +m=m +linear meter=linear meter +lm=lm +square meter=square meter +m2=m² +cubic meter=cubic meter +m3=m³ +liter=liter +l=L ProductCodeModel=Product ref template ServiceCodeModel=Service ref template AddThisProductCard=Create product card diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 2d0c1cca468..fa7dc78092c 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -6,7 +6,8 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011-2012 Juanjo Menent * Copyright (C) 2012 Christophe Battarel -** + * Copyright (C) 2012 Cedric Salvador + * * 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 @@ -172,6 +173,12 @@ else if ($action == 'set') $res = dolibarr_set_const($db, "PRODUIT_USE_ECOTAXE", $ecotaxe,'chaine',0,'',$conf->entity); }*/ +else if ($action == 'useUnits') +{ + $useUnits = GETPOST('activate_units', 'alpha'); + $res = dolibarr_set_const($db, "PRODUCT_USE_UNITS", $useUnits, 'chaine', 0, '', $conf->entity); +} + if($action) { if (! $res > 0) $error++; @@ -424,6 +431,21 @@ print ''; print ''; print ''; +// Use units +$var=!$var; +print '
'; +print ''; +print ''; +print ''; +print ''.$langs->trans("UseUnits").''; +print ''; +print $form->selectyesno("activate_units",$conf->global->PRODUCT_USE_UNITS,1); +print ''; +print ''; +print ''; +print ''; +print '
'; + // View product description in thirdparty language if (! empty($conf->global->MAIN_MULTILANGS)) { diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 50ed04a29df..03f62221c05 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -7,7 +7,7 @@ * Copyright (C) 2006 Auguria SARL * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2013-2014 Marcos García - * Copyright (C) 2013 Cédric Salvador + * Copyright (C) 2012-2013 Cédric Salvador * Copyright (C) 2011-2014 Alexandre Spangaro * Copyright (C) 2014 Cédric Gross * Copyright (C) 2014 Ferran Marcet @@ -179,6 +179,8 @@ if (empty($reshook)) if (! $error) { + $units = GETPOST('units', 'int'); + $object->ref = $ref; $object->libelle = GETPOST('libelle'); $object->price_base_type = GETPOST('price_base_type'); @@ -240,6 +242,9 @@ if (empty($reshook)) $object->volume_units = GETPOST('volume_units'); $object->finished = GETPOST('finished'); $object->hidden = GETPOST('hidden')=='yes'?1:0; + if ($fk_unit > 0) { + $object->fk_unit = $fk_unit; + } $object->accountancy_code_sell = GETPOST('accountancy_code_sell'); $object->accountancy_code_buy = GETPOST('accountancy_code_buy'); @@ -318,6 +323,14 @@ if (empty($reshook)) $object->finished = GETPOST('finished'); $object->hidden = GETPOST('hidden')=='yes'?1:0; + $units = GETPOST('units', 'int'); + + if ($units > 0) { + $object->fk_unit = $units; + } else { + $object->fk_unit = null; + } + $object->barcode_type = GETPOST('fk_barcode_type'); $object->barcode = GETPOST('barcode'); // Set barcode_type_xxx from barcode_type id @@ -554,7 +567,19 @@ if (empty($reshook)) $object->id, GETPOST('remise_percent'), $price_base_type, - $pu_ttc + $pu_ttc, + 0, + 0, + -1, + 0, + 0, + 0, + 0, + '', + '', + '', + 0, + $object->fk_unit ); if ($result > 0) { @@ -646,7 +671,18 @@ if (empty($reshook)) '', '', $price_base_type, - $pu_ttc + $pu_ttc, + '', + '', + 0, + -1, + 0, + 0, + null, + 0, + '', + 0, + $object->fk_unit ); if ($result > 0) @@ -739,7 +775,20 @@ if (empty($reshook)) '', '', $price_base_type, - $pu_ttc + $pu_ttc, + Facture::TYPE_STANDARD, + -1, + 0, + '', + 0, + 0, + null, + 0, + '', + 0, + 100, + '', + $object->fk_unit ); if ($result > 0) @@ -993,10 +1042,20 @@ else // We use dolibarr_details as type of DolEditor here, because we must not accept images as description is included into PDF and not accepted by TCPDF. $doleditor = new DolEditor('note', GETPOST('note'), '', 140, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, 8, 70); - $doleditor->Create(); + $doleditor->Create(); - print ""; - print ''; + print ""; + + // Units + if($conf->global->PRODUCT_USE_UNITS) + { + print ''.$langs->trans('Unit').''; + print ''; + $form->select_units("units"); + print ''; print '
'; @@ -1261,8 +1320,18 @@ else $doleditor = new DolEditor('note', $object->note, '', 140, 'dolibarr_notes', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, 4, 80); $doleditor->Create(); - print ""; - print ''; + print ""; + + // Units + if($conf->global->PRODUCT_USE_UNITS) + { + print ''.$langs->trans('Unit').''; + print ''; + $form->select_units($object->fk_unit); + print ''; + } + + print ''; print '
'; @@ -1529,6 +1598,18 @@ else print "\n"; } + // Unit + if($conf->global->PRODUCT_USE_UNITS) + { + $unit = $object->get_unit_label(); + + print ''.$langs->trans('Unit').''; + if ($unit !== '') { + print $langs->trans($unit); + } + print ''; + } + // Custom code if (empty($conf->global->PRODUCT_DISABLE_CUSTOM_INFO)) { diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 43da5af3cea..10b0599e371 100755 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5,6 +5,7 @@ * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2007-2011 Jean Heimburger * Copyright (C) 2010-2013 Juanjo Menent + * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013-2014 Cedric GROSS * Copyright (C) 2013-2014 Marcos García * Copyright (C) 2011-2014 Alexandre Spangaro @@ -169,6 +170,12 @@ class Product extends CommonObject var $fk_price_expression; + /** + * Unit + * @var int + */ + public $fk_unit; + /** * Constructor * @@ -360,6 +367,7 @@ class Product extends CommonObject $sql.= ", canvas"; $sql.= ", finished"; $sql.= ", tobatch"; + $sql.= ", fk_unit"; $sql.= ") VALUES ("; $sql.= "'".$this->db->idate($now)."'"; $sql.= ", ".$conf->entity; @@ -380,6 +388,7 @@ class Product extends CommonObject $sql.= ", '".$this->canvas."'"; $sql.= ", ".((! isset($this->finished) || $this->finished < 0 || $this->finished == '') ? 'null' : (int) $this->finished); $sql.= ", ".((empty($this->status_batch) || $this->status_batch < 0)? '0':$this->status_batch); + $sql.= ", ".(!$this->fk_unit ? 'NULL' : $this->fk_unit); $sql.= ")"; dol_syslog(get_class($this)."::Create", LOG_DEBUG); @@ -669,6 +678,7 @@ class Product extends CommonObject $sql.= ", accountancy_code_buy = '" . $this->accountancy_code_buy."'"; $sql.= ", accountancy_code_sell= '" . $this->accountancy_code_sell."'"; $sql.= ", desiredstock = " . ((isset($this->desiredstock) && $this->desiredstock != '') ? $this->desiredstock : "null"); + $sql.= ", fk_unit= " . (!$this->fk_unit ? 'NULL' : $this->fk_unit); $sql.= " WHERE rowid = " . $id; dol_syslog(get_class($this)."update", LOG_DEBUG); @@ -1467,7 +1477,7 @@ class Product extends CommonObject $sql.= " tobuy, fk_product_type, duration, seuil_stock_alerte, canvas,"; $sql.= " weight, weight_units, length, length_units, surface, surface_units, volume, volume_units, barcode, fk_barcode_type, finished,"; $sql.= " accountancy_code_buy, accountancy_code_sell, stock, pmp,"; - $sql.= " datec, tms, import_key, entity, desiredstock, tobatch"; + $sql.= " datec, tms, import_key, entity, desiredstock, tobatch, fk_unit"; $sql.= " ,ref_ext, fk_price_expression"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; if ($id) $sql.= " WHERE rowid = ".$this->db->escape($id); @@ -1546,6 +1556,7 @@ class Product extends CommonObject $this->ref_ext = $obj->ref_ext; $this->fk_price_expression = $obj->fk_price_expression; + $this->fk_unit = $obj->fk_unit; $this->db->free($resql); @@ -3727,6 +3738,48 @@ class Product extends CommonObject $this->barcode=-1; // Create barcode automatically } + /** + * Returns the text label from units dictionnary + * + * @param string $type Label type (long or short) + * @return string|int <0 if ko, label if ok + */ + function get_unit_label($type='long') + { + global $langs; + + if (!$this->fk_unit) { + return ''; + } + + $langs->load('products'); + + $this->db->begin(); + + $label_type = 'label'; + + if ($type == 'short') + { + $label_type = 'short_label'; + } + + $sql = 'select '.$label_type.' from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; + $resql = $this->db->query($sql); + if($resql && $this->db->num_rows($resql) > 0) + { + $res = $this->db->fetch_array($resql); + $label = $res[$label_type]; + $this->db->free($resql); + return $label; + } + else + { + $this->error=$this->db->error().' sql='.$sql; + dol_syslog(get_class($this)."::get_unit_label Error ".$this->error, LOG_ERR); + return -1; + } + } + /** * Return if object has a sell-by date or eat-by date *