Commit 1ea276bc authored by Maxime Biloé's avatar Maxime Biloé Committed by GitHub
Browse files

Merge pull request #7117 from aleeks/fix-gsa

Fixed some ASM problems
parents e9daa8b1 2e2a5243
......@@ -760,9 +760,7 @@ class AdminControllerCore extends Controller
'fields' => &$this->fields_list,
));
if (!isset($this->list_id)) {
$this->list_id = $this->table;
}
$this->ensureListIdDefinition();
$prefix = $this->getCookieFilterPrefix();
......@@ -2838,9 +2836,7 @@ class AdminControllerCore extends Controller
*/
public function initProcess()
{
if (!isset($this->list_id)) {
$this->list_id = $this->table;
}
$this->ensureListIdDefinition();
// Manage list filtering
if (Tools::isSubmit('submitFilter'.$this->list_id)
......@@ -3017,24 +3013,21 @@ class AdminControllerCore extends Controller
* @param int $start Offset in LIMIT clause
* @param int|null $limit Row count in LIMIT clause
* @param int|bool $id_lang_shop
* @throws PrestaShopDatabaseException
* @throws PrestaShopException
* @throws \PrestaShopDatabaseExceptionCore
* @throws \PrestaShopExceptionCore
*/
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
public function getList(
$id_lang,
$order_by = null,
$order_way = null,
$start = 0,
$limit = null,
$id_lang_shop = false
)
{
Hook::exec('action'.$this->controller_name.'ListingFieldsModifier', array(
'select' => &$this->_select,
'join' => &$this->_join,
'where' => &$this->_where,
'group_by' => &$this->_group,
'order_by' => &$this->_orderBy,
'order_way' => &$this->_orderWay,
'fields' => &$this->fields_list,
));
$this->dispatchFieldsListingModifierEvent();
if (!isset($this->list_id)) {
$this->list_id = $this->table;
}
$this->ensureListIdDefinition();
/* Manage default params values */
$use_limit = true;
......@@ -4381,4 +4374,24 @@ class AdminControllerCore extends Controller
$this->meta_title[] = $entry;
}
}
protected function dispatchFieldsListingModifierEvent()
{
Hook::exec('action' . $this->controller_name . 'ListingFieldsModifier', array(
'select' => &$this->_select,
'join' => &$this->_join,
'where' => &$this->_where,
'group_by' => &$this->_group,
'order_by' => &$this->_orderBy,
'order_way' => &$this->_orderWay,
'fields' => &$this->fields_list,
));
}
protected function ensureListIdDefinition()
{
if (!isset($this->list_id)) {
$this->list_id = $this->table;
}
}
}
......@@ -93,6 +93,9 @@ class DbQueryCore
public function from($table, $alias = null)
{
if (!empty($table)) {
if (empty($this->query['from'])) {
$this->query['from'] = array();
}
$this->query['from'][] = '`'._DB_PREFIX_.$table.'`'.($alias ? ' '.$alias : '');
}
......
This diff is collapsed.
......@@ -55,16 +55,31 @@ interface StockManagerInterface
/**
* For a given product, removes a given quantity
*
* @param int $id_product
* @param int $id_product_attribute
* @param Warehouse $warehouse
* @param int $quantity
* @param int $id_stock_movement_reason
* @param bool $is_usable
* @param int $id_order Optionnal
* @param int $id_product
* @param int|null $id_product_attribute
* @param Warehouse $warehouse
* @param int $quantity
* @param int $id_stock_mvt_reason
* @param bool $is_usable
* @param int|null $id_order
* @param int $ignore_pack
* @param Employee|null $employee
* @param Stock|null $stock
*
* @return array - empty if an error occurred | details of removed products quantities with corresponding prices otherwise
*/
public function removeProduct($id_product, $id_product_attribute, Warehouse $warehouse, $quantity, $id_stock_movement_reason, $is_usable = true, $id_order = null);
public function removeProduct(
$id_product,
$id_product_attribute,
Warehouse $warehouse,
$quantity,
$id_stock_movement_reason,
$is_usable = true,
$id_order = null,
$ignore_pack = 0,
$employee = null,
Stock $stock = null
);
/**
* For a given product, returns its physical quantity
......
......@@ -137,7 +137,7 @@ class SupplyOrderStateCore extends ObjectModel
}
//check if the state correspond to a receipt state
elseif ($is_receipt_state) {
$query->where('s.receipt_state = 1');
$query->where('s.receipt_state = 1 AND s.id_supply_order_state > '.(int)$id_state_referrer);
}
}
......
......@@ -126,6 +126,7 @@ class AdminStockCoverControllerCore extends AdminController
if (Tools::isSubmit('id_product')) {
// if a product id is submit
$this->list_no_link = true;
$this->lang = false;
$this->list_id = 'details';
$this->tpl_list_vars['show_filter'] = false;
......@@ -143,7 +144,8 @@ class AdminStockCoverControllerCore extends AdminController
$this->_select = 'a.id_product_attribute as id, a.id_product, stock_view.reference, stock_view.ean13,
stock_view.upc, stock_view.usable_quantity as stock';
$this->_join = ' INNER JOIN
$this->_join = 'INNER JOIN `'._DB_PREFIX_.'product` p ON (p.id_product = a.id_product AND p.advanced_stock_management = 1)';
$this->_join .= ' INNER JOIN
(
SELECT SUM(s.usable_quantity) as usable_quantity, s.id_product_attribute, s.reference, s.ean13, s.upc
FROM '._DB_PREFIX_.'stock s
......@@ -177,6 +179,7 @@ class AdminStockCoverControllerCore extends AdminController
'.Shop::addSqlAssociation('product_attribute', 'pa', false).'
INNER JOIN `'._DB_PREFIX_.'stock` s ON (s.id_product = a.id_product)';
$this->_group = 'GROUP BY a.id_product';
$this->_where = 'AND a.advanced_stock_management = 1';
self::$currentIndex .= '&coverage_period='.(int)$this->getCurrentCoveragePeriod().'&warn_days='.(int)$this->getCurrentWarning();
if ($this->getCurrentCoverageWarehouse() != -1) {
......
......@@ -90,14 +90,6 @@ class AdminStockInstantStateControllerCore extends AdminController
'orderby' => true,
'search' => false,
),
'real_quantity' => array(
'title' => $this->l('Real quantity'),
'class' => 'fixed-width-xs',
'align' => 'center',
'orderby' => false,
'search' => false,
'hint' => $this->l('Physical quantity (usable) - Client orders + Supply Orders'),
),
);
$this->addRowAction('details');
......@@ -142,19 +134,30 @@ class AdminStockInstantStateControllerCore extends AdminController
*/
public function renderList()
{
$this->fields_list['real_quantity'] = array(
'title' => $this->l('Real quantity'),
'class' => 'fixed-width-xs',
'align' => 'center',
'orderby' => false,
'search' => false,
'hint' => $this->l('Physical quantity (usable) - Client orders + Supply Orders'),
);
// query
$this->_select = '
$this->_select = 'IFNULL(pa.ean13, p.ean13) as ean13,
IFNULL(pa.upc, p.upc) as upc,
IFNULL(pa.reference, p.reference) as reference,
IFNULL(CONCAT(pl.name, \' : \', GROUP_CONCAT(DISTINCT agl.`name`, \' - \', al.name SEPARATOR \', \')),pl.name) as name,
w.id_currency';
$this->_group = 'GROUP BY a.id_product, a.id_product_attribute';
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'warehouse` w ON (w.id_warehouse = a.id_warehouse)';
$this->_join = 'INNER JOIN `'._DB_PREFIX_.'product` p ON (p.id_product = a.id_product AND p.advanced_stock_management = 1)';
$this->_join .= 'LEFT JOIN `'._DB_PREFIX_.'warehouse` w ON (w.id_warehouse = a.id_warehouse)';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (
a.id_product = pl.id_product
AND pl.id_lang = '.(int)$this->context->language->id.'
)';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON (pac.id_product_attribute = a.id_product_attribute)';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.id_product_attribute = a.id_product_attribute)';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'attribute` atr ON (atr.id_attribute = pac.id_attribute)';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (
al.id_attribute = pac.id_attribute
......@@ -165,6 +168,11 @@ class AdminStockInstantStateControllerCore extends AdminController
AND agl.id_lang = '.(int)$this->context->language->id.'
)';
$this->_group = 'GROUP BY a.id_product, a.id_product_attribute';
$this->_orderBy = 'name';
$this->_orderWay = 'ASC';
if ($this->getCurrentCoverageWarehouse() != -1) {
$this->_where .= ' AND a.id_warehouse = '.$this->getCurrentCoverageWarehouse();
self::$currentIndex .= '&id_warehouse='.(int)$this->getCurrentCoverageWarehouse();
......@@ -208,6 +216,7 @@ class AdminStockInstantStateControllerCore extends AdminController
if (Tools::isSubmit('id_stock')) {
// if a product id is submit
$this->list_no_link = true;
$this->lang = false;
$this->table = 'stock';
$this->list_id = 'details';
......@@ -224,14 +233,19 @@ class AdminStockInstantStateControllerCore extends AdminController
$id_product = $ids[0];
$id_product_attribute = $ids[1];
$id_warehouse = Tools::getValue('id_warehouse', -1);
$this->_select = 'IFNULL(CONCAT(pl.name, \' : \', GROUP_CONCAT(DISTINCT agl.`name`, \' - \', al.name SEPARATOR \', \')),pl.name) as name,
$this->_select = 'IFNULL(pa.ean13, p.ean13) as ean13,
IFNULL(pa.upc, p.upc) as upc,
IFNULL(pa.reference, p.reference) as reference,
IFNULL(CONCAT(pl.name, \' : \', GROUP_CONCAT(DISTINCT agl.`name`, \' - \', al.name SEPARATOR \', \')),pl.name) as name,
w.id_currency, a.price_te';
$this->_join = ' LEFT JOIN `'._DB_PREFIX_.'warehouse` AS w ON w.id_warehouse = a.id_warehouse';
$this->_join = 'INNER JOIN `'._DB_PREFIX_.'product` p ON (p.id_product = a.id_product AND p.advanced_stock_management = 1)';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'warehouse` AS w ON w.id_warehouse = a.id_warehouse';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (
a.id_product = pl.id_product
AND pl.id_lang = '.(int)$this->context->language->id.'
)';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON (pac.id_product_attribute = a.id_product_attribute)';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.id_product_attribute = a.id_product_attribute)';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'attribute` atr ON (atr.id_attribute = pac.id_attribute)';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (
al.id_attribute = pac.id_attribute
......@@ -247,6 +261,9 @@ class AdminStockInstantStateControllerCore extends AdminController
$this->_where .= ' AND a.id_warehouse = '.(int)$id_warehouse;
}
$this->_orderBy = 'name';
$this->_orderWay = 'ASC';
$this->_group = 'GROUP BY a.price_te';
self::$currentIndex = self::$currentIndex.'&id_stock='.Tools::getValue('id_stock').'&detailsstock';
......@@ -280,11 +297,11 @@ class AdminStockInstantStateControllerCore extends AdminController
// gets quantities and valuation
$query = new DbQuery();
$query->select('SUM(physical_quantity) as physical_quantity');
$query->select('SUM(usable_quantity) as usable_quantity');
$query->select('physical_quantity');
$query->select('usable_quantity');
$query->select('SUM(price_te * physical_quantity) as valuation');
$query->from('stock');
$query->where('id_product = '.(int)$item['id_product'].' AND id_product_attribute = '.(int)$item['id_product_attribute']);
$query->where('id_stock = '.(int)$item['id_stock'].' AND id_product = '.(int)$item['id_product'].' AND id_product_attribute = '.(int)$item['id_product_attribute']);
if ($this->getCurrentCoverageWarehouse() != -1) {
$query->where('id_warehouse = '.(int)$this->getCurrentCoverageWarehouse());
......
......@@ -76,8 +76,14 @@ class AdminStockMvtControllerCore extends AdminController
'-1' => $this->l('Decrease'),
),
'icon' => array(
-1 => 'remove_stock.png',
1 => 'add_stock.png'
-1 => array(
'src' => 'remove_stock.png',
'alt' => $this->l('Increase'),
),
1 => array(
'src' => 'add_stock.png',
'alt' => $this->l('Decrease'),
)
),
'class' => 'fixed-width-xs'
),
......@@ -174,6 +180,9 @@ class AdminStockMvtControllerCore extends AdminController
self::$currentIndex .= '&id_warehouse='.$id_warehouse;
}
$this->_orderBy = 'a.date_add';
$this->_orderWay = 'DESC';
// sets the current warehouse
$this->tpl_list_vars['current_warehouse'] = $this->getCurrentWarehouseId();
......
......@@ -1220,6 +1220,7 @@ class AdminSupplyOrdersControllerCore extends AdminController
if (!count($this->errors)) {
$supply_order->id_supply_order_state = $state['id_supply_order_state'];
if ($supply_order->save()) {
// create stock entry if not exist when order is in pending_receipt
if ($new_state->pending_receipt) {
$supply_order_details = $supply_order->getEntries();
foreach ($supply_order_details as $supply_order_detail) {
......@@ -1243,6 +1244,53 @@ class AdminSupplyOrdersControllerCore extends AdminController
}
}
// add stock when is received completely
if ($new_state->receipt_state && $new_state->enclosed) {
$supply_order_details = $supply_order->getEntries();
$warehouse = new Warehouse($supply_order->id_warehouse);
$id_warehouse = $warehouse->id;
$stock_manager = StockManagerFactory::getManager();
foreach ($supply_order_details as $detail) {
$id_product = $detail['id_product'];
$id_product_attribute = $detail['id_product_attribute'];
if ($stock_manager->addProduct(
$detail['id_product'],
$detail['id_product_attribute'],
$warehouse,
(int)($detail['quantity_expected'] - $detail['quantity_received']),
Configuration::get('PS_STOCK_MVT_SUPPLY_ORDER'),
$detail['unit_price_te'],
true,
$supply_order->id
)) {
// Create warehouse_product_location entry if we add stock to a new warehouse
$id_wpl = (int)WarehouseProductLocation::getIdByProductAndWarehouse($id_product, $id_product_attribute, $id_warehouse);
if (!$id_wpl) {
$wpl = new WarehouseProductLocation();
$wpl->id_product = (int)$id_product;
$wpl->id_product_attribute = (int)$id_product_attribute;
$wpl->id_warehouse = (int)$id_warehouse;
$wpl->save();
}
$supply_order_detail_mvt = new SupplyOrderDetail($detail['id_supply_order_detail']);
$supply_order_detail_mvt_params = array(
'quantity_received' => (int)$detail['quantity_expected'],
);
// saves supply order detail
$supply_order_detail_mvt->hydrate($supply_order_detail_mvt_params);
$supply_order_detail_mvt->update();
} else {
$this->errors[] = $this->l('An error occurred. No stock was added.');
}
}
}
// if pending_receipt,
// or if the order is being canceled,
// or if the order is received completely
......
......@@ -496,7 +496,14 @@ class AdminWarehousesControllerCore extends AdminController
*
* @throws PrestaShopException
*/
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
public function getList(
$id_lang,
$order_by = null,
$order_way = null,
$start = 0,
$limit = null,
$id_lang_shop = false
)
{
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
......@@ -522,22 +529,42 @@ class AdminWarehousesControllerCore extends AdminController
}
}
/**
* @return bool
*/
public function initContent()
{
if (!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
$this->warnings[md5('PS_ADVANCED_STOCK_MANAGEMENT')] = $this->l('You need to activate advanced stock management before using this feature.');
return false;
if ($this->isAdvancedStockManagementActive()) {
return parent::initContent();
}
parent::initContent();
return false;
}
/**
* @return bool
*/
public function initProcess()
{
if (!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
$this->warnings[md5('PS_ADVANCED_STOCK_MANAGEMENT')] = $this->l('You need to activate advanced stock management before using this feature.');
return false;
if ($this->isAdvancedStockManagementActive()) {
return parent::initProcess();
}
parent::initProcess();
return false;
}
/**
* @return bool
*/
protected function isAdvancedStockManagementActive()
{
if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
return true;
}
$this->warnings[md5('PS_ADVANCED_STOCK_MANAGEMENT')] = $this->l('You need to activate advanced stock management before using this feature.');
return false;
}
/**
......@@ -561,17 +588,16 @@ class AdminWarehousesControllerCore extends AdminController
protected function updateAddress()
{
// updates/creates address if it does not exist
/** @var AddressCore $address */
$address = new Address();
if (Tools::isSubmit('id_address') && (int)Tools::getValue('id_address') > 0) {
$address = new Address((int)Tools::getValue('id_address'));
} // updates address
else {
$address = new Address();
} // creates address
// sets the address
}
$address->alias = Tools::getValue('reference', null);
$address->lastname = 'warehouse'; // skip problem with numeric characters in warehouse name
$address->firstname = 'warehouse'; // skip problem with numeric characters in warehouse name
$address->lastname = 'warehouse'; // skip problem with numeric characters
$address->firstname = 'warehouse'; // in warehouse name
$address->address1 = Tools::getValue('address', null);
$address->address2 = Tools::getValue('address2', null);
$address->postcode = Tools::getValue('postcode', null);
......@@ -580,9 +606,13 @@ class AdminWarehousesControllerCore extends AdminController
$address->id_state = Tools::getValue('id_state', null);
$address->city = Tools::getValue('city', null);
if (!($country = new Country($address->id_country, Configuration::get('PS_LANG_DEFAULT'))) || !Validate::isLoadedObject($country)) {
if (
!($country = new Country($address->id_country, Configuration::get('PS_LANG_DEFAULT'))) ||
!Validate::isLoadedObject($country)
) {
$this->errors[] = Tools::displayError('Country is invalid');
}
$contains_state = isset($country) && is_object($country) ? (int)$country->contains_states: 0;
$id_state = isset($address) && is_object($address) ? (int)$address->id_state: 0;
if ($contains_state && !$id_state) {
......@@ -599,7 +629,10 @@ class AdminWarehousesControllerCore extends AdminController
foreach ($validation as $item) {
$this->errors[] = $item;
}
$this->errors[] = Tools::displayError('The address is not correct. Please make sure all of the required fields are completed.');
$this->errors[] = Tools::displayError(
'The address is not correct. Please make sure all of the required fields are completed.'
);
} else {
// valid
......@@ -613,34 +646,80 @@ class AdminWarehousesControllerCore extends AdminController
}
/**
* @see AdminController::processDelete();
* When submitting a warehouse deletion request,
* make an attempt to load a warehouse instance from an identifier,
* ensure the warehouse to be deleted,
* - does not contain any products,
* - nor it has some pending supply orders
* before actual deletion
*
* @return bool|mixed
*/
public function processDelete()
{
if (Tools::isSubmit('delete'.$this->table)) {
/** @var Warehouse $obj */
// check if the warehouse exists and can be deleted
if (!($obj = $this->loadObject(true))) {
return;
} elseif ($obj->getQuantitiesOfProducts() > 0) { // not possible : products
$this->errors[] = $this->l('It is not possible to delete a warehouse when there are products in it.');
} elseif (SupplyOrder::warehouseHasPendingOrders($obj->id)) { // not possible : supply orders
$this->errors[] = $this->l('It is not possible to delete a Warehouse if it has pending supply orders.');
} else {
// else, it can be deleted
if (!Tools::isSubmit('delete'.$this->table)) {
return false;
}
// sets the address of the warehouse as deleted
$address = new Address($obj->id_address);
$address->deleted = 1;
$address->save();
/** @var Warehouse $warehouse */
$warehouse = $this->loadObject(true);
if ($this->shouldForbidWarehouseDeletion($warehouse)) {
return false;
}
// removes associations with carriers/shops/products location
$obj->setCarriers(array());
$obj->resetProductsLocations();
return $this->deleteWarehouse($warehouse);
}
return parent::processDelete();
}
/**
* @param $warehouse
* @return bool
*/
protected function shouldForbidWarehouseDeletion($warehouse)
{
if (!$warehouse) {
return true;
}
if ($warehouse->getQuantitiesOfProducts() > 0) {
$this->errors[] = $this->l('It is not possible to delete a warehouse when there are products in it.');
return true;
}
if (SupplyOrder::warehouseHasPendingOrders($warehouse->id)) {
$this->errors[] = $this->l('It is not possible to delete a Warehouse if it has pending supply orders.');
return true;
}
return false;
}
/**
* @param Warehouse $warehouse
* @return mixed
*/
protected function deleteWarehouse(Warehouse $warehouse)
{
$address = new Address($warehouse->id_address);
$this->markAddressAsDeleted($address);
/** @var WarehouseCore $warehouse */
$warehouse->setCarriers(array());
$warehouse->resetProductsLocations();
return parent::processDelete();
}
/**
* @param Address $address
*/
protected function markAddressAsDeleted(Address $address)
{
/** @var AddressCore $address */
$address->deleted = 1;
$address->save();
}