diff --git a/admin-dev/ajax_supplier_order_products_list.php b/admin-dev/ajax_supplier_order_products_list.php index 5a6913852..fdc385e94 100644 --- a/admin-dev/ajax_supplier_order_products_list.php +++ b/admin-dev/ajax_supplier_order_products_list.php @@ -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'); diff --git a/admin-dev/themes/template/supplier_orders/form.tpl b/admin-dev/themes/template/supplier_orders/form.tpl index 8eb3344c1..5a9dd5909 100644 --- a/admin-dev/themes/template/supplier_orders/form.tpl +++ b/admin-dev/themes/template/supplier_orders/form.tpl @@ -29,7 +29,8 @@ {if isset($show_product_management_form)}

 

- + +
@@ -48,7 +49,7 @@ @@ -69,27 +70,32 @@ @@ -123,14 +129,14 @@ // add a new line in the products table $('#products_in_supplier_order > tbody:last').append( ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + '' ); @@ -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]; diff --git a/classes/AdminController.php b/classes/AdminController.php index 2b220712f..93fbe39de 100644 --- a/classes/AdminController.php +++ b/classes/AdminController.php @@ -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 ' '.$this->table.' '. 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 diff --git a/classes/stock/SupplierOrder.php b/classes/stock/SupplierOrder.php index 900d4e2cd..907e80c64 100755 --- a/classes/stock/SupplierOrder.php +++ b/classes/stock/SupplierOrder.php @@ -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.*'); diff --git a/classes/stock/SupplierOrderDetail.php b/classes/stock/SupplierOrderDetail.php index b6a5874e9..4044752ac 100755 --- a/classes/stock/SupplierOrderDetail.php +++ b/classes/stock/SupplierOrderDetail.php @@ -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); diff --git a/controllers/admin/AdminSupplierOrdersController.php b/controllers/admin/AdminSupplierOrdersController.php index d1709ee2d..60498125d 100644 --- a/controllers/admin/AdminSupplierOrdersController.php +++ b/controllers/admin/AdminSupplierOrdersController.php @@ -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 = ''; + + $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(); } } -} \ No newline at end of file +}
{$product.reference} + + + {$product.ean13} + {$product.name} + - + - + - + - + - + {l s='Remove this product from the order'}
'+product_infos.reference+''+product_infos.ean13+''+product_infos.name+''+ + ''+product_infos.reference+''+product_infos.ean13+''+product_infos.name+''+ '{l s='+ '