Task 559 : add use of price by qty in product selection (select and ajax search)

This commit is contained in:
Maxime Kohlhaas 2012-10-26 01:00:03 +02:00
parent 84df6bd639
commit 0f1617c31d
4 changed files with 272 additions and 146 deletions

View File

@ -1148,6 +1148,18 @@ class Form
{
$sql.= ", pl.label as label_translated";
}
// Price by quantity
if (! empty($conf->global->PRODUIT_PRICE_BY_QTY))
{
$sql.= ", (SELECT pp.rowid FROM ".MAIN_DB_PREFIX."product_price as pp WHERE pp.fk_product = p.rowid";
if ($price_level >= 1) $sql.= " AND price_level=".$price_level;
$sql.= " ORDER BY date_price";
$sql.= " DESC LIMIT 1) as price_rowid";
$sql.= ", (SELECT pp.price_by_qty FROM ".MAIN_DB_PREFIX."product_price as pp WHERE pp.fk_product = p.rowid";
if ($price_level >= 1) $sql.= " AND price_level=".$price_level;
$sql.= " ORDER BY date_price";
$sql.= " DESC LIMIT 1) as price_by_qty";
}
$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
// Multilang : we add translation
if (! empty($conf->global->MAIN_MULTILANGS))
@ -1209,143 +1221,50 @@ class Form
$i = 0;
while ($num && $i < $num)
{
$outkey='';
$outval='';
$outref='';
$outlabel='';
$outdesc='';
$outtype='';
$outprice_ht='';
$outprice_ttc='';
$outpricebasetype='';
$outtva_tx='';
$objp = $this->db->fetch_object($result);
$label=$objp->label;
if (! empty($objp->label_translated)) $label=$objp->label_translated;
if ($filterkey && $filterkey != '') $label=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$label,1);
$outkey=$objp->rowid;
$outref=$objp->ref;
$outlabel=$objp->label;
$outdesc=$objp->description;
$outtype=$objp->fk_product_type;
$opt = '<option value="'.$objp->rowid.'"';
$opt.= ($objp->rowid == $selected)?' selected="selected"':'';
if (! empty($conf->stock->enabled) && $objp->fk_product_type == 0 && isset($objp->stock))
{
if ($objp->stock > 0)
{
$opt.= ' style="background-color:#32CD32; color:#F5F5F5;"';
}
else if ($objp->stock <= 0)
{
$opt.= ' style="background-color:#FF0000; color:#F5F5F5;"';
}
}
$opt.= '>';
$opt.= $objp->ref.' - '.dol_trunc($label,32).' - ';
$objRef = $objp->ref;
if ($filterkey && $filterkey != '') $objRef=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRef,1);
$outval.=$objRef.' - '.dol_trunc($label,32).' - ';
$found=0;
$currencytext=$langs->trans("Currency".$conf->currency);
$currencytextnoent=$langs->transnoentities("Currency".$conf->currency);
if (dol_strlen($currencytext) > 10) $currencytext=$conf->currency; // If text is too long, we use the short code
if (dol_strlen($currencytextnoent) > 10) $currencytextnoent=$conf->currency; // If text is too long, we use the short code
// Multiprice
if ($price_level >= 1) // If we need a particular price level (from 1 to 6)
{
$sql = "SELECT price, price_ttc, price_base_type, tva_tx";
$sql.= " FROM ".MAIN_DB_PREFIX."product_price";
$sql.= " WHERE fk_product='".$objp->rowid."'";
$sql.= " AND price_level=".$price_level;
$sql.= " ORDER BY date_price";
$sql.= " DESC LIMIT 1";
dol_syslog(get_class($this)."::select_produits_do search price for level '.$price_level.' sql=".$sql);
$result2 = $this->db->query($sql);
if ($result2)
{
$objp2 = $this->db->fetch_object($result2);
if ($objp2)
{
$found=1;
if ($objp2->price_base_type == 'HT')
{
$opt.= price($objp2->price,1).' '.$currencytext.' '.$langs->trans("HT");
$outval.= price($objp2->price,1).' '.$currencytextnoent.' '.$langs->transnoentities("HT");
}
else
{
$opt.= price($objp2->price_ttc,1).' '.$currencytext.' '.$langs->trans("TTC");
$outval.= price($objp2->price_ttc,1).' '.$currencytextnoent.' '.$langs->transnoentities("TTC");
}
$outprice_ht=price($objp2->price);
$outprice_ttc=price($objp2->price_ttc);
$outpricebasetype=$objp2->price_base_type;
$outtva_tx=$objp2->tva_tx;
}
}
else
{
dol_print_error($this->db);
}
}
// If level no defined or multiprice not found, we used the default price
if (! $found)
{
if ($objp->price_base_type == 'HT')
{
$opt.= price($objp->price,1).' '.$currencytext.' '.$langs->trans("HT");
$outval.= price($objp->price,1).' '.$currencytextnoent.' '.$langs->transnoentities("HT");
}
else
{
$opt.= price($objp->price_ttc,1).' '.$currencytext.' '.$langs->trans("TTC");
$outval.= price($objp->price_ttc,1).' '.$currencytextnoent.' '.$langs->transnoentities("TTC");
}
$outprice_ht=price($objp->price);
$outprice_ttc=price($objp->price_ttc);
$outpricebasetype=$objp->price_base_type;
$outtva_tx=$objp->tva_tx;
}
if (! empty($conf->stock->enabled) && isset($objp->stock) && $objp->fk_product_type == 0)
{
$opt.= ' - '.$langs->trans("Stock").':'.$objp->stock;
$outval.=' - '.$langs->transnoentities("Stock").':'.$objp->stock;
}
if ($objp->duration)
{
$duration_value = substr($objp->duration,0,dol_strlen($objp->duration)-1);
$duration_unit = substr($objp->duration,-1);
if ($duration_value > 1)
{
$dur=array("h"=>$langs->trans("Hours"),"d"=>$langs->trans("Days"),"w"=>$langs->trans("Weeks"),"m"=>$langs->trans("Months"),"y"=>$langs->trans("Years"));
}
else
{
$dur=array("h"=>$langs->trans("Hour"),"d"=>$langs->trans("Day"),"w"=>$langs->trans("Week"),"m"=>$langs->trans("Month"),"y"=>$langs->trans("Year"));
}
$opt.= ' - '.$duration_value.' '.$langs->trans($dur[$duration_unit]);
$outval.=' - '.$duration_value.' '.$langs->transnoentities($dur[$duration_unit]);
}
$opt.= "</option>\n";
// Add new entry
// "key" value of json key array is used by jQuery automatically as selected value
// "label" value of json key array is used by jQuery automatically as text for combo box
$outselect.=$opt;
array_push($outjson, array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>$outprice_ht, 'price_ttc'=>$outprice_ttc, 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx));
$opt = '';
$optJson = array();
$objp = $this->db->fetch_object($result);
if(!empty($objp->price_by_qty) && $objp->price_by_qty == 1) { // Price by quantity will return many prices for the same product
$sql = "SELECT rowid, qty_min, price, price_ttc, remise_percent, remise";
$sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty";
$sql.= " WHERE fk_product_price=".$objp->price_rowid;
dol_syslog(get_class($this)."::select_produits_do search price by qty sql=".$sql);
$result2 = $this->db->query($sql);
if ($result2)
{
$nb_prices = $this->db->num_rows($result2);
$j = 0;
while ($nb_prices && $j < $nb_prices) {
$objp2 = $this->db->fetch_object($result2);
$objp->quantity = $objp2->qty_min;
$objp->price = $objp2->price;
$objp->unitprice = $objp2->price;
$objp->remise_percent = $objp2->remise_percent;
$objp->remise = $objp2->remise;
$objp->price_by_qty_rowid = $objp2->rowid;
$this->_construct_product_list_option($objp, $opt, $optJson, 0, $selected);
$j++;
// Add new entry
// "key" value of json key array is used by jQuery automatically as selected value
// "label" value of json key array is used by jQuery automatically as text for combo box
$outselect.=$opt;
array_push($outjson, $optJson);
}
}
} else {
$this->_construct_product_list_option($objp, $opt, $optJson, $price_level, $selected);
// Add new entry
// "key" value of json key array is used by jQuery automatically as selected value
// "label" value of json key array is used by jQuery automatically as text for combo box
$outselect.=$opt;
array_push($outjson, $optJson);
}
$i++;
}
@ -1363,6 +1282,180 @@ class Form
}
}
function _construct_product_list_option(&$objp, &$opt, &$optJson, $price_level, $selected) {
global $langs,$conf,$user,$db;
$outkey='';
$outval='';
$outref='';
$outlabel='';
$outdesc='';
$outtype='';
$outprice_ht='';
$outprice_ttc='';
$outpricebasetype='';
$outtva_tx='';
$outqty=1;
$outdiscount=0;
$label=$objp->label;
if (! empty($objp->label_translated)) $label=$objp->label_translated;
if ($filterkey && $filterkey != '') $label=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$label,1);
$outkey=$objp->rowid;
$outref=$objp->ref;
$outlabel=$objp->label;
$outdesc=$objp->description;
$outtype=$objp->fk_product_type;
$opt = '<option value="'.$objp->rowid.'"';
$opt.= ($objp->rowid == $selected)?' selected="selected"':'';
$opt.= (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0)?' pbq="'.$objp->price_by_qty_rowid.'"':'';
if (! empty($conf->stock->enabled) && $objp->fk_product_type == 0 && isset($objp->stock))
{
if ($objp->stock > 0)
{
$opt.= ' style="background-color:#32CD32; color:#F5F5F5;"';
}
else if ($objp->stock <= 0)
{
$opt.= ' style="background-color:#FF0000; color:#F5F5F5;"';
}
}
$opt.= '>';
$opt.= $objp->ref.' - '.dol_trunc($label,32).' - ';
$objRef = $objp->ref;
if ($filterkey && $filterkey != '') $objRef=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRef,1);
$outval.=$objRef.' - '.dol_trunc($label,32).' - ';
$found=0;
$currencytext=$langs->trans("Currency".$conf->currency);
$currencytextnoent=$langs->transnoentities("Currency".$conf->currency);
if (dol_strlen($currencytext) > 10) $currencytext=$conf->currency; // If text is too long, we use the short code
if (dol_strlen($currencytextnoent) > 10) $currencytextnoent=$conf->currency; // If text is too long, we use the short code
// Multiprice
if ($price_level >= 1) // If we need a particular price level (from 1 to 6)
{
$sql = "SELECT price, price_ttc, price_base_type, tva_tx";
$sql.= " FROM ".MAIN_DB_PREFIX."product_price";
$sql.= " WHERE fk_product='".$objp->rowid."'";
$sql.= " AND price_level=".$price_level;
$sql.= " ORDER BY date_price";
$sql.= " DESC LIMIT 1";
dol_syslog(get_class($this)."::select_produits_do search price for level '.$price_level.' sql=".$sql);
$result2 = $this->db->query($sql);
if ($result2)
{
$objp2 = $this->db->fetch_object($result2);
if ($objp2)
{
$found=1;
if ($objp2->price_base_type == 'HT')
{
$opt.= price($objp2->price,1).' '.$currencytext.' '.$langs->trans("HT");
$outval.= price($objp2->price,1).' '.$currencytextnoent.' '.$langs->transnoentities("HT");
}
else
{
$opt.= price($objp2->price_ttc,1).' '.$currencytext.' '.$langs->trans("TTC");
$outval.= price($objp2->price_ttc,1).' '.$currencytextnoent.' '.$langs->transnoentities("TTC");
}
$outprice_ht=price($objp2->price);
$outprice_ttc=price($objp2->price_ttc);
$outpricebasetype=$objp2->price_base_type;
$outtva_tx=$objp2->tva_tx;
}
}
else
{
dol_print_error($this->db);
}
}
// Price by quantity
if (!empty($objp->quantity) && $objp->quantity >= 1) {
$found = 1;
$outqty=$objp->quantity;
$outdiscount=$objp->remise_percent;
if ($objp->quantity == 1)
{
$opt.= price($objp->price).' '.$currencytext."/";
$outval.= price($objp->price).' '.$currencytextnoent."/";
$opt.= $langs->trans("Unit"); // Do not use strtolower because it breaks utf8 encoding
$outval.=$langs->transnoentities("Unit");
}
else
{
$opt.= price($objp->price).' '.$currencytext."/".$objp->quantity;
$outval.= price($objp->price).' '.$currencytextnoent."/".$objp->quantity;
$opt.= $langs->trans("Units"); // Do not use strtolower because it breaks utf8 encoding
$outval.=$langs->transnoentities("Units");
}
$outprice_ht=price($objp->price);
$outprice_ttc=price($objp->price_ttc);
$outpricebasetype=$objp->price_base_type;
$outtva_tx=$objp->tva_tx;
}
if (!empty($objp->quantity) && $objp->quantity >= 1)
{
$opt.=" (".price($objp->unitprice).' '.$currencytext."/".$langs->trans("Unit").")"; // Do not use strtolower because it breaks utf8 encoding
$outval.=" (".price($objp->unitprice).' '.$currencytextnoent."/".$langs->transnoentities("Unit").")"; // Do not use strtolower because it breaks utf8 encoding
}
if (!empty($objp->remise_percent) && $objp->remise_percent >= 1)
{
$opt.=" - ".$langs->trans("Discount")." : ".vatrate($objp->remise_percent).' %';
$outval.=" - ".$langs->transnoentities("Discount")." : ".vatrate($objp->remise_percent).' %';
}
// If level no defined or multiprice not found, we used the default price
if (! $found)
{
if ($objp->price_base_type == 'HT')
{
$opt.= price($objp->price,1).' '.$currencytext.' '.$langs->trans("HT");
$outval.= price($objp->price,1).' '.$currencytextnoent.' '.$langs->transnoentities("HT");
}
else
{
$opt.= price($objp->price_ttc,1).' '.$currencytext.' '.$langs->trans("TTC");
$outval.= price($objp->price_ttc,1).' '.$currencytextnoent.' '.$langs->transnoentities("TTC");
}
$outprice_ht=price($objp->price);
$outprice_ttc=price($objp->price_ttc);
$outpricebasetype=$objp->price_base_type;
$outtva_tx=$objp->tva_tx;
}
if (! empty($conf->stock->enabled) && isset($objp->stock) && $objp->fk_product_type == 0)
{
$opt.= ' - '.$langs->trans("Stock").':'.$objp->stock;
$outval.=' - '.$langs->transnoentities("Stock").':'.$objp->stock;
}
if ($objp->duration)
{
$duration_value = substr($objp->duration,0,dol_strlen($objp->duration)-1);
$duration_unit = substr($objp->duration,-1);
if ($duration_value > 1)
{
$dur=array("h"=>$langs->trans("Hours"),"d"=>$langs->trans("Days"),"w"=>$langs->trans("Weeks"),"m"=>$langs->trans("Months"),"y"=>$langs->trans("Years"));
}
else
{
$dur=array("h"=>$langs->trans("Hour"),"d"=>$langs->trans("Day"),"w"=>$langs->trans("Week"),"m"=>$langs->trans("Month"),"y"=>$langs->trans("Year"));
}
$opt.= ' - '.$duration_value.' '.$langs->trans($dur[$duration_unit]);
$outval.=' - '.$duration_value.' '.$langs->transnoentities($dur[$duration_unit]);
}
$opt.= "</option>\n";
$optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>$outprice_ht, 'price_ttc'=>$outprice_ttc, 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount);
}
/**
* Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_do)
*

View File

@ -79,7 +79,9 @@ if (! empty($conf->margin->enabled)) {
'price_ht' => 'price_ht',
'origin_price_ht_cache' => 'price_ht',
'origin_tva_tx_cache' => 'tva_tx',
'origin_price_ttc_cache' => 'price_ttc'
'origin_price_ttc_cache' => 'price_ttc',
'qty' => 'qty',
'remise_percent' => 'discount'
),
'update_textarea' => array(
'product_desc' => 'desc'
@ -158,7 +160,7 @@ if (! empty($conf->margin->enabled)) {
<input type="hidden" id="origin_price_ttc_cache" name="origin_price_ttc_cache" value="" />
</td>
<td align="right"><input type="text" size="3" id="qty" name="qty" value="<?php echo (GETPOST('qty')?GETPOST('qty'):1); ?>"></td>
<td align="right" nowrap="nowrap"><input type="text" size="1" value="<?php echo $buyer->remise_client; ?>" name="remise_percent">%</td>
<td align="right" nowrap="nowrap"><input type="text" size="1" value="<?php echo $buyer->remise_client; ?>" id="remise_percent" name="remise_percent">%</td>
<?php
$colspan = 4;
if (! empty($conf->margin->enabled)) {
@ -225,7 +227,9 @@ $(document).ready(function() {
$.post('<?php echo DOL_URL_ROOT; ?>/product/ajax/products.php', {
'action': 'fetch',
'id': $(this).val(),
'price_level': <?php echo empty($buyer->price_level)?1:$buyer->price_level; ?>},
'price_level': <?php echo empty($buyer->price_level)?1:$buyer->price_level; ?>,
'pbq': $("option:selected", this).attr('pbq')
},
function(data) {
if (typeof data != 'undefined') {
$('#product_ref').val(data.ref);
@ -237,6 +241,8 @@ $(document).ready(function() {
$('#origin_tva_tx_cache').val(data.tva_tx);
$('#select_type').val(data.type).attr('disabled','disabled').trigger('change');
//$('#price_base_type_area').show();
$('#qty').val(data.qty);
$('#remise_percent').val(data.discount);
if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances['product_desc'] != "undefined") {
CKEDITOR.instances['product_desc'].setData(data.desc).focus();

View File

@ -38,9 +38,10 @@ $type=GETPOST('type','int');
$mode=GETPOST('mode','int');
$status=((GETPOST('status','int') >= 0) ? GETPOST('status','int') : -1);
$outjson=(GETPOST('outjson','int') ? GETPOST('outjson','int') : 0);
$pricelevel=GETPOST('price_level','int');
$price_level=GETPOST('price_level','int');
$action=GETPOST('action', 'alpha');
$id=GETPOST('id', 'int');
$price_by_qty_rowid=GETPOST('pbq', 'int');
/*
* View
@ -65,11 +66,37 @@ if (! empty($action) && $action == 'fetch' && ! empty($id))
$outlabel=$object->label;
$outdesc=$object->description;
$outtype=$object->type;
$outqty=1;
$outdiscount=0;
$found=false;
// Price by qty
if (!empty($price_by_qty_rowid) && $price_by_qty_rowid >= 1) // If we need a particular price related to qty
{
$sql = "SELECT price, price_ttc, qty_min, remise_percent";
$sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty ";
$sql.= " WHERE rowid=".$price_by_qty_rowid."";
$result = $db->query($sql);
if ($result)
{
$objp = $db->fetch_object($result);
if ($objp)
{
$found=true;
$outprice_ht=price($objp->price);
$outprice_ttc=price($objp->price_ttc);
$outpricebasetype=$object->price_base_type;
$outtva_tx=$object->tva_tx;
$outqty=$objp->qty_min;
$outdiscount=$objp->remise_percent;
}
}
}
// Multiprice
if (isset($price_level) && $price_level >= 1) // If we need a particular price level (from 1 to 6)
if (! $found && isset($price_level) && $price_level >= 1) // If we need a particular price level (from 1 to 6)
{
$sql = "SELECT price, price_ttc, price_base_type, tva_tx";
$sql.= " FROM ".MAIN_DB_PREFIX."product_price ";
@ -78,10 +105,10 @@ if (! empty($action) && $action == 'fetch' && ! empty($id))
$sql.= " ORDER BY date_price";
$sql.= " DESC LIMIT 1";
$result = $this->db->query($sql);
$result = $db->query($sql);
if ($result)
{
$objp = $this->db->fetch_object($result);
$objp = $db->fetch_object($result);
if ($objp)
{
$found=true;
@ -101,7 +128,7 @@ if (! empty($action) && $action == 'fetch' && ! empty($id))
$outtva_tx=$object->tva_tx;
}
$outjson = array('ref'=>$outref, 'label'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>$outprice_ht, 'price_ttc'=>$outprice_ttc, 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx);
$outjson = array('ref'=>$outref, 'label'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>$outprice_ht, 'price_ttc'=>$outprice_ttc, 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount);
}
echo json_encode($outjson);

View File

@ -366,7 +366,7 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES))
print '<td><input size="5" type="text" value="'.$prices['qty_min'].'" name="qty_min"></td>';
print '<td align="right" colspan="2"><input size="10" type="text" value="'.$prices['price'].'" name="price">&nbsp;'.$object->price_base_type.'</td>';
//print '<td align="right">&nbsp;</td>';
print '<td align="right"><input size="5" type="text" value="'.$prices['remise_percent'].'" name="remise_percent"><&nbsp;%/td>';
print '<td align="right"><input size="5" type="text" value="'.$prices['remise_percent'].'" name="remise_percent">&nbsp;%</td>';
print '<td align="center"><input type="submit" value="'.$langs->trans("Modify").'" class="button"></td>';
print '</tr>';
print '</form>';