diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index b9185624209..87914442b1d 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -6,6 +6,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012-2013 Juanjo Menent * Copyright (C) 2014 Christophe Battarel + * Copyright (C) 2014 Cédric Gross * * 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 @@ -65,7 +66,7 @@ class modProduct extends DolibarrModules // Dependencies $this->depends = array(); - $this->requiredby = array("modStock","modBarcode"); + $this->requiredby = array("modStock","modBarcode","modProductBatch"); // Config pages $this->config_page_url = array("product.php@product"); diff --git a/htdocs/core/modules/modProductBatch.class.php b/htdocs/core/modules/modProductBatch.class.php new file mode 100644 index 00000000000..3a3e8e32d4f --- /dev/null +++ b/htdocs/core/modules/modProductBatch.class.php @@ -0,0 +1,137 @@ + + * Copyright (C) 2004-2012 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013-2014 Cedric GROSS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \defgroup productbatch Module batch number management + * \brief Management module for batch number, eat-by and sell-by date for product + * \file htdocs/core/modules/modProductBatch.class.php + * \ingroup productbatch + * \brief Description and activation file for module productbatch + */ +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; + + +/** + * Description and activation class for module productdluo + */ +class modProductBatch extends DolibarrModules +{ + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $langs,$conf; + + $this->db = $db; + $this->numero = 150010; + + $this->family = "products"; + $this->name = preg_replace('/^mod/i','',get_class($this)); + $this->description = "Batch number, eat-by and sell-by date management module"; + + $this->rights_class = 'stock'; + // Possible values for version are: 'development', 'experimental', 'dolibarr' or version + $this->version = 'experimental'; + // Key used in llx_const table to save module status enabled/disabled (where dluo is value of property name of module in uppercase) + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + $this->special = 0; + + $this->picto='stock'; + + $this->module_parts = array(); + + // Data directories to create when module is enabled. + $this->dirs = array(); + + // Config pages. Put here list of php page, stored into productdluo/admin directory, to use to setup module. + $this->config_page_url = array(); + + // Dependencies + $this->depends = array("modProduct","modStock"); // List of modules id that must be enabled if this module is enabled + $this->requiredby = array(); // List of modules id to disable if this one is disabled + $this->phpmin = array(5,0); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(3,0); // Minimum version of Dolibarr required by module + $this->langfiles = array("productbatch"); + + // Constants + $this->const = array(); + + $this->tabs = array(); + + // Dictionnaries + if (! isset($conf->productbatch->enabled)) + { + $conf->productbatch=new stdClass(); + $conf->productbatch->enabled=0; + } + $this->dictionnaries=array(); + + // Boxes + $this->boxes = array(); // List of boxes + + // Permissions + $this->rights = array(); // Permission array used by this module + $r=0; + + // Main menu entries + $this->menu = array(); // List of menus to add + $r=0; + + // Exports + $r=0; + + } + + /** + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function init($options='') + { + $sql = array(); + + return $this->_init($sql, $options); + } + + /** + * Function called when module is disabled. + * Remove from database constants, boxes and permissions from Dolibarr database. + * Data directories are not deleted + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function remove($options='') + { + $sql = array(); + + return $this->_remove($sql, $options); + } + +} + +?> diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php index abf6add2c29..830247843fa 100644 --- a/htdocs/core/modules/modStock.class.php +++ b/htdocs/core/modules/modStock.class.php @@ -66,7 +66,7 @@ class modStock extends DolibarrModules // Dependencies $this->depends = array("modProduct"); - $this->requiredby = array(); + $this->requiredby = array("modProductBatch"); $this->langfiles = array("stocks"); // Constants diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql index 763309273f3..1332ce5e6eb 100644 --- a/htdocs/install/mysql/tables/llx_product.sql +++ b/htdocs/install/mysql/tables/llx_product.sql @@ -50,6 +50,7 @@ create table llx_product fk_user_author integer, tosell tinyint DEFAULT 1, tobuy tinyint DEFAULT 1, + tobatch tinyint DEFAULT 0 NOT NULL, fk_product_type integer DEFAULT 0, -- Type 0 for regular product, 1 for service, 9 for other (used by external module) duration varchar(6), seuil_stock_alerte integer DEFAULT 0, diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 292dca00320..d157aeccbf0 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -518,6 +518,8 @@ Module59000Name=Margins Module59000Desc=Module to manage margins Module60000Name=Commissions Module60000Desc=Module to manage commissions +Module150010Name=Batch number, eat-by date and sell-by date +Module150010Desc=batch number, eat-by date and sell-by date management for product Permission11=Read customer invoices Permission12=Create/modify customer invoices Permission13=Unvalidate customer invoices diff --git a/htdocs/langs/en_US/productbatch.lang b/htdocs/langs/en_US/productbatch.lang new file mode 100644 index 00000000000..09806e2261a --- /dev/null +++ b/htdocs/langs/en_US/productbatch.lang @@ -0,0 +1,7 @@ +# ProductBATCH language file - en_US - ProductBATCH +CHARSET= UTF-8 +ProductStatusOnBatch= Managed +ProductStatusNotOnBatch= Not Managed +ProductStatusOnBatchShort= Managed +ProductStatusNotOnBatchShort= Not Managed +Batch=Batch diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 215ea7900ef..50198562df7 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -510,6 +510,8 @@ Module59000Name=Marges Module59000Desc=Module pour gĂ©rer les marges Module60000Name=Commissions Module60000Desc=Module pour gĂ©rer les commissions +Module150010Name=NumĂ©ro de lot, DLC, DLUO +Module150010Desc=Gestion des numĂ©ros de lot, DLC et DLUO pour les produits stockĂ©s Permission11=Consulter les factures clients Permission12=CrĂ©er/modifier les factures clients Permission13=DĂ©-valider les factures clients diff --git a/htdocs/langs/fr_FR/productbatch.lang b/htdocs/langs/fr_FR/productbatch.lang new file mode 100644 index 00000000000..24231f0e6e2 --- /dev/null +++ b/htdocs/langs/fr_FR/productbatch.lang @@ -0,0 +1,7 @@ +# ProductBATCH language file - fr_FR - ProductBATCH +CHARSET= UTF-8 +ProductStatusOnBatch= GĂ©rer +ProductStatusNotOnBatch= Non gĂ©rer +ProductStatusOnBatchShort= GĂ©rer +ProductStatusNotOnBatchShort= Non gĂ©rer +Batch=Lot diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 1c94cf5f3c6..1aebe0307eb 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -5,7 +5,7 @@ * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2007-2011 Jean Heimburger * Copyright (C) 2010-2013 Juanjo Menent - * Copyright (C) 2013 Cedric GROSS + * Copyright (C) 2013-2014 Cedric GROSS * Copyright (C) 2013 Marcos GarcĂ­a * Copyright (C) 2011-2014 Alexandre Spangaro * @@ -96,6 +96,8 @@ class Product extends CommonObject var $status_buy; // Statut indique si le produit est un produit fini '1' ou une matiere premiere '0' var $finished; + // We must manage batch number, sell-by date and so on : '1':yes '0':no + var $status_batch; var $customcode; // Customs code var $country_id; // Country origin id @@ -169,6 +171,7 @@ class Product extends CommonObject $this->seuil_stock_alerte = 0; $this->desiredstock = 0; $this->canvas = ''; + $this->status_batch=0; } /** @@ -337,6 +340,7 @@ class Product extends CommonObject $sql.= ", accountancy_code_sell"; $sql.= ", canvas"; $sql.= ", finished"; + $sql.= ", tobatch"; $sql.= ") VALUES ("; $sql.= "'".$this->db->idate($now)."'"; $sql.= ", ".$conf->entity; @@ -356,6 +360,7 @@ class Product extends CommonObject $sql.= ", '".$this->accountancy_code_sell."'"; $sql.= ", '".$this->canvas."'"; $sql.= ", ".((! isset($this->finished) || $this->finished < 0 || $this->finished == '') ? 'null' : $this->finished); + $sql.= ", ".((empty($this->status_batch) || $this->status_batch < 0)? '0':$this->status_batch); $sql.= ")"; dol_syslog(get_class($this)."::Create sql=".$sql); @@ -592,6 +597,7 @@ class Product extends CommonObject $sql.= ", tosell = " . $this->status; $sql.= ", tobuy = " . $this->status_buy; + $sql.= ", tobatch = " . ((empty($this->status_batch) || $this->status_batch < 0) ? '0' : $this->status_batch); $sql.= ", finished = " . ((! isset($this->finished) || $this->finished < 0) ? "null" : $this->finished); $sql.= ", weight = " . ($this->weight!='' ? "'".$this->weight."'" : 'null'); $sql.= ", weight_units = " . ($this->weight_units!='' ? "'".$this->weight_units."'": 'null'); @@ -1275,7 +1281,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"; + $sql.= " datec, tms, import_key, entity, desiredstock, tobatch"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; if ($id) $sql.= " WHERE rowid = ".$this->db->escape($id); else @@ -1303,6 +1309,7 @@ class Product extends CommonObject $this->type = $obj->fk_product_type; $this->status = $obj->tosell; $this->status_buy = $obj->tobuy; + $this->status_batch = $obj->tobatch; $this->customcode = $obj->customcode; $this->country_id = $obj->fk_country; @@ -2631,15 +2638,23 @@ class Product extends CommonObject * Return label of status of object * * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto - * @param int $type 0=Shell, 1=Buy + * @param int $type 0=Sell, 1=Buy, 2=Batch Number management * @return string Label of status */ function getLibStatut($mode=0, $type=0) { - if($type==0) + switch ($type) + { + case 0: return $this->LibStatut($this->status,$mode,$type); - else + case 1: return $this->LibStatut($this->status_buy,$mode,$type); + case 2: + return $this->LibStatut($this->status_batch,$mode,$type); + default: + //Simulate previous behavior but should return an error string + return $this->LibStatut($this->status_buy,$mode,$type); + } } /** @@ -2647,14 +2662,42 @@ class Product extends CommonObject * * @param int $status Statut * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto - * @param int $type 0=Status "to sell", 1=Status "to buy" + * @param int $type 0=Status "to sell", 1=Status "to buy", 2=Status "to Batch" * @return string Label of status */ function LibStatut($status,$mode=0,$type=0) { global $langs; $langs->load('products'); + if ($conf->productbatch->enabled) $langs->load("productbatch"); + if ($type == 2) + { + switch ($mode) + { + case 0: + return ($status == 0 ? $langs->trans('ProductStatusNotOnBatch') : $langs->trans('ProductStatusOnBatch')); + case 1: + return ($status == 0 ? $langs->trans('ProductStatusNotOnBatchShort') : $langs->trans('ProductStatusOnBatchShort')); + case 2: + return $this->LibStatut($status,3,2).' '.$this->LibStatut($status,1,2); + case 3: + if ($status == 0 ) + { + return img_picto($langs->trans('ProductStatusNotOnBatch'),'statut5'); + } + else + { + return img_picto($langs->trans('ProductStatusOnBatch'),'statut4'); + } + case 4: + return $this->LibStatut($status,3,2).' '.$this->LibStatut($status,0,2); + case 5: + return $this->LibStatut($status,1,2).' '.$this->LibStatut($status,3,2); + default: + return $langs->trans('Unknown'); + } + } if ($mode == 0) { if ($status == 0) return ($type==0 ? $langs->trans('ProductStatusNotOnSellShort'):$langs->trans('ProductStatusNotOnBuyShort')); @@ -3261,10 +3304,21 @@ class Product extends CommonObject $this->country_id=1; $this->tosell=1; $this->tobuy=1; + $this->tobatch=0; $this->type=0; $this->note='This is a comment (private)'; $this->barcode=-1; // Create barcode automatically } + + /** + * Return if object has a sell-by date or eat-by date + * + * @return boolean True if it's has + */ + function hasbatch() + { + return ($this->status_batch == 1 ? true : false); + } } ?> diff --git a/htdocs/product/fiche.php b/htdocs/product/fiche.php index 6a86dbe3217..d0b4f914210 100644 --- a/htdocs/product/fiche.php +++ b/htdocs/product/fiche.php @@ -9,6 +9,7 @@ * Copyright (C) 2013 Marcos GarcĂ­a * Copyright (C) 2013 CĂ©dric Salvador * Copyright (C) 2011-2014 Alexandre Spangaro + * Copyright (C) 2014 CĂ©dric Gross * * 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 @@ -45,6 +46,7 @@ $langs->load("products"); $langs->load("other"); if (! empty($conf->stock->enabled)) $langs->load("stocks"); if (! empty($conf->facture->enabled)) $langs->load("bills"); +if ($conf->productbatch->enabled) $langs->load("productbatch"); $mesg=''; $error=0; $errors=array(); $_error=0; @@ -197,6 +199,7 @@ if (empty($reshook)) $object->type = $type; $object->status = GETPOST('statut'); $object->status_buy = GETPOST('statut_buy'); + $object->status_batch = GETPOST('status_batch'); $object->barcode_type = GETPOST('fk_barcode_type'); $object->barcode = GETPOST('barcode'); @@ -280,6 +283,7 @@ if (empty($reshook)) $object->country_id = GETPOST('country_id'); $object->status = GETPOST('statut'); $object->status_buy = GETPOST('statut_buy'); + $object->status_batch = GETPOST('status_batch'); $object->seuil_stock_alerte = GETPOST('seuil_stock_alerte'); $object->desiredstock = GETPOST('desiredstock'); $object->duration_value = GETPOST('duration_value'); @@ -763,9 +767,18 @@ else // To buy print ''.$langs->trans("Status").' ('.$langs->trans("Buy").')'; $statutarray=array('1' => $langs->trans("ProductStatusOnBuy"), '0' => $langs->trans("ProductStatusNotOnBuy")); - print $form->selectarray('statut_buy',$statutarray,GETPOST('statut_buy"')); + print $form->selectarray('statut_buy',$statutarray,GETPOST('statut_buy')); print ''; + // batch number management + if ($conf->productbatch->enabled) { + print ''.$langs->trans("Status").' ('.$langs->trans("Batch").')'; + $statutarray=array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch")); + print $form->selectarray('status_batch',$statutarray,GETPOST('status_batch')); + print ''; + } + + $showbarcode=(! empty($conf->barcode->enabled) && $user->rights->barcode->lire); if ($showbarcode) @@ -1009,6 +1022,14 @@ else print ''; print ''; + // Batch number managment + if ($conf->productbatch->enabled) { + print ''.$langs->trans("Status").' ('.$langs->trans("Lot").')'; + $statutarray=array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch")); + print $form->selectarray('status_batch',$statutarray,$object->status_batch); + print ''; + } + // Barcode $showbarcode=(! empty($conf->barcode->enabled) && $user->rights->barcode->lire); @@ -1291,6 +1312,13 @@ else print $object->getLibStatut(2,1); print ''; + // Batch number management (to batch) + if ($conf->productbatch->enabled) { + print ''.$langs->trans("Status").' ('.$langs->trans("Lot").')'; + print $object->getLibStatut(2,2); + print ''; + } + // Description print ''.$langs->trans("Description").''.(dol_textishtml($object->description)?$object->description:dol_nl2br($object->description,1,true)).'';