Skip to content

Commit

Permalink
BUG Fix of old hidden feature price per quantity
Browse files Browse the repository at this point in the history
  • Loading branch information
eldy committed Dec 22, 2017
1 parent d1cfbc2 commit 2b056b0
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 92 deletions.
19 changes: 14 additions & 5 deletions htdocs/core/class/html.form.class.php
Expand Up @@ -1909,8 +1909,9 @@ function select_produits_list($selected='',$htmlname='productid',$filtertype='',
$sql = "SELECT ";
$sql.= $selectFields . $selectFieldsGrouped;
//Price by customer
if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
$sql.=' ,pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,';
if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid))
{
$sql.=', pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,';
$sql.=' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx';
$selectFields.= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx";
}
Expand Down Expand Up @@ -2045,7 +2046,7 @@ function select_produits_list($selected='',$htmlname='productid',$filtertype='',

if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) && !empty($objp->price_by_qty) && $objp->price_by_qty == 1)
{ // Price by quantity will return many prices for the same product
$sql = "SELECT rowid, quantity, price, unitprice, remise_percent, remise";
$sql = "SELECT rowid, quantity, price, unitprice, remise_percent, remise, price_base_type";
$sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty";
$sql.= " WHERE fk_product_price=".$objp->price_rowid;
$sql.= " ORDER BY quantity ASC";
Expand All @@ -2059,12 +2060,17 @@ function select_produits_list($selected='',$htmlname='productid',$filtertype='',
while ($nb_prices && $j < $nb_prices) {
$objp2 = $this->db->fetch_object($result2);

$objp->price_by_qty_rowid = $objp2->rowid;
$objp->price_by_qty_price_base_type = $objp2->price_base_type;
$objp->price_by_qty_quantity = $objp2->quantity;
$objp->price_by_qty_unitprice = $objp2->unitprice;
$objp->price_by_qty_remise_percent = $objp2->remise_percent;
// For backward compatibility
$objp->quantity = $objp2->quantity;
$objp->price = $objp2->price;
$objp->unitprice = $objp2->unitprice;
$objp->remise_percent = $objp2->remise_percent;
$objp->remise = $objp2->remise;
$objp->price_by_qty_rowid = $objp2->rowid;

$this->constructProductListOption($objp, $opt, $optJson, 0, $selected, $hidepriceinlabel);

Expand Down Expand Up @@ -2164,7 +2170,10 @@ private function constructProductListOption(&$objp, &$opt, &$optJson, $price_lev

$opt = '<option value="'.$objp->rowid.'"';
$opt.= ($objp->rowid == $selected)?' selected':'';
$opt.= (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0)?' pbq="'.$objp->price_by_qty_rowid.'"':'';
if (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0)
{
$opt.= ' pbq="'.$objp->price_by_qty_rowid.'" data-pbq="'.$objp->price_by_qty_rowid.'" data-pbqqty="'.$objp->price_by_qty_quantity.'" data-pbqpercent="'.$objp->price_by_qty_remise_percent.'"';
}
if (! empty($conf->stock->enabled) && $objp->fk_product_type == 0 && isset($objp->stock))
{
if ($objp->stock > 0) $opt.= ' class="product_line_stock_ok"';
Expand Down
27 changes: 25 additions & 2 deletions htdocs/core/tpl/objectline_create.tpl.php
Expand Up @@ -56,7 +56,7 @@

// Define colspan for button Add
$colspan = 3; // Col total ht + col edit + col delete
if (in_array($object->element,array('propal', 'supplier_proposal','facture','facturerec','invoice','commande','order','order_supplier','invoice_supplier'))) $colspan++; // With this, there is a column move button
if (in_array($object->element,array('propal','commande','order','facture','facturerec','invoice','supplier_proposal','order_supplier','invoice_supplier'))) $colspan++; // With this, there is a column move button
//print $object->element;
?>

Expand Down Expand Up @@ -208,7 +208,7 @@

if (empty($senderissupplier))
{
if ($conf->global->ENTREPOT_EXTRA_STATUS)
if (! empty($conf->global->ENTREPOT_EXTRA_STATUS))
{
// hide products in closed warehouse, but show products for internal transfer
$form->select_produits(GETPOST('idprod'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, 1, 2, '', 1, array(),$buyer->id, '1', 0, '', 0, 'warehouseopen,warehouseinternal', GETPOST('combinations', 'array'));
Expand Down Expand Up @@ -238,6 +238,7 @@

$form->select_produits_fournisseurs($object->socid, GETPOST('idprodfournprice'), 'idprodfournprice', '', '', $ajaxoptions, 1, $alsoproductwithnosupplierprice);
}
echo '<input type="hidden" name="pbq" id="pbq" value="">';
echo '</span>';
}

Expand Down Expand Up @@ -709,6 +710,28 @@ function checkFreeLine(e, npRate)
}
?>

/* To process customer price per quantity */
var pbq = $('option:selected', this).attr('data-pbq');
var pbqqty = $('option:selected', this).attr('data-pbqqty');
var pbqpercent = $('option:selected', this).attr('data-pbqpercent');
if (jQuery('#idprod').val() > 0 && typeof pbq !== "undefined")
{
console.log("We choose a price by quanty price_by_qty id = "+pbq+" price_by_qty qty = "+pbqqty+" price_by_qty percent = "+pbqpercent);
jQuery("#pbq").val(pbq);
if (jQuery("#qty").val() < pbqqty)
{
jQuery("#qty").val(pbqqty);
}
if (jQuery("#remise_percent").val() < pbqpercent)
{
jQuery("#remise_percent").val(pbqpercent);
}
}
else
{
jQuery("#pbq").val('');
}

/* To set focus */
if (jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val() > 0)
{
Expand Down
16 changes: 16 additions & 0 deletions htdocs/install/mysql/migration/6.0.0-7.0.0.sql
Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions htdocs/install/mysql/tables/llx_product_price_by_qty.sql
Expand Up @@ -17,19 +17,29 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- 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
(
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;
1 change: 1 addition & 0 deletions htdocs/langs/en_US/products.lang
Expand Up @@ -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
Expand Down
13 changes: 5 additions & 8 deletions htdocs/product/admin/product.php
Expand Up @@ -36,8 +36,7 @@
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)))
Expand All @@ -55,12 +54,10 @@
'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)) {
Expand Down
30 changes: 17 additions & 13 deletions htdocs/product/class/product.class.php
Expand Up @@ -1483,12 +1483,14 @@ function _log_price($user,$level=0)
* @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)
{
Expand All @@ -1499,7 +1501,6 @@ function log_price_delete($user,$rowid)
$this->error=$this->db->lasterror();
return -1;
}

}


Expand Down Expand Up @@ -1642,13 +1643,13 @@ function get_buyprice($prodfournprice, $qty, $product_id=0, $fourn_ref='', $fk_s
* @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;

Expand All @@ -1667,7 +1668,7 @@ function updatePrice($newprice, $newpricebase, $user, $newvat='',$newminprice=''
// 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))
Expand Down Expand Up @@ -1781,7 +1782,7 @@ function updatePrice($newprice, $newpricebase, $user, $newvat='',$newminprice=''
$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

Expand Down Expand Up @@ -1994,7 +1995,7 @@ function fetch($id='', $ref='', $ref_ext='', $ignore_expression=0)
// Récuperation de la liste des prix selon qty si flag positionné
if ($this->prices_by_qty[$i] == 1)
{
$sql = "SELECT rowid, price, unitprice, quantity, remise_percent, remise";
$sql = "SELECT rowid, price, unitprice, quantity, remise_percent, remise, price_base_type";
$sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty";
$sql.= " WHERE fk_product_price = ".$this->prices_by_qty_id[$i];
$sql.= " ORDER BY quantity ASC";
Expand All @@ -2010,7 +2011,8 @@ function fetch($id='', $ref='', $ref_ext='', $ignore_expression=0)
$resultat[$ii]["unitprice"]= $result["unitprice"];
$resultat[$ii]["quantity"]= $result["quantity"];
$resultat[$ii]["remise_percent"]= $result["remise_percent"];
$resultat[$ii]["remise"]= $result["remise"];
$resultat[$ii]["remise"]= $result["remise"]; // deprecated
$resultat[$ii]["price_base_type"]= $result["price_base_type"];
$ii++;
}
$this->prices_by_qty_list[$i]=$resultat;
Expand All @@ -2028,7 +2030,8 @@ function fetch($id='', $ref='', $ref_ext='', $ignore_expression=0)
return -1;
}
}
} else if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
}
else if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
{
$sql = "SELECT price, price_ttc, price_min, price_min_ttc,";
$sql.= " price_base_type, tva_tx, default_vat_code, tosell, price_by_qty, rowid";
Expand All @@ -2047,7 +2050,7 @@ function fetch($id='', $ref='', $ref_ext='', $ignore_expression=0)
// Récuperation de la liste des prix selon qty si flag positionné
if ($this->prices_by_qty[0] == 1)
{
$sql = "SELECT rowid,price, unitprice, quantity, remise_percent, remise";
$sql = "SELECT rowid,price, unitprice, quantity, remise_percent, remise, remise, price_base_type";
$sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty";
$sql.= " WHERE fk_product_price = ".$this->prices_by_qty_id[0];
$sql.= " ORDER BY quantity ASC";
Expand All @@ -2063,7 +2066,8 @@ function fetch($id='', $ref='', $ref_ext='', $ignore_expression=0)
$resultat[$ii]["unitprice"]= $result["unitprice"];
$resultat[$ii]["quantity"]= $result["quantity"];
$resultat[$ii]["remise_percent"]= $result["remise_percent"];
$resultat[$ii]["remise"]= $result["remise"];
$resultat[$ii]["remise"]= $result["remise"]; // deprecated
$resultat[$ii]["price_base_type"]= $result["price_base_type"];
$ii++;
}
$this->prices_by_qty_list[0]=$resultat;
Expand Down

0 comments on commit 2b056b0

Please sign in to comment.