diff --git a/vendor/magento/module-visual-merchandiser/Block/Adminhtml/Category/Merchandiser.php b/vendor/magento/module-visual-merchandiser/Block/Adminhtml/Category/Merchandiser.php
index 179ca6362869..1d34f5aedc15 100644
--- a/vendor/magento/module-visual-merchandiser/Block/Adminhtml/Category/Merchandiser.php
+++ b/vendor/magento/module-visual-merchandiser/Block/Adminhtml/Category/Merchandiser.php
@@ -7,6 +7,7 @@
use Magento\Backend\Block\Template;
use Magento\Backend\Block\Widget\Context;
+use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Registry;
use Magento\VisualMerchandiser\Model\Position\Cache;
@@ -49,6 +50,7 @@ public function __construct(
* Get dialog URL
*
* @return string
+ * @throws NoSuchEntityException
* @since 100.1.0
*/
public function getDialogUrl()
@@ -57,7 +59,9 @@ public function getDialogUrl()
'merchandiser/*/addproduct',
[
'cache_key' => $this->getPositionCacheKey(),
- 'componentJson' => true
+ 'componentJson' => true,
+ 'category_id' => $this->getCategoryId(),
+ 'store_id' => $this->getStoreId()
]
);
}
@@ -95,6 +99,17 @@ public function getCategoryId()
return $this->getRequest()->getParam('id');
}
+ /**
+ * Retrieve current store id
+ *
+ * @return int
+ * @throws NoSuchEntityException
+ */
+ private function getStoreId(): int
+ {
+ return $this->_storeManager->getStore()->getId();
+ }
+
/**
* Get position cache key
*
diff --git a/vendor/magento/module-visual-merchandiser/Model/Category/Products.php b/vendor/magento/module-visual-merchandiser/Model/Category/Products.php
index 8a809eaae391..d2fcb04e8b3b 100644
--- a/vendor/magento/module-visual-merchandiser/Model/Category/Products.php
+++ b/vendor/magento/module-visual-merchandiser/Model/Category/Products.php
@@ -146,6 +146,9 @@ public function getCollectionForGrid($categoryId, $store = null, $productPositio
'small_image'
]
);
+ if ($store !== null) {
+ $collection->setStoreId((int)$store);
+ }
$collection = $this->quantityStockResolver->joinStock($collection);
diff --git a/vendor/magento/module-visual-merchandiser/Model/Product/DataProvider.php b/vendor/magento/module-visual-merchandiser/Model/Product/DataProvider.php
index 8c6715732a34..074a9f2864e2 100755
--- a/vendor/magento/module-visual-merchandiser/Model/Product/DataProvider.php
+++ b/vendor/magento/module-visual-merchandiser/Model/Product/DataProvider.php
@@ -6,13 +6,15 @@
namespace Magento\VisualMerchandiser\Model\Product;
use InvalidArgumentException;
+use Magento\Catalog\Model\Category\Product\PositionResolver;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\Api\Filter;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Exception\LocalizedException;
-use Magento\Store\Model\Store;
use Magento\Ui\DataProvider\AbstractDataProvider;
use Magento\VisualMerchandiser\Model\Position\Cache;
+use Magento\VisualMerchandiser\Model\Resolver\QuantityAndStock;
/**
* Class DataProvider for the Visual Merchandiser product selection grid
@@ -39,6 +41,17 @@ class DataProvider extends AbstractDataProvider
*/
private $request;
+ /**
+ * @var PositionResolver
+ */
+ private $positionResolver;
+
+ /**
+ * @var QuantityAndStock|mixed
+ */
+ private QuantityAndStock $quantityAndStock;
+
+
/**
* @param string $name
* @param string $primaryFieldName
@@ -48,7 +61,10 @@ class DataProvider extends AbstractDataProvider
* @param Cache $cache
* @param array $meta
* @param array $data
+ * @param PositionResolver|null $positionResolver
+ * @param QuantityAndStock|null $quantityAndStock
* @throws LocalizedException
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
$name,
@@ -58,12 +74,16 @@ public function __construct(
RequestInterface $request,
Cache $cache,
array $meta = [],
- array $data = []
+ array $data = [],
+ ?PositionResolver $positionResolver = null,
+ ?QuantityAndStock $quantityAndStock = null
) {
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
$this->request = $request;
$this->cache = $cache;
+ $this->positionResolver = $positionResolver ?: ObjectManager::getInstance()->get(PositionResolver::class);
+ $this->quantityAndStock = $quantityAndStock ?: ObjectManager::getInstance()->get(QuantityAndStock::class);
$this->collection = $collectionFactory->create()->addAttributeToSelect(
'sku'
@@ -77,14 +97,13 @@ public function __construct(
'price'
);
- $this->collection->joinField(
- 'qty',
- 'cataloginventory_stock_item',
- 'qty',
- 'product_id=entity_id',
- '{{table}}.stock_id=1',
- 'left'
- );
+ $this->collection->setStoreId($this->request->getParam('store_id', "0"));
+ $this->collection = $this->quantityAndStock->joinStock($this->collection);
+
+ $this->collection->getSelect()->group('e.entity_id');
+ $subSelect = clone($this->collection->getSelect());
+ $this->collection->getSelect()->reset()->from(['e' => $subSelect]);
+ $this->collection->addStaticField('stock');
$this->prepareUpdateUrl();
}
@@ -127,12 +146,16 @@ protected function prepareUpdateUrl()
if ('*' == $paramValue) {
$paramValue = $this->request->getParam($paramName);
$this->positionCacheKey = $paramValue;
+ } elseif ('%category_id%' === $paramValue) {
+ $paramValue = $this->request->getParam($paramName);
+ } elseif ('%store_id%' === $paramValue) {
+ $paramValue = $this->request->getParam($paramName, "0");
}
if ($paramValue) {
$this->data['config']['update_url'] = sprintf(
- '%s%s/%s',
- $this->data['config']['update_url'],
+ '%s/%s/%s',
+ rtrim($this->data['config']['update_url'], '/'),
$paramName,
$paramValue
);
@@ -149,13 +172,16 @@ protected function prepareUpdateUrl()
public function addPositionData()
{
$positions = $this->cache->getPositions($this->positionCacheKey);
+ $categoryId = $this->request->getParam('category_id');
- if ($positions === false) {
+ if ($positions === false && $categoryId !== null) {
+ $positions = $this->positionResolver->getPositions((int) $categoryId);
+ } elseif ($positions === false && $categoryId === null) {
return;
}
foreach ($this->collection as $item) {
- if (array_key_exists($item->getEntityId(), $positions)) {
+ if (is_array($positions) && array_key_exists($item->getEntityId(), $positions)) {
$item->setPosition(
$positions[$item->getEntityId()]
);
@@ -177,17 +203,25 @@ public function addPositionData()
*/
public function getData()
{
- $this->collection->setStoreId(Store::DEFAULT_STORE_ID);
$this->collection->getLimitationFilters()->setUsePriceIndex(false);
$this->addPositionData();
+ $positions = $this->cache->getPositions($this->positionCacheKey);
+ $categoryId = $this->request->getParam('category_id');
$arrItems = [];
- $arrItems['totalRecords'] = $this->collection->getSize();
$arrItems['items'] = [];
- $arrItems['selectedData'] = $this->cache->getPositions($this->positionCacheKey);
- $arrItems['allIds'] = $this->collection->getAllIds();
+ if ($positions === false && $categoryId !== null) {
+ $arrItems['selectedData'] = $this->positionResolver->getPositions((int) $categoryId);
+ } else {
+ $arrItems['selectedData'] = $positions;
+ }
+ $arrItems['allIds'] = array_map('intval', $this->collection->getAllIds());
+ $arrItems['totalRecords'] = count($arrItems['allIds']);
foreach ($this->collection->getItems() as $item) {
- $arrItems['items'][] = $item->toArray();
+ $itemDetails = $item->toArray();
+ $itemDetails['qty'] = $itemDetails['stock'] ?? 0;
+ $arrItems['items'][] = $itemDetails;
+ $arrItems['allIds'][] = $item->getId();
}
return $arrItems;
diff --git a/vendor/magento/module-visual-merchandiser/view/adminhtml/ui_component/merchandiser_product_listing.xml b/vendor/magento/module-visual-merchandiser/view/adminhtml/ui_component/merchandiser_product_listing.xml
index c3ca2b6fd3cd..3ceb7a06bc8b 100755
--- a/vendor/magento/module-visual-merchandiser/view/adminhtml/ui_component/merchandiser_product_listing.xml
+++ b/vendor/magento/module-visual-merchandiser/view/adminhtml/ui_component/merchandiser_product_listing.xml
@@ -22,6 +22,8 @@
*
+ %category_id%
+ %store_id%
@@ -77,7 +79,7 @@
-
+
textRange
number
diff --git a/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/mass_sku.js b/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/mass_sku.js
index b746a2ba352f..a48323eb3cec 100644
--- a/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/mass_sku.js
+++ b/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/mass_sku.js
@@ -4,8 +4,9 @@
*/
/*global setLocation:true*/
define([
- 'jquery'
-], function ($) {
+ 'jquery',
+ 'uiRegistry'
+], function ($, registry) {
'use strict';
$.widget('mage.visualMerchandiserMassSku', {
@@ -20,6 +21,7 @@ define([
* @private
*/
_create: function () {
+ this.registry = registry;
this.form = this.element.find('form');
this._bind();
},
@@ -28,9 +30,36 @@ define([
* @private
*/
_bind: function () {
+ var self = this;
+
+ self._disableActionButtons(true);
+ this.registry.get(
+ 'merchandiser_product_listing.merchandiser_product_listing_data_source',
+ function (listingDataSource) {
+ if (!listingDataSource.firstLoad) {
+ self._disableActionButtons(false);
+ }
+ listingDataSource.on('reload', function () {
+ self._disableActionButtons(true);
+ });
+ listingDataSource.on('reloaded', function () {
+ self._disableActionButtons(false);
+ });
+ }
+ );
$(this.options.massAssignButton).on('click', $.proxy(this._massAssignAction, this));
},
+ /**
+ * Toggle state of action buttons.
+ *
+ * @param {Boolean} disabled
+ * @private
+ */
+ _disableActionButtons: function (disabled) {
+ $(this.options.massAssignButton).attr('disabled', disabled);
+ },
+
/**
* @param {Event} event
* @private