From 44b84b21772b694f6293c3f26f956a55226aee58 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas <mko@atm-consulting.fr> Date: Thu, 9 Aug 2012 01:41:55 +0200 Subject: [PATCH] task # 326 : Add a numbering module to suggest automatically a product ref --- ChangeLog | 1 + .../product/mod_codeproduct_elephant.php | 302 ++++++++++++++++++ .../product/mod_codeproduct_leopard.php | 123 +++++++ .../modules/product/modules_product.class.php | 213 ++++++++++++ htdocs/install/mysql/data/llx_const.sql | 4 + htdocs/langs/fr_FR/admin.lang | 3 + htdocs/langs/fr_FR/companies.lang | 2 +- htdocs/langs/fr_FR/products.lang | 4 +- htdocs/product/admin/product.php | 137 ++++++++ htdocs/product/fiche.php | 14 +- 10 files changed, 800 insertions(+), 3 deletions(-) create mode 100644 htdocs/core/modules/product/mod_codeproduct_elephant.php create mode 100644 htdocs/core/modules/product/mod_codeproduct_leopard.php create mode 100644 htdocs/core/modules/product/modules_product.class.php diff --git a/ChangeLog b/ChangeLog index bddd25d5dd1..7c180afdb68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -38,6 +38,7 @@ For users: - New: Update libs/tools/logo for DoliWamp. - Fix: No images into product description lines as PDF generation does not work with this. +- New: [ task #326 ]: Add a numbering module to suggest automatically a product ref For developers: - New: Add webservice for thirdparty creation and list. diff --git a/htdocs/core/modules/product/mod_codeproduct_elephant.php b/htdocs/core/modules/product/mod_codeproduct_elephant.php new file mode 100644 index 00000000000..437e9e6f4e8 --- /dev/null +++ b/htdocs/core/modules/product/mod_codeproduct_elephant.php @@ -0,0 +1,302 @@ +<?php +/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2006-2009 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2007-2012 Regis Houssin <regis@dolibarr.fr> + * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es> + * + * 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 <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/product/mod_codeproduct_elephant.php + * \ingroup product + * \brief File of class to manage product code with elephant rule + */ + +require_once(DOL_DOCUMENT_ROOT."/core/modules/product/modules_product.class.php"); + + +/** + * \class mod_codeproduct_elephant + * \brief Class to manage product code with elephant rule + */ +class mod_codeproduct_elephant extends ModeleProductCode +{ + var $nom='Elephant'; // Nom du modele + var $code_modifiable; // Code modifiable + var $code_modifiable_invalide; // Code modifiable si il est invalide + var $code_modifiable_null; // Code modifiables si il est null + var $code_null; // Code facultatif + var $version='dolibarr'; // 'development', 'experimental', 'dolibarr' + var $code_auto; // Numerotation automatique + + var $searchcode; // String de recherche + var $numbitcounter; // Nombre de chiffres du compteur + var $prefixIsRequired; // Le champ prefix du tiers doit etre renseigne quand on utilise {pre} + + + /** + * Constructor + */ + function __construct() + { + $this->code_null = 0; + $this->code_modifiable = 1; + $this->code_modifiable_invalide = 1; + $this->code_modifiable_null = 1; + $this->code_auto = 1; + $this->prefixIsRequired = 0; + } + + + /** Return description of module + * + * @param string $langs Object langs + * @return string Description of module + */ + function info($langs) + { + global $conf, $mc; + + $langs->load("products"); + + $form = new Form($this->db); + + $disabled = ((! empty($mc->sharings['referent']) && $mc->sharings['referent'] != $conf->entity) ? ' disabled="disabled"' : ''); + + $texte = $langs->trans('GenericNumRefModelDesc')."<br>\n"; + $texte.= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">'; + $texte.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $texte.= '<input type="hidden" name="action" value="setModuleOptions">'; + $texte.= '<input type="hidden" name="param1" value="PRODUCT_ELEPHANT_MASK_PRODUCT">'; + $texte.= '<input type="hidden" name="param2" value="PRODUCT_ELEPHANT_MASK_SERVICE">'; + $texte.= '<table class="nobordernopadding" width="100%">'; + + $tooltip=$langs->trans("GenericMaskCodes",$langs->transnoentities("Product"),$langs->transnoentities("Product")); + $tooltip.=$langs->trans("GenericMaskCodes3"); + $tooltip.=$langs->trans("GenericMaskCodes4c"); + $tooltip.=$langs->trans("GenericMaskCodes5"); + + // Parametrage du prefix customers + $texte.= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("ProductCodeModel").'):</td>'; + $texte.= '<td align="right">'.$form->textwithpicto('<input type="text" class="flat" size="24" name="value1" value="'.$conf->global->PRODUCT_ELEPHANT_MASK_PRODUCT.'"'.$disabled.'>',$tooltip,1,1).'</td>'; + + $texte.= '<td align="left" rowspan="2"> <input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button"'.$disabled.'></td>'; + + $texte.= '</tr>'; + + // Parametrage du prefix suppliers + $texte.= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("ServiceCodeModel").'):</td>'; + $texte.= '<td align="right">'.$form->textwithpicto('<input type="text" class="flat" size="24" name="value2" value="'.$conf->global->PRODUCT_ELEPHANT_MASK_SERVICE.'"'.$disabled.'>',$tooltip,1,1).'</td>'; + $texte.= '</tr>'; + + $texte.= '</table>'; + $texte.= '</form>'; + + return $texte; + } + + + /** + * Return an example of result returned by getNextValue + * + * @param Translate $langs Object langs + * @param product $objproduct Object product + * @param int $type Type of third party (1:customer, 2:supplier, -1:autodetect) + * @return string Return string example + */ + function getExample($langs,$objproduct=0,$type=-1) + { + if ($type == 0 || $type == -1) + { + $exampleproduct = $this->getNextValue($objproduct,0); + if (! $exampleproduct) + { + $exampleproduct = $langs->trans('NotConfigured'); + } + if($exampleproduct=="ErrorBadMask") + { + $langs->load("errors"); + $exampleproduct=$langs->trans($exampleproduct); + } + } + if ($type == 1 || $type == -1) + { + $exampleservice = $this->getNextValue($objproduct,1); + if (! $exampleservice) + { + $exampleservice = $langs->trans('NotConfigured'); + } + if($exampleservice=="ErrorBadMask") + { + $langs->load("errors"); + $exampleservice=$langs->trans($exampleservice); + } + } + + if ($type == 0) return $exampleproduct; + if ($type == 1) return $exampleservice; + return $exampleproduct.'<br>'.$exampleservice; + } + + /** + * Return next value + * + * @param Product $objproduct Object product + * @param int $type Produit ou service (0:product, 1:service) + * @return string Value if OK, '' if module not configured, <0 if KO + */ + function getNextValue($objproduct=0,$type=-1) + { + global $db,$conf; + + require_once(DOL_DOCUMENT_ROOT ."/core/lib/functions2.lib.php"); + + // Get Mask value + $mask = ''; + if ($type==0) $mask = $conf->global->PRODUCT_ELEPHANT_MASK_PRODUCT; + if ($type==1) $mask = $conf->global->PRODUCT_ELEPHANT_MASK_SERVICE; + if (! $mask) + { + $this->error='NotConfigured'; + return ''; + } + + $field='';$where=''; + if ($type == 0) + { + $field = 'ref'; + //$where = ' AND client in (1,2)'; + } + else if ($type == 1) + { + $field = 'ref'; + //$where = ' AND fournisseur = 1'; + } + else return -1; + + $now=dol_now(); + + $numFinal=get_next_value($db,$mask,'product',$field,$where,'',$now); + + return $numFinal; + } + + + /** + * Check if mask/numbering use prefix + * + * @return int 0 or 1 + */ + function verif_prefixIsUsed() + { + global $conf; + + $mask = $conf->global->PRODUCT_ELEPHANT_MASK_PRODUCT; + if (preg_match('/\{pre\}/i',$mask)) return 1; + + $mask = $conf->global->PRODUCT_ELEPHANT_MASK_SERVICE; + if (preg_match('/\{pre\}/i',$mask)) return 1; + + return 0; + } + + + /** + * Check validity of code according to its rules + * + * @param DoliDB $db Database handler + * @param string &$code Code to check/correct + * @param Product $product Object product + * @param int $type 0 = customer/prospect , 1 = supplier + * @return int 0 if OK + * -1 ErrorBadCustomerCodeSyntax + * -2 ErrorCustomerCodeRequired + * -3 ErrorCustomerCodeAlreadyUsed + * -4 ErrorPrefixRequired + */ + function verif($db, &$code, $product, $type) + { + global $conf; + + require_once(DOL_DOCUMENT_ROOT ."/core/lib/functions2.lib.php"); + + $result=0; + $code = strtoupper(trim($code)); + + if (empty($code) && $this->code_null && empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED)) + { + $result=0; + } + else if (empty($code) && (! $this->code_null || ! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED)) ) + { + $result=-2; + } + else + { + // Get Mask value + $mask = ''; + if ($type==0) $mask = empty($conf->global->PRODUCT_ELEPHANT_MASK_PRODUCT)?'':$conf->global->PRODUCT_ELEPHANT_MASK_PRODUCT; + if ($type==1) $mask = empty($conf->global->PRODUCT_ELEPHANT_MASK_SSERVICE)?'':$conf->global->PRODUCT_ELEPHANT_MASK_SERVICE; + if (! $mask) + { + $this->error='NotConfigured'; + return ''; + } + + $result=check_value($mask,$code); + } + + dol_syslog("mod_codeclient_elephant::verif type=".$type." result=".$result); + return $result; + } + + + /** + * Renvoi si un code est pris ou non (par autre tiers) + * + * @param DoliDB $db Handler acces base + * @param string $code Code a verifier + * @param Product $product Objet product + * @return int 0 if available, <0 if KO + */ + function verif_dispo($db, $code, $product) + { + $sql = "SELECT ref FROM ".MAIN_DB_PREFIX."product"; + $sql.= " WHERE ref = '".$code."'"; + if ($product->id > 0) $sql.= " AND rowid <> ".$product->id; + + $resql=$db->query($sql); + if ($resql) + { + if ($db->num_rows($resql) == 0) + { + return 0; + } + else + { + return -1; + } + } + else + { + return -2; + } + + } + +} + +?> diff --git a/htdocs/core/modules/product/mod_codeproduct_leopard.php b/htdocs/core/modules/product/mod_codeproduct_leopard.php new file mode 100644 index 00000000000..d1a6b529da9 --- /dev/null +++ b/htdocs/core/modules/product/mod_codeproduct_leopard.php @@ -0,0 +1,123 @@ +<?php +/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2006-2009 Laurent Destailleur <eldy@users.sourceforge.net> + * + * 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 <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/product/mod_codeproduct_leopard.php + * \ingroup product + * \brief Fichier de la classe des gestion leopard des codes produits + */ + +require_once(DOL_DOCUMENT_ROOT."/core/modules/product/modules_product.class.php"); + + +/** + * \class mod_codeproduct_leopard + * \brief Classe permettant la gestion leopard des codes produits + */ +class mod_codeproduct_leopard extends ModeleProductCode +{ + /* + * 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 $nom='Leopard'; // Nom du modele + var $code_modifiable; // Code modifiable + var $code_modifiable_invalide; // Code modifiable si il est invalide + var $code_modifiable_null; // Code modifiables si il est null + var $code_null; // Code facultatif + var $version='dolibarr'; // 'development', 'experimental', 'dolibarr' + var $code_auto; // Numerotation automatique + + + /** + * Constructor + */ + 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 + * + * @param string $langs Object langs + * @return string Description of module + */ + function info($langs) + { + 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 + */ + function getNextValue($objproduct=0,$type=-1) + { + global $langs; + return ''; + } + + + /** + * Check validity of code according to its rules + * + * @param DoliDB $db Database handler + * @param string &$code Code to check/correct + * @param Product $product Object product + * @param int $type 0 = product , 1 = service + * @return int 0 if OK + * -1 ErrorBadProductCodeSyntax + * -2 ErrorProductCodeRequired + * -3 ErrorProductCodeAlreadyUsed + * -4 ErrorPrefixRequired + */ + function verif($db, &$code, $product, $type) + { + global $conf; + + $result=0; + $code = strtoupper(trim($code)); + + if (empty($code) && $this->code_null && empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED)) + { + $result=0; + } + else if (empty($code) && (! $this->code_null || ! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED)) ) + { + $result=-2; + } + + dol_syslog("mod_codeproduct_leopard::verif type=".$type." result=".$result); + return $result; + } +} + +?> diff --git a/htdocs/core/modules/product/modules_product.class.php b/htdocs/core/modules/product/modules_product.class.php new file mode 100644 index 00000000000..26a5ad6aab4 --- /dev/null +++ b/htdocs/core/modules/product/modules_product.class.php @@ -0,0 +1,213 @@ +<?php +/* Copyright (C) 2003-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com> + * Copyright (C) 2005-2012 Regis Houssin <regis@dolibarr.fr> + * + * 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 <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + + +/** + * \class ModeleProductCode + * \brief Parent class for product code generators + */ +abstract class ModeleProductCode +{ + var $error=''; + + /** Renvoi la description par defaut du modele de numerotation + * + * @param Translate $langs Object langs + * @return string Texte descripif + */ + function info($langs) + { + $langs->load("bills"); + return $langs->trans("NoDescription"); + } + + /** Renvoi nom module + * + * @param Translate $langs Object langs + * @return string Nom du module + */ + function getNom($langs) + { + return $this->nom; + } + + + /** Renvoi un exemple de numerotation + * + * @param Translate $langs Object langs + * @return string Example + */ + function getExample($langs) + { + $langs->load("bills"); + return $langs->trans("NoExample"); + } + + /** Test si les numeros deja en vigueur dans la base ne provoquent pas de + * de conflits qui empechera cette numerotation de fonctionner. + * + * @return boolean false si conflit, true si ok + */ + function canBeActivated() + { + return true; + } + + /** + * Return next value available + * + * @param Product $objproduct Object product + * @param int $type Type + * @return string Value + */ + function getNextValue($objproduct=0,$type=-1) + { + global $langs; + return $langs->trans("Function_getNextValue_InModuleNotWorking"); + } + + + /** Return version of module + * + * @return string Version + */ + 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; + return $langs->trans("NotAvailable"); + } + + /** + * Renvoi la liste des modeles de numérotation + * + * @param DoliDB $db Database handler + * @param string $maxfilenamelength Max length of value to show + * @return array List of numbers + */ + static function liste_modeles($db,$maxfilenamelength=0) + { + $liste=array(); + $sql =""; + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $row = $db->fetch_row($resql); + $liste[$row[0]]=$row[1]; + $i++; + } + } + else + { + return -1; + } + return $liste; + } + + /** + * Return description of module parameters + * + * @param Translate $langs Output language + * @param Product $product Product object + * @param int $type -1=Nothing, 0=Customer, 1=Supplier + * @return string HTML translated description + */ + function getToolTip($langs,$product,$type) + { + global $conf; + + $langs->load("admin"); + + $s=''; + if ($type == -1) $s.=$langs->trans("Name").': <b>'.$this->nom.'</b><br>'; + if ($type == -1) $s.=$langs->trans("Version").': <b>'.$this->getVersion().'</b><br>'; + if ($type == 0) $s.=$langs->trans("ProductCodeDesc").'<br>'; + if ($type == 1) $s.=$langs->trans("ServiceCodeDesc").'<br>'; + if ($type != -1) $s.=$langs->trans("ValidityControledByModule").': <b>'.$this->getNom($langs).'</b><br>'; + $s.='<br>'; + $s.='<u>'.$langs->trans("ThisIsModuleRules").':</u><br>'; + if ($type == 0) + { + $s.=$langs->trans("RequiredIfProduct").': '; + if (! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && ! empty($this->code_null)) $s.='<strike>'; + $s.=yn(!$this->code_null,1,2); + if (! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && ! empty($this->code_null)) $s.='</strike> '.yn(1,1,2).' ('.$langs->trans("ForcedToByAModule",$langs->transnoentities("yes")).')'; + $s.='<br>'; + } + if ($type == 1) + { + $s.=$langs->trans("RequiredIfService").': '; + if (! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && ! empty($this->code_null)) $s.='<strike>'; + $s.=yn(!$this->code_null,1,2); + if (! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && ! empty($this->code_null)) $s.='</strike> '.yn(1,1,2).' ('.$langs->trans("ForcedToByAModule",$langs->transnoentities("yes")).')'; + $s.='<br>'; + } + if ($type == -1) + { + $s.=$langs->trans("Required").': '; + if (! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && ! empty($this->code_null)) $s.='<strike>'; + $s.=yn(!$this->code_null,1,2); + if (! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && ! empty($this->code_null)) $s.='</strike> '.yn(1,1,2).' ('.$langs->trans("ForcedToByAModule",$langs->transnoentities("yes")).')'; + $s.='<br>'; + } + $s.=$langs->trans("CanBeModifiedIfOk").': '; + $s.=yn($this->code_modifiable,1,2); + $s.='<br>'; + $s.=$langs->trans("CanBeModifiedIfKo").': '.yn($this->code_modifiable_invalide,1,2).'<br>'; + $s.=$langs->trans("AutomaticCode").': '.yn($this->code_auto,1,2).'<br>'; + $s.='<br>'; + if ($type == 0 || $type == -1) + { + $nextval=$this->getNextValue($product,0); + if (empty($nextval)) $nextval=$langs->trans("Undefined"); + $s.=$langs->trans("NextValue").($type == -1?' ('.$langs->trans("Product").')':'').': <b>'.$nextval.'</b><br>'; + } + if ($type == 1 || $type == -1) + { + $nextval=$this->getNextValue($product,1); + if (empty($nextval)) $nextval=$langs->trans("Undefined"); + $s.=$langs->trans("NextValue").($type == -1?' ('.$langs->trans("Service").')':'').': <b>'.$nextval.'</b>'; + } + return $s; + } + + /** + * Check if mask/numbering use prefix + * + * @return int 0=no, 1=yes + */ + function verif_prefixIsUsed() + { + return 0; + } + +} + +?> diff --git a/htdocs/install/mysql/data/llx_const.sql b/htdocs/install/mysql/data/llx_const.sql index 18a81459535..8d7434e80a6 100644 --- a/htdocs/install/mysql/data/llx_const.sql +++ b/htdocs/install/mysql/data/llx_const.sql @@ -89,3 +89,7 @@ insert into llx_const (name, value, type, note, visible) values('SOCIETE_CODECOM -- insert into llx_const (name, value, type, note, visible) values ('MAILING_EMAIL_FROM','dolibarr@domain.com','chaine','EMail emmetteur pour les envois d emailings',0); +-- +-- Product +-- +insert into llx_const (name, value, type, note, visible) values('PRODUCT_CODEPRODUCT_ADDON','mod_codeproduct_leopard','yesno','Module to control product codes',0); \ No newline at end of file diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index a6b91499d6b..3f4b5b69751 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -278,6 +278,7 @@ GenericMaskCodes2= <b>{cccc}</b> le code client sur n lettres<br><b>{cccc000}</b GenericMaskCodes3= Tout autre caractère dans le masque sera laissé inchangé.<br>Les espaces ne sont pas permis.<br> GenericMaskCodes4a= <u>Exemple sur la 99eme %s du tiers LaCompanie faite le 31/03/2007:</u><br> GenericMaskCodes4b= <u>Exemple sur un tiers créé le 31/03/2007:</u><br> +GenericMaskCodes4c= <u>Exemple sur un produit/service créé le 31/03/2007:</u><br> GenericMaskCodes5= <b>ABC{yy}{mm}-{000000}</b> donnera <b>ABC0703-000099</b><br><b>{0000+100}-XXX/{dd}/YYY</b> donnera <b>0199-XXX/31/YYY</b> GenericNumRefModelDesc= Renvoie un numéro personnalisable selon un masque à définir. ServerAvailableOnIPOrPort= Serveur disponible à l'adresse <b>%s</b> sur le port <b>%s</b> @@ -1144,6 +1145,8 @@ UseSearchToSelectProduct= Utiliser un formulaire de recherche pour le choix d'un UseEcoTaxeAbility= Prise en charge des éco-taxes (DEEE) SetDefaultBarcodeTypeProducts= Type de code-barres utilisé par défaut pour les produits SetDefaultBarcodeTypeThirdParties= Type de code-barres utilisé par défaut pour les tiers +ProductCodeChecker= Modèle de numérotation des produits / services +ProductOtherConf= Paramètres des produits / services ##### Syslog ##### SyslogSetup= Configuration du module Logs et traces SyslogOutput= Sortie des log diff --git a/htdocs/langs/fr_FR/companies.lang b/htdocs/langs/fr_FR/companies.lang index acd7e4eeacf..ae6b8c44369 100644 --- a/htdocs/langs/fr_FR/companies.lang +++ b/htdocs/langs/fr_FR/companies.lang @@ -394,4 +394,4 @@ ActivityStateFilter=Statut d'activité # Monkey MonkeyNumRefModelDesc=Renvoie le numéro sous la forme %syymm-nnnn pour les codes clients et %syymm-nnnn pour les codes fournisseurs où yy est l'année, mm le mois et nnnn un compteur séquentiel sans rupture et sans remise à 0. # Leopard -LeopardNumRefModelDesc=Code client/fournisseur libre sans vérification. Peut être modifié à tout moment. +LeopardNumRefModelDesc=Code libre sans vérification. Peut être modifié à tout moment. diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 2d3dfd12b2d..4484e5686c8 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -169,4 +169,6 @@ SuppliersPrices=Prix fournisseurs CustomCode=Code douane CountryOrigin=Pays d'origine HiddenIntoCombo=Caché dans les listes -Nature=Nature \ No newline at end of file +Nature=Nature +ProductCodeModel=Modèle de code produit +ServiceCodeModel=Modèle de code service \ No newline at end of file diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 9c12199496c..eddac8c041d 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -46,6 +46,47 @@ $value = GETPOST('value','alpha'); /* * Actions */ +if ($action == 'setcodeproduct') +{ + if (dolibarr_set_const($db, "PRODUCT_CODEPRODUCT_ADDON",$value,'chaine',0,'',$conf->entity) > 0) + { + Header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } + else + { + dol_print_error($db); + } +} + +// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) +if ($action == 'setModuleOptions') +{ + $post_size=count($_POST); + + $db->begin(); + + for($i=0;$i < $post_size;$i++) + { + if (array_key_exists('param'.$i,$_POST)) + { + $param=GETPOST("param".$i,'alpha'); + $value=GETPOST("value".$i,'alpha'); + if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + } + } + if (! $error) + { + $db->commit(); + $mesg = "<font class=\"ok\">".$langs->trans("SetupSaved")."</font>"; + } + else + { + $db->rollback(); + $mesg = "<font class=\"error\">".$langs->trans("Error")."</font>"; + } +} if ($action == 'nbprod') { @@ -136,6 +177,102 @@ $head = product_admin_prepare_head(); dol_fiche_head($head, 'general', $tab, 0, 'product'); $form=new Form($db); + +/* + * Module to manage product / services code + */ +$dirproduct=array('/core/modules/product/'); + +print_titre($langs->trans("ProductCodeChecker")); + +print '<table class="noborder" width="100%">'."\n"; +print '<tr class="liste_titre">'."\n"; +print ' <td>'.$langs->trans("Name").'</td>'; +print ' <td>'.$langs->trans("Description").'</td>'; +print ' <td>'.$langs->trans("Example").'</td>'; +print ' <td align="center" width="80">'.$langs->trans("Status").'</td>'; +print ' <td align="center" width="60">'.$langs->trans("Infos").'</td>'; +print "</tr>\n"; + +$var = true; +foreach ($dirproduct as $dirroot) +{ + $dir = dol_buildpath($dirroot,0); + + $handle = @opendir($dir); + if (is_resource($handle)) + { + // Loop on each module find in opened directory + while (($file = readdir($handle))!==false) + { + if (substr($file, 0, 16) == 'mod_codeproduct_' && substr($file, -3) == 'php') + { + $file = substr($file, 0, dol_strlen($file)-4); + + try { + dol_include_once($dirroot.$file.".php"); + } + catch(Exception $e) + { + dol_syslog($e->getMessage(), LOG_ERR); + } + + $modCodeProduct = new $file; + + // Show modules according to features level + if ($modCodeProduct->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($modCodeProduct->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + $var = !$var; + print '<tr '.$bc[$var].'>'."\n"; + print '<td width="140">'.$modCodeProduct->nom.'</td>'."\n"; + print '<td>'.$modCodeProduct->info($langs).'</td>'."\n"; + print '<td nowrap="nowrap">'.$modCodeProduct->getExample($langs).'</td>'."\n"; + + if ($conf->global->PRODUCT_CODEPRODUCT_ADDON == "$file") + { + print '<td align="center">'."\n"; + print img_picto($langs->trans("Activated"),'switch_on'); + print "</td>\n"; + } + else + { + // @todo : What's that ? + /*$disabled = false; + if (! empty($conf->multicompany->enabled) && (is_object($mc) && ! empty($mc->sharings['referent']) && $mc->sharings['referent'] == $conf->entity) ? false : true); + print '<td align="center">'; + if (! $disabled) print '<a href="'.$_SERVER['PHP_SELF'].'?action=setcodeclient&value='.$file.'">'; + print img_picto($langs->trans("Disabled"),'switch_off'); + if (! $disabled) print '</a>'; + print '</td>';*/ + print '<td align="center">'; + print '<a href="'.$_SERVER['PHP_SELF'].'?action=setcodeproduct&value='.$file.'">'; + print img_picto($langs->trans("Disabled"),'switch_off'); + print '</a>'; + print '</td>'; + } + + print '<td align="center">'; + $s=$modCodeProduct->getToolTip($langs,null,-1); + print $form->textwithpicto('',$s,1); + print '</td>'; + + print '</tr>'; + } + } + closedir($handle); + } +} +print '</table>'; + +/* + * Other conf + */ + +print "<br>"; + +print_titre($langs->trans("ProductOtherConf")); + $var=true; print '<table class="noborder" width="100%">'; print '<tr class="liste_titre">'; diff --git a/htdocs/product/fiche.php b/htdocs/product/fiche.php index ce4573e47a5..4aa49ee651a 100644 --- a/htdocs/product/fiche.php +++ b/htdocs/product/fiche.php @@ -696,11 +696,22 @@ else { //WYSIWYG Editor require_once(DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php"); + + // Load object modCodeProduct + $module=$conf->global->PRODUCT_CODEPRODUCT_ADDON; + if (! $module) dolibarr_error('',$langs->trans("ErrorModuleThirdPartyCodeInCompanyModuleNotDefined")); + if (substr($module, 0, 16) == 'mod_codeproduct_' && substr($module, -3) == 'php') + { + $module = substr($module, 0, dol_strlen($module)-4); + } + dol_include_once('/core/modules/product/'.$module.".php"); + $modCodeProduct = new $module; print '<form action="fiche.php" method="post">'; print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; print '<input type="hidden" name="action" value="add">'; print '<input type="hidden" name="type" value="'.$type.'">'."\n"; + if ($modCodeProduct->code_auto) print '<input type="hidden" name="code_auto" value="1">'; if ($type==1) $title=$langs->trans("NewService"); else $title=$langs->trans("NewProduct"); @@ -710,7 +721,8 @@ else print '<table class="border" width="100%">'; print '<tr>'; - print '<td class="fieldrequired" width="20%">'.$langs->trans("Ref").'</td><td><input name="ref" size="40" maxlength="32" value="'.$ref.'">'; + if ($modCodeProduct->code_auto) $tmpcode=$modCodeProduct->getNextValue($object,$type); + print '<td class="fieldrequired" width="20%">'.$langs->trans("Ref").'</td><td><input name="ref" size="40" maxlength="32" value="'.$tmpcode.'">'; if ($_error) { print $langs->trans("RefAlreadyExists"); -- GitLab