I want to add salable quantity in the product in categories section in adminside. In below image I want to add salable quantity column instead of QTY and get corresponding values.
1 Answer
you need to override the Magento\Catalog\Block\Adminhtml\Category\Tab\Product.php
in you module using preference.
Vendor/Module/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Catalog\Block\Adminhtml\Category\Tab\Product" type="Vendor\Module\Block\Adminhtml\Category\Tab\Product" />
</config>
Vendor\Module\Block\Adminhtml\Category\Tab\Product.php
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/**
* Product in category grid
*
* @author Magento Core Team <[email protected]>
*/
namespace Vendor\Module\Block\Adminhtml\Category\Tab;
use Magento\Backend\Block\Widget\Grid;
use Magento\Backend\Block\Widget\Grid\Column;
use Magento\Backend\Block\Widget\Grid\Extended;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Framework\App\ObjectManager;
class Product extends \Magento\Backend\Block\Widget\Grid\Extended
{
/**
* Core registry
*
* @var \Magento\Framework\Registry
*/
protected $_coreRegistry = null;
/**
* @var \Magento\Catalog\Model\ProductFactory
*/
protected $_productFactory;
/**
* @var Status
*/
private $status;
/**
* @var Visibility
*/
private $visibility;
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Backend\Helper\Data $backendHelper
* @param \Magento\Catalog\Model\ProductFactory $productFactory
* @param \Magento\Framework\Registry $coreRegistry
* @param array $data
* @param Visibility|null $visibility
* @param Status|null $status
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Backend\Helper\Data $backendHelper,
\Magento\Catalog\Model\ProductFactory $productFactory,
\Magento\Framework\Registry $coreRegistry,
array $data = [],
Visibility $visibility = null,
Status $status = null
) {
$this->_productFactory = $productFactory;
$this->_coreRegistry = $coreRegistry;
$this->visibility = $visibility ?: ObjectManager::getInstance()->get(Visibility::class);
$this->status = $status ?: ObjectManager::getInstance()->get(Status::class);
parent::__construct($context, $backendHelper, $data);
}
/**
* @return void
*/
protected function _construct()
{
parent::_construct();
$this->setId('catalog_category_products');
$this->setDefaultSort('entity_id');
$this->setUseAjax(true);
}
/**
* @return array|null
*/
public function getCategory()
{
return $this->_coreRegistry->registry('category');
}
/**
* @param Column $column
* @return $this
*/
protected function _addColumnFilterToCollection($column)
{
// Set custom filter for in category flag
if ($column->getId() == 'in_category') {
$productIds = $this->_getSelectedProducts();
if (empty($productIds)) {
$productIds = 0;
}
if ($column->getFilter()->getValue()) {
$this->getCollection()->addFieldToFilter('entity_id', ['in' => $productIds]);
} elseif (!empty($productIds)) {
$this->getCollection()->addFieldToFilter('entity_id', ['nin' => $productIds]);
}
} else {
parent::_addColumnFilterToCollection($column);
}
return $this;
}
/**
* @return Grid
*/
protected function _prepareCollection()
{
if ($this->getCategory()->getId()) {
$this->setDefaultFilter(['in_category' => 1]);
}
$collection = $this->_productFactory->create()->getCollection()->addAttributeToSelect(
'name'
)->addAttributeToSelect(
'sku'
)->addAttributeToSelect(
'visibility'
)->addAttributeToSelect(
'status'
)->addAttributeToSelect(
'price'
)->joinField(
'position',
'catalog_category_product',
'position',
'product_id=entity_id',
'category_id=' . (int)$this->getRequest()->getParam('id', 0),
'left'
);
$storeId = (int)$this->getRequest()->getParam('store', 0);
if ($storeId > 0) {
$collection->addStoreFilter($storeId);
}
$this->setCollection($collection);
if ($this->getCategory()->getProductsReadonly()) {
$productIds = $this->_getSelectedProducts();
if (empty($productIds)) {
$productIds = 0;
}
$this->getCollection()->addFieldToFilter('entity_id', ['in' => $productIds]);
}
return parent::_prepareCollection();
}
/**
* @return Extended
*/
protected function _prepareColumns()
{
if (!$this->getCategory()->getProductsReadonly()) {
$this->addColumn(
'in_category',
[
'type' => 'checkbox',
'name' => 'in_category',
'values' => $this->_getSelectedProducts(),
'index' => 'entity_id',
'header_css_class' => 'col-select col-massaction',
'column_css_class' => 'col-select col-massaction'
]
);
}
$this->addColumn(
'entity_id',
[
'header' => __('ID'),
'sortable' => true,
'index' => 'entity_id',
'header_css_class' => 'col-id',
'column_css_class' => 'col-id'
]
);
$this->addColumn('name', ['header' => __('Name'), 'index' => 'name']);
$this->addColumn('sku', ['header' => __('SKU'), 'index' => 'sku']);
$this->addColumn(
'visibility',
[
'header' => __('Visibility'),
'index' => 'visibility',
'type' => 'options',
'options' => $this->visibility->getOptionArray(),
'header_css_class' => 'col-visibility',
'column_css_class' => 'col-visibility'
]
);
$this->addColumn(
'status',
[
'header' => __('Status'),
'index' => 'status',
'type' => 'options',
'options' => $this->status->getOptionArray()
]
);
$this->addColumn(
'price',
[
'header' => __('Price'),
'type' => 'currency',
'currency_code' => (string)$this->_scopeConfig->getValue(
\Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
),
'index' => 'price'
]
);
$this->addColumn(
'position',
[
'header' => __('Position'),
'type' => 'number',
'index' => 'position',
'editable' => !$this->getCategory()->getProductsReadonly()
]
);
//Qty Column
$this->addColumn(
'qty',
[
'header' => __('Quantity'),
'type' => 'number',
'index' => 'qty',
'renderer' =>
'vendor\module\Block\Adminhtml\Category\Tab\Grid\Column\Renderer\SaleableQty'
]
);
return parent::_prepareColumns();
}
/**
* @return string
*/
public function getGridUrl()
{
return $this->getUrl('catalog/*/grid', ['_current' => true]);
}
/**
* @return array
*/
protected function _getSelectedProducts()
{
$products = $this->getRequest()->getPost('selected_products');
if ($products === null) {
$products = $this->getCategory()->getProductsPosition();
return array_keys($products);
}
return $products;
}
}
vendor\module\Block\Adminhtml\Category\Tab\Grid\Column\Renderer\SaleableQty.php
<?php
namespace vendor\module\Block\Adminhtml\Category\Tab\Grid\Column\Renderer;
use Magento\Framework\DataObject;
use Magento\InventorySalesAdminUi\Model\GetSalableQuantityDataBySku;
class SaleableQty extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
{
private $getSalableQuantityDataBySku;
public function __construct(
GetSalableQuantityDataBySku $getSalableQuantityDataBySku
) {
$this->getSalableQuantityDataBySku = $getSalableQuantityDataBySku;
}
/**
* get category name
* @param DataObject $row
* @return string
*/
public function render(DataObject $row)
{
if($row['type_id'] != "configurable" && $row['type_id'] != "bundle" && $row['type_id'] != "grouped"){
$sku = $row->getSku();
$salable = $this->getSalableQuantityDataBySku->execute($sku);
return $salable[0]['qty'];
}
}
}
-
I did over ride the Magento\Catalog\Block\Adminhtml\Category\Tab\Product.php and did the quantity column. its working fine. But for salable quantity, I couldn't find a way to list in the grid. Is there any way to do that?– mageFeb 4, 2022 at 5:53
-
you can use the renderer to list the saleable qty in grid please check the edited answer– MehranFeb 4, 2022 at 7:49
-
The answer you provided is corrected and working fine now. but there is an issue came while opening the catalog->product. The page is showing infinity load and while checking system log, ' Argument 1 passed to Magento\InventorySalesAdminUi\Model\GetSalableQuantityDataBySku::execute() must be of the type string, null given, called in /var/www/html/test/vendor/magento/module-inventory-sales-admin-ui/Ui/Component/Listing/Column/SalableQuantity.php on line 70 '.– mageFeb 5, 2022 at 10:23
-
I solved the issue. in my ' catalog_product_entity ' table , there is some SKU showing NULL. So I updated by using the ' UPDATE catalog_product_entity SET sku='' WHERE sku IS NULL; ' query and the issue solved Also, the salable quantity is working fine. Thank you, Mehran for your help– mageFeb 5, 2022 at 10:50
-