Skip to content

Commit 49c6967

Browse files
authored
Add fallback for disabled MSI modules (#283)
* Add fallback for disabled MSI modules * corrected DI and default value * fixed tests * added missing dependency * do not call the MultiSourceInventory class * add phpcs exception * make methods private
1 parent fb60534 commit 49c6967

File tree

10 files changed

+175
-27
lines changed

10 files changed

+175
-27
lines changed

app/code/Meta/BusinessExtension/Model/System/Config.php

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ class Config
7070
public const XML_PATH_FACEBOOK_BUSINESS_EXTENSION_PAGE_ACCESS_TOKEN =
7171
'facebook/business_extension/page_access_token';
7272
private const XML_PATH_FACEBOOK_USE_MULTI_SOURCE_INVENTORY =
73-
'facebook/inventory_management/use_multi_source_inventory';
74-
private const XML_PATH_FACEBOOK_INVENTORY_STOCK = 'facebook/inventory_management/inventory_stock';
73+
'facebook/catalog_management/use_multi_source_inventory';
7574
private const XML_PATH_FACEBOOK_BUSINESS_EXTENSION_OUT_OF_STOCK_THRESHOLD =
7675
'facebook/catalog_management/out_of_stock_threshold';
7776

@@ -331,18 +330,6 @@ public function useMultiSourceInventory($scopeId = null, $scope = null): bool
331330
return (bool)$this->getConfig(self::XML_PATH_FACEBOOK_USE_MULTI_SOURCE_INVENTORY, $scopeId, $scope);
332331
}
333332

334-
/**
335-
* Get inventory stock
336-
*
337-
* @param int $scopeId
338-
* @param int $scope
339-
* @return mixed
340-
*/
341-
public function getInventoryStock($scopeId = null, $scope = null)
342-
{
343-
return $this->getConfig(self::XML_PATH_FACEBOOK_INVENTORY_STOCK, $scopeId, $scope);
344-
}
345-
346333
/**
347334
* Get out of stock threshold
348335
*

app/code/Meta/Catalog/Model/Product/Feed/Builder.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ class Builder
105105
private $builderTools;
106106

107107
/**
108-
* @var InventoryInterface
108+
* @var InventoryInterface|null
109109
*/
110-
private $inventory;
110+
private ?InventoryInterface $inventory = null;
111111

112112
/**
113113
* @var ProductIdentifier
@@ -146,7 +146,6 @@ class Builder
146146
* @param CategoryCollectionFactory $categoryCollectionFactory
147147
* @param BuilderTools $builderTools
148148
* @param ProductIdentifier $productIdentifier
149-
* @param InventoryInterface $inventory
150149
* @param Escaper $escaper
151150
* @param SystemConfig $systemConfig
152151
*/
@@ -155,15 +154,13 @@ public function __construct(
155154
CategoryCollectionFactory $categoryCollectionFactory,
156155
BuilderTools $builderTools,
157156
ProductIdentifier $productIdentifier,
158-
InventoryInterface $inventory,
159157
Escaper $escaper,
160158
SystemConfig $systemConfig
161159
) {
162160
$this->fbeHelper = $fbeHelper;
163161
$this->categoryCollectionFactory = $categoryCollectionFactory;
164162
$this->builderTools = $builderTools;
165163
$this->productIdentifier = $productIdentifier;
166-
$this->inventory = $inventory;
167164
$this->escaper = $escaper;
168165
$this->systemConfig = $systemConfig;
169166
}
@@ -501,6 +498,11 @@ public function getUnitPrice($product)
501498
*/
502499
private function getInventory(Product $product): InventoryInterface
503500
{
501+
if ($this->inventory === null) {
502+
$this->inventory = $this->builderTools->getInventoryObject(
503+
$this->systemConfig->useMultiSourceInventory($this->storeId)
504+
);
505+
}
504506
$this->inventory->initInventoryForProduct($product);
505507
return $this->inventory;
506508
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* Copyright (c) Meta Platforms, Inc. and affiliates.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
namespace Meta\Catalog\Model\Product\Feed\Builder;
22+
23+
use Meta\BusinessExtension\Model\System\Config as SystemConfig;
24+
use Magento\Catalog\Model\Product;
25+
use Magento\CatalogInventory\Api\Data\StockItemInterface;
26+
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory;
27+
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
28+
29+
class Inventory implements InventoryInterface
30+
{
31+
/**
32+
* @var StockItemRepositoryInterface
33+
*/
34+
private $stockItemRepository;
35+
36+
/**
37+
* @var StockItemCriteriaInterfaceFactory
38+
*/
39+
private $stockItemCriteriaInterfaceFactory;
40+
41+
/**
42+
* @var Product
43+
*/
44+
private $product;
45+
46+
/**
47+
* @var SystemConfig
48+
*/
49+
private $systemConfig;
50+
51+
/**
52+
* @var StockItemInterface
53+
*/
54+
private $productStock;
55+
56+
/**
57+
* @param StockItemRepositoryInterface $stockItemRepository
58+
* @param StockItemCriteriaInterfaceFactory $stockItemCriteriaInterfaceFactory
59+
* @param SystemConfig $systemConfig
60+
*/
61+
public function __construct(
62+
StockItemRepositoryInterface $stockItemRepository,
63+
StockItemCriteriaInterfaceFactory $stockItemCriteriaInterfaceFactory,
64+
SystemConfig $systemConfig
65+
) {
66+
$this->stockItemRepository = $stockItemRepository;
67+
$this->stockItemCriteriaInterfaceFactory = $stockItemCriteriaInterfaceFactory;
68+
$this->systemConfig = $systemConfig;
69+
}
70+
71+
/**
72+
* Get stock item
73+
*
74+
* @param Product $product
75+
* @return StockItemInterface|null
76+
*/
77+
public function getStockItem(Product $product): ?StockItemInterface
78+
{
79+
$criteria = $this->stockItemCriteriaInterfaceFactory->create();
80+
$criteria->setProductsFilter($product->getId());
81+
$stocksItems = $this->stockItemRepository->getList($criteria)->getItems();
82+
return array_shift($stocksItems);
83+
}
84+
85+
/**
86+
* Init inventory for product
87+
*
88+
* @param Product $product
89+
* @return $this
90+
*/
91+
public function initInventoryForProduct(Product $product): Inventory
92+
{
93+
$this->product = $product;
94+
$this->productStock = $this->getStockItem($product);
95+
return $this;
96+
}
97+
98+
/**
99+
* Get product stock status
100+
*
101+
* @return string
102+
*/
103+
public function getAvailability(): string
104+
{
105+
return $this->productStock && $this->productStock->getIsInStock()
106+
&& ($this->getInventory() - $this->systemConfig->getOutOfStockThreshold() > 0)
107+
? self::STATUS_IN_STOCK : self::STATUS_OUT_OF_STOCK;
108+
}
109+
110+
/**
111+
* Get available product qty
112+
*
113+
* @return int
114+
*/
115+
public function getInventory(): int
116+
{
117+
if (!($this->product && $this->productStock)) {
118+
return 0;
119+
}
120+
121+
if (!$this->productStock->getManageStock()) {
122+
return self::UNMANAGED_STOCK_QTY; // fake quantity to make product available if Manage Stock is off
123+
}
124+
125+
$outOfStockThreshold = $this->systemConfig->getOutOfStockThreshold($this->product->getStoreId());
126+
return (int)max($this->productStock->getQty() - $outOfStockThreshold, 0);
127+
}
128+
}

app/code/Meta/Catalog/Model/Product/Feed/Builder/InventoryInterface.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,19 @@ interface InventoryInterface
3535
* @param Product $product
3636
* @return $this
3737
*/
38-
public function initInventoryForProduct(Product $product);
38+
public function initInventoryForProduct(Product $product): InventoryInterface;
3939

4040
/**
4141
* Get availability
4242
*
4343
* @return string
4444
*/
45-
public function getAvailability();
45+
public function getAvailability(): string;
4646

4747
/**
4848
* Get inventory
4949
*
5050
* @return int
5151
*/
52-
public function getInventory();
52+
public function getInventory(): int;
5353
}

app/code/Meta/Catalog/Model/Product/Feed/Builder/Tools.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use Exception;
2424
use Magento\Catalog\Model\Product;
2525
use Magento\Framework\Currency;
26+
use Magento\Framework\ObjectManagerInterface;
2627
use Magento\Framework\Pricing\PriceCurrencyInterface;
2728
use Magento\Framework\Escaper;
2829
use Meta\BusinessExtension\Model\System\Config as SystemConfig;
@@ -35,6 +36,11 @@ class Tools
3536
*/
3637
private $priceCurrency;
3738

39+
/**
40+
* @var ObjectManagerInterface
41+
*/
42+
private $objectManager;
43+
3844
/**
3945
* @var Escaper
4046
*/
@@ -54,17 +60,20 @@ class Tools
5460
* Tools constructor
5561
*
5662
* @param PriceCurrencyInterface $priceCurrency
63+
* @param ObjectManagerInterface $objectManager
5764
* @param Escaper $escaper
5865
* @param SystemConfig $systemConfig
5966
* @param CatalogHelper $catalogHelper
6067
*/
6168
public function __construct(
6269
PriceCurrencyInterface $priceCurrency,
70+
ObjectManagerInterface $objectManager,
6371
Escaper $escaper,
6472
SystemConfig $systemConfig,
6573
CatalogHelper $catalogHelper
6674
) {
6775
$this->priceCurrency = $priceCurrency;
76+
$this->objectManager = $objectManager;
6877
$this->escaper = $escaper;
6978
$this->systemConfig = $systemConfig;
7079
$this->catalogHelper = $catalogHelper;
@@ -227,4 +236,19 @@ public function getProductSalePriceEffectiveDate(Product $product)
227236
}
228237
return '';
229238
}
239+
240+
/**
241+
* Get inventory object
242+
*
243+
* @param bool $useMultiSource
244+
* @return InventoryInterface
245+
*/
246+
public function getInventoryObject(bool $useMultiSource = true): InventoryInterface
247+
{
248+
//phpcs:disable Magento2.PHP.LiteralNamespaces
249+
return $useMultiSource
250+
? $this->objectManager->get('Meta\Catalog\Model\Product\Feed\Builder\MultiSourceInventory')
251+
: $this->objectManager->get('Meta\Catalog\Model\Product\Feed\Builder\Inventory');
252+
//phpcs:enable Magento2.PHP.LiteralNamespaces
253+
}
230254
}

app/code/Meta/Catalog/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"magento/module-inventory-sales-api": "*",
99
"magento/module-backend": "*",
1010
"magento/module-catalog": "*",
11+
"magento/module-catalog-inventory": "*",
1112
"magento/module-configurable-product": "*",
1213
"magento/module-config": "*",
1314
"magento/module-eav": "*",

app/code/Meta/Catalog/etc/adminhtml/system.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@
1414
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
1515
<comment>Enable catalog syncing with Meta</comment>
1616
</field>
17-
<field id="product_feed" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="1">
17+
<field id="product_feed" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="1">
1818
<label>Push Products</label>
1919
<depends>
2020
<field id="facebook_business_extension/catalog_management/enable_catalog_sync">1</field>
2121
</depends>
2222
<frontend_model>Meta\Catalog\Block\Adminhtml\System\Config\ProductFeed</frontend_model>
2323
</field>
24+
<field id="use_multi_source_inventory" translate="label comment" type="select" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="1">
25+
<label>Use Multi Source Inventory</label>
26+
<config_path>facebook/catalog_management/use_multi_source_inventory</config_path>
27+
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
28+
<comment>Set to 'Yes' if you'd like to use Magento's Multi Source Inventory (MSI) for products sold on Meta</comment>
29+
</field>
2430
<field id="price_incl_tax" translate="label comment" type="select" sortOrder="60" showInDefault="0" showInWebsite="0" showInStore="0">
2531
<label>Price Including Tax</label>
2632
<depends>
@@ -30,7 +36,7 @@
3036
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
3137
<comment>Use price including tax in feed. Should be "No" for the US and "Yes" for the UK. Note: only works if Sales -> Tax -> Price Display Settings -> Display Product Prices In Catalog is set to "Including Tax"</comment>
3238
</field>
33-
<field id="out_of_stock_threshold" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="1">
39+
<field id="out_of_stock_threshold" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="0" showInStore="1">
3440
<label>Out-of-Stock Threshold</label>
3541
<depends>
3642
<field id="facebook_business_extension/catalog_management/enable_catalog_sync">1</field>

app/code/Meta/Catalog/etc/config.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<price_incl_tax>0</price_incl_tax>
88
<collections_sync>0</collections_sync>
99
<out_of_stock_threshold>0</out_of_stock_threshold>
10+
<use_multi_source_inventory>1</use_multi_source_inventory>
1011
</catalog_management>
1112
</facebook>
1213
</default>

app/code/Meta/Catalog/etc/di.xml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<?xml version="1.0"?>
22
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
33
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
4-
<preference for="Meta\Catalog\Model\Product\Feed\Builder\InventoryInterface" type="Meta\Catalog\Model\Product\Feed\Builder\MultiSourceInventory" />
5-
64
<virtualType name="Meta\Catalog\Model\Logger\ProductFeedDebugger" type="Magento\Framework\Logger\Handler\Base">
75
<arguments>
86
<argument name="fileName" xsi:type="string">/var/log/facebook/product-feed.log</argument>
@@ -66,7 +64,7 @@
6664
<item name="9" xsi:type="array">
6765
<item name="value" xsi:type="string">Apparel &amp; Accessories > Handbag &amp; Wallet Accessories</item>
6866
<item name="label" xsi:type="string">Apparel &amp; Accessories > Handbag &amp; Wallet Accessories</item>
69-
</item>
67+
</item>
7068
<item name="10" xsi:type="array">
7169
<item name="value" xsi:type="string">Apparel &amp; Accessories > Handbags, Wallets &amp; Cases</item>
7270
<item name="label" xsi:type="string">Apparel &amp; Accessories > Handbags, Wallets &amp; Cases</item>

app/code/Meta/Catalog/etc/module.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<sequence>
55
<module name="Magento_Backend"/>
66
<module name="Magento_Catalog"/>
7+
<module name="Magento_CatalogInventory"/>
78
<module name="Magento_ConfigurableProduct"/>
89
<module name="Magento_Config"/>
910
<module name="Magento_Customer"/>

0 commit comments

Comments
 (0)