// #PSFV-94 : Add possibility to add product in a supplier order
This commit is contained in:
@@ -50,6 +50,7 @@ $query->select('
|
||||
CONCAT(p.id_product, \'_\', IFNULL(pa.id_product_attribute, \'0\')) as id,
|
||||
p.reference,
|
||||
p.ean13,
|
||||
md5(CONCAT(\''._COOKIE_KEY_.'\', p.id_product, \'_\', IFNULL(pa.id_product_attribute, \'0\'))) as checksum,
|
||||
IFNULL(CONCAT(pl.name, \' : \', GROUP_CONCAT(agl.name, \' - \', al.name SEPARATOR \', \')), pl.name) as name
|
||||
');
|
||||
$query->from('product p');
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
{if isset($show_product_management_form)}
|
||||
<p> </p>
|
||||
|
||||
<input type="hidden" id="product_ids" name="product_ids" value=""/>
|
||||
<input type="hidden" id="product_ids" name="product_ids" value="{$product_ids}" />
|
||||
<input type="hidden" name="updatesupplier_order" value="1" />
|
||||
|
||||
<fieldset>
|
||||
<legend>
|
||||
@@ -48,7 +49,7 @@
|
||||
<td>
|
||||
<table
|
||||
id="products_in_supplier_order"
|
||||
class="table {if $table_dnd}tableDnD{/if}"
|
||||
class="table"
|
||||
cellpadding="0" cellspacing="0"
|
||||
style="width: 100%; margin-bottom:10px;"
|
||||
>
|
||||
@@ -69,27 +70,32 @@
|
||||
<tr style="height:50px;">
|
||||
<td>
|
||||
{$product.reference}
|
||||
<input type="hidden" name="input_check_{$product.id_product}_{$product.id_product_attribute}" value="{$product.checksum}" />
|
||||
<input type="hidden" name="input_reference_{$product.id_product}_{$product.id_product_attribute}" value="{$product.reference}" />
|
||||
<input type="hidden" name="input_id_{$product.id_product}_{$product.id_product_attribute}" value="{$product.id_supplier_order_detail}" />
|
||||
</td>
|
||||
<td>
|
||||
{$product.ean13}
|
||||
<input type="hidden" name="input_ean13_{$product.id_product}_{$product.id_product_attribute}" value="{$product.ean13}" />
|
||||
</td>
|
||||
<td>
|
||||
{$product.name}
|
||||
<input type="hidden" name="input_name_{$product.id_product}_{$product.id_product_attribute}" value="{$product.name}" />
|
||||
</td>
|
||||
<td class="center">
|
||||
<input type="text" name="input_unit_price_te|{$product.$id_product}_{$product.$id_product_attribute}" value="{$product.unit_price_te|escape:'htmlall':'UTF-8'}" />
|
||||
<input type="text" name="input_unit_price_te_{$product.id_product}_{$product.id_product_attribute}" value="{$product.unit_price_te|escape:'htmlall':'UTF-8'}" size="8" />
|
||||
</td>
|
||||
<td class="center">
|
||||
<input type="text" name="input_quantity|{$product.$id_product}_{$product.$id_product_attribute}" value="{$product.quantity|escape:'htmlall':'UTF-8'}" />
|
||||
<input type="text" name="input_quantity_{$product.id_product}_{$product.id_product_attribute}" value="{$product.quantity|escape:'htmlall':'UTF-8'}" size="5" />
|
||||
</td>
|
||||
<td class="center">
|
||||
<input type="text" name="input_discount_rate|{$product.$id_product}_{$product.$id_product_attribute}" value="{$product.discount_rate|escape:'htmlall':'UTF-8'}" />
|
||||
<input type="text" name="input_discount_rate_{$product.id_product}_{$product.id_product_attribute}" value="{$product.discount_rate|escape:'htmlall':'UTF-8'}" size="5" />
|
||||
</td>
|
||||
<td class="center">
|
||||
<input type="text" name="input_tax_rate|{$product.$id_product}_{$product.$id_product_attribute}" value="{$product.tax_rate|escape:'htmlall':'UTF-8'}" />
|
||||
<input type="text" name="input_tax_rate_{$product.id_product}_{$product.id_product_attribute}" value="{$product.tax_rate|escape:'htmlall':'UTF-8'}" size="5" />
|
||||
</td>
|
||||
<td class="center">
|
||||
<a href="#" id="deletelink|{$product.$id_product}_{$product.$id_product_attribute}" class="removeProductFromSupplierOrderLink">
|
||||
<a href="#" id="deletelink_{$product.id_product}_{$product.id_product_attribute}" class="removeProductFromSupplierOrderLink">
|
||||
<img src="../img/admin/delete.gif" alt="{l s='Remove this product from the order'}" title="{l s='Remove this product from the order'}" />
|
||||
</a>
|
||||
</td>
|
||||
@@ -123,14 +129,14 @@
|
||||
// add a new line in the products table
|
||||
$('#products_in_supplier_order > tbody:last').append(
|
||||
'<tr style="height:50px;">'+
|
||||
'<td>'+product_infos.reference+'</td>'+
|
||||
'<td>'+product_infos.ean13+'</td>'+
|
||||
'<td>'+product_infos.name+'</td>'+
|
||||
'<td class="center"><input type="text" name="input_unit_price_te|'+product_infos.id+'" value="" size="8" /></td>'+
|
||||
'<td class="center"><input type="text" name="input_quantity|'+product_infos.id+'" value="" size="5" /></td>'+
|
||||
'<td class="center"><input type="text" name="input_discount_rate|'+product_infos.id+'" value="" size="5" /></td>'+
|
||||
'<td class="center"><input type="text" name="input_tax_rate|'+product_infos.id+'" value="" size="5" /></td>'+
|
||||
'<td class="center"><a href="#" class="removeProductFromSupplierOrderLink" id="deletelink|'+product_infos.id+'">'+
|
||||
'<td>'+product_infos.reference+'<input type="hidden" name="input_check_'+product_infos.id+'" value="'+product_infos.checksum+'" /><input type="hidden" name="input_name_'+product_infos.id+'" value="'+product_infos.reference+'" /></td>'+
|
||||
'<td>'+product_infos.ean13+'<input type="hidden" name="input_ean13_'+product_infos.id+'" value="'+product_infos.ean13+'" /></td>'+
|
||||
'<td>'+product_infos.name+'<input type="hidden" name="input_name_'+product_infos.id+'" value="'+product_infos.name+'" /></td>'+
|
||||
'<td class="center"><input type="text" name="input_unit_price_te_'+product_infos.id+'" value="0" size="8" /></td>'+
|
||||
'<td class="center"><input type="text" name="input_quantity_'+product_infos.id+'" value="0" size="5" /></td>'+
|
||||
'<td class="center"><input type="text" name="input_discount_rate_'+product_infos.id+'" value="0" size="5" /></td>'+
|
||||
'<td class="center"><input type="text" name="input_tax_rate_'+product_infos.id+'" value="0" size="5" /></td>'+
|
||||
'<td class="center"><a href="#" class="removeProductFromSupplierOrderLink" id="deletelink_'+product_infos.id+'">'+
|
||||
'<img src="../img/admin/delete.gif" alt="{l s="Remove this product from the order"}" title="{l s="Remove this product from the order"}" />'+
|
||||
'</a></td></tr>'
|
||||
);
|
||||
@@ -151,7 +157,7 @@
|
||||
/* function autocomplete */
|
||||
$(function() {
|
||||
// add click event on just created delete item link
|
||||
$('.removeProductFromSupplierOrderLink').live('click', function() {
|
||||
$('a.removeProductFromSupplierOrderLink').live('click', function() {
|
||||
var id = $(this).attr('id');
|
||||
var product_id = id.split('|')[1];
|
||||
|
||||
|
||||
+13
-13
@@ -269,7 +269,7 @@ class AdminControllerCore extends Controller
|
||||
|
||||
/**
|
||||
* set default toolbar_title to admin breadcrumb
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initToolbarTitle()
|
||||
@@ -356,12 +356,12 @@ class AdminControllerCore extends Controller
|
||||
|
||||
// Sub included tab postProcessing
|
||||
$this->includeSubTab('postProcess', array('status', 'submitAdd1', 'submitDel', 'delete', 'submitFilter', 'submitReset'));
|
||||
|
||||
|
||||
if (!empty($this->action) && method_exists($this, 'process'.ucfirst(Tools::toCamelCase($this->action))))
|
||||
$this->{'process'.Tools::toCamelCase($this->action)}($token);
|
||||
else if (method_exists($this, $this->action))
|
||||
call_user_func(array($this, $this->action), $this->boxes);
|
||||
|
||||
|
||||
/* Manage list filtering */
|
||||
if ($this->filter)
|
||||
{
|
||||
@@ -429,7 +429,7 @@ class AdminControllerCore extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Object Delete images
|
||||
*
|
||||
@@ -450,9 +450,9 @@ class AdminControllerCore extends Controller
|
||||
}
|
||||
$this->_errors[] = Tools::displayError('An error occurred during image deletion (cannot load object).');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Object Delete
|
||||
* Object Delete
|
||||
*
|
||||
* @param string $token
|
||||
*/
|
||||
@@ -492,7 +492,7 @@ class AdminControllerCore extends Controller
|
||||
Tools::displayError('(cannot load object)');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Object update and creation
|
||||
* TODO: split processAdd and processUpdate
|
||||
@@ -614,7 +614,7 @@ class AdminControllerCore extends Controller
|
||||
}
|
||||
$this->_errors = array_unique($this->_errors);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change object required fields
|
||||
*
|
||||
@@ -631,7 +631,7 @@ class AdminControllerCore extends Controller
|
||||
else
|
||||
Tools::redirectAdmin(self::$currentIndex.'&conf=4&token='.$token);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change object statuts (active, inactive)
|
||||
*
|
||||
@@ -654,7 +654,7 @@ class AdminControllerCore extends Controller
|
||||
' <b>'.$this->table.'</b> '.
|
||||
Tools::displayError('(cannot load object)');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change object position
|
||||
*
|
||||
@@ -676,7 +676,7 @@ class AdminControllerCore extends Controller
|
||||
Tools::redirectAdmin($redirect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cancel all filters for this tab
|
||||
*
|
||||
@@ -710,7 +710,7 @@ class AdminControllerCore extends Controller
|
||||
unset($_POST);
|
||||
$this->filter = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update options and preferences
|
||||
*
|
||||
@@ -2280,7 +2280,7 @@ EOF;
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Overload this method for custom checking
|
||||
|
||||
@@ -246,13 +246,52 @@ class SupplierOrderCore extends ObjectModel
|
||||
$this->discount_value_te = $this->total_te - $this->total_with_discount_te;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the product entries for the current order
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getEntries($id_lang = null)
|
||||
{
|
||||
if ($id_lang == null)
|
||||
$id_lang = Context::getContext()->language->id;
|
||||
|
||||
// build query
|
||||
$query = new DbQuery();
|
||||
|
||||
$query->select('
|
||||
s.*,
|
||||
IFNULL(CONCAT(pl.name, \' : \', GROUP_CONCAT(agl.name, \' - \', al.name SEPARATOR \', \')), pl.name) as name,
|
||||
p.reference as reference,
|
||||
p.ean13 as ean13');
|
||||
|
||||
$query->from('supplier_order_detail s');
|
||||
|
||||
$query->innerjoin('product_lang pl ON (pl.id_product = s.id_product AND pl.id_lang = '.$id_lang.')');
|
||||
|
||||
$query->leftjoin('product p ON p.id_product = s.id_product');
|
||||
$query->leftjoin('product_attribute_combination pac ON (pac.id_product_attribute = s.id_product_attribute)');
|
||||
$query->leftjoin('attribute atr ON (atr.id_attribute = pac.id_attribute)');
|
||||
$query->leftjoin('attribute_lang al ON (al.id_attribute = atr.id_attribute AND al.id_lang = '.$id_lang.')');
|
||||
$query->leftjoin('attribute_group_lang agl ON (agl.id_attribute_group = atr.id_attribute_group AND agl.id_lang = '.$id_lang.')');
|
||||
|
||||
$query->where('s.id_supplier_order = '.(int)$this->id);
|
||||
|
||||
$query->groupBy('s.id_supplier_order_detail');
|
||||
|
||||
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the product entries collection for the current order
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getEntriesCollection()
|
||||
public function getEntriesCollection($id_lang = null)
|
||||
{
|
||||
if ($id_lang == null)
|
||||
$id_lang = Context::getContext()->language->id;
|
||||
|
||||
// build query
|
||||
$query = new DbQuery();
|
||||
$query->select('s.*');
|
||||
|
||||
@@ -110,7 +110,7 @@ class SupplierOrderDetailCore extends ObjectModel
|
||||
* @var float This is like $price_with_discount_te, considering the global order discount.
|
||||
* (i.e. if SupplierOrder::discount_rate is set)
|
||||
*/
|
||||
public $price_with_order_discount_te;
|
||||
public $price_with_order_discount_te = 0;
|
||||
|
||||
protected $fieldsRequired = array(
|
||||
'id_supplier_order',
|
||||
@@ -167,13 +167,13 @@ class SupplierOrderDetailCore extends ObjectModel
|
||||
{
|
||||
$this->validateFields();
|
||||
|
||||
$fields['id_supplier_order'] = (int)$this->id_supplier;
|
||||
$fields['id_product'] = (int)$this->id_employee;
|
||||
$fields['id_product_attribute'] = (int)$this->id_warehouse;
|
||||
$fields['id_supplier_order'] = (int)$this->id_supplier_order;
|
||||
$fields['id_product'] = (int)$this->id_product;
|
||||
$fields['id_product_attribute'] = (int)$this->id_product_attribute;
|
||||
$fields['id_currency'] = (int)$this->id_currency;
|
||||
$fields['exchange_rate'] = (float)$this->exchange_rate;
|
||||
$fields['unit_price_te'] = (float)$this->unit_price_te;
|
||||
$fields['quantity'] = (int)$this->id_state;
|
||||
$fields['quantity'] = (int)$this->quantity;
|
||||
$fields['price_te'] = (float)$this->price_te;
|
||||
$fields['discount_rate'] = (float)$this->discount_rate;
|
||||
$fields['discount_value_te'] = (float)$this->discount_value_te;
|
||||
@@ -221,10 +221,10 @@ class SupplierOrderDetailCore extends ObjectModel
|
||||
|
||||
// calcul entry discount value
|
||||
if ($this->discount_rate != null && is_numeric($this->discount_rate) && $this->discount_rate > 0)
|
||||
$htis->discount_value_te = (float)$htis->price_te * ((float)$this->discount_rate / 100);
|
||||
$htis->discount_value_te = (float)$this->price_te * ((float)$this->discount_rate / 100);
|
||||
|
||||
// calcul entry price with discount
|
||||
$this->price_with_discount_te = $htis->price_te - $htis->discount_value_te;
|
||||
$this->price_with_discount_te = $this->price_te - $this->discount_value_te;
|
||||
|
||||
// calcul tax value
|
||||
$this->tax_value = $this->price_with_discount_te * ((float)$this->tax_rate / 100);
|
||||
|
||||
@@ -114,7 +114,7 @@ class AdminSupplierOrdersControllerCore extends AdminController
|
||||
Tools::isSubmit('submitAddsupplier_order') ||
|
||||
(Tools::isSubmit('updatesupplier_order') && Tools::isSubmit('id_supplier_order')))
|
||||
{
|
||||
// override table, land, className and identifier for the current controller
|
||||
// override table, lang, className and identifier for the current controller
|
||||
$this->table = 'supplier_order';
|
||||
$this->className = 'SupplierOrder';
|
||||
$this->identifier = 'id_supplier_order';
|
||||
@@ -643,16 +643,40 @@ class AdminSupplierOrdersControllerCore extends AdminController
|
||||
if (Validate::isLoadedObject($supplier_order))
|
||||
{
|
||||
// load products of this order
|
||||
$products = $supplier_order->getEntriesCollection();
|
||||
$products = $supplier_order->getEntries();
|
||||
$product_ids = array();
|
||||
|
||||
if (isset($this->order_products_errors) && is_array($this->order_products_errors))
|
||||
{
|
||||
//for each product in error array, check if it is in products array, and remove it to conserve last user values
|
||||
foreach ($this->order_products_errors as $pe)
|
||||
foreach ($products as $index_p => $p)
|
||||
if(($p['id_product'] == $pe['id_product']) && ($p['id_product_attribute'] == $pe['id_product_attribute']))
|
||||
unset($products[$index_p]);
|
||||
|
||||
// then merge arrays
|
||||
$products = array_merge($this->order_products_errors, $products);
|
||||
}
|
||||
|
||||
foreach ($products as &$item)
|
||||
{
|
||||
// calculate md5 checksum on each product for use in tpl
|
||||
$item['checksum'] = md5(_COOKIE_KEY_.$item['id_product'].'_'.$item['id_product_attribute']);
|
||||
|
||||
// add id to ids list
|
||||
$product_ids[] = $item['id_product'].'_'.$item['id_product_attribute'];
|
||||
}
|
||||
|
||||
$this->tpl_form_vars['products_list'] = $products;
|
||||
$this->tpl_form_vars['product_ids'] = implode($product_ids, '|');
|
||||
$this->tpl_form_vars['supplier_id'] = $supplier_order->id_supplier;
|
||||
}
|
||||
}
|
||||
|
||||
$this->tpl_form_vars['content'] = $this->content;
|
||||
$this->tpl_form_vars['show_product_management_form'] = true;
|
||||
|
||||
// first call parent initcontent to render standard form content
|
||||
// call parent initcontent to render standard form content
|
||||
parent::initContent();
|
||||
}
|
||||
|
||||
@@ -809,12 +833,13 @@ class AdminSupplierOrdersControllerCore extends AdminController
|
||||
*/
|
||||
public function manageOrderProducts()
|
||||
{
|
||||
// loads supplier order
|
||||
// load supplier order
|
||||
$id_supplier_order = (int)Tools::getValue('id_supplier_order', null);
|
||||
|
||||
if ($id_supplier_order != null)
|
||||
{
|
||||
$supplier_order = new SupplierOrder($id_supplier_order);
|
||||
$currency = new Currency($supplier_order->id_ref_currency);
|
||||
|
||||
if (Validate::isLoadedObject($supplier_order))
|
||||
{
|
||||
@@ -832,20 +857,77 @@ class AdminSupplierOrdersControllerCore extends AdminController
|
||||
{
|
||||
// gets all product ids to manage
|
||||
$product_ids_str = Tools::getValue('product_ids', null);
|
||||
|
||||
$product_ids = preg_split('/|/', $product_ids_str);
|
||||
$product_ids = explode('|', $product_ids_str);
|
||||
|
||||
// updates existing products ids
|
||||
foreach ($product_ids as $id)
|
||||
{
|
||||
$pos = strpos($id, '_');
|
||||
$errors = array();
|
||||
|
||||
// check if a checksum is available for this product and test it
|
||||
$check = Tools::getValue('input_check_'.$id, '');
|
||||
$check_valid = md5(_COOKIE_KEY_.$id);
|
||||
|
||||
if ($check_valid != $check)
|
||||
continue;
|
||||
|
||||
$pos = strpos($id, '_');
|
||||
if ($pos === false)
|
||||
continue;
|
||||
|
||||
// gets id_product and id_product attribute
|
||||
$id_product = substr($id, 0, $pos);
|
||||
$id_product_attribute = substr($id, $pos);
|
||||
// Load / Create supplier order detail
|
||||
$entry = new SupplierOrderDetail();
|
||||
$id_supplier_order_detail = (int)Tools::getValue('input_id_'.$id, 0);
|
||||
if ($id_supplier_order_detail > 0)
|
||||
{
|
||||
$existing_entry = new SupplierOrderDetail($id_supplier_order_detail);
|
||||
if (Validate::isLoadedObject($supplier_order))
|
||||
$entry = &$existing_entry;
|
||||
}
|
||||
|
||||
// get product informations
|
||||
$entry->id_product = substr($id, 0, $pos);
|
||||
$entry->id_product_attribute = substr($id, $pos+1);
|
||||
$entry->unit_price_te = (float)Tools::getValue('input_unit_price_te_'.$id, 0);
|
||||
$entry->quantity = (int)Tools::getValue('input_quantity_'.$id, 0);
|
||||
$entry->discount_rate = (float)Tools::getValue('input_discount_rate_'.$id, 0);
|
||||
$entry->tax_rate = (float)Tools::getValue('input_tax_rate_'.$id, 0);
|
||||
$entry->reference = Tools::getValue('input_reference_'.$id, '');
|
||||
$entry->ean13 = Tools::getValue('input_ean13_'.$id, '');
|
||||
$entry->name = Tools::getValue('input_name_'.$id, '');
|
||||
$entry->exchange_rate = $currency->conversion_rate;
|
||||
$entry->id_currency = $currency->id;
|
||||
$entry->id_supplier_order = $supplier_order->id;
|
||||
|
||||
$errors = $entry->validateController();
|
||||
|
||||
// if there is a problem, handle error for the current product
|
||||
if (count($errors) > 0)
|
||||
{
|
||||
// add the product to error array => display again product line
|
||||
$this->order_products_errors[] = array(
|
||||
'id_product' => $entry->id_product,
|
||||
'id_product_attribute' => $entry->id_product_attribute,
|
||||
'unit_price_te' => $entry->unit_price_te,
|
||||
'quantity' => $entry->quantity,
|
||||
'discount_rate' => $entry->discount_rate,
|
||||
'tax_rate' => $entry->tax_rate,
|
||||
'name' => $entry->name,
|
||||
'reference' => $entry->reference,
|
||||
'ean13' => $entry->ean13,
|
||||
);
|
||||
|
||||
$error_str = '<ul>';
|
||||
foreach ($errors as $e)
|
||||
$error_str .= '<li>'.$this->l('field ').$e.'</li>';
|
||||
$error_str .= '</ul>';
|
||||
|
||||
$this->_errors[] = Tools::displayError($this->l('Please verify informations of the product: ').$entry->name.' '.$error_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
$entry->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -889,7 +971,7 @@ class AdminSupplierOrdersControllerCore extends AdminController
|
||||
$_POST['id_supplier_order_state'] = 1; //defaut creation state
|
||||
|
||||
// specify global reference currency
|
||||
$_POST['id_ref_currency'] = $this->context->currency->id;
|
||||
$_POST['id_ref_currency'] = Currency::getDefaultCurrency()->id;
|
||||
|
||||
// manage each associated product
|
||||
$this->manageOrderProducts();
|
||||
@@ -1323,4 +1405,4 @@ class AdminSupplierOrdersControllerCore extends AdminController
|
||||
parent::initToolbar();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user