Skip to content

Commit 8c9d8ed

Browse files
committed
PB-107: Display total number of products matched into ProductsList
1 parent 8cef68e commit 8c9d8ed

File tree

4 files changed

+84
-29
lines changed

4 files changed

+84
-29
lines changed

app/code/Magento/PageBuilder/Controller/Adminhtml/Form/Element/ProductTotals.php

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,14 @@ class ProductTotals extends \Magento\Backend\App\Action implements HttpPostActio
5757
private $stockFilter;
5858

5959
/**
60-
* Constructor.
61-
*
6260
* @param \Magento\Backend\App\Action\Context $context
6361
* @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
6462
* @param \Magento\Rule\Model\Condition\Sql\Builder $sqlBuilder
6563
* @param \Magento\CatalogWidget\Model\Rule $rule
6664
* @param \Magento\Widget\Helper\Conditions $conditionsHelper
6765
* @param \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
6866
* @param \Magento\Framework\Controller\Result\JsonFactory $jsonFactory
67+
* @param \Magento\CatalogInventory\Helper\Stock $stockFilter
6968
*/
7069
public function __construct(
7170
\Magento\Backend\App\Action\Context $context,
@@ -115,11 +114,12 @@ private function getConditions()
115114
/**
116115
* Prepare and return product collection
117116
*
118-
* @return \Magento\Catalog\Model\ResourceModel\Product\Collection
117+
* @return Collection
118+
* @throws \Magento\Framework\Exception\LocalizedException
119119
*/
120120
private function createCollection()
121121
{
122-
/** @var $collection \Magento\Catalog\Model\ResourceModel\Product\Collection */
122+
/** @var $collection Collection */
123123
$collection = $this->productCollectionFactory->create();
124124

125125
/** @var \Magento\Rule\Model\Condition\Combine $conditions */
@@ -143,6 +143,8 @@ public function execute()
143143
{
144144
/** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */
145145
$collection = $this->createCollection();
146+
147+
// Exclude any linked products, e.g. simple products assigned to a configurable, bundle or group
146148
$collection->getSelect()->joinLeft(
147149
['super_link_table' => $collection->getTable('catalog_product_super_link')],
148150
'super_link_table.product_id = e.entity_id',
@@ -153,20 +155,44 @@ public function execute()
153155
['product_id']
154156
)->where('link_table.product_id IS NULL OR super_link_table.product_id IS NULL');
155157

156-
// Clone the collection before we add enabled status filter
157-
$disabledProductsCollection = clone $collection;
158-
$disabledProductsCollection->addAttributeToFilter('status', Status::STATUS_DISABLED);
159-
160-
// Only display enabled products in totals count
161-
$collection->addAttributeToFilter('status', Status::STATUS_ENABLED);
162-
$collection->setVisibility(Visibility::VISIBILITY_BOTH);
163-
$this->stockFilter->addIsInStockFilterToCollection($collection);
158+
// Retrieve all disabled products
159+
$disabledCollection = clone $collection;
160+
$disabledCollection->addAttributeToFilter('status', Status::STATUS_DISABLED);
161+
162+
// Retrieve all not visible individually products
163+
$notVisibleCollection = clone $collection;
164+
$notVisibleCollection->addAttributeToFilter(
165+
'visibility',
166+
[
167+
Visibility::VISIBILITY_NOT_VISIBLE,
168+
Visibility::VISIBILITY_IN_SEARCH
169+
]
170+
);
171+
172+
// Retrieve in stock products, then subtract them from the total
173+
$outOfStockCollection = clone $collection;
174+
$this->stockFilter->addIsInStockFilterToCollection($outOfStockCollection);
175+
// Remove existing stock_status where condition from query
176+
$outOfStockWhere = $outOfStockCollection->getSelect()->getPart(\Magento\Framework\DB\Select::WHERE);
177+
$outOfStockWhere = array_filter(
178+
$outOfStockWhere,
179+
function ($whereCondition) {
180+
return !stristr($whereCondition, 'stock_status');
181+
}
182+
);
183+
$outOfStockCollection->getSelect()->setPart(\Magento\Framework\DB\Select::WHERE, $outOfStockWhere);
184+
$outOfStockCollection->getSelect()->where(
185+
'stock_status_index.stock_status = ?',
186+
\Magento\CatalogInventory\Model\Stock\Status::STATUS_OUT_OF_STOCK
187+
);
164188

165189
return $this->jsonFactory->create()
166190
->setData(
167191
[
168192
'total' => $collection->getSize(),
169-
'disabled' => $disabledProductsCollection->getSize()
193+
'disabled' => $disabledCollection->getSize(),
194+
'notVisible' => $notVisibleCollection->getSize(),
195+
'outOfStock' => $outOfStockCollection->getSize(),
170196
]
171197
);
172198
}

app/code/Magento/PageBuilder/i18n/en_US.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,3 +305,7 @@ OK,OK
305305
"Stock: low stock first","Stock: low stock first"
306306
"Stock: high stock first","Stock: high stock first"
307307
"Comma separated product SKUs.","Comma separated product SKUs."
308+
"of %1 total","of %1 total"
309+
"%1 disabled","%1 disabled"
310+
"%1 not visible","%1 not visible"
311+
"%1 out of stock","%1 out of stock"

app/code/Magento/PageBuilder/view/adminhtml/ui_component/pagebuilder_products_form.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@
222222
<field name="product_totals" sortOrder="20" formElement="input" component="Magento_PageBuilder/js/form/element/product-totals">
223223
<argument name="data" xsi:type="array">
224224
<item name="config" xsi:type="array">
225-
<item name="default" xsi:type="string">of ${ $.totalProductCount } (${ $.totalDisabledProducts } disabled)</item>
225+
<item name="default" xsi:type="string">of ${ $.totalProductCount } total</item>
226226
<item name="url" xsi:type="url" path="pagebuilder/form/element_producttotals"/>
227227
</item>
228228
</argument>

app/code/Magento/PageBuilder/view/adminhtml/web/js/form/element/product-totals.js

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ define([
1919
formData: {},
2020
totalProductCount: 0,
2121
totalDisabledProducts: 0,
22+
totalNotVisibleProducts: 0,
23+
totalOutOfStockProducts: 0,
2224
listens: {
2325
conditionOption: 'updateProductTotals',
24-
conditionValue: 'updateProductTotals',
26+
conditionValue: 'updateProductTotals'
2527
},
2628
imports: {
2729
formData: '${ $.provider }:data'
@@ -30,27 +32,34 @@ define([
3032
value: false
3133
},
3234
url: null,
33-
valuePlaceholder: $t('of %1 (%2 disabled)'),
35+
valuePlaceholder: $t('of %1 total'),
36+
disabledPlaceholder: $t('%1 disabled'),
37+
notVisiblePlaceholder: $t('%1 not visible'),
38+
outOfStockPlaceholder: $t('%1 out of stock'),
3439
showSpinner: true,
3540
loading: false
3641
},
3742

3843
/** @inheritdoc */
3944
initObservable: function () {
4045
return this._super()
41-
.observe('value totalProductCount totalDisabledProducts loading');
46+
.observe('value totalProductCount totalDisabledProducts totalNotVisibleProducts ' +
47+
'totalOutOfStockProducts loading');
4248
},
4349

4450
/**
4551
* Update product count.
4652
*
4753
*/
4854
updateProductTotals: _.debounce(function () {
55+
var totalText,
56+
negativeTotals = [];
57+
4958
if (!this.conditionOption || _.isEmpty(this.formData)) {
5059
return;
5160
}
5261

53-
if (this.conditionOption === 'category_ids' && typeof this.formData[this.conditionOption] != "string") {
62+
if (this.conditionOption === 'category_ids' && typeof this.formData[this.conditionOption] != 'string') {
5463
this.formData[this.conditionOption] = '';
5564
}
5665

@@ -65,19 +74,35 @@ define([
6574
conditionValue: this.formData['conditions_encoded']
6675
}
6776
}).done(function (response) {
68-
this.totalProductCount(response['total']);
69-
this.totalDisabledProducts(response['disabled']);
70-
this.value(
71-
this.valuePlaceholder
72-
.replace('%1', this.totalProductCount())
73-
.replace('%2', this.totalDisabledProducts())
74-
);
75-
this.loading(false);
76-
}.bind(this)
77-
).fail(function () {
77+
this.totalProductCount(parseInt(response.total, 10));
78+
this.totalDisabledProducts(parseInt(response.disabled, 10));
79+
this.totalNotVisibleProducts(parseInt(response.notVisible, 10));
80+
this.totalOutOfStockProducts(parseInt(response.outOfStock, 10));
81+
totalText = this.valuePlaceholder
82+
.replace('%1', parseInt(response.total, 10));
83+
84+
if (parseInt(response.disabled, 10) > 0) {
85+
negativeTotals.push(this.disabledPlaceholder.replace('%1', parseInt(response.disabled, 10)));
86+
}
87+
88+
if (parseInt(response.notVisible, 10) > 0) {
89+
negativeTotals.push(this.notVisiblePlaceholder.replace('%1', parseInt(response.notVisible, 10)));
90+
}
91+
92+
if (parseInt(response.outOfStock, 10) > 0) {
93+
negativeTotals.push(this.outOfStockPlaceholder.replace('%1', parseInt(response.outOfStock, 10)));
94+
}
95+
96+
if (negativeTotals.length > 0) {
97+
totalText += ' (' + negativeTotals.join(', ') + ')';
98+
}
99+
100+
this.value(totalText);
101+
this.loading(false);
102+
}.bind(this)).fail(function () {
78103
this.value($t('An unknown error occurred. Please try again.'));
79104
this.loading(false);
80105
}.bind(this));
81-
}, 10),
106+
}, 10)
82107
});
83108
});

0 commit comments

Comments
 (0)