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