From 3a4161fdf7ea229b6080b012f0062e37481a922c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 18 Feb 2014 19:49:36 +0100 Subject: [PATCH 01/13] Fix: css --- htdocs/theme/cameleo/style.css.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/theme/cameleo/style.css.php b/htdocs/theme/cameleo/style.css.php index 88858ee3211..2d5c1bc337d 100644 --- a/htdocs/theme/cameleo/style.css.php +++ b/htdocs/theme/cameleo/style.css.php @@ -1302,7 +1302,7 @@ span.tabspan { div.divButAction { margin-bottom: 1.4em; } -.butAction:link, .butAction:visited, .butAction:hover, .butAction:active, .butActionDelete, .butActionRefused, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active { +.butAction, .butAction:link, .butAction:visited, .butAction:hover, .butAction:active, .butActionDelete, .butActionRefused, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active { font-family: ; font-weight: bold; /*background: url() repeat-x;*/ From 03d056319ca481dff567702c425b6c0140e640fd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 18 Feb 2014 20:49:22 +0100 Subject: [PATCH 02/13] Qual: Clean code for adding menu entries into Modules system admin entry. New: Add entry for admin page Mass barcode init. --- htdocs/core/menus/standard/auguria_menu.php | 28 +++++++++++++++++---- htdocs/core/menus/standard/eldy.lib.php | 4 ++- htdocs/core/modules/modBarcode.class.php | 16 ++++++++++-- htdocs/core/modules/modProduct.class.php | 14 +++++++++++ htdocs/core/modules/modService.class.php | 16 ++++++++++++ htdocs/langs/en_US/admin.lang | 2 ++ htdocs/langs/en_US/products.lang | 2 +- 7 files changed, 73 insertions(+), 9 deletions(-) diff --git a/htdocs/core/menus/standard/auguria_menu.php b/htdocs/core/menus/standard/auguria_menu.php index 74612aa57fd..5f585794d39 100644 --- a/htdocs/core/menus/standard/auguria_menu.php +++ b/htdocs/core/menus/standard/auguria_menu.php @@ -110,11 +110,11 @@ class MenuManager // Modules system tools // TODO Find a way to add parent menu only if child menu exists. For the moment, no other method than hard coded methods. - if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->global->MAIN_MENU_ENABLE_MODULETOOLS)) + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->barcode->enabled) // TODO We should enabled module system tools entry without hardcoded test on some modules + || ! empty($conf->global->MAIN_MENU_ENABLE_MODULETOOLS)) { if (empty($user->societe_id)) { - //$newmenu->add("/admin/tools/index.php?mainmenu=home&leftmenu=modulesadmintools", $langs->trans("ModulesSystemTools"), 0, 1, '', 'home', 'modulesadmintools'); if ($leftmenu=="modulesadmintools" && $user->admin) { $langs->load("products"); @@ -131,9 +131,27 @@ class MenuManager 'type'=>'left', 'position'=>20 ); - array_unshift($tabMenu,$array_menu_product); - //$newmenu->add("/product/admin/product_tools.php?mainmenu=home&leftmenu=modulesadmintools", $langs->trans("ProductVatMassChange"), 1, $user->admin); + array_unshift($tabMenu,$array_menu_product); // add at beginning of array } + if ($leftmenu=="modulesadmintools" && $user->admin) + { + $langs->load("admin"); + $array_menu_product=array( + 'url'=>"/barcode/codeinit.php?mainmenu=home&leftmenu=modulesadmintools", + 'titre'=>$langs->trans("MassBarcodeInit"), + 'enabled'=>($user->admin?true:false), + 'perms'=>($user->admin?true:false), + 'fk_mainmenu'=>'home', + 'fk_leftmenu'=>'modulesadmintools', + 'fk_menu'=>-1, + 'mainmenu'=>'home', + 'leftmenu'=>'modulesadmintools_massbarcode', + 'type'=>'left', + 'position'=>21 + ); + array_unshift($tabMenu,$array_menu_product); // add at beginning of array + } + // Main menu title $array_menu_product=array( 'url'=>"/admin/tools/index.php?mainmenu=home&leftmenu=modulesadmintools", 'titre'=>$langs->trans("ModulesSystemTools"), @@ -146,7 +164,7 @@ class MenuManager 'type'=>'left', 'position'=>20 ); - array_unshift($tabMenu,$array_menu_product); + array_unshift($tabMenu,$array_menu_product); // add at beginning of array } } diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 14de23b298f..5a2ae201a0f 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -539,11 +539,13 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } // Modules system tools - if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->global->MAIN_MENU_ENABLE_MODULETOOLS)) + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->barcode->enabled) // TODO We should enabled module system tools entry without hardcoded test on some modules + || ! empty($conf->global->MAIN_MENU_ENABLE_MODULETOOLS)) // Some external modules may need to force to have this entry on. { if (empty($user->societe_id)) { $newmenu->add("/admin/tools/index.php?mainmenu=home&leftmenu=modulesadmintools", $langs->trans("ModulesSystemTools"), 0, 1, '', $mainmenu, 'modulesadmintools'); + // Special case: This entry can't be embedded into modules because we need it for both module service and products and we don't want duplicate lines. if ((empty($leftmenu) || $leftmenu=="modulesadmintools") && $user->admin) { $langs->load("products"); diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php index 283d62e2700..92b237236cb 100644 --- a/htdocs/core/modules/modBarcode.class.php +++ b/htdocs/core/modules/modBarcode.class.php @@ -101,14 +101,26 @@ class modBarcode extends DolibarrModules 'leftmenu'=>'barcodeprint', 'type'=>'left', // This is a Left menu entry 'titre'=>'BarCodePrintsheet', - 'url'=>'/barcode/printsheet.php', + 'url'=>'/barcode/printsheet.php?mainmenu=home&leftmenu=modulesadmintools', 'langs'=>'products', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>200, 'enabled'=>'$conf->barcode->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both - $r++; + $r++; + + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'left', // This is a Left menu entry + 'titre'=>'MassBarcodeInit', + 'url'=>'/barcode/codeinit.php?mainmenu=home&leftmenu=modulesadmintools', + 'langs'=>'barcode', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>300, + 'enabled'=>'$conf->barcode->enabled && $leftmenu=="modulesadmintools"', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both + $r++; } diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index 43cab4f72cf..fed630a40a2 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -129,6 +129,20 @@ class modProduct extends DolibarrModules $this->rights[$r][4] = 'export'; $r++; + /* We can't enable this here because it must be enabled in both product and service module and this create duplicate insert + $r=0; + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'left', // This is a Left menu entry + 'titre'=>'ProductVatMassChange', + 'url'=>'/product/admin/product_tools.php?mainmenu=home&leftmenu=modulesadmintools', + 'langs'=>'admin', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>300, + 'enabled'=>'$conf->product->enabled && $leftmenu=="modulesadmintools"', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both + $r++; + */ // Exports //-------- diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index eb472a25799..780a32ad45c 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -114,6 +114,22 @@ class modService extends DolibarrModules $r++; + /* We can't enable this here because it must be enabled in both product and service module and this create duplicate insert + $r=0; + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'left', // This is a Left menu entry + 'titre'=>'ProductVatMassChange', + 'url'=>'/product/admin/product_tools.php?mainmenu=home&leftmenu=modulesadmintools', + 'langs'=>'admin', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>300, + 'enabled'=>'$conf->product->enabled && $leftmenu=="modulesadmintools"', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both + $r++; + */ + + // Exports //-------- $r=0; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index ae4d11548aa..6d00a3d89bc 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -347,6 +347,8 @@ GetSecuredUrl=Get calculated URL ButtonHideUnauthorized=Hide buttons for unauthorized actions instead of showing disabled buttons ProductVatMassChange=Mass VAT change ProductVatMassChangeDesc=This page can be used to modify a VAT rate defined on products or services from a value to another. Warning, this change is done on all database. +MassBarcodeInit=Mass barcode init +MassBarcodeInitDesc=This page can be used to initialize a barcode on objects that does not have barcode defined. Check before that setup of module barcode is complete. OldVATRates=Old VAT rate NewVATRates=New VAT rate PriceBaseTypeToChange=Modify on prices with base reference value defined on diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 96fdf76379b..abe1ee6ec3d 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -217,4 +217,4 @@ DefinitionOfBarCodeForThirdpartyNotComplete=Definition of type or value of bar c BarCodeDataForProduct=Barcode information of product %s : BarCodeDataForThirdparty=Barcode information of thirdparty %s : BarcodeStickersMask=xxx - + From 2e67bbc382e5df7e299b3cad35658ae489219d17 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Feb 2014 01:51:19 +0100 Subject: [PATCH 03/13] Maxi debug of barcode feature. New: Barcode format and mandatory requirement is checked. New: Start to add new page for barcode init. --- htdocs/core/menus/standard/auguria_menu.php | 22 +- htdocs/core/menus/standard/eldy.lib.php | 2 +- .../barcode/mod_barcode_product_standard.php | 57 +- htdocs/langs/en_US/errors.lang | 3 + htdocs/product/class/product.class.php | 516 +++++++++++------- htdocs/product/fiche.php | 82 ++- htdocs/societe/class/societe.class.php | 132 ++--- htdocs/societe/soc.php | 16 +- 8 files changed, 506 insertions(+), 324 deletions(-) diff --git a/htdocs/core/menus/standard/auguria_menu.php b/htdocs/core/menus/standard/auguria_menu.php index 5f585794d39..ac84a0713f3 100644 --- a/htdocs/core/menus/standard/auguria_menu.php +++ b/htdocs/core/menus/standard/auguria_menu.php @@ -110,12 +110,12 @@ class MenuManager // Modules system tools // TODO Find a way to add parent menu only if child menu exists. For the moment, no other method than hard coded methods. - if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->barcode->enabled) // TODO We should enabled module system tools entry without hardcoded test on some modules + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->barcode->enabled) // TODO We should enabled module system tools entry without hardcoded test, but when at least one modules bringing such entries are on || ! empty($conf->global->MAIN_MENU_ENABLE_MODULETOOLS)) { if (empty($user->societe_id)) { - if ($leftmenu=="modulesadmintools" && $user->admin) + if ((! empty($conf->product->enabled) || ! empty($conf->service->enabled)) && ($leftmenu=="modulesadmintools" && $user->admin)) { $langs->load("products"); $array_menu_product=array( @@ -133,24 +133,6 @@ class MenuManager ); array_unshift($tabMenu,$array_menu_product); // add at beginning of array } - if ($leftmenu=="modulesadmintools" && $user->admin) - { - $langs->load("admin"); - $array_menu_product=array( - 'url'=>"/barcode/codeinit.php?mainmenu=home&leftmenu=modulesadmintools", - 'titre'=>$langs->trans("MassBarcodeInit"), - 'enabled'=>($user->admin?true:false), - 'perms'=>($user->admin?true:false), - 'fk_mainmenu'=>'home', - 'fk_leftmenu'=>'modulesadmintools', - 'fk_menu'=>-1, - 'mainmenu'=>'home', - 'leftmenu'=>'modulesadmintools_massbarcode', - 'type'=>'left', - 'position'=>21 - ); - array_unshift($tabMenu,$array_menu_product); // add at beginning of array - } // Main menu title $array_menu_product=array( 'url'=>"/admin/tools/index.php?mainmenu=home&leftmenu=modulesadmintools", diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 5a2ae201a0f..6c7e64d118a 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -539,7 +539,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } // Modules system tools - if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->barcode->enabled) // TODO We should enabled module system tools entry without hardcoded test on some modules + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->barcode->enabled) // TODO We should enabled module system tools entry without hardcoded test, but when at least one modules bringing such entries are on || ! empty($conf->global->MAIN_MENU_ENABLE_MODULETOOLS)) // Some external modules may need to force to have this entry on. { if (empty($user->societe_id)) diff --git a/htdocs/core/modules/barcode/mod_barcode_product_standard.php b/htdocs/core/modules/barcode/mod_barcode_product_standard.php index d20c7502f4a..c7a48c80b2f 100644 --- a/htdocs/core/modules/barcode/mod_barcode_product_standard.php +++ b/htdocs/core/modules/barcode/mod_barcode_product_standard.php @@ -190,15 +190,29 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode } else { - // Get Mask value - $mask = empty($conf->global->BARCODE_STANDARD_PRODUCT_MASK)?'':$conf->global->BARCODE_STANDARD_PRODUCT_MASK; - if (! $mask) + if ($this->verif_syntax($code) >= 0) { - $this->error='NotConfigured'; - return ''; + $is_dispo = $this->verif_dispo($db, $code, $product); + if ($is_dispo <> 0) + { + $result=-3; + } + else + { + $result=0; + } + } + else + { + if (dol_strlen($code) == 0) + { + $result=-2; + } + else + { + $result=-1; + } } - - $result=check_value($mask,$code); } dol_syslog(get_class($this)."::verif type=".$type." result=".$result); @@ -216,8 +230,8 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode */ function verif_dispo($db, $code, $product) { - $sql = "SELECT ref FROM ".MAIN_DB_PREFIX."product"; - $sql.= " WHERE ref = '".$code."'"; + $sql = "SELECT barcode FROM ".MAIN_DB_PREFIX."product"; + $sql.= " WHERE barcode = '".$code."'"; if ($product->id > 0) $sql.= " AND rowid <> ".$product->id; $resql=$db->query($sql); @@ -239,6 +253,31 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode } + /** + * Renvoi si un code respecte la syntaxe + * + * @param string $code Code a verifier + * @return int 0 if OK, <0 if KO + */ + function verif_syntax($code) + { + global $conf; + + $res = 0; + + // Get Mask value + $mask = empty($conf->global->BARCODE_STANDARD_PRODUCT_MASK)?'':$conf->global->BARCODE_STANDARD_PRODUCT_MASK; + if (! $mask) + { + $this->error='NotConfigured'; + return ''; + } + + $result=check_value($mask,$code); + + return $result; + } + } ?> diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 5dd292aa10b..fa0b87cc506 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -26,8 +26,11 @@ ErrorFromToAccountsMustDiffers=Source and targets bank accounts must be differen ErrorBadThirdPartyName=Bad value for third party name ErrorProdIdIsMandatory=The %s is mandatory ErrorBadCustomerCodeSyntax=Bad syntax for customer code +ErrorBadBarCodeSyntax=Bad syntax for bar code ErrorCustomerCodeRequired=Customer code required +ErrorBarCodeRequired=Bar code required ErrorCustomerCodeAlreadyUsed=Customer code already used +ErrorBarCodeAlreadyUsed=Bar code already used ErrorPrefixRequired=Prefix required ErrorUrlNotValid=The website address is incorrect ErrorBadSupplierCodeSyntax=Bad syntax for supplier code diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index f5070cf3eda..42209bbcca1 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2013 Laurent Destailleur + * Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2007-2011 Jean Heimburger @@ -202,7 +202,7 @@ class Product extends CommonObject * * @param User $user User making insert * @param int $notrigger Disable triggers - * @return int Id of product/service if OK or number of error < 0 + * @return int Id of product/service if OK, < 0 if KO */ function create($user,$notrigger=0) { @@ -300,141 +300,230 @@ class Product extends CommonObject // For automatic creation during create action (not used by Dolibarr GUI, can be used by scripts) if ($this->barcode == -1) $this->get_barcode($this,$this->barcode_type_code); - $sql = "SELECT count(*) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."product"; - $sql.= " WHERE entity IN (".getEntity('product', 1).")"; - $sql.= " AND ref = '" .$this->ref."'"; + // Check more parameters + // If error, this->errors[] is filled + $result = $this->verify(); - $result = $this->db->query($sql); - if ($result) - { - $obj = $this->db->fetch_object($result); - if ($obj->nb == 0) + if ($result >= 0) + { + $sql = "SELECT count(*) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."product"; + $sql.= " WHERE entity IN (".getEntity('product', 1).")"; + $sql.= " AND ref = '" .$this->ref."'"; + + $result = $this->db->query($sql); + if ($result) { - // Produit non deja existant - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product ("; - $sql.= "datec"; - $sql.= ", entity"; - $sql.= ", ref"; - $sql.= ", ref_ext"; - $sql.= ", price_min"; - $sql.= ", price_min_ttc"; - $sql.= ", label"; - $sql.= ", fk_user_author"; - $sql.= ", fk_product_type"; - $sql.= ", price"; - $sql.= ", price_ttc"; - $sql.= ", price_base_type"; - $sql.= ", tobuy"; - $sql.= ", tosell"; - $sql.= ", accountancy_code_buy"; - $sql.= ", accountancy_code_sell"; - $sql.= ", canvas"; - $sql.= ", finished"; - $sql.= ") VALUES ("; - $sql.= "'".$this->db->idate($now)."'"; - $sql.= ", ".$conf->entity; - $sql.= ", '".$this->db->escape($this->ref)."'"; - $sql.= ", ".(! empty($this->ref_ext)?"'".$this->db->escape($this->ref_ext)."'":"null"); - $sql.= ", ".price2num($price_min_ht); - $sql.= ", ".price2num($price_min_ttc); - $sql.= ", ".(! empty($this->libelle)?"'".$this->db->escape($this->libelle)."'":"null"); - $sql.= ", ".$user->id; - $sql.= ", ".$this->type; - $sql.= ", ".price2num($price_ht); - $sql.= ", ".price2num($price_ttc); - $sql.= ", '".$this->price_base_type."'"; - $sql.= ", ".$this->status; - $sql.= ", ".$this->status_buy; - $sql.= ", '".$this->accountancy_code_buy."'"; - $sql.= ", '".$this->accountancy_code_sell."'"; - $sql.= ", '".$this->canvas."'"; - $sql.= ", ".((! isset($this->finished) || $this->finished < 0 || $this->finished == '') ? 'null' : $this->finished); - $sql.= ")"; - - dol_syslog(get_class($this)."::Create sql=".$sql); - $result = $this->db->query($sql); - if ( $result ) + $obj = $this->db->fetch_object($result); + if ($obj->nb == 0) { - $id = $this->db->last_insert_id(MAIN_DB_PREFIX."product"); + // Produit non deja existant + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product ("; + $sql.= "datec"; + $sql.= ", entity"; + $sql.= ", ref"; + $sql.= ", ref_ext"; + $sql.= ", price_min"; + $sql.= ", price_min_ttc"; + $sql.= ", label"; + $sql.= ", fk_user_author"; + $sql.= ", fk_product_type"; + $sql.= ", price"; + $sql.= ", price_ttc"; + $sql.= ", price_base_type"; + $sql.= ", tobuy"; + $sql.= ", tosell"; + $sql.= ", accountancy_code_buy"; + $sql.= ", accountancy_code_sell"; + $sql.= ", canvas"; + $sql.= ", finished"; + $sql.= ") VALUES ("; + $sql.= "'".$this->db->idate($now)."'"; + $sql.= ", ".$conf->entity; + $sql.= ", '".$this->db->escape($this->ref)."'"; + $sql.= ", ".(! empty($this->ref_ext)?"'".$this->db->escape($this->ref_ext)."'":"null"); + $sql.= ", ".price2num($price_min_ht); + $sql.= ", ".price2num($price_min_ttc); + $sql.= ", ".(! empty($this->libelle)?"'".$this->db->escape($this->libelle)."'":"null"); + $sql.= ", ".$user->id; + $sql.= ", ".$this->type; + $sql.= ", ".price2num($price_ht); + $sql.= ", ".price2num($price_ttc); + $sql.= ", '".$this->price_base_type."'"; + $sql.= ", ".$this->status; + $sql.= ", ".$this->status_buy; + $sql.= ", '".$this->accountancy_code_buy."'"; + $sql.= ", '".$this->accountancy_code_sell."'"; + $sql.= ", '".$this->canvas."'"; + $sql.= ", ".((! isset($this->finished) || $this->finished < 0 || $this->finished == '') ? 'null' : $this->finished); + $sql.= ")"; - if ($id > 0) + dol_syslog(get_class($this)."::Create sql=".$sql); + $result = $this->db->query($sql); + if ( $result ) { - $this->id = $id; - $this->price = $price_ht; - $this->price_ttc = $price_ttc; - $this->price_min = $price_min_ht; - $this->price_min_ttc = $price_min_ttc; + $id = $this->db->last_insert_id(MAIN_DB_PREFIX."product"); - $result = $this->_log_price($user); - if ($result > 0) + if ($id > 0) { - if ($this->update($id, $user, true, 'add') <= 0) + $this->id = $id; + $this->price = $price_ht; + $this->price_ttc = $price_ttc; + $this->price_min = $price_min_ht; + $this->price_min_ttc = $price_min_ttc; + + $result = $this->_log_price($user); + if ($result > 0) { - $error++; + if ($this->update($id, $user, true, 'add') <= 0) + { + $error++; + } + } + else + { + $error++; + $this->error=$this->db->lasterror(); } } else { $error++; - $this->error=$this->db->lasterror(); + $this->error='ErrorFailedToGetInsertedId'; } } else { $error++; - $this->error='ErrorFailedToGetInsertedId'; + $this->error=$this->db->lasterror(); } } else { + // Product already exists with this ref + $langs->load("products"); $error++; - $this->error=$this->db->lasterror(); + $this->error = "ErrorProductAlreadyExists"; } } else { - // Product already exists with this ref - $langs->load("products"); $error++; - $this->error = "ErrorProductAlreadyExists"; + $this->error=$this->db->lasterror(); } - } - else - { - $error++; - $this->error=$this->db->lasterror(); - } - if (! $error && ! $notrigger) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('PRODUCT_CREATE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } + if (! $error && ! $notrigger) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('PRODUCT_CREATE',$this,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; } + // Fin appel triggers + } + + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -$error; + } + } + else + { + $this->db->rollback(); + dol_syslog(get_class($this)."::Create fails verify ".join(',',$this->errors), LOG_WARNING); + return -3; + } - if (! $error) - { - $this->db->commit(); - return $this->id; - } - else - { - $this->db->rollback(); - return -$error; - } } + + /** + * Check properties of product are ok (like name, barcode, ...) + * + * @return int 0 if OK, <0 if KO + */ + function verify() + { + $this->errors=array(); + + $result = 0; + $this->ref = trim($this->ref); + + if (! $this->ref) + { + $this->errors[] = 'ErrorBadRef'; + $result = -2; + } + + $rescode = $this->check_barcode($this->barcode); + if ($rescode <> 0) + { + if ($rescode == -1) + { + $this->errors[] = 'ErrorBadBarCodeSyntax'; + } + if ($rescode == -2) + { + $this->errors[] = 'ErrorBarCodeRequired'; + } + if ($rescode == -3) + { + $this->errors[] = 'ErrorBarCodeAlreadyUsed'; + } + $result = -3; + } + + return $result; + } + + /** + * Check customer code + * + * @param string $valuetotest Value to test + * @return int 0 if OK + * -1 ErrorBadBarCodeSyntax + * -2 ErrorBarCodeRequired + * -3 ErrorBarCodeAlreadyUsed + */ + function check_barcode($valuetotest) + { + global $conf; + if (! empty($conf->barcode->enabled) && ! empty($conf->global->BARCODE_PRODUCT_ADDON_NUM)) + { + $module=strtolower($conf->global->BARCODE_PRODUCT_ADDON_NUM); + + $dirsociete=array_merge(array('/core/modules/barcode/'),$conf->modules_parts['barcode']); + foreach ($dirsociete as $dirroot) + { + $res=dol_include_once($dirroot.$module.'.php'); + if ($res) break; + } + + $mod = new $module(); + + dol_syslog(get_class($this)."::check_barcode barcode=".$valuetotest." module=".$module); + $result = $mod->verif($this->db, $valuetotest, $this, 0); + return $result; + } + else + { + return 0; + } + } + /** * Update a record into database * * @param int $id Id of product * @param User $user Object user making update * @param int $notrigger Disable triggers - * @param string $action Current action for hookmanager + * @param string $action Current action for hookmanager ('add' or 'update') * @return int 1 if OK, -1 if ref already exists, -2 if other error */ function update($id, $user, $notrigger=false, $action='update') @@ -443,9 +532,7 @@ class Product extends CommonObject $error=0; - $this->db->begin(); - - // Verification parametres + // Check parameters if (! $this->libelle) $this->libelle = 'MISSING LABEL'; // Clean parameters @@ -473,135 +560,154 @@ class Product extends CommonObject //Gencod $this->barcode=trim($this->barcode); - // For automatic creation - if ($this->barcode == -1) $this->get_barcode($this,$this->barcode_type_code); - $this->accountancy_code_buy = trim($this->accountancy_code_buy); $this->accountancy_code_sell= trim($this->accountancy_code_sell); - $sql = "UPDATE ".MAIN_DB_PREFIX."product"; - $sql.= " SET label = '" . $this->db->escape($this->libelle) ."'"; - $sql.= ", ref = '" . $this->ref ."'"; - $sql.= ", ref_ext = ".(! empty($this->ref_ext)?"'".$this->db->escape($this->ref_ext)."'":"null"); - $sql.= ", tva_tx = " . $this->tva_tx; - $sql.= ", recuperableonly = " . $this->tva_npr; - $sql.= ", localtax1_tx = " . $this->localtax1_tx; - $sql.= ", localtax2_tx = " . $this->localtax2_tx; - $sql.= ", barcode = ". (empty($this->barcode)?"null":"'".$this->db->escape($this->barcode)."'"); - $sql.= ", fk_barcode_type = ". (empty($this->barcode_type)?"null":$this->db->escape($this->barcode_type)); + $this->db->begin(); - $sql.= ", tosell = " . $this->status; - $sql.= ", tobuy = " . $this->status_buy; - $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'); - $sql.= ", length = " . ($this->length!='' ? "'".$this->length."'" : 'null'); - $sql.= ", length_units = " . ($this->length_units!='' ? "'".$this->length_units."'" : 'null'); - $sql.= ", surface = " . ($this->surface!='' ? "'".$this->surface."'" : 'null'); - $sql.= ", surface_units = " . ($this->surface_units!='' ? "'".$this->surface_units."'" : 'null'); - $sql.= ", volume = " . ($this->volume!='' ? "'".$this->volume."'" : 'null'); - $sql.= ", volume_units = " . ($this->volume_units!='' ? "'".$this->volume_units."'" : 'null'); - $sql.= ", seuil_stock_alerte = " . ((isset($this->seuil_stock_alerte) && $this->seuil_stock_alerte != '') ? "'".$this->seuil_stock_alerte."'" : "null"); - $sql.= ", description = '" . $this->db->escape($this->description) ."'"; - $sql.= ", customcode = '" . $this->db->escape($this->customcode) ."'"; - $sql.= ", fk_country = " . ($this->country_id > 0 ? $this->country_id : 'null'); - $sql.= ", note = '" . $this->db->escape($this->note) ."'"; - $sql.= ", duration = '" . $this->duration_value . $this->duration_unit ."'"; - $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.= " WHERE rowid = " . $id; + // Check name is required and codes are ok or unique. + // If error, this->errors[] is filled + if ($action != 'add') + { + $result = $this->verify(); // We don't check when update called during a create because verify was already done + } - dol_syslog(get_class($this)."update sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - $this->id = $id; + if ($result >= 0) + { + // For automatic creation + if ($this->barcode == -1) $this->get_barcode($this,$this->barcode_type_code); - // Multilangs - if (! empty($conf->global->MAIN_MULTILANGS)) + $sql = "UPDATE ".MAIN_DB_PREFIX."product"; + $sql.= " SET label = '" . $this->db->escape($this->libelle) ."'"; + $sql.= ", ref = '" . $this->ref ."'"; + $sql.= ", ref_ext = ".(! empty($this->ref_ext)?"'".$this->db->escape($this->ref_ext)."'":"null"); + $sql.= ", tva_tx = " . $this->tva_tx; + $sql.= ", recuperableonly = " . $this->tva_npr; + $sql.= ", localtax1_tx = " . $this->localtax1_tx; + $sql.= ", localtax2_tx = " . $this->localtax2_tx; + + $sql.= ", barcode = ". (empty($this->barcode)?"null":"'".$this->db->escape($this->barcode)."'"); + $sql.= ", fk_barcode_type = ". (empty($this->barcode_type)?"null":$this->db->escape($this->barcode_type)); + + $sql.= ", tosell = " . $this->status; + $sql.= ", tobuy = " . $this->status_buy; + $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'); + $sql.= ", length = " . ($this->length!='' ? "'".$this->length."'" : 'null'); + $sql.= ", length_units = " . ($this->length_units!='' ? "'".$this->length_units."'" : 'null'); + $sql.= ", surface = " . ($this->surface!='' ? "'".$this->surface."'" : 'null'); + $sql.= ", surface_units = " . ($this->surface_units!='' ? "'".$this->surface_units."'" : 'null'); + $sql.= ", volume = " . ($this->volume!='' ? "'".$this->volume."'" : 'null'); + $sql.= ", volume_units = " . ($this->volume_units!='' ? "'".$this->volume_units."'" : 'null'); + $sql.= ", seuil_stock_alerte = " . ((isset($this->seuil_stock_alerte) && $this->seuil_stock_alerte != '') ? "'".$this->seuil_stock_alerte."'" : "null"); + $sql.= ", description = '" . $this->db->escape($this->description) ."'"; + $sql.= ", customcode = '" . $this->db->escape($this->customcode) ."'"; + $sql.= ", fk_country = " . ($this->country_id > 0 ? $this->country_id : 'null'); + $sql.= ", note = '" . $this->db->escape($this->note) ."'"; + $sql.= ", duration = '" . $this->duration_value . $this->duration_unit ."'"; + $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.= " WHERE rowid = " . $id; + + dol_syslog(get_class($this)."update sql=".$sql); + $resql=$this->db->query($sql); + if ($resql) { - if ( $this->setMultiLangs() < 0) - { - $this->error=$langs->trans("Error")." : ".$this->db->error()." - ".$sql; - return -2; - } - } + $this->id = $id; - // Actions on extra fields (by external module or standard code) - $hookmanager->initHooks(array('productdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + // Multilangs + if (! empty($conf->global->MAIN_MULTILANGS)) { - $result=$this->insertExtraFields(); - if ($result < 0) + if ( $this->setMultiLangs() < 0) { - $error++; + $this->error=$langs->trans("Error")." : ".$this->db->error()." - ".$sql; + return -2; } } - } - else if ($reshook < 0) $error++; - if (! $error && ! $notrigger) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('PRODUCT_MODIFY',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - - if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref != $this->ref)) - { - // We remove directory - if ($conf->product->dir_output) + // Actions on extra fields (by external module or standard code) + $hookmanager->initHooks(array('productdao')); + $parameters=array('id'=>$this->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) { - $olddir = $conf->product->dir_output . "/" . dol_sanitizeFileName($this->oldcopy->ref); - $newdir = $conf->product->dir_output . "/" . dol_sanitizeFileName($this->ref); - if (file_exists($olddir)) + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used { - include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $res=@dol_move($olddir, $newdir); - if (! $res) + $result=$this->insertExtraFields(); + if ($result < 0) { - $this->error='ErrorFailToMoveDir'; $error++; } } } - } + else if ($reshook < 0) $error++; - if (! $error) - { - $this->db->commit(); - return 1; + if (! $error && ! $notrigger) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('PRODUCT_MODIFY',$this,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; } + // Fin appel triggers + } + + if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref != $this->ref)) + { + // We remove directory + if ($conf->product->dir_output) + { + $olddir = $conf->product->dir_output . "/" . dol_sanitizeFileName($this->oldcopy->ref); + $newdir = $conf->product->dir_output . "/" . dol_sanitizeFileName($this->ref); + if (file_exists($olddir)) + { + include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + $res=@dol_move($olddir, $newdir); + if (! $res) + { + $this->error='ErrorFailToMoveDir'; + $error++; + } + } + } + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -$error; + } } else { - $this->db->rollback(); - return -$error; + if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $this->error=$langs->trans("Error")." : ".$langs->trans("ErrorProductAlreadyExists",$this->ref); + $this->db->rollback(); + return -1; + } + else + { + $this->error=$langs->trans("Error")." : ".$this->db->error()." - ".$sql; + $this->db->rollback(); + return -2; + } } - } - else - { - if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') - { - $this->error=$langs->trans("Error")." : ".$langs->trans("ErrorProductAlreadyExists",$this->ref); - $this->db->rollback(); - return -1; - } - else - { - $this->error=$langs->trans("Error")." : ".$this->db->error()." - ".$sql; - $this->db->rollback(); - return -2; - } - } + } + else + { + $this->db->rollback(); + dol_syslog(get_class($this)."::Update fails verify ".join(',',$this->errors), LOG_WARNING); + return -3; + } } /** @@ -3156,6 +3262,8 @@ class Product extends CommonObject $this->tobuy=1; $this->type=0; $this->note='This is a comment (private)'; + + $this->barcode=-1; // Create barcode automatically } } ?> diff --git a/htdocs/product/fiche.php b/htdocs/product/fiche.php index ca47227e1f0..6a86dbe3217 100644 --- a/htdocs/product/fiche.php +++ b/htdocs/product/fiche.php @@ -117,10 +117,25 @@ if (empty($reshook)) // Barcode value if ($action == 'setbarcode' && $user->rights->barcode->creer) { - //Todo: ajout verification de la validite du code barre en fonction du type - $result = $object->setValueFrom('barcode', GETPOST('barcode')); - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; + $result=$object->check_barcode(GETPOST('barcode')); + + if ($result >= 0) + { + $result = $object->setValueFrom('barcode', GETPOST('barcode')); + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + $langs->load("errors"); + if ($result == -1) $errors[] = 'ErrorBadBarCodeSyntax'; + else if ($result == -2) $errors[] = 'ErrorBarCodeRequired'; + else if ($result == -3) $errors[] = 'ErrorBarCodeAlreadyUsed'; + else $errors[] = 'FailedToValidateBarCode'; + + $error++; + setEventMessage($errors,'errors'); + } } if ($action == 'setaccountancy_code_buy') @@ -236,8 +251,9 @@ if (empty($reshook)) exit; } else - { - setEventMessage($langs->trans($object->error), 'errors'); + { + if (count($object->errors)) setEventMessage($object->errors, 'errors'); + else setEventMessage($langs->trans($object->error), 'errors'); $action = "create"; } } @@ -279,7 +295,11 @@ if (empty($reshook)) $object->volume_units = GETPOST('volume_units'); $object->finished = GETPOST('finished'); $object->hidden = GETPOST('hidden')=='yes'?1:0; - $object->accountancy_code_sell = GETPOST('accountancy_code_sell'); + + $object->barcode_type = GETPOST('fk_barcode_type'); + $object->barcode = GETPOST('barcode'); + + $object->accountancy_code_sell = GETPOST('accountancy_code_sell'); $object->accountancy_code_buy = GETPOST('accountancy_code_buy'); // Fill array 'array_options' with data from add form @@ -292,14 +312,16 @@ if (empty($reshook)) $action = 'view'; } else - { - setEventMessage($langs->trans($object->error), 'errors'); + { + if (count($object->errors)) setEventMessage($object->errors, 'errors'); + else setEventMessage($langs->trans($object->error), 'errors'); $action = 'edit'; } } else - { - setEventMessage($langs->trans("ErrorProductBadRefOrLabel"), 'errors'); + { + if (count($object->errors)) setEventMessage($object->errors, 'errors'); + else setEventMessage($langs->trans("ErrorProductBadRefOrLabel"), 'errors'); $action = 'edit'; } } @@ -762,8 +784,8 @@ else print $formbarcode->select_barcode_type($fk_barcode_type, 'fk_barcode_type', 1); print ''.$langs->trans("BarcodeValue").''; $tmpcode=isset($_POST['barcode'])?GETPOST('barcode'):$object->barcode; - if (! empty($modBarCodeProduct->code_auto)) $tmpcode=$modBarCodeProduct->getNextValue($object,$type); - print ''; + if (empty($tmpcode) && ! empty($modBarCodeProduct->code_auto)) $tmpcode=$modBarCodeProduct->getNextValue($object,$type); + print ''; print ''; } @@ -871,7 +893,7 @@ else // We must set them on prices tab. } else - { + { print ''; // PRIX @@ -955,7 +977,7 @@ else // Label print ''; - // Status + // Status To sell print ''; - // To Buy + // Status To Buy print ''; + // Barcode + $showbarcode=(! empty($conf->barcode->enabled) && $user->rights->barcode->lire); + + if ($showbarcode) + { + print ''; + } + // Description (used in invoice, propal...) print '
'.$langs->trans("Label").'
'.$langs->trans("Status").' ('.$langs->trans("Sell").')'; print ''; print '
'.$langs->trans("Status").' ('.$langs->trans("Buy").')'; print ''; print '
'.$langs->trans('BarcodeType').''; + if (isset($_POST['fk_barcode_type'])) + { + $fk_barcode_type=GETPOST('fk_barcode_type'); + } + else + { + if (empty($fk_barcode_type) && ! empty($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE)) $fk_barcode_type = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE; + } + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbarcode.class.php'; + $formbarcode = new FormBarCode($db); + print $formbarcode->select_barcode_type($fk_barcode_type, 'fk_barcode_type', 1); + print ''.$langs->trans("BarcodeValue").''; + $tmpcode=isset($_POST['barcode'])?GETPOST('barcode'):$object->barcode; + if (empty($tmpcode) && ! empty($modBarCodeProduct->code_auto)) $tmpcode=$modBarCodeProduct->getNextValue($object,$type); + print ''; + print '
'.$langs->trans("Description").''; @@ -1100,7 +1146,7 @@ else print ''; // Accountancy_code_sell - print ''; + print ''; print ''; @@ -1121,7 +1167,7 @@ else } // Fiche en mode visu else - { + { $head=product_prepare_head($object, $user); $titre=$langs->trans("CardProduct".$object->type); $picto=($object->type==1?'service':'product'); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 93befedfc76..225a2dab5c8 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2010 Laurent Destailleur + * Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2003 Brian Fraval * Copyright (C) 2006 Andre Cianfarani @@ -208,8 +208,8 @@ class Societe extends CommonObject $this->db->begin(); // For automatic creation during create action (not used by Dolibarr GUI, can be used by scripts) - if ($this->code_client == -1) $this->get_codeclient($this->prefix_comm,0); - if ($this->code_fournisseur == -1) $this->get_codefournisseur($this->prefix_comm,1); + if ($this->code_client == -1) $this->get_codeclient($this,0); + if ($this->code_fournisseur == -1) $this->get_codefournisseur($this,1); // Check more parameters // If error, this->errors[] is filled @@ -290,14 +290,21 @@ class Societe extends CommonObject } else - { + { $this->db->rollback(); dol_syslog(get_class($this)."::Create fails verify ".join(',',$this->errors), LOG_WARNING); return -3; } } - function create_individual($user) { + /** + * Create a contact/address from thirdparty + * + * @param User $user Object user + * @return int <0 if KO, >0 if OK + */ + function create_individual($user) + { require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; $contact=new Contact($this->db); @@ -313,11 +320,13 @@ class Societe extends CommonObject $contact->zip = $this->zip; $contact->town = $this->town; $contact->phone_pro = $this->phone; + $result = $contact->create($user); - if ($result < 0) { + if ($result < 0) + { $this->error = $contact->error; $this->errors = $contact->errors; - dol_syslog("Societe::create_individual ERROR:" . $this->error, LOG_ERR); + dol_syslog(get_class($this)."::create_individual ERROR:" . $this->error, LOG_ERR); } return $result; @@ -325,6 +334,7 @@ class Societe extends CommonObject /** * Check properties of third party are ok (like name, third party codes, ...) + * Used before an add or update. * * @return int 0 if OK, <0 if KO */ @@ -342,10 +352,8 @@ class Societe extends CommonObject $result = -2; } - if ($this->client && $this->codeclient_modifiable()) + if ($this->client) { - // On ne verifie le code client que si la societe est un client / prospect et que le code est modifiable - // Si il n'est pas modifiable il n'est pas mis a jour lors de l'update $rescode = $this->check_codeclient(); if ($rescode <> 0) { @@ -369,10 +377,8 @@ class Societe extends CommonObject } } - if ($this->fournisseur && $this->codefournisseur_modifiable()) + if ($this->fournisseur) { - // On ne verifie le code fournisseur que si la societe est un fournisseur et que le code est modifiable - // Si il n'est pas modifiable il n'est pas mis a jour lors de l'update $rescode = $this->check_codefournisseur(); if ($rescode <> 0) { @@ -407,7 +413,7 @@ class Societe extends CommonObject * @param int $call_trigger 0=non, 1=oui * @param int $allowmodcodeclient Inclut modif code client et code compta * @param int $allowmodcodefournisseur Inclut modif code fournisseur et code compta fournisseur - * @param string $action 'create' or 'update' + * @param string $action 'add' or 'update' * @param int $nosyncmember Do not synchronize info of linked member * @return int <0 if KO, >=0 if OK */ @@ -467,8 +473,8 @@ class Societe extends CommonObject $this->barcode=trim($this->barcode); // For automatic creation - if ($this->code_client == -1) $this->get_codeclient($this->prefix_comm,0); - if ($this->code_fournisseur == -1) $this->get_codefournisseur($this->prefix_comm,1); + if ($this->code_client == -1) $this->get_codeclient($this,0); + if ($this->code_fournisseur == -1) $this->get_codefournisseur($this,1); $this->code_compta=trim($this->code_compta); $this->code_compta_fournisseur=trim($this->code_compta_fournisseur); @@ -517,7 +523,7 @@ class Societe extends CommonObject // Check name is required and codes are ok or unique. // If error, this->errors[] is filled - $result = $this->verify(); + if ($action != 'add') $result = $this->verify(); // We don't check when update called during a create because verify was already done if ($result >= 0) { @@ -574,16 +580,12 @@ class Societe extends CommonObject if ($customer) { - //$this->check_codeclient(); - $sql .= ", code_client = ".(! empty($this->code_client)?"'".$this->db->escape($this->code_client)."'":"null"); $sql .= ", code_compta = ".(! empty($this->code_compta)?"'".$this->db->escape($this->code_compta)."'":"null"); } if ($supplier) { - //$this->check_codefournisseur(); - $sql .= ", code_fournisseur = ".(! empty($this->code_fournisseur)?"'".$this->db->escape($this->code_fournisseur)."'":"null"); $sql .= ", code_compta_fournisseur = ".(! empty($this->code_compta_fournisseur)?"'".$this->db->escape($this->code_compta_fournisseur)."'":"null"); } @@ -621,7 +623,7 @@ class Societe extends CommonObject //$lmember->lastname=$this->lastname?$this->lastname:$lmember->lastname; // We keep firstname and lastname of member unchanged $lmember->address=$this->address; $lmember->email=$this->email; - $lmember->skype=$this->skype; + $lmember->skype=$this->skype; $lmember->phone=$this->phone; $result=$lmember->update($user,0,1,1,1); // Use nosync to 1 to avoid cyclic updates @@ -700,7 +702,7 @@ class Societe extends CommonObject } } else - { + { $this->db->rollback(); dol_syslog(get_class($this)."::Update fails verify ".join(',',$this->errors), LOG_WARNING); return -3; @@ -1815,19 +1817,20 @@ class Societe extends CommonObject global $conf; if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON)) { + $module=$conf->global->SOCIETE_CODECLIENT_ADDON; + $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']); foreach ($dirsociete as $dirroot) { - $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php'); + $res=dol_include_once($dirroot.$module.'.php'); if ($res) break; } - $var = $conf->global->SOCIETE_CODECLIENT_ADDON; - $mod = new $var; + $mod = new $module(); $this->code_client = $mod->getNextValue($objsoc,$type); $this->prefixCustomerIsRequired = $mod->prefixIsRequired; - dol_syslog(get_class($this)."::get_codeclient code_client=".$this->code_client." module=".$var); + dol_syslog(get_class($this)."::get_codeclient code_client=".$this->code_client." module=".$module); } } @@ -1844,18 +1847,19 @@ class Societe extends CommonObject global $conf; if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON)) { + $module=$conf->global->SOCIETE_CODECLIENT_ADDON; + $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']); foreach ($dirsociete as $dirroot) { - $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php'); + $res=dol_include_once($dirroot.$module.'.php'); if ($res) break; } - $var = $conf->global->SOCIETE_CODECLIENT_ADDON; - $mod = new $var; + $mod = new $module(); $this->code_fournisseur = $mod->getNextValue($objsoc,$type); - dol_syslog(get_class($this)."::get_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$var); + dol_syslog(get_class($this)."::get_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$module); } } @@ -1863,25 +1867,25 @@ class Societe extends CommonObject * Verifie si un code client est modifiable en fonction des parametres * du module de controle des codes. * - * @return int 0=Non, 1=Oui + * @return int 0=No, 1=Yes */ function codeclient_modifiable() { global $conf; if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON)) { + $module=$conf->global->SOCIETE_CODECLIENT_ADDON; + $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']); foreach ($dirsociete as $dirroot) { - $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php'); + $res=dol_include_once($dirroot.$module.'.php'); if ($res) break; } - $var = $conf->global->SOCIETE_CODECLIENT_ADDON; + $mod = new $module(); - $mod = new $var; - - dol_syslog(get_class($this)."::codeclient_modifiable code_client=".$this->code_client." module=".$var); + dol_syslog(get_class($this)."::codeclient_modifiable code_client=".$this->code_client." module=".$module); if ($mod->code_modifiable_null && ! $this->code_client) return 1; if ($mod->code_modifiable_invalide && $this->check_codeclient() < 0) return 1; if ($mod->code_modifiable) return 1; // A mettre en dernier @@ -1897,25 +1901,25 @@ class Societe extends CommonObject /** * Verifie si un code fournisseur est modifiable dans configuration du module de controle des codes * - * @return int 0=Non, 1=Oui + * @return int 0=No, 1=Yes */ function codefournisseur_modifiable() { global $conf; if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON)) { + $module=$conf->global->SOCIETE_CODECLIENT_ADDON; + $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']); foreach ($dirsociete as $dirroot) { - $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php'); + $res=dol_include_once($dirroot.$module.'.php'); if ($res) break; } - $var = $conf->global->SOCIETE_CODECLIENT_ADDON; + $mod = new $module(); - $mod = new $var; - - dol_syslog(get_class($this)."::codefournisseur_modifiable code_founisseur=".$this->code_fournisseur." module=".$var); + dol_syslog(get_class($this)."::codefournisseur_modifiable code_founisseur=".$this->code_fournisseur." module=".$module); if ($mod->code_modifiable_null && ! $this->code_fournisseur) return 1; if ($mod->code_modifiable_invalide && $this->check_codefournisseur() < 0) return 1; if ($mod->code_modifiable) return 1; // A mettre en dernier @@ -1929,36 +1933,36 @@ class Societe extends CommonObject /** - * Check customer code + * Check customer code * - * @return int 0 if OK - * -1 ErrorBadCustomerCodeSyntax - * -2 ErrorCustomerCodeRequired - * -3 ErrorCustomerCodeAlreadyUsed - * -4 ErrorPrefixRequired + * @return int 0 if OK + * -1 ErrorBadCustomerCodeSyntax + * -2 ErrorCustomerCodeRequired + * -3 ErrorCustomerCodeAlreadyUsed + * -4 ErrorPrefixRequired */ function check_codeclient() { global $conf; if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON)) { - $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']); + $module=$conf->global->SOCIETE_CODECLIENT_ADDON; + + $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']); foreach ($dirsociete as $dirroot) { - $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php'); + $res=dol_include_once($dirroot.$module.'.php'); if ($res) break; } - $var = $conf->global->SOCIETE_CODECLIENT_ADDON; + $mod = new $module(); - $mod = new $var; - - dol_syslog(get_class($this)."::check_codeclient code_client=".$this->code_client." module=".$var); - $result = $mod->verif($this->db, $this->code_client, $this, 0); + dol_syslog(get_class($this)."::check_codeclient code_client=".$this->code_client." module=".$module); + $result = $mod->verif($this->db, $this->code_client, $this, 0); return $result; } else - { + { return 0; } } @@ -1977,23 +1981,23 @@ class Societe extends CommonObject global $conf; if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON)) { - $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']); + $module=$conf->global->SOCIETE_CODECLIENT_ADDON; + + $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']); foreach ($dirsociete as $dirroot) { - $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php'); + $res=dol_include_once($dirroot.$module.'.php'); if ($res) break; } - $var = $conf->global->SOCIETE_CODECLIENT_ADDON; + $mod = new $module(); - $mod = new $var; - - dol_syslog(get_class($this)."::check_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$var); + dol_syslog(get_class($this)."::check_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$module); $result = $mod->verif($this->db, $this->code_fournisseur, $this, 1); return $result; } else - { + { return 0; } } diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index ab753855b4c..47c5c779582 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -789,8 +789,8 @@ else print ''; $out.= ''; + $out.= '\n"; } diff --git a/htdocs/expedition/fiche.php b/htdocs/expedition/fiche.php index 0a5d3d0cfcf..c04c4966efe 100644 --- a/htdocs/expedition/fiche.php +++ b/htdocs/expedition/fiche.php @@ -1542,7 +1542,7 @@ else if ($id || $ref) } // Show form - $formmail->show_form(); + print $formmail->get_form(); print '
'; } diff --git a/htdocs/fichinter/fiche.php b/htdocs/fichinter/fiche.php index e40d2b44daa..15e08bad604 100644 --- a/htdocs/fichinter/fiche.php +++ b/htdocs/fichinter/fiche.php @@ -1709,7 +1709,7 @@ else if ($id > 0 || ! empty($ref)) $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); } - $formmail->show_form(); + print $formmail->get_form(); print '
'; } diff --git a/htdocs/fourn/commande/fiche.php b/htdocs/fourn/commande/fiche.php index ffa72ecf9ac..8da53a67477 100644 --- a/htdocs/fourn/commande/fiche.php +++ b/htdocs/fourn/commande/fiche.php @@ -1634,13 +1634,13 @@ elseif (! empty($object->id)) } print ''; - + if (is_object($hookmanager)) { $parameters=array('line'=>$line,'num'=>$num,'i'=>$i); $reshook=$hookmanager->executeHooks('printObjectLine',$parameters,$object,$action); } - + if ($object->statut == 0 && $user->rights->fournisseur->commande->creer) { print ''; print ''; - + if (is_object($hookmanager)) { $parameters=array('line'=>$object->lines[$i],'num'=>$num,'i'=>$i); $reshook=$hookmanager->executeHooks('printObjectLine',$parameters,$object,$action); } - + print '
'.$langs->trans("ProductAccountancySellCode").'
'.$langs->trans("ProductAccountancySellCode").''; print '
'.$langs->trans('CustomerCode').''; print '"; - $sql = "SELECT p.rowid, p.lastname, p.firstname, p.fk_pays, p.poste, p.phone, p.phone_mobile, p.fax, p.email, p.skype, p.statut "; + $sql = "SELECT p.rowid, p.lastname, p.firstname, p.fk_pays as country_id, p.poste, p.phone, p.phone_mobile, p.fax, p.email, p.skype, p.statut "; $sql .= ", p.civilite, p.address, p.zip, p.town"; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as p"; $sql .= " WHERE p.fk_soc = ".$object->id; if ($search_status!='') $sql .= " AND p.statut = ".$db->escape($search_status); - if ($search_name) $sql .= " AND (p.lastname LIKE '%".$db->escape(strtolower($search_name))."%' OR p.firstname LIKE '%".$db->escape(strtolower($search_name))."%')"; + if ($search_name) $sql .= " AND (p.lastname LIKE '%".$db->escape($search_name)."%' OR p.firstname LIKE '%".$db->escape($search_name)."%')"; $sql.= " ORDER BY $sortfield $sortorder"; dol_syslog('core/lib/company.lib.php :: show_contacts sql='.$sql,LOG_DEBUG); @@ -665,12 +665,13 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') $contactstatic->statut = $obj->statut; $contactstatic->lastname = $obj->lastname; $contactstatic->firstname = $obj->firstname; + $contactstatic->civilite = $obj->civilite; print $contactstatic->getNomUrl(1); print ''; print ''; - $country_code = getCountry($obj->fk_pays, 'all'); + $country_code = getCountry($obj->country_id, 'all'); // Lien click to dial print ''; - // Copy to clipboard - $coords = ''; - if (!empty($object->name)) - $coords .= addslashes($object->name)."
"; - if (!empty($obj->civilite)) - $coords .= addslashes($obj->civilite).' '; - if (!empty($obj->firstname)) - $coords .= addslashes($obj->firstname).' '; - if (!empty($obj->lastname)) - $coords .= addslashes($obj->lastname); - $coords .= "
"; - if (!empty($obj->address)) - { - $coords .= addslashes(dol_nl2br($obj->address,1,true))."
"; - if (!empty($obj->cp)) - $coords .= addslashes($obj->zip).' '; - if (!empty($obj->ville)) - $coords .= addslashes($obj->town); - if (!empty($obj->pays)) - $coords .= "
".addslashes($country_code['label']); - } - elseif (!empty($object->address)) - { - $coords .= addslashes(dol_nl2br($object->address,1,true))."
"; - if (!empty($object->zip)) - $coords .= addslashes($object->zip).' '; - if (!empty($object->town)) - $coords .= addslashes($object->town); - if (!empty($object->country)) - $coords .= "
".addslashes($object->country); - } - - print ''; + print ''; // Add to agenda if (! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create) @@ -761,7 +747,7 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') } } else - { + { print ""; print ''; print "\n"; @@ -775,16 +761,6 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') - function copyToClipboard (text) { - text = text.replace(/
/g,"\n"); - var newElem = "

'.$langs->trans('HelpCopyToClipboard').'"; - $("#dialog").html(newElem); - $( "#dialog" ).dialog(); - $("#coords").select(); - return false; - } - '; return $i; } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index b9e25aa58f1..19d2adeea93 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -438,7 +438,7 @@ function dol_string_nospecial($str,$newstr='_',$badchars='') * Returns text escaped for inclusion into javascript code * * @param string $stringtoescape String to escape - * @param string $mode 0=Escape also ' and " into ', 1=Escape ' but not " for usage into 'string', 2=Escape " but not ' for usage into "string" + * @param string $mode 0=Escape also ' and " into ', 1=Escape ' but not " for usage into 'string', 2=Escape " but not ' for usage into "string", 3=Escape ' and " with \ * @return string Escaped string. Both ' and " are escaped into ' if they are escaped. */ function dol_escape_js($stringtoescape, $mode=0) @@ -449,6 +449,7 @@ function dol_escape_js($stringtoescape, $mode=0) if (empty($mode)) { $substitjs["'"]="\\'"; $substitjs['"']="\\'"; } else if ($mode == 1) $substitjs["'"]="\\'"; else if ($mode == 2) { $substitjs['"']='\\"'; } + else if ($mode == 3) { $substitjs["'"]="\\'"; $substitjs['"']="\\\""; } return strtr($stringtoescape, $substitjs); } From 3ea8af957a4515005a9ead4da89c801fc3ab586c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Feb 2014 11:19:43 +0100 Subject: [PATCH 09/13] First version of page to init barcode --- htdocs/barcode/codeinit.php | 94 +++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 htdocs/barcode/codeinit.php diff --git a/htdocs/barcode/codeinit.php b/htdocs/barcode/codeinit.php new file mode 100644 index 00000000000..f016423f44b --- /dev/null +++ b/htdocs/barcode/codeinit.php @@ -0,0 +1,94 @@ + + * + * 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/barcode/codeinit.php + * \ingroup member + * \brief Page to make mass init of barcode + */ +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + +$langs->load("admin"); +$langs->load("members"); +$langs->load("errors"); + +// Choix de l'annee d'impression ou annee courante. +$now = dol_now(); +$year=dol_print_date($now,'%Y'); +$month=dol_print_date($now,'%m'); +$day=dol_print_date($now,'%d'); +$forbarcode=GETPOST('forbarcode'); +$fk_barcode_type=GETPOST('fk_barcode_type'); +$mode=GETPOST('mode'); +$modellabel=GETPOST("modellabel"); // Doc template to use +$numberofsticker=GETPOST('numberofsticker','int'); + +$mesg=''; + +$action=GETPOST('action'); + +$producttmp=new Product($db); +$thirdpartytmp=new Societe($db); + + +/* + * Actions + */ + +if ($action == 'init') +{ + $action=''; + + +} + + + +/* + * View + */ + +$form=new Form($db); + +llxHeader('',$langs->trans("MassBarcodeInit")); + +print_fiche_titre($langs->trans("MassBarcodeInit")); +print '
'; + +print $langs->trans("MassBarcodeInitDesc").'
'; +print '
'; + +dol_htmloutput_errors($mesg); + +//print img_picto('','puce').' '.$langs->trans("PrintsheetForOneBarCode").'
'; +//print '
'; + +print '
'; +print ''; +print ''; + +print '
'; + +print ''; +print '
'; + +llxFooter(); + +$db->close(); +?> From 4915ec8916a0adeef0dfdc29beafbe92fe3aeb9c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Feb 2014 15:33:04 +0100 Subject: [PATCH 10/13] Fix: Bad space in predefined messages. Fix: Signature was not added for email sent from thirdparty page. --- ChangeLog | 2 + htdocs/core/class/html.formmail.class.php | 9 +- htdocs/langs/en_US/other.lang | 17 +-- htdocs/langs/fr_FR/other.lang | 17 +-- htdocs/societe/soc.php | 134 +++++++++++----------- 5 files changed, 92 insertions(+), 87 deletions(-) diff --git a/ChangeLog b/ChangeLog index aec1231f66b..a90f737ab4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,8 @@ Fix: Enable extrafields for customer order, proposal and invoice lines. This fea fix enough quickly for 3.5.0 release. Fix: user right on Holiday for month report nor working. Fix: [ bug #1250 ] "Supplier Ref. product" sidebar search box does not work +Fix: Bad space in predefined messages. +Fix: Signature was not added for email sent from thirdparty page. ***** ChangeLog for 3.5 compared to 3.4.* ***** For users: diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 66fd945c01d..c39c5f05277 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -76,7 +76,7 @@ class FormMail * @param DoliDB $db Database handler */ function __construct($db) - { + { $this->db = $db; $this->withform=1; @@ -554,7 +554,8 @@ class FormMail elseif ($this->param["models"]=='invoice_supplier_send') { $defaultmessage=$langs->transnoentities("PredefinedMailContentSendSupplierInvoice"); } elseif ($this->param["models"]=='shipping_send') { $defaultmessage=$langs->transnoentities("PredefinedMailContentSendShipping"); } elseif ($this->param["models"]=='fichinter_send') { $defaultmessage=$langs->transnoentities("PredefinedMailContentSendFichInter"); } - elseif (! is_numeric($this->withbody)) { $defaultmessage=$this->withbody; } + elseif ($this->param["models"]=='thirdparty') { $defaultmessage=$langs->transnoentities("PredefinedMailContentThirdparty"); } + elseif (! is_numeric($this->withbody)) { $defaultmessage=$this->withbody; } // Complete substitution array if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_ADD_PAYMENT_URL)) @@ -576,14 +577,14 @@ class FormMail } $defaultmessage=str_replace('\n',"\n",$defaultmessage); - + // Deal with format differences between message and signature (text / HTML) if(dol_textishtml($defaultmessage) && !dol_textishtml($this->substit['__SIGNATURE__'])) { $this->substit['__SIGNATURE__'] = dol_nl2br($this->substit['__SIGNATURE__']); } else if(!dol_textishtml($defaultmessage) && dol_textishtml($this->substit['__SIGNATURE__'])) { $defaultmessage = dol_nl2br($defaultmessage); } - + $defaultmessage=make_substitutions($defaultmessage,$this->substit); if (isset($_POST["message"])) $defaultmessage=$_POST["message"]; diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 76acd7022fc..f8f8a5fd87b 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -49,14 +49,15 @@ Miscellaneous=Miscellaneous NbOfActiveNotifications=Number of notifications PredefinedMailTest=This is a test mail.\nThe two lines are separated by a carriage return.\n\n__SIGNATURE__ PredefinedMailTestHtml=This is a test mail (the word test must be in bold).
The two lines are separated by a carriage return.

__SIGNATURE__ -PredefinedMailContentSendInvoice=__CONTACTCIVNAME__ \n\n You will find here the invoice __FACREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ -PredefinedMailContentSendInvoiceReminder=__CONTACTCIVNAME__ \n\n We would like to warn you that the invoice __FACREF__ seems to not being payed. So this is the invoice in attachment again, as a reminder.\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ -PredefinedMailContentSendProposal=__CONTACTCIVNAME__ \n\n You will find here the commercial proposal __PROPREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ -PredefinedMailContentSendOrder=__CONTACTCIVNAME__ \n\n You will find here the order __ORDERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ -PredefinedMailContentSendSupplierOrder=__CONTACTCIVNAME__ \n\n You will find here our order __ORDERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ -PredefinedMailContentSendSupplierInvoice=__CONTACTCIVNAME__ \n\n You will find here the invoice __FACREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ -PredefinedMailContentSendShipping=__CONTACTCIVNAME__ \n\n You will find here the shipping __SHIPPINGREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ -PredefinedMailContentSendFichInter=__CONTACTCIVNAME__ \n\n You will find here the intervention __FICHINTERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ +PredefinedMailContentSendInvoice=__CONTACTCIVNAME__\n\nYou will find here the invoice __FACREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ +PredefinedMailContentSendInvoiceReminder=__CONTACTCIVNAME__\n\nWe would like to warn you that the invoice __FACREF__ seems to not being payed. So this is the invoice in attachment again, as a reminder.\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ +PredefinedMailContentSendProposal=__CONTACTCIVNAME__\n\nYou will find here the commercial proposal __PROPREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ +PredefinedMailContentSendOrder=__CONTACTCIVNAME__\n\nYou will find here the order __ORDERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ +PredefinedMailContentSendSupplierOrder=__CONTACTCIVNAME__\n\nYou will find here our order __ORDERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ +PredefinedMailContentSendSupplierInvoice=__CONTACTCIVNAME__\n\nYou will find here the invoice __FACREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ +PredefinedMailContentSendShipping=__CONTACTCIVNAME__\n\nYou will find here the shipping __SHIPPINGREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ +PredefinedMailContentSendFichInter=__CONTACTCIVNAME__\n\nYou will find here the intervention __FICHINTERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ +PredefinedMailContentThirdparty=__CONTACTCIVNAME__\n\n__PERSONALIZED__\n\n__SIGNATURE__ DemoDesc=Dolibarr is a compact ERP/CRM composed by several functional modules. A demo that includes all modules does not mean anything as this never occurs. So, several demo profiles are available. ChooseYourDemoProfil=Choose the demo profile that match your activity... DemoFundation=Manage members of a foundation diff --git a/htdocs/langs/fr_FR/other.lang b/htdocs/langs/fr_FR/other.lang index 9814d4f3704..355dadad2ba 100644 --- a/htdocs/langs/fr_FR/other.lang +++ b/htdocs/langs/fr_FR/other.lang @@ -49,14 +49,15 @@ Miscellaneous=Divers NbOfActiveNotifications=Nombre de notifications PredefinedMailTest=Ceci est un message de test.\nLes 2 lignes sont séparées par un retour à la ligne.\n\n__SIGNATURE__ PredefinedMailTestHtml=Ceci est un message de test (le mot test doit être en gras).
Les 2 lignes sont séparées par un retour à la ligne.

__SIGNATURE__ -PredefinedMailContentSendInvoice=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint la facture __FACREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ -PredefinedMailContentSendInvoiceReminder=__CONTACTCIVNAME__ \n\nNous voudrions porter à votre connaissance que la facture __FACREF__ ne semble pas avoir été réglée. La voici donc, pour rappel, en pièce jointe.\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ -PredefinedMailContentSendProposal=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint la proposition commerciale __PROPREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ -PredefinedMailContentSendOrder=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint la commande __ORDERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ -PredefinedMailContentSendSupplierOrder=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint notre commande __ORDERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ -PredefinedMailContentSendSupplierInvoice=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint la facture __FACREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ -PredefinedMailContentSendShipping=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint le bon d'expédition __SHIPPINGREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ -PredefinedMailContentSendFichInter=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint la fiche d'intervention __FICHINTERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ +PredefinedMailContentSendInvoice=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint la facture __FACREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ +PredefinedMailContentSendInvoiceReminder=__CONTACTCIVNAME__\n\nNous voudrions porter à votre connaissance que la facture __FACREF__ ne semble pas avoir été réglée. La voici donc, pour rappel, en pièce jointe.\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ +PredefinedMailContentSendProposal=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint la proposition commerciale __PROPREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ +PredefinedMailContentSendOrder=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint la commande __ORDERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ +PredefinedMailContentSendSupplierOrder=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint notre commande __ORDERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ +PredefinedMailContentSendSupplierInvoice=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint la facture __FACREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ +PredefinedMailContentSendShipping=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint le bon d'expédition __SHIPPINGREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ +PredefinedMailContentSendFichInter=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint la fiche d'intervention __FICHINTERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__ +PredefinedMailContentThirdparty=__CONTACTCIVNAME__\n\n__PERSONALIZED__\n\n__SIGNATURE__ DemoDesc=Dolibarr est un logiciel de gestion d'activité (professionnelle ou associative) composé de modules fonctionnels indépendants et optionnels. Une démonstration qui inclut tous ces modules n'a pas de sens car les modules ne sont jamais tous utilisés en même temps. Aussi, plusieurs profils de démonstration type sont disponibles. ChooseYourDemoProfil=Veuillez choisir le profil de démonstration qui correspond le mieux à votre activité… DemoFundation=Gestion des adhérents d'une association diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index 5b1cca98c77..149cec123e8 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -1826,7 +1826,7 @@ else else { $langs->load("mails"); - print ''; + print ''; } if ($user->rights->societe->creer) @@ -1851,85 +1851,85 @@ else if ($action == 'presend') { - /* - * Affiche formulaire mail - */ + /* + * Affiche formulaire mail + */ - // By default if $action=='presend' - $titreform='SendMail'; - $topicmail=''; - $action='send'; - $modelmail='thirdparty'; + // By default if $action=='presend' + $titreform='SendMail'; + $topicmail=''; + $action='send'; + $modelmail='thirdparty'; - print '
'; - print_titre($langs->trans($titreform)); + print '
'; + print_titre($langs->trans($titreform)); - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->fromtype = 'user'; - $formmail->fromid = $user->id; - $formmail->fromname = $user->getFullName($langs); - $formmail->frommail = $user->email; - $formmail->withfrom=1; - $formmail->withtopic=1; - $liste=array(); - foreach ($object->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; - $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; - $formmail->withtofree=0; - $formmail->withtocc=$liste; - $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; - $formmail->withfile=2; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - $formmail->withcancel=1; - // Tableau des substitutions - $formmail->substit['__SIGNATURE__']=$user->signature; - $formmail->substit['__PERSONALIZED__']=''; - $formmail->substit['__CONTACTCIVNAME__']=''; + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->fromtype = 'user'; + $formmail->fromid = $user->id; + $formmail->fromname = $user->getFullName($langs); + $formmail->frommail = $user->email; + $formmail->withfrom=1; + $formmail->withtopic=1; + $liste=array(); + foreach ($object->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; + $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; + $formmail->withtofree=0; + $formmail->withtocc=$liste; + $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; + $formmail->withfile=2; + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + $formmail->substit['__SIGNATURE__']=$user->signature; + $formmail->substit['__PERSONALIZED__']=''; + $formmail->substit['__CONTACTCIVNAME__']=''; - //Find the good contact adress - /* - $custcontact=''; - $contactarr=array(); - $contactarr=$object->liste_contact(-1,'external'); + //Find the good contact adress + /* + $custcontact=''; + $contactarr=array(); + $contactarr=$object->liste_contact(-1,'external'); - if (is_array($contactarr) && count($contactarr)>0) - { - foreach($contactarr as $contact) - { - if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { + if (is_array($contactarr) && count($contactarr)>0) + { + foreach($contactarr as $contact) + { + if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { - require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; + require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; - $contactstatic=new Contact($db); - $contactstatic->fetch($contact['id']); - $custcontact=$contactstatic->getFullName($langs,1); - } - } + $contactstatic=new Contact($db); + $contactstatic->fetch($contact['id']); + $custcontact=$contactstatic->getFullName($langs,1); + } + } - if (!empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__']=$custcontact; - } - }*/ + if (!empty($custcontact)) { + $formmail->substit['__CONTACTCIVNAME__']=$custcontact; + } + }*/ - // Tableau des parametres complementaires du post - $formmail->param['action']=$action; - $formmail->param['models']=$modelmail; - $formmail->param['socid']=$object->id; - $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?socid='.$object->id; + // Tableau des parametres complementaires du post + $formmail->param['action']=$action; + $formmail->param['models']=$modelmail; + $formmail->param['socid']=$object->id; + $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?socid='.$object->id; - // Init list of files - if (GETPOST("mode")=='init') - { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); - } + // Init list of files + if (GETPOST("mode")=='init') + { + $formmail->clear_attached_files(); + $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); + } - $formmail->show_form(); + $formmail->show_form(); - print '
'; + print '
'; } else { From 0b7f623c3195c70d66914e0672f741d46da9c62f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Feb 2014 17:04:21 +0100 Subject: [PATCH 11/13] New: Add an admin page to make a mass init of barcode values for all products. --- ChangeLog | 5 +- htdocs/barcode/codeinit.php | 198 +++++++++++++++++++++++++++++++++- htdocs/barcode/printsheet.php | 16 +-- htdocs/langs/en_US/admin.lang | 6 ++ 4 files changed, 211 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index b995520482e..654817fb168 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,11 +16,12 @@ For users: to automatically add timestamp and user line into editionf field when editing a note. - New: Add button cancel into edition of notes. - New: Improved Opensurvey module and added options to disable comments and disable - public votes + public votes. - New: The box "balance of bank accounts" show all opened accounts. - New: Add option MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE. - New: Add warning if supplier payment is higher that due amount. -- New increase length of url into bookmark module. +- New: Increase length of url into bookmark module. +- New: Add an admin page to make a mass init of barcode values for all products. TODO - New: Predefined product and free product use same form. diff --git a/htdocs/barcode/codeinit.php b/htdocs/barcode/codeinit.php index f016423f44b..bae8d90e589 100644 --- a/htdocs/barcode/codeinit.php +++ b/htdocs/barcode/codeinit.php @@ -46,16 +46,109 @@ $action=GETPOST('action'); $producttmp=new Product($db); $thirdpartytmp=new Societe($db); +$modBarCodeProduct=''; + /* * Actions */ -if ($action == 'init') +// Define barcode template for products +if (! empty($conf->global->BARCODE_PRODUCT_ADDON_NUM)) { + $dirbarcodenum=array_merge(array('/core/modules/barcode/'),$conf->modules_parts['barcode']); + + foreach ($dirbarcodenum as $dirroot) + { + $dir = dol_buildpath($dirroot,0); + + $handle = @opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + if (preg_match('/^mod_barcode_product_.*php$/', $file)) + { + $file = substr($file, 0, dol_strlen($file)-4); + + try { + dol_include_once($dirroot.$file.'.php'); + } + catch(Exception $e) + { + dol_syslog($e->getMessage(), LOG_ERR); + } + + $modBarCodeProduct = new $file(); + break; + } + } + closedir($handle); + } + } +} + +if ($action == 'initbarcodeproducts') +{ + if (! is_object($modBarCodeProduct)) + { + $error++; + setEventMessage($langs->trans("NoBarcodeNumberingTemplateDefined"),'errors'); + } + + if (! $error) + { + $productstatic=new Product($db); + + $db->begin(); + + $sql="SELECT rowid, ref, fk_product_type FROM ".MAIN_DB_PREFIX."product where barcode IS NULL or barcode = ''"; + $resql=$db->query($sql); + if ($resql) + { + $num=$db->num_rows($resql); + + $i=0; $nbok=$nbtry=0; + while ($i < $num) + { + $obj=$db->fetch_object($resql); + if ($obj) + { + $productstatic->id=$obj->rowid; + $productstatic->ref=$obj->ref; + $productstatic->type=$obj->fk_product_type; + $nextvalue=$modBarCodeProduct->getNextValue($productstatic,''); + + print 'Set value '.$nextvalue.' to product '.$productstatic->id." ".$productstatic->ref." ".$productstatic->type."
\n"; + $result=$productstatic->setValueFrom('barcode', $nextvalue); + + $nbtry++; + if ($result > 0) $nbok++; + } + + $i++; + } + } + else + { + $error++; + dol_print_error($db); + } + + if (! $error) + { + setEventMessage($langs->trans("RecordsModified",$nbok),'mesgs'); + + //$db->rollback(); + $db->commit(); + } + else + { + $db->rollback(); + } + } + $action=''; - - } @@ -64,6 +157,9 @@ if ($action == 'init') * View */ +if (!$user->admin) accessforbidden(); +if (empty($conf->barcode->enabled)) accessforbidden(); + $form=new Form($db); llxHeader('',$langs->trans("MassBarcodeInit")); @@ -81,9 +177,101 @@ dol_htmloutput_errors($mesg); print '
'; print ''; -print ''; +print ''; + +print '
'; + +// For thirdparty +if ($conf->societe->enabled) +{ + $nbno=$nbtotal=0; + + print_fiche_titre($langs->trans("BarcodeInitForThirdparties"),'','').'
'."\n"; + $sql="SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."societe where barcode IS NULL or barcode = ''"; + $resql=$db->query($sql); + if ($resql) + { + $obj=$db->fetch_object($resql); + $nbno=$obj->nb; + } + else dol_print_error($db); + + $sql="SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."societe"; + $resql=$db->query($sql); + if ($resql) + { + $obj=$db->fetch_object($resql); + $nbtotal=$obj->nb; + } + else dol_print_error($db); + + print $langs->trans("CurrentlyNWithoutBarCode", $nbno, $nbtotal, $langs->transnoentitiesnoconv("Thirdparties")).'
'."\n"; + + print '
'; + print '


'; +} + + +// For products +if ($conf->product->enabled || $conf->product->service) +{ + $nbno=$nbtotal=0; + + print_fiche_titre($langs->trans("BarcodeInitForProductsOrServices"),'','').'
'."\n"; + $sql="SELECT count(rowid) as nb, fk_product_type FROM ".MAIN_DB_PREFIX."product where barcode IS NULL or barcode = '' GROUP BY fk_product_type"; + $resql=$db->query($sql); + if ($resql) + { + $num=$db->num_rows($resql); + + $i=0; + while($i < $num) + { + $obj=$db->fetch_object($resql); + $nbno+=$obj->nb; + + $i++; + } + } + else dol_print_error($db); + + $sql="SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."product"; + $resql=$db->query($sql); + if ($resql) + { + $obj=$db->fetch_object($resql); + $nbtotal=$obj->nb; + } + else dol_print_error($db); + + print $langs->trans("CurrentlyNWithoutBarCode", $nbno, $nbtotal, $langs->transnoentitiesnoconv("ProductsOrServices")).'
'."\n"; + + if (is_object($modBarCodeProduct)) + { + print $langs->trans("BarCodeNumberManager").": "; + $objproduct=new Product($db); + print ''.$modBarCodeProduct->nom.' - '.$langs->trans("NextValue").': '.$modBarCodeProduct->getNextValue($objproduct).'
'; + $disabled=0; + } + else + { + $disabled=1; + $titleno=$langs->trans("NoBarcodeNumberingTemplateDefined"); + print ''.$langs->trans("NoBarcodeNumberingTemplateDefined").'
'; + } + if (empty($nbno)) + { + $disabled=1; + $titleno=$langs->trans("NoRecordWithoutBarcodeDefined"); + print ''.$langs->trans("NoRecordWithoutBarcodeDefined").'
'; + } + + print '
'; + print '


'; +} -print '
'; print ''; print '
'; diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index 5e2e52366fc..aa2be8d136f 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -63,12 +63,12 @@ if (GETPOST('submitproduct') && GETPOST('submitproduct')) $producttmp->fetch(GETPOST('productid')); $forbarcode=$producttmp->barcode; $fk_barcode_type=$thirdpartytmp->barcode_type_code; - + if (empty($fk_barcode_type) && ! empty($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE)) $fk_barcode_type = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE; - + if (empty($forbarcode) || empty($fk_barcode_type)) { - setEventMessage($langs->trans("DefinitionOfBarCodeForProductNotComplete",$producttmp->getNomUrl()), 'warnings'); + setEventMessage($langs->trans("DefinitionOfBarCodeForProductNotComplete",$producttmp->getNomUrl()), 'warnings'); } } } @@ -80,12 +80,12 @@ if (GETPOST('submitthirdparty') && GETPOST('submitthirdparty')) $thirdpartytmp->fetch(GETPOST('socid')); $forbarcode=$thirdpartytmp->barcode; $fk_barcode_type=$thirdpartytmp->barcode_type_code; - + if (empty($fk_barcode_type) && ! empty($conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY)) $fk_barcode_type = $conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY; - + if (empty($forbarcode) || empty($fk_barcode_type)) { - setEventMessage($langs->trans("DefinitionOfBarCodeForProductNotComplete",$thirdpartytmp->getNomUrl()), 'warnings'); + setEventMessage($langs->trans("DefinitionOfBarCodeForProductNotComplete",$thirdpartytmp->getNomUrl()), 'warnings'); } } } @@ -243,6 +243,8 @@ if ($action == 'builddoc') * View */ +if (empty($conf->barcode->enabled)) accessforbidden(); + $form=new Form($db); llxHeader('',$langs->trans("BarCodePrintsheet")); @@ -329,7 +331,7 @@ jQuery(document).ready(function() { jQuery(".radiobarcodeselect").click(function() { init_selectors(); }); - + function init_gendoc_button() { if (jQuery("#select_fk_barcode_type").val() > 0 && jQuery("#forbarcode").val()) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index a7bf4b21b18..2b0bbd05d78 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -379,6 +379,12 @@ KeepEmptyToUseDefault=Keep empty to use default value DefaultLink=Default link ValueOverwrittenByUserSetup=Warning, this value may be overwritten by user specific setup (each user can set his own clicktodial url) ExternalModule=External module - Installed into directory %s +BarcodeInitForThirdparties=Mass barcode init for thirdparties +BarcodeInitForProductsOrServices=Mass barcode init for products or services +CurrentlyNWithoutBarCode=Currently, you have %s records on %s %s without barcode defined. +InitEmptyBarCode=Init the %s barcode +NoBarcodeNumberingTemplateDefined=No numbering barcode template enabled into barcode module setup. +NoRecordWithoutBarcodeDefined=No record with no barcode value defined. # Modules Module0Name=Users & groups From c2db656c860e8596686f9812d15db391a35f6f5e Mon Sep 17 00:00:00 2001 From: simnandez Date: Wed, 19 Feb 2014 17:32:20 +0100 Subject: [PATCH 12/13] Fix: Action event SHIPPING_VALIDATE is not implemented --- ChangeLog | 1 + ...terface_50_modAgenda_ActionsAuto.class.php | 21 ++++++++++++++++++- htdocs/langs/ca_ES/agenda.lang | 1 + htdocs/langs/en_US/agenda.lang | 1 + htdocs/langs/es_ES/agenda.lang | 1 + htdocs/langs/fr_FR/agenda.lang | 1 + 6 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 654817fb168..c72f312e918 100644 --- a/ChangeLog +++ b/ChangeLog @@ -82,6 +82,7 @@ Fix: user right on Holiday for month report nor working. Fix: [ bug #1250 ] "Supplier Ref. product" sidebar search box does not work Fix: Bad space in predefined messages. Fix: Signature was not added for email sent from thirdparty page. +Fix: Action event SHIPPING_VALIDATE is not implemented ***** ChangeLog for 3.5 compared to 3.4.* ***** For users: diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index b089b5487a7..6ab80b6ad88 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2009-2011 Regis Houssin - * Copyright (C) 2011 Juanjo Menent + * Copyright (C) 2011-2013 Juanjo Menent * Copyright (C) 2013 Cedric GROSS * * This program is free software; you can redistribute it and/or modify @@ -373,6 +373,25 @@ class InterfaceActionsAuto // Parameters $object->sendotid defined by caller //$object->sendtoid=0; $ok=1; + } + elseif ($action == 'SHIPPING_VALIDATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + $langs->load("other"); + $langs->load("sendings"); + $langs->load("agenda"); + + $object->actiontypecode='AC_OTH_AUTO'; + if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ShippingValidated",$object->ref); + if (empty($object->actionmsg)) + { + $object->actionmsg=$langs->transnoentities("ShippingValidated",$object->ref); + $object->actionmsg.="\n".$langs->transnoentities("Author").': '.$user->login; + } + + // Parameters $object->sendtoid defined by caller + //$object->sendtoid=0; + $ok=1; } elseif ($action == 'SHIPPING_SENTBYMAIL') { diff --git a/htdocs/langs/ca_ES/agenda.lang b/htdocs/langs/ca_ES/agenda.lang index 238911047e3..f0612d4abe2 100644 --- a/htdocs/langs/ca_ES/agenda.lang +++ b/htdocs/langs/ca_ES/agenda.lang @@ -52,6 +52,7 @@ InvoiceSentByEMail=Factura a client %s enviada per e-mail SupplierOrderSentByEMail=Comanda a proveïdor %s enviada per e-mail SupplierInvoiceSentByEMail=Factura de proveïdor %s enviada per e-mail ShippingSentByEMail=Expedició %s enviada per e-mail +ShippingValidated=Expedició %s validada InterventionSentByEMail=Intervenció %s enviada per e-mail NewCompanyToDolibarr= Tercer creat DateActionPlannedStart= Data d'inici prevista diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 187f818210e..0e37d3290f7 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -52,6 +52,7 @@ InvoiceSentByEMail=Customer invoice %s sent by EMail SupplierOrderSentByEMail=Supplier order %s sent by EMail SupplierInvoiceSentByEMail=Supplier invoice %s sent by EMail ShippingSentByEMail=Shipping %s sent by EMail +ShippingValidated= Shipping %s validated InterventionSentByEMail=Intervention %s sent by EMail NewCompanyToDolibarr= Third party created DateActionPlannedStart= Planned start date diff --git a/htdocs/langs/es_ES/agenda.lang b/htdocs/langs/es_ES/agenda.lang index 7abb1dd277b..d832ae6afb5 100644 --- a/htdocs/langs/es_ES/agenda.lang +++ b/htdocs/langs/es_ES/agenda.lang @@ -52,6 +52,7 @@ InvoiceSentByEMail=Factura a cliente %s enviada por e-mail SupplierOrderSentByEMail=Pedido a proveedor %s enviada por e-mail SupplierInvoiceSentByEMail=Factura de proveedor %s enviada por e-mail ShippingSentByEMail=Expedición %s enviada por e-mail +ShippingValidated= Expedición %s validada InterventionSentByEMail=Intervención %s enviada por e-mail NewCompanyToDolibarr= Tercero creado DateActionPlannedStart= Fecha de inicio prevista diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index 190c08ad2ac..d21617fde47 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -52,6 +52,7 @@ InvoiceSentByEMail=Facture client %s envoyée par EMail SupplierOrderSentByEMail=Commande fournisseur %s envoyée par EMail SupplierInvoiceSentByEMail=Facture fournisseur %s envoyée par Email ShippingSentByEMail=Bon d'expédition %s envoyé par Email +ShippingValidated=Bon d'expédition %s validée InterventionSentByEMail=Intervention %s envoyée par Email NewCompanyToDolibarr= Tiers créé DateActionPlannedStart= Date de début de réalisation prévue From 6f962397e4264c304890e692385c6fc8a7dd502a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Feb 2014 20:23:02 +0100 Subject: [PATCH 13/13] Start to work on a mass send remind feature. --- htdocs/admin/mails.php | 8 +- htdocs/comm/mailing/fiche.php | 2 +- htdocs/comm/propal.php | 26 +- htdocs/commande/fiche.php | 2 +- htdocs/compta/facture.php | 6 +- htdocs/compta/facture/class/facture.class.php | 2 +- htdocs/compta/facture/impayees.php | 301 ++++++++++++++++-- htdocs/core/class/html.formmail.class.php | 64 ++-- htdocs/expedition/fiche.php | 2 +- htdocs/fichinter/fiche.php | 2 +- htdocs/fourn/commande/fiche.php | 6 +- htdocs/fourn/facture/fiche.php | 6 +- htdocs/langs/en_US/mails.lang | 4 + htdocs/societe/soc.php | 2 +- 14 files changed, 348 insertions(+), 85 deletions(-) diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index ec3faca6625..e29bea1a2e6 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -132,7 +132,7 @@ if (! empty($_POST['removedfile']) || ! empty($_POST['removedfilehtml'])) if (($action == 'send' || $action == 'sendhtml') && ! GETPOST('addfile') && ! GETPOST('addfilehtml') && ! GETPOST('removedfile') && ! GETPOST('cancel')) { $error=0; - + $email_from=''; if (! empty($_POST["fromname"])) $email_from=$_POST["fromname"].' '; if (! empty($_POST["frommail"])) $email_from.='<'.$_POST["frommail"].'>'; @@ -144,12 +144,12 @@ if (($action == 'send' || $action == 'sendhtml') && ! GETPOST('addfile') && ! GE $subject = $_POST['subject']; $body = $_POST['message']; $deliveryreceipt= $_POST["deliveryreceipt"]; - + //Check if we have to decode HTML if (!empty($conf->global->FCKEDITOR_ENABLE_MAILING) && dol_textishtml(dol_html_entity_decode($body, ENT_COMPAT | ENT_HTML401))) { $body=dol_html_entity_decode($body, ENT_COMPAT | ENT_HTML401); } - + // Create form object include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($db); @@ -693,7 +693,7 @@ else $formmail->clear_attached_files(); } - $formmail->show_form(($action == 'testhtml'?'addfilehtml':'addfile'),($action == 'testhtml'?'removefilehtml':'removefile')); + print $formmail->get_form(($action == 'testhtml'?'addfilehtml':'addfile'),($action == 'testhtml'?'removefilehtml':'removefile')); print '
'; } diff --git a/htdocs/comm/mailing/fiche.php b/htdocs/comm/mailing/fiche.php index 8217727e202..bc833b18955 100644 --- a/htdocs/comm/mailing/fiche.php +++ b/htdocs/comm/mailing/fiche.php @@ -947,7 +947,7 @@ else $formmail->param["mailid"]=$object->id; $formmail->param["returnurl"]=$_SERVER['PHP_SELF']."?id=".$object->id; - $formmail->show_form(); + print $formmail->get_form(); print '
'; } diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index a8dd4ab2a9e..4ad74c01af3 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -2149,14 +2149,14 @@ else { print ''; } - + // ReOpen if (($object->statut == 2 || $object->statut == 3) && $user->rights->propal->cloturer) { print ''; } - + // Send if ($object->statut == 1 || $object->statut == 2) { @@ -2166,7 +2166,7 @@ else } else print ''; } - + // Create an order if (! empty($conf->commande->enabled) && $object->statut == 2) { @@ -2175,18 +2175,18 @@ else print ''; } } - + // Create contract if ($conf->contrat->enabled && $object->statut == 2) { $langs->load("contracts"); - + if ($user->rights->contrat->creer) { print ''; } } - + // Create an invoice and classify billed if ($object->statut == 2) { @@ -2194,37 +2194,37 @@ else { print ''; } - + $arraypropal=$object->getInvoiceArrayList(); if (is_array($arraypropal) && count($arraypropal) > 0) { print ''; } } - + // Close if ($object->statut == 1 && $user->rights->propal->cloturer) { print ''; } - + // Clone if ($user->rights->propal->creer) { print ''; } - + // Delete if ($user->rights->propal->supprimer) { print ''; } - + } } - + print ''; } print "
\n"; @@ -2374,7 +2374,7 @@ else $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); } - $formmail->show_form(); + print $formmail->get_form(); print '
'; } diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php index 760324d23e8..480fdb95841 100644 --- a/htdocs/commande/fiche.php +++ b/htdocs/commande/fiche.php @@ -2676,7 +2676,7 @@ else } // Show form - $formmail->show_form(); + print $formmail->get_form(); print '
'; } diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index c900b0d7ebb..de05b11a64c 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -3914,8 +3914,8 @@ else if ($id > 0 || ! empty($ref)) { $liste[$key]=$value; } - $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; - $formmail->withtocc=$liste; + $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; // List suggested for send to + $formmail->withtocc=$liste; // List suggested for CC $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; if(empty($object->ref_client)) { @@ -3972,7 +3972,7 @@ else if ($id > 0 || ! empty($ref)) $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); } - $formmail->show_form(); + print $formmail->get_form(); print '
'; } diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 53adade47ab..cf15d3f13fc 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -90,7 +90,7 @@ class Facture extends CommonInvoice var $close_code; //! Commentaire si mis a paye sans paiement complet var $close_note; - //! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code + //! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code) var $paye; //! id of source invoice if replacement invoice or credit note var $fk_facture_source; diff --git a/htdocs/compta/facture/impayees.php b/htdocs/compta/facture/impayees.php index dd374eb1a6f..36cc7944105 100644 --- a/htdocs/compta/facture/impayees.php +++ b/htdocs/compta/facture/impayees.php @@ -37,6 +37,7 @@ $langs->load("bills"); $id = (GETPOST('facid','int') ? GETPOST('facid','int') : GETPOST('id','int')); $action = GETPOST('action','alpha'); $option = GETPOST('option'); +$mode=GETPOST('mode'); // Security check if ($user->societe_id) $socid=$user->societe_id; @@ -45,11 +46,157 @@ $result = restrictedArea($user,'facture',$id,''); $diroutputpdf=$conf->facture->dir_output . '/unpaid/temp'; if (! $user->rights->societe->client->voir || $socid) $diroutputpdf.='/private/'.$user->id; // If user has no permission to see all, output dir is specific to user +$resultmasssend=''; + /* * Action */ +// Send remind email +if ($action == 'presend' && GETPOST('cancel')) $action=''; + +if ($action == 'presend' && GETPOST('sendmail')) +{ + if (!isset($user->email)) + { + $error++; + setEventMessage("NoSenderEmailDefined"); + } + + $countToSend = count($_POST['toSend']); + if (empty($countToSend)) + { + $error++; + setEventMessage("InvoiceNotChecked","warnings"); + } + + if (! $error) + { + $compteEmailEnvoi = 0; + $nbignored = 0; + + for ($i = 0; $i < $countToSend; $i++) + { + $object = new Facture($db); + $result = $object->fetch($_POST['toSend'][$i]); + + if ($result > 0) // Invoice was found + { + if ($object->statut != 1) continue; // Payment done or started or canceled + + // Read PDF + $filename=dol_sanitizeFileName($object->ref); + $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref); + $file = $filedir . '/' . $filename.'.pdf'; // TODO What if ODT ? + + if (dol_is_file($file)) + { + $object->fetch_thirdparty(); + $sendto = $object->thirdparty->email; + + if (empty($sendto)) $nbignored++; + + if (dol_strlen($sendto)) + { + $langs->load("commercial"); + $from = $user->getFullName($langs) . ' <' . $user->email .'>'; + $replyto = $from; + $message = $conf->global->RELANCES_MASSE_TEXTE_EMAIL; + $subject = $conf->global->RELANCES_MASSE_OBJET_EMAIL; + + $substitutionarray= + make_substitutions($message, $substitutionarray); + + $actiontypecode='AC_FAC'; + $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; + if ($message) + { + $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; + $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; + $actionmsg.=$message; + } + // Create form object + include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'); + $formmail = new FormMail($db); + $formmail->clear_attached_files(); + $formmail->add_attached_files($file, $object->ref.'.pdf', 'application/pdf'); + $attachedfiles=$formmail->get_attached_files(); + $filepath = $attachedfiles['paths']; + $filename = $attachedfiles['names']; + $mimetype = $attachedfiles['mimes']; + + // Send mail + require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'); + $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); + if ($mailfile->error) + { + $resultmasssend.='
'.$mailfile->error.'
'; + } + else + { + $result=$mailfile->sendfile(); + if ($result) + { + $resultmasssend.=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); // Must not contain " + + $error=0; + + // Initialisation donnees + $object->sendtoid = 0; + $object->actiontypecode = $actiontypecode; + $object->actionmsg = $actionmsg; // Long text + $object->actionmsg2 = $actionmsg2; // Short text + $object->fk_element = $object->id; + $object->elementtype = $object->element; + + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php"); + $interface=new Interfaces($db); + $result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; } + // Fin appel triggers + + if ($error) + { + dol_print_error($db); + } + $compteEmailEnvoi ++; + + } + else + { + $langs->load("other"); + $resultmasssend.='
'; + if ($mailfile->error) + { + $resultmasssend.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); + $resultmasssend.='
'.$mailfile->error; + } + else + { + $resultmasssend.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + } + $resultmasssend.='
'; + } + } + } + } + else + { + $langs->load("other"); + print $resultmasssend='
'.$langs->trans('ErrorCantReadFile',$file).'
'; + dol_syslog('Failed to read file: '.$file); + break ; + } + } + } + + setEventMessage($compteEmailEnvoi. '/'.$countToSend.' '.$langs->trans("RemindSent")); + } +} + + if ($action == "builddoc" && $user->rights->facture->lire && ! GETPOST('button_search')) { if (is_array($_POST['toGenerate'])) @@ -61,9 +208,12 @@ if ($action == "builddoc" && $user->rights->facture->lire && ! GETPOST('button_s // liste les fichiers $files = array(); $factures_bak = $factures ; - foreach($_POST['toGenerate'] as $basename){ - foreach($factures as $facture){ - if(strstr($facture["name"],$basename)){ + foreach($_POST['toGenerate'] as $basename) + { + foreach($factures as $facture) + { + if(strstr($facture["name"],$basename)) + { $files[] = $conf->facture->dir_output.'/'.$basename.'/'.$facture["name"]; } } @@ -121,12 +271,12 @@ if ($action == "builddoc" && $user->rights->facture->lire && ! GETPOST('button_s } else { - $mesg='
'.$langs->trans('NoPDFAvailableForChecked').'
'; + setEventMessage($langs->trans('NoPDFAvailableForChecked'),'errors'); } } else { - $mesg='
'.$langs->trans('InvoiceNotChecked').'
' ; + setEventMessage($langs->trans('InvoiceNotChecked'), 'warnings'); } } @@ -167,6 +317,12 @@ $(document).ready(function() { $("#checknone").click(function() { $(".checkformerge").attr('checked', false); }); + $("#checkallsend").click(function() { + $(".checkforsend").attr('checked', true); + }); + $("#checknonesend").click(function() { + $(".checkforsend").attr('checked', false); + }); }); '; print ''; + print ''; if ($late) print ''; $i = 0; @@ -283,7 +440,14 @@ if ($resql) print_liste_field_titre($langs->trans("Received"),$_SERVER["PHP_SELF"],"am","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Rest"),$_SERVER["PHP_SELF"],"am","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"fk_statut,paye,am","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Merge"),$_SERVER["PHP_SELF"],"","",$param,'align="center"',$sortfield,$sortorder); + if (empty($mode)) + { + print_liste_field_titre($langs->trans("PDFMerge"),$_SERVER["PHP_SELF"],"","",$param,'align="center"',$sortfield,$sortorder); + } + else + { + print_liste_field_titre($langs->trans("Remind"),$_SERVER["PHP_SELF"],"","",$param,'align="center"',$sortfield,$sortorder); + } print "\n"; // Lignes des champs de filtre @@ -302,9 +466,18 @@ if ($resql) print '
'; - print ''; + if (empty($mode)) + { + print ''; + } + else + { + print ''; + } print "\n"; if ($num > 0) @@ -384,13 +557,23 @@ if ($resql) print $facturestatic->LibStatut($objp->paye,$objp->fk_statut,5,$objp->am); print ''; - // Checkbox - print '' ; + } else - print ' '; - print '' ; + { + // Checkbox to send remind + print '' ; + } print "\n"; $total_ht+=$objp->total_ht; @@ -415,17 +598,85 @@ if ($resql) print "
'; $tmpcode=$object->code_client; - if ($modCodeClient->code_auto) $tmpcode=$modCodeClient->getNextValue($object,0); - print ''; + if (empty($tmpcode) && ! empty($modCodeClient->code_auto)) $tmpcode=$modCodeClient->getNextValue($object,0); + print ''; print ''; $s=$modCodeClient->getToolTip($langs,$object,0); print $form->textwithpicto('',$s,1); @@ -807,8 +807,8 @@ else print ''.$langs->trans('SupplierCode').''; print ''; print ''; - // Assujeti a TVA ou pas - print ''; - print ''; - print ''; - print '
'; $tmpcode=$object->code_fournisseur; - if ($modCodeFournisseur->code_auto) $tmpcode=$modCodeFournisseur->getNextValue($object,1); - print ''; + if (empty($tmpcode) && ! empty($modCodeFournisseur->code_auto)) $tmpcode=$modCodeFournisseur->getNextValue($object,1); + print ''; print ''; $s=$modCodeFournisseur->getToolTip($langs,$object,1); print $form->textwithpicto('',$s,1); @@ -1189,8 +1189,8 @@ else if ((!$object->code_client || $object->code_client == -1) && $modCodeClient->code_auto) { $tmpcode=$object->code_client; - if (empty($tmpcode) && $modCodeClient->code_auto) $tmpcode=$modCodeClient->getNextValue($object,0); - print ''; + if (empty($tmpcode) && ! empty($modCodeClient->code_auto)) $tmpcode=$modCodeClient->getNextValue($object,0); + print ''; } else if ($object->codeclient_modifiable()) { @@ -1221,8 +1221,8 @@ else if ((!$object->code_fournisseur || $object->code_fournisseur == -1) && $modCodeFournisseur->code_auto) { $tmpcode=$object->code_fournisseur; - if (empty($tmpcode) && $modCodeFournisseur->code_auto) $tmpcode=$modCodeFournisseur->getNextValue($object,1); - print ''; + if (empty($tmpcode) && ! empty($modCodeFournisseur->code_auto)) $tmpcode=$modCodeFournisseur->getNextValue($object,1); + print ''; } else if ($object->codefournisseur_modifiable()) { From 18f90520cf6a81746d41e23393724583207e895d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Feb 2014 02:19:54 +0100 Subject: [PATCH 04/13] Uniformize fields shown --- htdocs/categories/categorie.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/htdocs/categories/categorie.php b/htdocs/categories/categorie.php index 1750097b120..8232da94989 100644 --- a/htdocs/categories/categorie.php +++ b/htdocs/categories/categorie.php @@ -153,7 +153,7 @@ if (empty($reshook)) setEventMessage($cat->errors,'errors'); } } - + // Add object into a category if ($parent > 0) { @@ -310,13 +310,6 @@ if ($socid) print '
'.$langs->trans('Phone').''.dol_print_phone($soc->phone,$soc->country_code,0,$soc->id,'AC_TEL').''.$langs->trans('Fax').''.dol_print_phone($soc->fax,$soc->country_code,0,$soc->id,'AC_FAX').'
'.$langs->trans('VATIsUsed').''; - print yn($soc->tva_assuj); - print '
'; dol_fiche_end(); @@ -631,7 +624,7 @@ function formCategory($db,$object,$typeid,$socid=0,$showclassifyform=1) print '
'; print_fiche_titre($title,'',''); - + // Form to add record into a category if ($showclassifyform) { From 96e798526691c333a49e71dfe20ef12c63e0f0a5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Feb 2014 02:27:13 +0100 Subject: [PATCH 05/13] Fix: Translation of menu entries must not be into admin lang file (We don't want to load this file for common pages). --- htdocs/core/modules/modBarcode.class.php | 2 +- htdocs/core/modules/modProduct.class.php | 2 +- htdocs/core/modules/modService.class.php | 2 +- htdocs/langs/en_US/admin.lang | 4 ---- htdocs/langs/en_US/products.lang | 4 ++++ 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php index 92b237236cb..bbc16750dd6 100644 --- a/htdocs/core/modules/modBarcode.class.php +++ b/htdocs/core/modules/modBarcode.class.php @@ -114,7 +114,7 @@ class modBarcode extends DolibarrModules 'type'=>'left', // This is a Left menu entry 'titre'=>'MassBarcodeInit', 'url'=>'/barcode/codeinit.php?mainmenu=home&leftmenu=modulesadmintools', - 'langs'=>'barcode', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'langs'=>'products', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>300, 'enabled'=>'$conf->barcode->enabled && $leftmenu=="modulesadmintools"', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index fed630a40a2..b9185624209 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -135,7 +135,7 @@ class modProduct extends DolibarrModules 'type'=>'left', // This is a Left menu entry 'titre'=>'ProductVatMassChange', 'url'=>'/product/admin/product_tools.php?mainmenu=home&leftmenu=modulesadmintools', - 'langs'=>'admin', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'langs'=>'products', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>300, 'enabled'=>'$conf->product->enabled && $leftmenu=="modulesadmintools"', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 780a32ad45c..695ff596e6e 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -120,7 +120,7 @@ class modService extends DolibarrModules 'type'=>'left', // This is a Left menu entry 'titre'=>'ProductVatMassChange', 'url'=>'/product/admin/product_tools.php?mainmenu=home&leftmenu=modulesadmintools', - 'langs'=>'admin', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'langs'=>'products', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>300, 'enabled'=>'$conf->product->enabled && $leftmenu=="modulesadmintools"', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 6d00a3d89bc..a7bf4b21b18 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -345,10 +345,6 @@ SecurityTokenIsUnique=Use a unique securekey parameter for each URL EnterRefToBuildUrl=Enter reference for object %s GetSecuredUrl=Get calculated URL ButtonHideUnauthorized=Hide buttons for unauthorized actions instead of showing disabled buttons -ProductVatMassChange=Mass VAT change -ProductVatMassChangeDesc=This page can be used to modify a VAT rate defined on products or services from a value to another. Warning, this change is done on all database. -MassBarcodeInit=Mass barcode init -MassBarcodeInitDesc=This page can be used to initialize a barcode on objects that does not have barcode defined. Check before that setup of module barcode is complete. OldVATRates=Old VAT rate NewVATRates=New VAT rate PriceBaseTypeToChange=Modify on prices with base reference value defined on diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index abe1ee6ec3d..fa3144d0475 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -13,6 +13,10 @@ NewProduct=New product NewService=New service ProductCode=Product code ServiceCode=Service code +ProductVatMassChange=Mass VAT change +ProductVatMassChangeDesc=This page can be used to modify a VAT rate defined on products or services from a value to another. Warning, this change is done on all database. +MassBarcodeInit=Mass barcode init +MassBarcodeInitDesc=This page can be used to initialize a barcode on objects that does not have barcode defined. Check before that setup of module barcode is complete. ProductAccountancyBuyCode=Accountancy code (buy) ProductAccountancySellCode=Accountancy code (sell) ProductOrService=Product or Service From 03a60236af8adfafe1572e4c2623bbd69f67cfed Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Feb 2014 03:03:26 +0100 Subject: [PATCH 06/13] Fix: sort on supplier ref. --- htdocs/fourn/facture/impayees.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/htdocs/fourn/facture/impayees.php b/htdocs/fourn/facture/impayees.php index f7d62f8692e..1d81ae01230 100644 --- a/htdocs/fourn/facture/impayees.php +++ b/htdocs/fourn/facture/impayees.php @@ -146,10 +146,8 @@ if ($user->rights->fournisseur->facture->lire) $sql.= " GROUP BY s.rowid, s.nom, f.rowid, f.ref, f.ref_supplier, f.total_ht, f.total_ttc, f.datef, f.date_lim_reglement, f.paye, f.fk_statut, s.rowid, s.nom"; if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", sc.fk_soc, sc.fk_user "; - $sql.= " ORDER BY "; - $listfield=explode(',',$sortfield); - foreach ($listfield as $key => $value) $sql.=$listfield[$key]." ".$sortorder.","; - $sql.= " f.ref_supplier DESC"; + $sql.=$db->order($sortfield,$sortorder); + if (! in_array("f.ref_supplier",explode(',',$sortfield))) $sql.= ", f.ref_supplier DESC"; $resql = $db->query($sql); if ($resql) From d7c9ebd5ee4e3f2a920470a39c5dd8c68dee2eb4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Feb 2014 03:03:26 +0100 Subject: [PATCH 07/13] Fix: sort on supplier ref. --- htdocs/fourn/facture/impayees.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/htdocs/fourn/facture/impayees.php b/htdocs/fourn/facture/impayees.php index f7d62f8692e..1d81ae01230 100644 --- a/htdocs/fourn/facture/impayees.php +++ b/htdocs/fourn/facture/impayees.php @@ -146,10 +146,8 @@ if ($user->rights->fournisseur->facture->lire) $sql.= " GROUP BY s.rowid, s.nom, f.rowid, f.ref, f.ref_supplier, f.total_ht, f.total_ttc, f.datef, f.date_lim_reglement, f.paye, f.fk_statut, s.rowid, s.nom"; if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", sc.fk_soc, sc.fk_user "; - $sql.= " ORDER BY "; - $listfield=explode(',',$sortfield); - foreach ($listfield as $key => $value) $sql.=$listfield[$key]." ".$sortorder.","; - $sql.= " f.ref_supplier DESC"; + $sql.=$db->order($sortfield,$sortorder); + if (! in_array("f.ref_supplier",explode(',',$sortfield))) $sql.= ", f.ref_supplier DESC"; $resql = $db->query($sql); if ($resql) From 8c9d2418d2a63c8fb855560658f15007a9a5242e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 19 Feb 2014 11:08:43 +0100 Subject: [PATCH 08/13] Qual: Move common javascript function into lib_head.js --- htdocs/core/js/lib_head.js | 18 ++++++++ htdocs/core/lib/company.lib.php | 74 +++++++++++-------------------- htdocs/core/lib/functions.lib.php | 3 +- 3 files changed, 45 insertions(+), 50 deletions(-) diff --git a/htdocs/core/js/lib_head.js b/htdocs/core/js/lib_head.js index cfb2977c370..a9b7f9e4c18 100644 --- a/htdocs/core/js/lib_head.js +++ b/htdocs/core/js/lib_head.js @@ -899,6 +899,24 @@ function confirmConstantAction(action, url, code, input, box, entity, yesButton, }); })( jQuery ); + +/* + * Function to output a dialog bog for copy/paste + * + * @param string text Text to put into copy/paste area + * @param string text2 Text to put under the copy/paste area + */ +function copyToClipboard(text,text2) +{ + text = text.replace(/
/g,"\n"); + var newElem = "

"+text2; + $("#dialog").html(newElem); + $("#dialog").dialog(); + $("#coords").select(); + return false; +} + + /* * Timer for delayed keyup function * diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 849b8901ab3..42da0b04d38 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -637,12 +637,12 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') print "
'.$obj->poste.''; @@ -695,41 +696,26 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') // Status print ''.$contactstatic->getLibStatut(5).''; - print img_picto($langs->trans("Address"), 'object_address.png'); - print ''; + if (! empty($conf->use_javascript_ajax)) + { + // Copy to clipboard + $coords = ''; + if (!empty($object->name)) $coords .= $object->name."
"; + $coords .= $contactstatic->getFullName($langs,1).' '; + $coords .= "
"; + if (!empty($obj->address)) + { + $coords .= dol_nl2br($obj->address,1,true)."
"; + if (!empty($obj->zip)) $coords .= $obj->zip.' '; + if (!empty($obj->town)) $coords .= $obj->town; + if (!empty($obj->country_id)) $coords .= "
".$country_code['label']; + } + print ''; + print img_picto($langs->trans("Address"), 'object_address.png'); + print ''; + } + print '
'.$langs->trans("None").'
'; print ''; print ''; - if ($conf->use_javascript_ajax) print ''.$langs->trans("All").' / '.$langs->trans("None").''; - print ''; + if ($conf->use_javascript_ajax) print ''.$langs->trans("All").' / '.$langs->trans("None").''; + print ''; + if ($conf->use_javascript_ajax) print ''.$langs->trans("All").' / '.$langs->trans("None").''; + print '
'; - if (! empty($formfile->numoffiles)) - print ''; + if (empty($mode)) + { + // Checkbox to merge + print ''; + if (! empty($formfile->numoffiles)) + print ''; + else + print ' '; + print ''; + print ''; + print '
"; - /* - * Show list of available documents - */ - $filedir=$diroutputpdf; - $genallowed=$user->rights->facture->lire; - $delallowed=$user->rights->facture->lire; - print '
'; - print ''; - // We disable multilang because we concat already existing pdf. - $formfile->show_documents('unpaid','',$filedir,$urlsource,$genallowed,$delallowed,'',1,1,0,48,1,$param,$langs->trans("PDFMerge"),$langs->trans("PDFMerge")); + if (empty($mode)) + { + /* + * Show list of available documents + */ + $filedir=$diroutputpdf; + $genallowed=$user->rights->facture->lire; + $delallowed=$user->rights->facture->lire; + + print '
'; + print ''; + // We disable multilang because we concat already existing pdf. + $formfile->show_documents('unpaid','',$filedir,$urlsource,$genallowed,$delallowed,'',1,1,0,48,1,$param,$langs->trans("PDFMerge"),$langs->trans("PDFMerge")); + } + else + { + $langs->load("mails"); + + if ($action != 'presend') + { + print '
'; + print ''.$langs->trans("SendRemind").''; + print '
'; + } + else + { + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + print '
'; + print_fiche_titre($langs->trans("SendRemind"),'','').'
'; + + $topicmail="MailTopicSendRemindUnpaidInvoices"; + $modelmail="facture_relance"; + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->fromtype = 'user'; + $formmail->fromid = $user->id; + $formmail->fromname = $user->getFullName($langs); + $formmail->frommail = $user->email; + $formmail->withfrom=1; + $liste=array(); + $formmail->withto=''; + $formmail->withtocc=1; + $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; + $formmail->withtopic=$langs->transnoentities($topicmail, '__FACREF__', '__REFCLIENT__'); + $formmail->withfile=$langs->trans("EachInvoiceWillBeAttachedToEmail"); + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + //$formmail->substit['__FACREF__']=''; + $formmail->substit['__SIGNATURE__']=$user->signature; + //$formmail->substit['__REFCLIENT__']=''; + $formmail->substit['__PERSONALIZED__']=''; + $formmail->substit['__CONTACTCIVNAME__']=''; + + // Tableau des parametres complementaires du post + $formmail->param['action']=$action; + $formmail->param['models']=$modelmail; + $formmail->param['facid']=$object->id; + $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + + print $formmail->get_form(); + + + } + + if ($resultmasssend) + { + print '
'.$langs->trans("ResultOfMassSending").':
'."\n"; + print $resultmasssend; + print '
'; + } + } + print ''; $db->free($resql); diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index c39c5f05277..7746d178e67 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -503,39 +503,47 @@ class FormMail { $out.= '
'.$langs->trans("MailFile").''; - // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript - $out.= ''."\n"; - $out.= ''."\n"; - if (count($listofpaths)) + if (is_numeric($this->withfile)) { - foreach($listofpaths as $key => $val) - { - $out.= '
'; - $out.= img_mime($listofnames[$key]).' '.$listofnames[$key]; - if (! $this->withfilereadonly) - { - $out.= ' '; - //$out.= ' '.img_delete($langs->trans("Delete").''; - } - $out.= '
'; - } + // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript + $out.= ''."\n"; + $out.= ''."\n"; + if (count($listofpaths)) + { + foreach($listofpaths as $key => $val) + { + $out.= '
'; + $out.= img_mime($listofnames[$key]).' '.$listofnames[$key]; + if (! $this->withfilereadonly) + { + $out.= ' '; + //$out.= ' '.img_delete($langs->trans("Delete").''; + } + $out.= '
'; + } + } + else + { + $out.= $langs->trans("NoAttachedFiles").'
'; + } + if ($this->withfile == 2) // Can add other files + { + $out.= ''; + $out.= ' '; + $out.= ''; + } } else { - $out.= $langs->trans("NoAttachedFiles").'
'; - } - if ($this->withfile == 2) // Can add other files - { - $out.= ''; - $out.= ' '; - $out.= ''; + $out.=$this->withfile; } $out.= "
'.price($line->total_ht).'id.'#'.$line->id.'">'; @@ -2132,7 +2132,7 @@ elseif (! empty($object->id)) } // Show form - $formmail->show_form(); + print $formmail->get_form(); print '
'; } diff --git a/htdocs/fourn/facture/fiche.php b/htdocs/fourn/facture/fiche.php index 3722ceaac51..6d095e48b93 100644 --- a/htdocs/fourn/facture/fiche.php +++ b/htdocs/fourn/facture/fiche.php @@ -1996,13 +1996,13 @@ else print '
'.price($object->lines[$i]->total_ht).''.price($object->lines[$i]->total_ttc).''; if ($object->statut == 0) print 'lines[$i]->rowid.'">'.img_edit().''; else print ' '; @@ -2370,7 +2370,7 @@ else } // Show form - $formmail->show_form(); + print $formmail->get_form(); print '
'; } diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index c16827bbdee..88d499ac7e0 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -79,6 +79,10 @@ MailtoEMail=Hyper link to email ActivateCheckRead=Allow to use the "Unsubcribe" link ActivateCheckReadKey=Key use to encrypt URL use for "Read Receipt" and "Unsubcribe" feature EMailSentToNRecipients=EMail sent to %s recipients. +EachInvoiceWillBeAttachedToEmail=A document using default invoice document template will be created and attached to each email. +MailTopicSendRemindUnpaidInvoices=Remind of invoice %s (%s) +SendRemind=Send remind by EMails +RemindSent=%S remind(s) sent # Libelle des modules de liste de destinataires mailing MailingModuleDescContactCompanies=Contacts/addresses of all third parties (customer, prospect, supplier, ...) diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index e415c808c5f..5731ce0196a 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -1932,7 +1932,7 @@ else $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); } - $formmail->show_form(); + print $formmail->get_form(); print '
'; }