diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index d5d52761140..e8ce515317f 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -328,6 +328,11 @@ function product_lot_admin_prepare_head() $h = 0; $head = array(); + $head[$h][0] = DOL_URL_ROOT."/product/admin/product_lot.php"; + $head[$h][1] = $langs->trans('Parameters'); + $head[$h][2] = 'settings'; + $h++; + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/core/modules/modProductBatch.class.php b/htdocs/core/modules/modProductBatch.class.php index 166b8f6e637..3d8359ebc3a 100644 --- a/htdocs/core/modules/modProductBatch.class.php +++ b/htdocs/core/modules/modProductBatch.class.php @@ -64,8 +64,8 @@ class modProductBatch extends DolibarrModules // Data directories to create when module is enabled. $this->dirs = array(); - // Config pages. Put here list of php page, stored into /product/admin/ directory, to setup the module. - $this->config_page_url = array("product_lot_extrafields.php@product"); + // Config pages. Put here list of php page, stored into productdluo/admin directory, to use to setup module. + $this->config_page_url = array("product_lot.php@product"); // Dependencies $this->hidden = false; // A condition to hide module diff --git a/htdocs/core/modules/product_batch/mod_lot_advanced.php b/htdocs/core/modules/product_batch/mod_lot_advanced.php new file mode 100644 index 00000000000..d8629b92dd6 --- /dev/null +++ b/htdocs/core/modules/product_batch/mod_lot_advanced.php @@ -0,0 +1,145 @@ + + * Copyright (C) 2004-2007 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand (Resultic) + * Copyright (C) 2019 Frédéric France + * Copyright (C) 2021 Christophe Battarel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/product_batch/mod_lot_advanced.php + * \ingroup productbatch + * \brief File containing class for numbering model of Lot advanced + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/product_batch/modules_product_batch.class.php'; + + +/** + * Class to manage Batch numbering rules advanced + */ +class mod_lot_advanced extends ModeleNumRefBatch +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + /** + * @var string Error message + */ + public $error = ''; + + /** + * @var string name + */ + public $name = 'lot_advanced'; + + + /** + * Returns the description of the numbering model + * + * @return string Texte descripif + */ + public function info() + { + global $conf, $langs, $db; + + $langs->load("bills"); + + $form = new Form($db); + + $texte = $langs->trans('GenericNumRefModelDesc')."
\n"; + $texte .= '
'; + $texte .= ''; + $texte .= ''; + $texte .= ''; + $texte .= ''; + + $tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Batch"), $langs->transnoentities("Batch")); + $tooltip .= $langs->trans("GenericMaskCodes2"); + $tooltip .= $langs->trans("GenericMaskCodes3"); + $tooltip .= $langs->trans("GenericMaskCodes4a", $langs->transnoentities("Batch"), $langs->transnoentities("Batch")); + $tooltip .= $langs->trans("GenericMaskCodes5"); + + // Parametrage du prefix + $texte .= ''; + $texte .= ''; + + $texte .= ''; + + $texte .= ''; + + $texte .= '
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).' 
'; + $texte .= '
'; + + return $texte; + } + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $conf, $langs, $mysoc; + + $old_code_client = $mysoc->code_client; + $old_code_type = $mysoc->typent_code; + $mysoc->code_client = 'CCCCCCCCCC'; + $mysoc->typent_code = 'TTTTTTTTTT'; + $numExample = $this->getNextValue($mysoc, ''); + $mysoc->code_client = $old_code_client; + $mysoc->typent_code = $old_code_type; + + if (!$numExample) { + $numExample = $langs->trans('NotConfigured'); + } + return $numExample; + } + + /** + * Return next free value + * + * @param Product $objprod Object product + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO + */ + public function getNextValue($objprod, $object) + { + global $db, $conf; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + + // We get cursor rule + $mask = $conf->global->BATCH_ADVANCED_MASK; + + if (!$mask) { + $this->error = 'NotConfigured'; + return 0; + } + + $date = $object->date; + + $numFinal = get_next_value($db, $mask, 'product_lot', 'ref', '', null, $date); + + return $numFinal; + } +} diff --git a/htdocs/core/modules/product_batch/mod_lot_free.php b/htdocs/core/modules/product_batch/mod_lot_free.php new file mode 100644 index 00000000000..0f069143ab1 --- /dev/null +++ b/htdocs/core/modules/product_batch/mod_lot_free.php @@ -0,0 +1,105 @@ + + * Copyright (C) 2006-2009 Laurent Destailleur + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/product/mod_lot_free.php + * \ingroup productbatch + * \brief File containing class for numbering model of Lot free + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/product_batch/modules_product_batch.class.php'; + +/** + * \class mod_codeproduct_leopard + * \brief Classe permettant la gestion leopard des codes produits + */ +class mod_lot_free extends ModeleNumRefBatch +{ + /* + * Attention ce module est utilise par defaut si aucun module n'a + * ete definit dans la configuration + * + * Le fonctionnement de celui-ci doit donc rester le plus ouvert possible + */ + + + /** + * @var string model name + */ + public $name = 'lot_free'; + + public $code_modifiable; // Code modifiable + + public $code_modifiable_invalide; // Code modifiable si il est invalide + + public $code_modifiable_null; // Code modifiables si il est null + + public $code_null; // Code facultatif + + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + /** + * @var int Automatic numbering + */ + public $code_auto; + + + /** + * Constructor + */ + public function __construct() + { + $this->code_null = 1; + $this->code_modifiable = 1; + $this->code_modifiable_invalide = 1; + $this->code_modifiable_null = 1; + $this->code_auto = 0; + } + + + /** + * Return description of module + * + * @return string Description of module + */ + public function info() + { + global $langs; + $langs->load("companies"); + return $langs->trans("LeopardNumRefModelDesc"); + } + + + /** + * Return an example of result returned by getNextValue + * + * @param product $objproduct Object product + * @param int $type Type of third party (1:customer, 2:supplier, -1:autodetect) + * @return string Return next value + */ + public function getNextValue($objproduct = 0, $type = -1) + { + global $langs; + return ''; + } +} diff --git a/htdocs/core/modules/product_batch/mod_lot_standard.php b/htdocs/core/modules/product_batch/mod_lot_standard.php new file mode 100644 index 00000000000..0d2b5a55139 --- /dev/null +++ b/htdocs/core/modules/product_batch/mod_lot_standard.php @@ -0,0 +1,145 @@ + + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2021 Christophe Battarel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/product_batch/mod_lot_standard.php + * \ingroup productbatch + * \brief File of class to manage Lot numbering rules standard + */ +require_once DOL_DOCUMENT_ROOT.'/core/modules/product_batch/modules_product_batch.class.php'; + +/** + * Class to manage MO numbering rules standard + */ +class mod_lot_standard extends ModeleNumRefBatch +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + public $prefix = 'LOT'; + + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var string name + */ + public $name = 'lot_standard'; + + + /** + * Return description of numbering module + * + * @return string Text with description + */ + public function info() + { + global $langs; + return $langs->trans("SimpleNumRefModelDesc", $this->prefix); + } + + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + return $this->prefix."0501-0001"; + } + + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @return boolean false if conflict, true if ok + */ + public function canBeActivated() + { + global $conf, $langs, $db; + + $coyymm = ''; $max = ''; + + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_lot"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + $sql .= " AND entity = ".$conf->entity; + + $resql = $db->query($sql); + if ($resql) { + $row = $db->fetch_row($resql); + if ($row) { $coyymm = substr($row[0], 0, 6); $max = $row[0]; } + } + if ($coyymm && !preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i', $coyymm)) { + $langs->load("errors"); + $this->error = $langs->trans('ErrorNumRefModel', $max); + return false; + } + + return true; + } + + /** + * Return next free value + * + * @param Product $objprod Object product + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO + */ + public function getNextValue($objprod, $object) + { + global $db, $conf; + + // First, we get the max value + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_lot"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + $sql .= " AND entity = ".$conf->entity; + + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + if ($obj) $max = intval($obj->max); + else $max = 0; + } else { + dol_syslog("mod_lot_standard::getNextValue", LOG_DEBUG); + return -1; + } + + //$date=time(); + $date = $object->date_creation; + $yymm = strftime("%y%m", $date); + + if ($max >= (pow(10, 4) - 1)) $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is + else $num = sprintf("%04s", $max + 1); + + dol_syslog("mod_lot_standard::getNextValue return ".$this->prefix.$yymm."-".$num); + return $this->prefix.$yymm."-".$num; + } +} diff --git a/htdocs/core/modules/product_batch/mod_sn_advanced.php b/htdocs/core/modules/product_batch/mod_sn_advanced.php new file mode 100644 index 00000000000..89d70a8239d --- /dev/null +++ b/htdocs/core/modules/product_batch/mod_sn_advanced.php @@ -0,0 +1,145 @@ + + * Copyright (C) 2004-2007 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand (Resultic) + * Copyright (C) 2019 Frédéric France + * Copyright (C) 2021 Christophe Battarel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/product_batch/mod_batch_advanced.php + * \ingroup productbatch + * \brief File containing class for numbering model of SN advanced + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/product_batch/modules_product_batch.class.php'; + + +/** + * Class to manage Batch numbering rules advanced + */ +class mod_sn_advanced extends ModeleNumRefBatch +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + /** + * @var string Error message + */ + public $error = ''; + + /** + * @var string name + */ + public $name = 'sn_advanced'; + + + /** + * Returns the description of the numbering model + * + * @return string Texte descripif + */ + public function info() + { + global $conf, $langs, $db; + + $langs->load("bills"); + + $form = new Form($db); + + $texte = $langs->trans('GenericNumRefModelDesc')."
\n"; + $texte .= '
'; + $texte .= ''; + $texte .= ''; + $texte .= ''; + $texte .= ''; + + $tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Batch"), $langs->transnoentities("Batch")); + $tooltip .= $langs->trans("GenericMaskCodes2"); + $tooltip .= $langs->trans("GenericMaskCodes3"); + $tooltip .= $langs->trans("GenericMaskCodes4a", $langs->transnoentities("Batch"), $langs->transnoentities("Batch")); + $tooltip .= $langs->trans("GenericMaskCodes5"); + + // Parametrage du prefix + $texte .= ''; + $texte .= ''; + + $texte .= ''; + + $texte .= ''; + + $texte .= '
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).' 
'; + $texte .= '
'; + + return $texte; + } + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $conf, $langs, $mysoc; + + $old_code_client = $mysoc->code_client; + $old_code_type = $mysoc->typent_code; + $mysoc->code_client = 'CCCCCCCCCC'; + $mysoc->typent_code = 'TTTTTTTTTT'; + $numExample = $this->getNextValue($mysoc, ''); + $mysoc->code_client = $old_code_client; + $mysoc->typent_code = $old_code_type; + + if (!$numExample) { + $numExample = $langs->trans('NotConfigured'); + } + return $numExample; + } + + /** + * Return next free value + * + * @param Product $objprod Object product + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO + */ + public function getNextValue($objprod, $object) + { + global $db, $conf; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + + // We get cursor rule + $mask = $conf->global->BATCH_ADVANCED_MASK; + + if (!$mask) { + $this->error = 'NotConfigured'; + return 0; + } + + $date = $object->date; + + $numFinal = get_next_value($db, $mask, 'product_sn', 'ref', '', null, $date); + + return $numFinal; + } +} diff --git a/htdocs/core/modules/product_batch/mod_sn_free.php b/htdocs/core/modules/product_batch/mod_sn_free.php new file mode 100644 index 00000000000..95e1bd20359 --- /dev/null +++ b/htdocs/core/modules/product_batch/mod_sn_free.php @@ -0,0 +1,104 @@ + + * Copyright (C) 2006-2009 Laurent Destailleur + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/product/mod_sn_free.php + * \ingroup productbatch + * \brief File containing class for numbering model of SN free + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/product_batch/modules_product_batch.class.php'; + +/** + * \class mod_codeproduct_leopard + * \brief Classe permettant la gestion leopard des codes produits + */ +class mod_sn_free extends ModeleNumRefBatch +{ + /* + * Attention ce module est utilise par defaut si aucun module n'a + * ete definit dans la configuration + * + * Le fonctionnement de celui-ci doit donc rester le plus ouvert possible + */ + + /** + * @var string model name + */ + public $name = 'sn_free'; + + public $code_modifiable; // Code modifiable + + public $code_modifiable_invalide; // Code modifiable si il est invalide + + public $code_modifiable_null; // Code modifiables si il est null + + public $code_null; // Code facultatif + + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + /** + * @var int Automatic numbering + */ + public $code_auto; + + + /** + * Constructor + */ + public function __construct() + { + $this->code_null = 1; + $this->code_modifiable = 1; + $this->code_modifiable_invalide = 1; + $this->code_modifiable_null = 1; + $this->code_auto = 0; + } + + + /** + * Return description of module + * + * @return string Description of module + */ + public function info() + { + global $langs; + $langs->load("companies"); + return $langs->trans("LeopardNumRefModelDesc"); + } + + + /** + * Return an example of result returned by getNextValue + * + * @param product $objproduct Object product + * @param int $type Type of third party (1:customer, 2:supplier, -1:autodetect) + * @return string Return next value + */ + public function getNextValue($objproduct = 0, $type = -1) + { + global $langs; + return ''; + } +} diff --git a/htdocs/core/modules/product_batch/mod_sn_standard.php b/htdocs/core/modules/product_batch/mod_sn_standard.php new file mode 100644 index 00000000000..bef5efcd9f8 --- /dev/null +++ b/htdocs/core/modules/product_batch/mod_sn_standard.php @@ -0,0 +1,145 @@ + + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2021 Christophe Battarel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/product_batch/mod_sn_standard.php + * \ingroup productbatch + * \brief File of class to manage SN numbering rules standard + */ +require_once DOL_DOCUMENT_ROOT.'/core/modules/product_batch/modules_product_batch.class.php'; + +/** + * Class to manage MO numbering rules standard + */ +class mod_sn_standard extends ModeleNumRefBatch +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + public $prefix = 'SN'; + + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var string name + */ + public $name = 'sn_standard'; + + + /** + * Return description of numbering module + * + * @return string Text with description + */ + public function info() + { + global $langs; + return $langs->trans("SimpleNumRefModelDesc", $this->prefix); + } + + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + return $this->prefix."0501-0001"; + } + + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @return boolean false if conflict, true if ok + */ + public function canBeActivated() + { + global $conf, $langs, $db; + + $coyymm = ''; $max = ''; + + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_lot"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + $sql .= " AND entity = ".$conf->entity; + + $resql = $db->query($sql); + if ($resql) { + $row = $db->fetch_row($resql); + if ($row) { $coyymm = substr($row[0], 0, 6); $max = $row[0]; } + } + if ($coyymm && !preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i', $coyymm)) { + $langs->load("errors"); + $this->error = $langs->trans('ErrorNumRefModel', $max); + return false; + } + + return true; + } + + /** + * Return next free value + * + * @param Product $objprod Object product + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO + */ + public function getNextValue($objprod, $object) + { + global $db, $conf; + + // First, we get the max value + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_lot"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + $sql .= " AND entity = ".$conf->entity; + + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + if ($obj) $max = intval($obj->max); + else $max = 0; + } else { + dol_syslog("mod_sn_standard::getNextValue", LOG_DEBUG); + return -1; + } + + //$date=time(); + $date = $object->date_creation; + $yymm = strftime("%y%m", $date); + + if ($max >= (pow(10, 4) - 1)) $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is + else $num = sprintf("%04s", $max + 1); + + dol_syslog("mod_sn_standard::getNextValue return ".$this->prefix.$yymm."-".$num); + return $this->prefix.$yymm."-".$num; + } +} diff --git a/htdocs/core/modules/product_batch/modules_product_batch.class.php b/htdocs/core/modules/product_batch/modules_product_batch.class.php index f5ef6ac3dda..42d4d052bfe 100644 --- a/htdocs/core/modules/product_batch/modules_product_batch.class.php +++ b/htdocs/core/modules/product_batch/modules_product_batch.class.php @@ -65,3 +65,89 @@ abstract class ModelePDFProductBatch extends CommonDocGenerator return $list; } } + +/** + * Parent class to manage numbering of batch products + */ +abstract class ModeleNumRefBatch +{ + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * Return if a module can be used or not + * + * @return boolean true if module can be used + */ + public function isEnabled() + { + return true; + } + + /** + * Returns the default description of the numbering template + * + * @return string Texte descripif + */ + public function info() + { + global $langs; + $langs->load("productbatch"); + return $langs->trans("NoDescription"); + } + + /** + * Returns an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $langs; + $langs->load("productbatch"); + return $langs->trans("NoExample"); + } + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @return boolean false if conflict, true if ok + */ + public function canBeActivated() + { + return true; + } + + /** + * Returns next assigned value + * + * @param Societe $objsoc Object thirdparty + * @param Object $object Object we need next value for + * @return string Valeur + */ + public function getNextValue($objsoc, $object) + { + global $langs; + return $langs->trans("NotAvailable"); + } + + /** + * Returns version of numbering module + * + * @return string Valeur + */ + public function getVersion() + { + global $langs; + $langs->load("admin"); + + if ($this->version == 'development') return $langs->trans("VersionDevelopment"); + if ($this->version == 'experimental') return $langs->trans("VersionExperimental"); + if ($this->version == 'dolibarr') return DOL_VERSION; + if ($this->version) return $this->version; + return $langs->trans("NotAvailable"); + } +} diff --git a/htdocs/langs/en_US/productbatch.lang b/htdocs/langs/en_US/productbatch.lang index 36adfd571fb..9e299baf8f3 100644 --- a/htdocs/langs/en_US/productbatch.lang +++ b/htdocs/langs/en_US/productbatch.lang @@ -26,3 +26,5 @@ ShowLogOfMovementIfLot=Show log of movements for couple product/lot StockDetailPerBatch=Stock detail per lot SerialNumberAlreadyInUse=Serial number %s is already used for product %s TooManyQtyForSerialNumber=You can only have one product %s for serial number %S +BatchLotNumberingModules=Options for automatic generation of batch products managed by lots +BatchSerialNumberingModules=Options for automatic generation of batch products managed by serial numbers \ No newline at end of file diff --git a/htdocs/langs/fr_FR/productbatch.lang b/htdocs/langs/fr_FR/productbatch.lang index 94ceb434bfd..eed5a063318 100644 --- a/htdocs/langs/fr_FR/productbatch.lang +++ b/htdocs/langs/fr_FR/productbatch.lang @@ -26,3 +26,5 @@ ShowLogOfMovementIfLot=Afficher l'historique des mouvements de couple produit / StockDetailPerBatch=Stock détaillé par lot SerialNumberAlreadyInUse=Le numéro de série %s est déjà utilisé pour le produit %s TooManyQtyForSerialNumber=Vous ne pouvez avoir qu'un produit %s avec le numéro de série %s +BatchLotNumberingModules=Modèle de génération et contrôle des numéros de lot +BatchSerialNumberingModules=Modèle de génération et contrôle des numéros de série \ No newline at end of file diff --git a/htdocs/product/admin/product_lot.php b/htdocs/product/admin/product_lot.php new file mode 100644 index 00000000000..13b47e56afd --- /dev/null +++ b/htdocs/product/admin/product_lot.php @@ -0,0 +1,279 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/product/admin/product_lot.php + * \ingroup produit + * \brief Setup page of product lot module + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("admin", "products", "productbatch")); + +// Security check +if (!$user->admin || (empty($conf->productbatch->enabled))) + accessforbidden(); + +$action = GETPOST('action', 'alpha'); +$value = GETPOST('value', 'alpha'); + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + +if ($action == 'updateMaskLot') { + $maskconstbatch = GETPOST('maskconstLot', 'alpha'); + $maskbatch = GETPOST('maskLot', 'alpha'); + + if ($maskconstbatch) $res = dolibarr_set_const($db, $maskconstbatch, $maskbatch, 'chaine', 0, '', $conf->entity); + + if (!$res > 0) $error++; + + if (!$error) { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} elseif ($action == 'updateMaskSN') { + $maskconstbatch = GETPOST('maskconstSN', 'alpha'); + $maskbatch = GETPOST('maskSN', 'alpha'); + + if ($maskconstbatch) $res = dolibarr_set_const($db, $maskconstbatch, $maskbatch, 'chaine', 0, '', $conf->entity); + + if (!$res > 0) $error++; + + if (!$error) { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} elseif ($action == 'setmodlot') { + dolibarr_set_const($db, "LOT_ADDON", $value, 'chaine', 0, '', $conf->entity); +} elseif ($action == 'setmodsn') { + dolibarr_set_const($db, "SN_ADDON", $value, 'chaine', 0, '', $conf->entity); +} + +/* + * View + */ + +$form = new Form($db); + +$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + +llxHeader("", $langs->trans("ProductLotSetup")); + +$linkback = ''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("ProductLotSetup"), $linkback, 'title_setup'); + +$head = product_lot_admin_prepare_head(); + +dol_fiche_head($head, 'settings', $langs->trans("Batch"), -1, 'productbatch'); + +/* + * Lot Numbering models + */ + +print load_fiche_titre($langs->trans("BatchLotNumberingModules"), '', ''); + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''."\n"; + +clearstatcache(); + +foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/product_batch/"); + + if (is_dir($dir)) { + $handle = opendir($dir); + if (is_resource($handle)) { + while (($file = readdir($handle)) !== false) { + if (substr($file, 0, 8) == 'mod_lot_' && substr($file, dol_strlen($file) - 3, 3) == 'php') { + $file = substr($file, 0, dol_strlen($file) - 4); + + require_once $dir.$file.'.php'; + + $module = new $file($db); + + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + if ($module->isEnabled()) { + print ''; + + // Show example of numbering model + print ''."\n"; + + print ''; + + $batch = new Productlot($db); + $batch->initAsSpecimen(); + + // Info + $htmltooltip = ''; + $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; + $nextval = $module->getNextValue($mysoc, $batch); + if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $htmltooltip .= ''.$langs->trans("NextValue").': '; + if ($nextval) { + if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') + $nextval = $langs->trans($nextval); + $htmltooltip .= $nextval.'
'; + } else { + $htmltooltip .= $langs->trans($module->error).'
'; + } + } + + print ''; + + print "\n"; + } + } + } + closedir($handle); + } + } +} + +print "
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->name."\n"; + print $module->info(); + print ''; + $tmp = $module->getExample(); + if (preg_match('/^Error/', $tmp)) print '
'.$langs->trans($tmp).'
'; + elseif ($tmp == 'NotConfigured') print $langs->trans($tmp); + else print $tmp; + print '
'; + if ($conf->global->LOT_ADDON == $file) { + print img_picto($langs->trans("Activated"), 'switch_on'); + } else { + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print '

\n"; + + +/* + * Serials Numbering models + */ + +print load_fiche_titre($langs->trans("BatchSerialNumberingModules"), '', ''); + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''."\n"; + +clearstatcache(); + +foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/product_batch/"); + + if (is_dir($dir)) { + $handle = opendir($dir); + if (is_resource($handle)) { + while (($file = readdir($handle)) !== false) { + if (substr($file, 0, 7) == 'mod_sn_' && substr($file, dol_strlen($file) - 3, 3) == 'php') { + $file = substr($file, 0, dol_strlen($file) - 4); + + require_once $dir.$file.'.php'; + + $module = new $file($db); + + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + if ($module->isEnabled()) { + print ''; + + // Show example of numbering model + print ''."\n"; + + print ''; + + $batch = new Productlot($db); + $batch->initAsSpecimen(); + + // Info + $htmltooltip = ''; + $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; + $nextval = $module->getNextValue($mysoc, $batch); + if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $htmltooltip .= ''.$langs->trans("NextValue").': '; + if ($nextval) { + if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') + $nextval = $langs->trans($nextval); + $htmltooltip .= $nextval.'
'; + } else { + $htmltooltip .= $langs->trans($module->error).'
'; + } + } + + print ''; + + print "\n"; + } + } + } + closedir($handle); + } + } +} + +print "
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->name."\n"; + print $module->info(); + print ''; + $tmp = $module->getExample(); + if (preg_match('/^Error/', $tmp)) print '
'.$langs->trans($tmp).'
'; + elseif ($tmp == 'NotConfigured') print $langs->trans($tmp); + else print $tmp; + print '
'; + if ($conf->global->SN_ADDON == $file) { + print img_picto($langs->trans("Activated"), 'switch_on'); + } else { + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print '

\n"; + +// End of page +llxFooter(); +$db->close();