From e7e152c122873c46143d06dc64bf4ff21802b534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Mon, 19 Oct 2015 15:13:19 +0200 Subject: [PATCH 01/11] NEW Level multiprice generator based on per cent variations over base price --- htdocs/core/lib/product.lib.php | 10 + .../install/mysql/migration/3.8.0-3.9.0.sql | 9 + htdocs/install/mysql/tables/llx_product.sql | 5 +- .../tables/llx_product_pricerules.key.sql | 19 ++ .../mysql/tables/llx_product_pricerules.sql | 26 +++ htdocs/langs/en_US/errors.lang | 1 + htdocs/langs/en_US/products.lang | 4 + htdocs/product/admin/price_rules.php | 196 ++++++++++++++++++ htdocs/product/class/product.class.php | 79 ++++++- htdocs/product/price.php | 108 ++++++---- 10 files changed, 411 insertions(+), 46 deletions(-) create mode 100644 htdocs/install/mysql/tables/llx_product_pricerules.key.sql create mode 100644 htdocs/install/mysql/tables/llx_product_pricerules.sql create mode 100644 htdocs/product/admin/price_rules.php diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index ff2e9c14dbe..8357f7a65ac 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -3,6 +3,7 @@ * Copyright (C) 2007 Rodolphe Quiedeville * Copyright (C) 2009-2010 Regis Houssin * Copyright (C) 2015 Raphaël Doursenaud + * Copyright (C) 2015 Marcos García * * 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 @@ -166,6 +167,15 @@ function product_admin_prepare_head() $head[$h][2] = 'general'; $h++; + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + $head[$h] = array( + 0 => DOL_URL_ROOT."/product/admin/price_rules.php", + 1 => $langs->trans('MultipriceRules'), + 2 => 'generator' + ); + $h++; + } + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql index a06736d3ce4..d9361cef4b6 100755 --- a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql +++ b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql @@ -67,6 +67,14 @@ ALTER TABLE llx_prelevement_lignes MODIFY COLUMN code_banque varchar(128); ALTER TABLE llx_societe_rib MODIFY COLUMN code_banque varchar(128); ALTER TABLE llx_contrat ADD COLUMN ref_customer varchar(30); +CREATE TABLE llx_product_pricerules +( + rowid INT PRIMARY KEY NOT NULL AUTO_INCREMENT, + level INT NOT NULL, -- Which price level is this rule for? + fk_level INT NOT NULL, -- Price variations are made over price of X + var_percent FLOAT NOT NULL, -- Price variation over based price + var_min_percent FLOAT NOT NULL -- Min price discount over general price +); ALTER TABLE llx_ecm_directories MODIFY COLUMN fullpath varchar(10000); @@ -94,3 +102,4 @@ ALTER TABLE llx_ecm_files ADD UNIQUE INDEX uk_ecm_files_fullpath(fullpath); ALTER TABLE llx_product ADD COLUMN onportal tinyint DEFAULT 0 after tobuy; +ALTER TABLE llx_product ADD COLUMN price_autogen TINYINT(1) DEFAULT 0; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql index 42832a6b227..b5df0ade60c 100755 --- a/htdocs/install/mysql/tables/llx_product.sql +++ b/htdocs/install/mysql/tables/llx_product.sql @@ -46,7 +46,7 @@ create table llx_product price_base_type varchar(3) DEFAULT 'HT', tva_tx double(6,3), -- Default VAT rate of product recuperableonly integer NOT NULL DEFAULT '0', -- French NPR VAT - localtax1_tx double(6,3) DEFAULT 0, -- Spanish local VAT 1 + localtax1_tx double(6,3) DEFAULT 0, -- Spanish local VAT 1 localtax2_tx double(6,3) DEFAULT 0, -- Spanish local VAT 2 fk_user_author integer DEFAULT NULL, -- user making creation fk_user_modif integer, -- user making last change @@ -81,5 +81,6 @@ create table llx_product import_key varchar(14), -- Import key fk_price_expression integer, -- Link to the rule for dynamic price calculation desiredstock integer DEFAULT 0, - fk_unit integer DEFAULT NULL + fk_unit integer DEFAULT NULL, + price_autogen TINYINT DEFAULT 0 )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product_pricerules.key.sql b/htdocs/install/mysql/tables/llx_product_pricerules.key.sql new file mode 100644 index 00000000000..42b9289d26a --- /dev/null +++ b/htdocs/install/mysql/tables/llx_product_pricerules.key.sql @@ -0,0 +1,19 @@ +-- ============================================================================ +-- Copyright (C) 2015 Marcos García +-- +-- 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 . +-- +-- =========================================================================== + +ALTER TABLE llx_product_pricerules ADD CONSTRAINT unique_level UNIQUE (level); \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_product_pricerules.sql b/htdocs/install/mysql/tables/llx_product_pricerules.sql new file mode 100644 index 00000000000..3e3dfc02ed1 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_product_pricerules.sql @@ -0,0 +1,26 @@ +-- ============================================================================ +-- Copyright (C) 2015 Marcos García +-- +-- 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 . +-- +-- =========================================================================== + +CREATE TABLE llx_product_pricerules +( + rowid INT PRIMARY KEY NOT NULL AUTO_INCREMENT, + level INT NOT NULL, -- Which price level is this rule for? + fk_level INT NOT NULL, -- Price variations are made over price of X + var_percent FLOAT NOT NULL, -- Price variation over based price + var_min_percent FLOAT NOT NULL -- Min price discount over general price +); \ No newline at end of file diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 6bf95ebe75b..858e76af447 100755 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -173,6 +173,7 @@ ErrorFieldMustBeAnInteger=Field %s must be an integer ErrorMandatoryParametersNotProvided=Mandatory parameter(s) not provided ErrorOppStatusRequiredIfAmount=You set an estimated amount for this opportunity/lead. So you must also enter its status ErrorBadDefinitionOfMenuArrayInModuleDescriptor=Bad Definition Of Menu Array In Module Descriptor (bad value for key fk_menu) +ErrorSavingChanges=An error has ocurred when saving the changes # Warnings WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 6dcf4ce60f9..957fe0640ad 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -232,6 +232,10 @@ PriceByQuantityRange=Quantity range ProductsDashboard=Products/Services summary UpdateOriginalProductLabel=Modify original label HelpUpdateOriginalProductLabel=Allows to edit the name of the product +MultipriceRules=Price level rules +UseMultipriceRules=Use price level rules +PercentVariationOver=%% variation over %s +PercentDiscountOver=%% discount over %s ### composition fabrication Building=Production and items dispatchment Build=Produce diff --git a/htdocs/product/admin/price_rules.php b/htdocs/product/admin/price_rules.php new file mode 100644 index 00000000000..d6d494cd61d --- /dev/null +++ b/htdocs/product/admin/price_rules.php @@ -0,0 +1,196 @@ +. + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; + +$langs->load("admin"); +$langs->load("products"); + +// Security check +if (! $user->admin || (empty($conf->product->enabled) && empty($conf->service->enabled))) + accessforbidden(); + +/** + * Actions + */ + +if ($_POST) { + + $var_percent = GETPOST('var_percent', 'array'); + $var_min_percent = GETPOST('var_min_percent', 'array'); + $fk_level = GETPOST('fk_level', 'array'); + + for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + + $check = isset($var_min_percent[$i]); + + if ($i != 1) { + $check = $check && isset($var_percent[$i]) && isset($fk_level[$i]); + } + + if (!$check) { + continue; + } + + if ($i != 1) { + $i_var_percent = (float) price2num($var_percent[$i]); + } else { + $i_var_percent = 0; + } + + $i_var_min_percent = (float) price2num($var_min_percent[$i]); + $i_fk_level = (int) $fk_level[$i]; + + if ($i == 1) { + $check1 = true; + $check2 = $i_var_min_percent; + } else { + $check1 = $i_fk_level >= 1 && $i_fk_level <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; + $check2 = $i_var_percent && $i_var_min_percent; + } + + if (!$check1 || !$check2) { + + //If the level is between range but percent fields are empty, then we ensure it does not exist in DB + if ($check1 && !$check2) { + $db->query("DELETE FROM ".MAIN_DB_PREFIX."product_pricerules WHERE level = ".(int)$i); + } + + continue; + } + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_pricerules + SET level = ".(int) $i.", fk_level = ".$db->escape($i_fk_level).", var_percent = ".$i_var_percent.", var_min_percent = ".$i_var_min_percent; + + if (!$db->query($sql)) { + + //If we could not create, then we try updating + $sql = "UPDATE ".MAIN_DB_PREFIX."product_pricerules + SET fk_level = ".$db->escape($i_fk_level).", var_percent = ".$i_var_percent.", var_min_percent = ".$i_var_min_percent." WHERE level = ".$i; + + if (!$db->query($sql)) { + setEventMessage($langs->trans('ErrorSavingChanges'), 'errors'); + } + } + + } + + setEventMessage($langs->trans("RecordSaved")); +} + +/* + * View + */ + +$sql = "SELECT * FROM ".MAIN_DB_PREFIX."product_pricerules"; +$query = $db->query($sql); + +$rules = array(); + +while ($result = $db->fetch_object($query)) { + $rules[$result->level] = $result; +} + +$title = $langs->trans('ProductServiceSetup'); +$tab = $langs->trans("ProductsAndServices"); + +if (empty($conf->produit->enabled)) { + $title = $langs->trans('ServiceSetup'); + $tab = $langs->trans('Services'); +} elseif (empty($conf->service->enabled)) { + $title = $langs->trans('ProductSetup'); + $tab = $langs->trans('Products'); +} + +llxHeader('', $langs->trans('MultipriceRules')); + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($title,$linkback,'title_setup'); + +$head = product_admin_prepare_head(); +dol_fiche_head($head, 'generator', $tab, 0, 'product'); + +print load_fiche_titre($langs->trans('MultipriceRules')); + +//Array that contains the number of prices available +$price_options = array(); + +for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + $price_options[$i] = $langs->trans('SellingPrice').' '.$i; +} + +$genPriceOptions = function($level) use ($price_options) { + + $return = array(); + + for ($i = 1; $i < $level; $i++) { + $return[$i] = $price_options[$i]; + } + + return $return; +}; + +?> + +
+ + + + + + + + + + + + global->PRODUIT_MULTIPRICES_LIMIT; $i++): ?> + + + + + + +
trans('PriceLevel') ?>trans('Price') ?>trans('MinPrice') ?>
trans('SellingPrice') ?> 1 trans('PercentDiscountOver', $langs->trans('SellingPrice').' 1') ?>
trans('SellingPrice').' '.$i; + // Label of price + if (! empty($conf->global->{"PRODUIT_MULTIPRICES_LABEL$i"})) { + print ' - '.$langs->trans($conf->global->$keyforlabel); + } + ?> + + + trans('PercentVariationOver', Form::selectarray("fk_level[$i]", $genPriceOptions($i), (isset($rules[$i]) ? $rules[$i]->fk_level : null))) ?> + + + trans('PercentDiscountOver', $langs->trans('SellingPrice').' '.$i) ?> +
+ +
+ +
+ +
+
+ +db->escape($this->accountancy_code_sell)."'"; $sql.= ", desiredstock = " . ((isset($this->desiredstock) && $this->desiredstock != '') ? $this->desiredstock : "null"); $sql.= ", fk_unit= " . (!$this->fk_unit ? 'NULL' : $this->fk_unit); + $sql.= ", price_autogen = " . (!$this->price_autogen ? 0 : 1); $sql.= " WHERE rowid = " . $id; dol_syslog(get_class($this)."::update", LOG_DEBUG); @@ -1337,9 +1344,10 @@ class Product extends CommonObject * @param int $level 0=standard, >0 = level if multilevel prices * @param int $newnpr 0=Standard vat rate, 1=Special vat rate for French NPR VAT * @param int $newpsq 1 if it has price by quantity + * @param int $ignore_autogen Used to avoid infinite loops * @return int <0 if KO, >0 if OK */ - function updatePrice($newprice, $newpricebase, $user, $newvat='',$newminprice='', $level=0, $newnpr=0, $newpsq=0) + function updatePrice($newprice, $newpricebase, $user, $newvat='',$newminprice='', $level=0, $newnpr=0, $newpsq=0, $ignore_autogen = 0) { global $conf,$langs; @@ -1353,6 +1361,12 @@ class Product extends CommonObject // Check parameters if ($newvat == '') $newvat=$this->tva_tx; + + //If multiprices are enabled, then we check if the current product is subject to price autogeneration + if (!empty($conf->global->PRODUIT_MULTIPRICES) && !$ignore_autogen && $this->price_autogen) { + return $this->generateMultiprices($user, $newprice, $newpricebase, $newvat, $newnpr, $newpsq); + } + if (! empty($newminprice) && ($newminprice > $newprice)) { $this->error='ErrorPriceCantBeLowerThanMinPrice'; @@ -1531,7 +1545,7 @@ class Product extends CommonObject $sql.= " weight, weight_units, length, length_units, surface, surface_units, volume, volume_units, barcode, fk_barcode_type, finished,"; $sql.= " accountancy_code_buy, accountancy_code_sell, stock, pmp,"; $sql.= " datec, tms, import_key, entity, desiredstock, tobatch, fk_unit"; - $sql.= " , fk_price_expression"; + $sql.= " , fk_price_expression, price_autogen"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; if ($id) $sql.= " WHERE rowid = ".$this->db->escape($id); else @@ -1608,6 +1622,7 @@ class Product extends CommonObject $this->ref_ext = $obj->ref_ext; $this->fk_price_expression = $obj->fk_price_expression; $this->fk_unit = $obj->fk_unit; + $this->price_autogen = $obj->price_autogen; $this->db->free($resql); @@ -3992,4 +4007,64 @@ class Product extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Generates prices for a product based on product multiprice generation rules + * + * @param User $user User that updates the prices + * @param float $baseprice Base price + * @param string $price_type Base price type + * @param float $price_vat VAT % tax + * @param int $npr NPR + * @param string $psq ¿? + * @return int -1 KO, 1 OK + */ + public function generateMultiprices(User $user, $baseprice, $price_type, $price_vat, $npr, $psq) + { + global $conf, $db; + + $sql = "SELECT * FROM ".MAIN_DB_PREFIX."product_pricerules"; + $query = $db->query($sql); + + $rules = array(); + + while ($result = $db->fetch_object($query)) { + $rules[$result->level] = $result; + } + + //Because prices can be based on other level's prices, we temporarily store them + $prices = array( + 1 => $baseprice + ); + + for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + + $price = $baseprice; + $price_min = 0; + + if ($i > 1) { + //We have to make sure it does exist and it is > 0 + if (isset($rules[$i]->var_percent) && $rules[$i]->var_percent) { + $price = $prices[$rules[$i]->fk_level] * (1 + ($rules[$i]->var_percent/100)); + } + } + + $prices[$i] = $price; + + //We have to make sure it does exist and it is > 0 + if (isset($rules[$i]->var_min_percent) && $rules[$i]->var_min_percent) { + $price_min = $price * (1 - ($rules[$i]->var_min_percent/100)); + } + + if ($price == $this->multiprices[$i] && ($price_min == $this->multiprices_min[$i])) { + continue; + } + + if ($this->updatePrice($price, $price_type, $user, $price_vat, $price_min, $i, $npr, $psq, true) < 0) { + return -1; + } + } + + return 1; + } } diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 9c7defc4643..27d00db18f2 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -82,39 +82,37 @@ $parameters=array('id'=>$id, 'ref'=>$ref); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -if (empty($reshook)) -{ - if ($action == 'update_price' && !$cancel && ($user->rights->produit->creer || $user->rights->service->creer)) - { +if (empty($reshook)) { + if ($action == 'update_price' && !$cancel && ($user->rights->produit->creer || $user->rights->service->creer)) { + $newprice = ''; + $newprice_min = ''; + $newpricebase = ''; + $newvat = ''; + $maxpricesupplier = $object->min_recommended_price(); $object->fk_price_expression = empty($eid) ? 0 : $eid; //0 discards expression // MultiPrix - if (! empty($conf->global->PRODUIT_MULTIPRICES)) - { - $newprice = ''; - $newprice_min = ''; - $newpricebase = ''; - $newvat = ''; + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) - { - if (isset($_POST ["price_" . $i])) - { + //Shall we generate prices using price rules? + $object->price_autogen = GETPOST('usePriceRules') == 'on' ? true : false; + $object->update($object->id, $user); + + for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) { + if (isset($_POST ["price_".$i])) { $level = $i; - $newprice = price2num($_POST ["price_" . $i], 'MU'); - $newprice_min = price2num($_POST ["price_min_" . $i], 'MU'); - $newpricebase = $_POST ["multiprices_base_type_" . $i]; - $newnpr = (preg_match('/\*/', $_POST ["tva_tx_" . $i]) ? 1 : 0); - $newvat = str_replace('*', '', $_POST ["tva_tx_" . $i]); + $newprice = price2num($_POST ["price_".$i], 'MU'); + $newprice_min = price2num($_POST ["price_min_".$i], 'MU'); + $newpricebase = $_POST ["multiprices_base_type_".$i]; + $newnpr = (preg_match('/\*/', $_POST ["tva_tx_".$i]) ? 1 : 0); + $newvat = str_replace('*', '', $_POST ["tva_tx_".$i]); $newpsq = GETPOST('psqflag'); $newpsq = empty($newpsq) ? 0 : $newpsq; break; // We found submited price } } - } - else - { + } else { $level = 0; $newprice = price2num($_POST ["price"], 'MU'); $newprice_min = price2num($_POST ["price_min"], 'MU'); @@ -125,42 +123,39 @@ if (empty($reshook)) $newpsq = empty($newpsq) ? 0 : $newpsq; } - if (! empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $newprice_min < $maxpricesupplier) - { - setEventMessage($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')),'errors'); - $error++; - $action='edit_price'; + if (!empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $newprice_min < $maxpricesupplier) { + setEventMessage($langs->trans("MinimumPriceLimit", price($maxpricesupplier, 0, '', 1, - 1, - 1, 'auto')), 'errors'); + $error ++; + $action = 'edit_price'; } - if ($newprice < $newprice_min && ! empty($object->fk_price_expression)) - { + if ($newprice < $newprice_min && !empty($object->fk_price_expression)) { $newprice = $newprice_min; //Set price same as min, the user will not see the } - if ($object->updatePrice($newprice, $newpricebase, $user, $newvat, $newprice_min, $level, $newnpr, $newpsq) > 0) - { + $res = $object->updatePrice($newprice, $newpricebase, $user, $newvat, $newprice_min, $level, $newnpr, $newpsq); + + if ($res) { + if ($object->fk_price_expression != 0) { //Check the expression validity by parsing it $priceparser = new PriceParser($db); $price_result = $priceparser->parseProduct($object); if ($price_result < 0) { //Expression is not valid - $error++; - $action='edit_price'; + $error ++; + $action = 'edit_price'; setEventMessage($priceparser->translatedError(), 'errors'); } } - if (empty($error) && ! empty($conf->dynamicprices->enabled)) - { - $ret=$object->setPriceExpression($object->fk_price_expression); - if ($ret < 0) - { - $error++; - $action='edit_price'; + if (empty($error) && !empty($conf->dynamicprices->enabled)) { + $ret = $object->setPriceExpression($object->fk_price_expression); + if ($ret < 0) { + $error ++; + $action = 'edit_price'; setEventMessage($object->error, 'errors'); } } - if (empty($error)) - { + if (empty($error)) { $action = ''; setEventMessage($langs->trans("RecordSaved")); } @@ -170,6 +165,7 @@ if (empty($reshook)) } } + if ($action == 'delete' && $user->rights->produit->supprimer) { $result = $object->log_price_delete($user, $_GET ["lineid"]); @@ -785,6 +781,33 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights-> } else { + + ?> + + global->PRODUIT_MULTIPRICES_LIMIT; $i ++) { print '
'; @@ -798,6 +821,7 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights-> // VAT if ($i == 1) { + print '' . $langs->trans('UseMultipriceRules'). 'price_autogen ? 'checked' : '').'>'; print '' . $langs->trans("VATRate") . ''; print $form->load_tva("tva_tx_" . $i, $object->multiprices_tva_tx ["$i"], $mysoc, '', $object->id); print ''; From 6db09a0d649a0bbc6fc3b072fc747a3873700976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Tue, 20 Oct 2015 11:35:49 +0200 Subject: [PATCH 02/11] Little correction --- htdocs/product/class/product.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 9b959517ce5..f5e95ff0e93 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1363,7 +1363,8 @@ class Product extends CommonObject if ($newvat == '') $newvat=$this->tva_tx; //If multiprices are enabled, then we check if the current product is subject to price autogeneration - if (!empty($conf->global->PRODUIT_MULTIPRICES) && !$ignore_autogen && $this->price_autogen) { + //Price will be modified ONLY when the first one is the one that is being modified + if (!empty($conf->global->PRODUIT_MULTIPRICES) && !$ignore_autogen && $this->price_autogen && ($level == 1)) { return $this->generateMultiprices($user, $newprice, $newpricebase, $newvat, $newnpr, $newpsq); } From 1b10612c4bee864b25b94991c0a631c172d23957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Tue, 20 Oct 2015 11:41:33 +0200 Subject: [PATCH 03/11] Fixed PHPCS check --- htdocs/product/admin/price_rules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/admin/price_rules.php b/htdocs/product/admin/price_rules.php index d6d494cd61d..76b907e14d4 100644 --- a/htdocs/product/admin/price_rules.php +++ b/htdocs/product/admin/price_rules.php @@ -71,7 +71,7 @@ if ($_POST) { //If the level is between range but percent fields are empty, then we ensure it does not exist in DB if ($check1 && !$check2) { - $db->query("DELETE FROM ".MAIN_DB_PREFIX."product_pricerules WHERE level = ".(int)$i); + $db->query("DELETE FROM ".MAIN_DB_PREFIX."product_pricerules WHERE level = ".(int) $i); } continue; From c6baeacd3d6560e6d3c6f38bff6621839bba022d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Tue, 20 Oct 2015 11:42:56 +0200 Subject: [PATCH 04/11] Removed JS debugging --- htdocs/product/price.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 27d00db18f2..7eb9ee0b7e8 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -789,8 +789,6 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights-> var otherPrices = $('div.fiche form:not(:first)'); var minPrice1 = $('div.fiche form:first tr:eq(3)'); - console.log('e'); - if (jQuery('input#usePriceRules').prop('checked')) { otherPrices.hide(); minPrice1.hide(); From 8602d41a28dfbe3a4efab348d196f84845a54a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 31 Oct 2015 09:46:56 +0100 Subject: [PATCH 05/11] Update COPYRIGHT --- COPYRIGHT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COPYRIGHT b/COPYRIGHT index 534770f0f75..66c74407fe7 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -56,7 +56,7 @@ JsTimezoneDetect 1.0.4 MIT License Yes Raven.js 1.1.19 MIT License Yes Used for client-side error logging with Sentry logger For licenses compatibility informations: -http://www.fsf.org/licensing/licenses/index_html +http://www.gnu.org/licenses/licenses.en.html Copyright From 41603426566875652229474f0a1c7002ac543320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 31 Oct 2015 10:05:34 +0100 Subject: [PATCH 06/11] Update llx_c_hrm_function.sql --- htdocs/install/mysql/data/llx_c_hrm_function.sql | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_hrm_function.sql b/htdocs/install/mysql/data/llx_c_hrm_function.sql index f8b56563689..dd5c6e832bd 100644 --- a/htdocs/install/mysql/data/llx_c_hrm_function.sql +++ b/htdocs/install/mysql/data/llx_c_hrm_function.sql @@ -26,9 +26,9 @@ INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(1, 5,'EXECBOARD', 'Executive board', 0, 1); INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(2, 10, 'MANAGDIR', 'Managing director', 1, 1); INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(3, 15, 'ACCOUNTMANAG', 'Account manager', 0, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(3, 20, 'ENGAGDIR', 'Engagement director', 1, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(4, 25, 'DIRECTOR', 'Director', 1, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(5, 30, 'PROJMANAG', 'Project manager', 0, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(6, 35, 'DEPHEAD', 'Department head', 0, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(7, 40, 'SECRETAR', 'Secretary', 0, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(8, 45, 'EMPLOYEE', 'Department employee', 0, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(4, 20, 'ENGAGDIR', 'Engagement director', 1, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(5, 25, 'DIRECTOR', 'Director', 1, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(6, 30, 'PROJMANAG', 'Project manager', 0, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(7, 35, 'DEPHEAD', 'Department head', 0, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(8, 40, 'SECRETAR', 'Secretary', 0, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(9, 45, 'EMPLOYEE', 'Department employee', 0, 1); From 4108f55c1e728b912af614fab0ac060779a8d671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 31 Oct 2015 10:07:13 +0100 Subject: [PATCH 07/11] Update 3.8.0-3.9.0.sql --- htdocs/install/mysql/migration/3.8.0-3.9.0.sql | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql index 4f1e308b370..1d6d7974285 100755 --- a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql +++ b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql @@ -134,12 +134,12 @@ CREATE TABLE IF NOT EXISTS llx_c_hrm_function INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(1, 5, 'EXECBOARD', 'Executive board', 0, 1); INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(2, 10, 'MANAGDIR', 'Managing director', 1, 1); INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(3, 15, 'ACCOUNTMANAG', 'Account manager', 0, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(3, 20, 'ENGAGDIR', 'Engagement director', 1, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(4, 25, 'DIRECTOR', 'Director', 1, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(5, 30, 'PROJMANAG', 'Project manager', 0, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(6, 35, 'DEPHEAD', 'Department head', 0, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(7, 40, 'SECRETAR', 'Secretary', 0, 1); -INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(8, 45, 'EMPLOYEE', 'Department employee', 0, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(4, 20, 'ENGAGDIR', 'Engagement director', 1, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(5, 25, 'DIRECTOR', 'Director', 1, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(6, 30, 'PROJMANAG', 'Project manager', 0, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(7, 35, 'DEPHEAD', 'Department head', 0, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(8, 40, 'SECRETAR', 'Secretary', 0, 1); +INSERT INTO llx_c_hrm_function (rowid, pos, code, label, c_level, active) VALUES(9, 45, 'EMPLOYEE', 'Department employee', 0, 1); CREATE TABLE IF NOT EXISTS llx_c_hrm_department ( From 592348850fa4a2cb63099d7189784113388d8762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 31 Oct 2015 11:48:17 +0100 Subject: [PATCH 08/11] Added missing SQL statements + reordered them --- .../install/mysql/migration/3.8.0-3.9.0.sql | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql index 83013214eb3..1b383b80624 100755 --- a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql +++ b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql @@ -69,17 +69,8 @@ ALTER TABLE llx_societe_rib MODIFY COLUMN code_banque varchar(128); ALTER TABLE llx_contrat ADD COLUMN ref_customer varchar(30); ALTER TABLE llx_commande ADD COLUMN fk_warehouse integer DEFAULT NULL after fk_shipping_method; -CREATE TABLE llx_product_pricerules -( - rowid INT PRIMARY KEY NOT NULL AUTO_INCREMENT, - level INT NOT NULL, -- Which price level is this rule for? - fk_level INT NOT NULL, -- Price variations are made over price of X - var_percent FLOAT NOT NULL, -- Price variation over based price - var_min_percent FLOAT NOT NULL -- Min price discount over general price -); ALTER TABLE llx_ecm_directories MODIFY COLUMN fullpath varchar(750); - ALTER TABLE llx_ecm_directories DROP INDEX idx_ecm_directories; ALTER TABLE llx_ecm_directories ADD UNIQUE INDEX uk_ecm_directories (label, fk_parent, entity); --ALTER TABLE llx_ecm_directories ADD UNIQUE INDEX uk_ecm_directories_fullpath(fullpath); @@ -263,4 +254,15 @@ ALTER TABLE llx_budget_lines ADD CONSTRAINT fk_budget_lines_budget FOREIGN KEY ( ALTER TABLE llx_c_typent ADD COLUMN position integer NOT NULL DEFAULT 0; ALTER TABLE llx_c_forme_juridique ADD COLUMN position integer NOT NULL DEFAULT 0; ALTER TABLE llx_c_type_fees ADD COLUMN position integer NOT NULL DEFAULT 0; -ALTER TABLE llx_product ADD COLUMN price_autogen TINYINT(1) DEFAULT 0; \ No newline at end of file + +-- NEW Level multiprice generator based on per cent variations over base price +CREATE TABLE llx_product_pricerules +( + rowid INT PRIMARY KEY NOT NULL AUTO_INCREMENT, + level INT NOT NULL, -- Which price level is this rule for? + fk_level INT NOT NULL, -- Price variations are made over price of X + var_percent FLOAT NOT NULL, -- Price variation over based price + var_min_percent FLOAT NOT NULL -- Min price discount over general price +); +ALTER TABLE llx_product ADD COLUMN price_autogen TINYINT(1) DEFAULT 0; +ALTER TABLE llx_product_pricerules ADD CONSTRAINT unique_level UNIQUE (level); \ No newline at end of file From ff5fcbbc10f4c877c627c3b408a0137820c4bfd0 Mon Sep 17 00:00:00 2001 From: philippe grand Date: Sat, 31 Oct 2015 17:21:48 +0100 Subject: [PATCH 09/11] [Qual] Uniformize code --- htdocs/cashdesk/admin/cashdesk.php | 4 ++-- htdocs/categories/card.php | 2 +- htdocs/categories/categorie.php | 9 ++++---- htdocs/comm/action/card.php | 9 ++++---- htdocs/comm/askpricesupplier/card.php | 32 ++++++++++++++------------- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/htdocs/cashdesk/admin/cashdesk.php b/htdocs/cashdesk/admin/cashdesk.php index 74560e8ff6a..fcafa84a5a2 100644 --- a/htdocs/cashdesk/admin/cashdesk.php +++ b/htdocs/cashdesk/admin/cashdesk.php @@ -66,12 +66,12 @@ if (GETPOST('action','alpha') == 'set') if (! $error) { $db->commit(); - setEventMessage($langs->trans("SetupSaved")); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); } else { $db->rollback(); - setEventMessage($langs->trans("Error"), 'errors'); + setEventMessages($langs->trans("Error"), null, 'errors'); } } diff --git a/htdocs/categories/card.php b/htdocs/categories/card.php index f5921ac4d06..6281307218c 100644 --- a/htdocs/categories/card.php +++ b/htdocs/categories/card.php @@ -155,7 +155,7 @@ if ($action == 'add' && $user->rights->categorie->creer) } else { - setEventMessage($object->error,'errors'); + setEventMessages($object->error, $object->errors, 'errors'); } } } diff --git a/htdocs/categories/categorie.php b/htdocs/categories/categorie.php index aca45c5ca52..d86a351cdff 100644 --- a/htdocs/categories/categorie.php +++ b/htdocs/categories/categorie.php @@ -151,8 +151,7 @@ if (empty($reshook)) $result=$cat->del_type($object,$elementtype); if ($result < 0) { - setEventMessage($cat->error,'errors'); - setEventMessage($cat->errors,'errors'); + setEventMessages($cat->error, $cat->errors, 'errors'); } } @@ -199,17 +198,17 @@ if (empty($reshook)) $result=$cat->add_type($object,$elementtype); if ($result >= 0) { - setEventMessage($langs->trans("WasAddedSuccessfully",$cat->label)); + setEventMessages($langs->trans("WasAddedSuccessfully",$cat->label), null, 'mesgs'); } else { if ($cat->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - setEventMessage($langs->trans("ObjectAlreadyLinkedToCategory"),'warnings'); + setEventMessages($langs->trans("ObjectAlreadyLinkedToCategory"), null, 'warnings'); } else { - setEventMessages( $cat->error, $cat->errors, 'errors' ); + setEventMessages($cat->error, $cat->errors, 'errors'); } } } diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 1f2f0c3b19e..2fe0df507cb 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -140,7 +140,7 @@ if ($action == 'confirm_clone' && $confirm == 'yes') { if (1 == 0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) { - setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); + setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors'); } else { @@ -151,7 +151,7 @@ if ($action == 'confirm_clone' && $confirm == 'yes') header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result); exit(); } else { - setEventMessage($object->error, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); $action = ''; } } @@ -347,7 +347,7 @@ if ($action == 'add') $db->rollback(); $langs->load("errors"); $error=$langs->trans($object->error); - setEventMessage($error,'errors'); + setEventMessages($error, null, 'errors'); $action = 'create'; $donotclearsession=1; } } @@ -551,8 +551,7 @@ if ($action == 'mupdate') $result=$object->update($user); if ($result < 0) { - setEventMessage($object->error,'errors'); - setEventMessage($object->errors,'errors'); + setEventMessages($object->error, $object->errors, 'errors'); } } if (! empty($backtopage)) diff --git a/htdocs/comm/askpricesupplier/card.php b/htdocs/comm/askpricesupplier/card.php index f57cb16e0e0..d59922c1cb4 100644 --- a/htdocs/comm/askpricesupplier/card.php +++ b/htdocs/comm/askpricesupplier/card.php @@ -114,7 +114,7 @@ if (empty($reshook)) { if (1 == 0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) { - setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); + setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors'); } else { @@ -123,8 +123,10 @@ if (empty($reshook)) if ($result > 0) { header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result); exit(); - } else { - setEventMessage($object->error, 'errors'); + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); $action = ''; } } @@ -140,7 +142,7 @@ if (empty($reshook)) exit(); } else { $langs->load("errors"); - setEventMessage($langs->trans($object->error), 'errors'); + setEventMessages($langs->trans($object->error), null, 'errors'); } } @@ -198,8 +200,8 @@ if (empty($reshook)) } } else { $langs->load("errors"); - if (count($object->errors) > 0) setEventMessage($object->errors, 'errors'); - else setEventMessage($langs->trans($object->error), 'errors'); + if (count($object->errors) > 0) setEventMessages($object->error, $object->errors, 'errors'); + else setEventMessages($langs->trans($object->error), null, 'errors'); } } @@ -249,7 +251,7 @@ if (empty($reshook)) $id = $object->create_from($user); } else { - setEventMessage($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_askpricesupplier')), 'errors'); + setEventMessages($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_askpricesupplier')), null, 'errors'); } } else { $object->ref = GETPOST('ref'); @@ -484,7 +486,7 @@ if (empty($reshook)) if ($object->id > 0) { $result = $object->insert_discount($_POST["remise_id"]); if ($result < 0) { - setEventMessage($object->error, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); } } } @@ -674,7 +676,7 @@ if (empty($reshook)) if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); - setEventMessage($mesg, 'errors'); + setEventMessages($mesg, null, 'errors'); } else { // Insert line $ref_fourn = GETPOST('fourn_ref'); @@ -716,7 +718,7 @@ if (empty($reshook)) } else { $db->rollback(); - setEventMessage($object->error, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); } } } @@ -774,7 +776,7 @@ if (empty($reshook)) $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { - setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); + setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors'); $error ++; } } else { @@ -823,7 +825,7 @@ if (empty($reshook)) } else { $db->rollback(); - setEventMessage($object->error, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); } } } @@ -865,9 +867,9 @@ if (empty($reshook)) $file = $upload_dir . '/' . GETPOST('file'); $ret = dol_delete_file($file, 0, 0, 0, $object); if ($ret) - setEventMessage($langs->trans("FileWasRemoved", GETPOST('file'))); + setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs'); else - setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors'); + setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors'); } } @@ -1325,7 +1327,7 @@ if ($action == 'create') $numref = $object->getNextNumRef($soc); if (empty($numref)) { $error ++; - setEventMessage($object->error, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); } } else { $numref = $object->ref; From df3af6979e484a57cfa894974a4aabfb2172f72f Mon Sep 17 00:00:00 2001 From: frederic34 Date: Sat, 31 Oct 2015 21:43:59 +0100 Subject: [PATCH 10/11] Translation in paypal lib --- htdocs/langs/en_US/paypal.lang | 5 +++++ htdocs/paypal/lib/paypal.lib.php | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/htdocs/langs/en_US/paypal.lang b/htdocs/langs/en_US/paypal.lang index b6b6d59d4a0..def6a08406f 100644 --- a/htdocs/langs/en_US/paypal.lang +++ b/htdocs/langs/en_US/paypal.lang @@ -23,3 +23,8 @@ PAYPAL_PAYONLINE_SENDEMAIL=EMail to warn after a payment (success or not) ReturnURLAfterPayment=Return URL after payment ValidationOfPaypalPaymentFailed=Validation of Paypal payment failed PaypalConfirmPaymentPageWasCalledButFailed=Payment confirmation page for Paypal was called by Paypal but confirmation failed +SetExpressCheckoutAPICallFailed=SetExpressCheckout API call failed. +DetailedErrorMessage=Detailed Error Message +ShortErrorMessage=Short Error Message +ErrorCode=Error Code +ErrorSeverityCode=Error Severity Code diff --git a/htdocs/paypal/lib/paypal.lib.php b/htdocs/paypal/lib/paypal.lib.php index f9ec79244a5..824f312a9af 100644 --- a/htdocs/paypal/lib/paypal.lib.php +++ b/htdocs/paypal/lib/paypal.lib.php @@ -406,11 +406,11 @@ function print_paypal_redirect($paymentAmount,$currencyCodeType,$paymentType,$re $ErrorLongMsg = urldecode($resArray["L_LONGMESSAGE0"]); $ErrorSeverityCode = urldecode($resArray["L_SEVERITYCODE0"]); - echo "SetExpressCheckout API call failed.
\n"; - echo "Detailed Error Message: " . $ErrorLongMsg."
\n"; - echo "Short Error Message: " . $ErrorShortMsg."
\n"; - echo "Error Code: " . $ErrorCode."
\n"; - echo "Error Severity Code: " . $ErrorSeverityCode."
\n"; + echo $langs->trans('SetExpressCheckoutAPICallFailed') . "
\n"; + echo $langs->trans('DetailedErrorMessage') . ": " . $ErrorLongMsg."
\n"; + echo $langs->trans('ShortErrorMessage') . ": " . $ErrorShortMsg."
\n"; + echo $langs->trans('ErrorCode') . ": " . $ErrorCode."
\n"; + echo $langs->trans('ErrorSeverityCode') . ": " . $ErrorSeverityCode."
\n"; } } From 22d1cf860c70a375f4c83684d5d24e514cb30de3 Mon Sep 17 00:00:00 2001 From: frederic34 Date: Sat, 31 Oct 2015 22:05:55 +0100 Subject: [PATCH 11/11] Add translation --- htdocs/langs/en_US/paypal.lang | 1 + htdocs/public/paypal/paymentok.php | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/langs/en_US/paypal.lang b/htdocs/langs/en_US/paypal.lang index def6a08406f..b2eadfce654 100644 --- a/htdocs/langs/en_US/paypal.lang +++ b/htdocs/langs/en_US/paypal.lang @@ -24,6 +24,7 @@ ReturnURLAfterPayment=Return URL after payment ValidationOfPaypalPaymentFailed=Validation of Paypal payment failed PaypalConfirmPaymentPageWasCalledButFailed=Payment confirmation page for Paypal was called by Paypal but confirmation failed SetExpressCheckoutAPICallFailed=SetExpressCheckout API call failed. +DoExpressCheckoutPaymentAPICallFailed=DoExpressCheckoutPayment API call failed. DetailedErrorMessage=Detailed Error Message ShortErrorMessage=Short Error Message ErrorCode=Error Code diff --git a/htdocs/public/paypal/paymentok.php b/htdocs/public/paypal/paymentok.php index f59bab46bd1..90f13aa6f17 100644 --- a/htdocs/public/paypal/paymentok.php +++ b/htdocs/public/paypal/paymentok.php @@ -224,11 +224,11 @@ if ($PAYPALTOKEN) $ErrorLongMsg = urldecode($resArray["L_LONGMESSAGE0"]); $ErrorSeverityCode = urldecode($resArray["L_SEVERITYCODE0"]); - echo "DoExpressCheckoutPayment API call failed.
\n"; - echo "Detailed Error Message: " . $ErrorLongMsg."
\n"; - echo "Short Error Message: " . $ErrorShortMsg."
\n"; - echo "Error Code: " . $ErrorCode."
\n"; - echo "Error Severity Code: " . $ErrorSeverityCode."
\n"; + echo $langs->trans('DoExpressCheckoutPaymentAPICallFailed') . "
\n"; + echo $langs->trans('DetailedErrorMessage') . ": " . $ErrorLongMsg."
\n"; + echo $langs->trans('ShortErrorMessage') . ": " . $ErrorShortMsg."
\n"; + echo $langs->trans('ErrorCode') . ": " . $ErrorCode."
\n"; + echo $langs->trans('ErrorSeverityCode') . ": " . $ErrorSeverityCode."
\n"; if ($mysoc->email) echo "\nPlease, send a screenshot of this page to ".$mysoc->email."
\n";