diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
index fea6c1a51e6..14fc29dedf8 100644
--- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
+++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
@@ -71,6 +71,22 @@ ALTER TABLE llx_website_page ADD COLUMN type_container varchar(16) NOT NULL DEFA
-- For 7.0
+ALTER TABLE llx_product_price_by_qty ADD COLUMN quantity double DEFAULT NULL;
+ALTER TABLE llx_product_price_by_qty ADD COLUMN unitprice double(24,8) DEFAULT 0;
+
+ALTER TABLE llx_product_price_by_qty ADD COLUMN price_base_type varchar(3) DEFAULT 'HT';
+ALTER TABLE llx_product_price_by_qty ADD COLUMN fk_multicurrency integer;
+ALTER TABLE llx_product_price_by_qty ADD COLUMN multicurrency_code varchar(255);
+ALTER TABLE llx_product_price_by_qty ADD COLUMN multicurrency_tx double(24,8) DEFAULT 1;
+ALTER TABLE llx_product_price_by_qty ADD COLUMN multicurrency_price double(24,8) DEFAULT NULL;
+ALTER TABLE llx_product_price_by_qty ADD COLUMN multicurrency_price_ttc double(24,8) DEFAULT NULL;
+
+-- VMYSQL4.0 DROP INDEX uk_product_price_by_qty_level on llx_product_price_by_qty;
+-- VPGSQL8.0 DROP INDEX uk_product_price_by_qty_level;
+
+ALTER TABLE llx_product_price_by_qty ADD UNIQUE INDEX uk_product_price_by_qty_level (fk_product_price, quantity);
+
+
ALTER TABLE llx_accounting_bookkeeping ADD INDEX idx_accounting_bookkeeping_fk_doc (fk_doc);
ALTER TABLE llx_c_revenuestamp ADD COLUMN revenuestamp_type varchar(16) DEFAULT 'fixed' NOT NULL;
diff --git a/htdocs/install/mysql/tables/llx_product_price_by_qty.sql b/htdocs/install/mysql/tables/llx_product_price_by_qty.sql
index 2b91647b80a..9dbeb530a34 100644
--- a/htdocs/install/mysql/tables/llx_product_price_by_qty.sql
+++ b/htdocs/install/mysql/tables/llx_product_price_by_qty.sql
@@ -17,6 +17,8 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see .
--
+-- This table is used to defined price by qty when a line into llx_product_price
+-- is set with price_by_qty = 1
-- ============================================================================
create table llx_product_price_by_qty
@@ -24,12 +26,20 @@ create table llx_product_price_by_qty
rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
fk_product_price integer NOT NULL,
price double(24,8) DEFAULT 0,
+ price_base_type varchar(3) DEFAULT 'HT',
quantity double DEFAULT NULL,
remise_percent double NOT NULL DEFAULT 0,
remise double NOT NULL DEFAULT 0,
unitprice double(24,8) DEFAULT 0,
fk_user_creat integer,
fk_user_modif integer,
+
+ fk_multicurrency integer,
+ multicurrency_code varchar(255),
+ multicurrency_tx double(24,8) DEFAULT 1,
+ multicurrency_price double(24,8) DEFAULT NULL,
+ multicurrency_price_ttc double(24,8) DEFAULT NULL,
+
tms timestamp,
import_key varchar(14)
)ENGINE=innodb;
diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
index a1d81183c41..179175041b8 100644
--- a/htdocs/langs/en_US/products.lang
+++ b/htdocs/langs/en_US/products.lang
@@ -196,6 +196,7 @@ CurrentProductPrice=Current price
AlwaysUseNewPrice=Always use current price of product/service
AlwaysUseFixedPrice=Use the fixed price
PriceByQuantity=Different prices by quantity
+DisablePriceByQty=Disable prices by quantity
PriceByQuantityRange=Quantity range
MultipriceRules=Price segment rules
UseMultipriceRules=Use price segment rules (defined into product module setup) to autocalculate prices of all other segment according to first segment
diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php
index 78829e489a6..abfe82d0dff 100644
--- a/htdocs/product/admin/product.php
+++ b/htdocs/product/admin/product.php
@@ -36,8 +36,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbarcode.class.php';
-$langs->load("admin");
-$langs->load("products");
+$langs->loadLangs(array("admin","products"));
// Security check
if (! $user->admin || (empty($conf->product->enabled) && empty($conf->service->enabled)))
@@ -55,12 +54,10 @@ $select_pricing_rules=array(
'PRODUIT_MULTIPRICES'=>$langs->trans('MultiPricesAbility'), // Several prices according to a customer level
'PRODUIT_CUSTOMER_PRICES'=>$langs->trans('PriceByCustomer'), // Different price for each customer
);
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2)
-{
- $langs->load("admin");
- $select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY'] = $langs->trans('PriceByQuantity').' ('.$langs->trans("VersionExperimental").')'; // TODO If this is enabled, price must be hidden when price by qty is enabled, also price for quantity must be used when adding product into order/propal/invoice
- $select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY&PRODUIT_MULTIPRICES'] = $langs->trans('MultiPricesAbility') . '+' . $langs->trans('PriceByQuantity').' ('.$langs->trans("VersionExperimental").')';
-}
+$keyforparam='PRODUIT_CUSTOMER_PRICES_BY_QTY';
+if ($conf->global->MAIN_FEATURES_LEVEL >= 2 || ! empty($conf->global->$keyforparam)) $select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY'] = $langs->trans('PriceByQuantity').' ('.$langs->trans("VersionExperimental").')'; // TODO If this is enabled, price must be hidden when price by qty is enabled, also price for quantity must be used when adding product into order/propal/invoice
+$keyforparam='PRODUIT_CUSTOMER_PRICES_BY_QTY&PRODUIT_MULTIPRICES';
+if ($conf->global->MAIN_FEATURES_LEVEL >= 2 || ! empty($conf->global->$keyforparam)) $select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY&PRODUIT_MULTIPRICES'] = $langs->trans('MultiPricesAbility') . '+' . $langs->trans('PriceByQuantity').' ('.$langs->trans("VersionExperimental").')';
// Clean param
if (! empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_MULTIPRICES_LIMIT)) {
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index 6868005f54f..ab6430d9d83 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -1483,12 +1483,14 @@ class Product extends CommonObject
* @param int $rowid Line id to delete
* @return int <0 if KO, >0 if OK
*/
- function log_price_delete($user,$rowid)
+ function log_price_delete($user, $rowid)
{
+ $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_price_by_qty";
+ $sql.= " WHERE fk_product_price=".$rowid;
+ $resql=$this->db->query($sql);
+
$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_price";
$sql.= " WHERE rowid=".$rowid;
-
- dol_syslog(get_class($this)."::log_price_delete", LOG_DEBUG);
$resql=$this->db->query($sql);
if ($resql)
{
@@ -1499,7 +1501,6 @@ class Product extends CommonObject
$this->error=$this->db->lasterror();
return -1;
}
-
}
@@ -1642,13 +1643,13 @@ class Product extends CommonObject
* @param double $newminprice New price min
* @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 $newpbq 1 if it has price by quantity
* @param int $ignore_autogen Used to avoid infinite loops
* @param array $localtaxes_array Array with localtaxes info array('0'=>type1,'1'=>rate1,'2'=>type2,'3'=>rate2) (loaded by getLocalTaxesFromRate(vatrate, 0, ...) function).
* @param string $newdefaultvatcode Default vat code
* @return int <0 if KO, >0 if OK
*/
- function updatePrice($newprice, $newpricebase, $user, $newvat='',$newminprice='', $level=0, $newnpr=0, $newpsq=0, $ignore_autogen=0, $localtaxes_array=array(), $newdefaultvatcode='')
+ function updatePrice($newprice, $newpricebase, $user, $newvat='',$newminprice='', $level=0, $newnpr=0, $newpbq=0, $ignore_autogen=0, $localtaxes_array=array(), $newdefaultvatcode='')
{
global $conf,$langs;
@@ -1667,7 +1668,7 @@ class Product extends CommonObject
// 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);
+ return $this->generateMultiprices($user, $newprice, $newpricebase, $newvat, $newnpr, $newpbq);
}
if (! empty($newminprice) && ($newminprice > $newprice))
@@ -1781,7 +1782,7 @@ class Product extends CommonObject
$this->localtax2_type = $localtaxtype2;
// Price by quantity
- $this->price_by_qty = $newpsq;
+ $this->price_by_qty = $newpbq;
$this->_log_price($user,$level); // Save price for level into table product_price
diff --git a/htdocs/product/price.php b/htdocs/product/price.php
index 3b33ea952b2..6b77ee3a0ee 100644
--- a/htdocs/product/price.php
+++ b/htdocs/product/price.php
@@ -379,32 +379,35 @@ if (empty($reshook))
if ($action == 'delete' && $user->rights->produit->supprimer)
{
- $result = $object->log_price_delete($user, $_GET ["lineid"]);
+ $result = $object->log_price_delete($user, GETPOST('lineid','int'));
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
}
- /**
- * ***************************************************
- * Price by quantity
- * ***************************************************
- */
- if ($action == 'activate_price_by_qty') { // Activating product price by quantity add a new price, specified as by quantity
-
- $level = GETPOST('level');
-
+ // Set Price by quantity
+ if ($action == 'activate_price_by_qty')
+ {
+ // Activating product price by quantity add a new price line with price_by_qty set to 1
+ $level = GETPOST('level','int');
$object->updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 1);
}
+ // Unset Price by quantity
+ if ($action == 'disable_price_by_qty')
+ {
+ // Disabling product price by quantity add a new price line with price_by_qty set to 0
+ $level = GETPOST('level','int');
+ $object->updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 0);
+ }
if ($action == 'edit_price_by_qty')
{ // Edition d'un prix par quantité
- $rowid = GETPOST('rowid');
+ $rowid = GETPOST('rowid','int');
}
+ // Add or update price by quantity
if ($action == 'update_price_by_qty')
- { // Ajout / Mise à jour d'un prix par quantité
-
+ {
// Récupération des variables
$rowid = GETPOST('rowid');
$priceid = GETPOST('priceid');
@@ -415,11 +418,11 @@ if (empty($reshook))
$remise = 0; // TODO : allow discount by amount when available on documents
if (empty($quantity)) {
- $error ++;
+ $error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Qty")), null, 'errors');
}
if (empty($newprice)) {
- $error ++;
+ $error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Price")), null, 'errors');
}
if (! $error) {
@@ -442,11 +445,13 @@ if (empty($reshook))
$sql .= " WHERE rowid = " . GETPOST('rowid');
$result = $db->query($sql);
+ if (! $result) dol_print_error($db);
} else {
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_price_by_qty (fk_product_price,price,unitprice,quantity,remise_percent,remise) values (";
$sql .= $priceid . ',' . $price . ',' . $unitPrice . ',' . $quantity . ',' . $remise_percent . ',' . $remise . ')';
$result = $db->query($sql);
+ if (! $result) dol_print_error($db);
}
}
}
@@ -920,8 +925,8 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES))
if ($action != 'edit_price_by_qty' && ($user->rights->produit->creer || $user->rights->service->creer)) {
print '