Incorrect Stock Status with Multi-Source Inventory
Problem
When using Magento’s Multi-Source Inventory , you may encounter scenarios where the stock status synced with Klevu doesn’t match the availability in the webstore.
Potential Solutions
Replace “Is Available” Check With “Is Salable”
Often, the problem can be traced to the Klevu integration checking whether is a product is available, rather than is salable, in the pipeline extraction.
We can validate this as a root cause with a small modification to the pipeline responsible for extracting product data, modifying the in_stock extract for products and variants found in the following locations:
- https://github.com/klevu/module-m2-indexing-products/blob/main/etc/pipeline/product/attributes/in_stock.yml
- https://github.com/klevu/module-m2-indexing-products/blob/main/etc/pipeline/product/attributes/in_stock/variant.yml
The specifics of modifying attribute data via pipeline customisations can be found in the following article: Changing Attribute Data Sent to Klevu IndexesChanging Attribute Data Sent to Klevu Indexes - Klevu Magento v4
Override the Extraction Method for Stock Status
Following the above article’s steps:
1. The YAML paths we need to modify are
- For Variant Products
- stages.iterateIndexingRecordsBatch.stages .iterateIndexingRecords.stages.processProduct.stages .variantProduct.stages.generateRecord.stages.attributes.stages .inStock.stages.checkStock.stages.getParentStock
- stages.iterateIndexingRecordsBatch.stages .iterateIndexingRecords.stages.processProduct.stages .variantProduct.stages.generateRecord.stages.attributes.stages .inStock.stages.checkStock.stages.getVariantStock
- For All Other Product Types
- stages.iterateIndexingRecordsBatch.stages .iterateIndexingRecords.stages.processProduct.stages .configurableProduct.stages.generateRecord.stages.attributes.stages .inStock.stages.getStock
- stages.iterateIndexingRecordsBatch.stages .iterateIndexingRecords.stages.processProduct.stages .groupedProduct.stages.generateRecord.stages.attributes.stages .inStock.stages.getStock
- stages.iterateIndexingRecordsBatch.stages .iterateIndexingRecords.stages.processProduct.stages .bundleProduct.stages.generateRecord.stages.attributes.stages .inStock.stages.getStock
- stages.iterateIndexingRecordsBatch.stages .iterateIndexingRecords.stages.processProduct.stages .virtualProduct.stages.generateRecord.stages.attributes.stages .inStock.stages.getStock
- stages.iterateIndexingRecordsBatch.stages .iterateIndexingRecords.stages.processProduct.stages .downloadableProduct.stages.generateRecord.stages.attributes.stages .inStock.stages.getStock
- stages.iterateIndexingRecordsBatch.stages .iterateIndexingRecords.stages.processProduct.stages .default.stages.generateRecord.stages.attributes.stages .inStock.stages.getStock
2. The change required is to change the extraction method from ::isAvailable() to ::isSalable()
3. Express the changes as YAML
- Variant Products
stages:
inStock:
stages:
checkStock:
stages:
getParentStock:
pipeline: Stage\Extract
args:
extraction: 'currentParentProduct::isSalable()'
getVariantStock:
pipeline: Stage\Extract
args:
extraction: 'currentProduct::isSalable()'
transformations: ToBooleanyAs the getParentStock stage essentially acts as a guard clause, you may not want or need to override this stage, depending on your site’s set up.
- All Other Product Types
stages:
inStock:
stages:
getStock:
pipeline: Stage\Extract
args:
extraction: 'currentProduct::isSalable()'
transformations: ToBoolean4. Implement the changes in a local or staging environment The easiest way is to add the above snippets under the attributes path for each applicable product type under var/klevu/indexing/pipeline/product/add_update.overrides.yml and trigger a sync. As this file is already registered, it will not require a recompilation before testing, allowing faster feedback on whether the change addresses the issue.
5. Transfer the changes to a dedicated customisation module
Complete YAML override based on above
Suggested filepath within module: etc/pipeline/indexing/product/add_update.overrides.yml
stages:
iterateIndexingRecordsBatch:
stages:
iterateIndexingRecords:
stages:
processProduct:
stages:
variantProduct:
stages:
generateRecord:
stages:
attributes:
stages:
inStock:
stages:
checkStock:
stages:
getParentStock:
pipeline: Stage\Extract
args:
extraction: 'currentParentProduct::isSalable()'
getVariantStock:
pipeline: Stage\Extract
args:
extraction: 'currentProduct::isSalable()'
transformations: ToBoolean
configurableProduct:
stages:
generateRecord:
stages:
attributes:
stages:
inStock:
stages:
inStock:
stages:
getStock:
pipeline: Stage\Extract
args:
extraction: 'currentProduct::isSalable()'
transformations: ToBoolean
groupedProduct:
stages:
generateRecord:
stages:
attributes:
stages:
inStock:
stages:
inStock:
stages:
getStock:
pipeline: Stage\Extract
args:
extraction: 'currentProduct::isSalable()'
transformations: ToBoolean
bundleProduct:
stages:
generateRecord:
stages:
attributes:
stages:
inStock:
stages:
inStock:
stages:
getStock:
pipeline: Stage\Extract
args:
extraction: 'currentProduct::isSalable()'
transformations: ToBoolean
virtualProduct:
stages:
generateRecord:
stages:
attributes:
stages:
inStock:
stages:
inStock:
stages:
getStock:
pipeline: Stage\Extract
args:
extraction: 'currentProduct::isSalable()'
transformations: ToBoolean
downloadableProduct:
stages:
generateRecord:
stages:
attributes:
stages:
inStock:
stages:
inStock:
stages:
getStock:
pipeline: Stage\Extract
args:
extraction: 'currentProduct::isSalable()'
transformations: ToBoolean
default:
stages:
generateRecord:
stages:
attributes:
stages:
inStock:
stages:
inStock:
stages:
getStock:
pipeline: Stage\Extract
args:
extraction: 'currentProduct::isSalable()'
transformations: ToBooleanAnd registration changes to be added to etc/di.xml
<virtualType name="Klevu\IndexingProducts\Service\Provider\PipelineConfigurationOverridesFilepathsProvider\Add">
<arguments>
<argument name="pipelineConfigurationOverrideFilepaths" xsi:type="array">
<item name="vendor_klevuindexingstockstatus_indexing_product_add_update"
xsi:type="string">Vendor_KlevuIndexingStockStatus::etc/pipeline/indexing/product/add_update.overrides.yml</item>
</argument>
</arguments>
</virtualType>
<virtualType name="Klevu\IndexingProducts\Service\Provider\PipelineConfigurationOverridesFilepathsProvider\Update">
<arguments>
<argument name="pipelineConfigurationOverrideFilepaths" xsi:type="array">
<item name="vendor_klevuindexingstockstatus_indexing_product_add_update"
xsi:type="string">Vendor_KlevuIndexingStockStatus::etc/pipeline/indexing/product/add_update.overrides.yml</item>
</argument>
</arguments>
</virtualType>6. Deploy the customisation module to production; requeue any affected products; and trigger an entity sync
Sample module: Vendor_KlevuIndexingStockStatus on Github