Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new site preference for indexing out-of-stock products #218

Open
wants to merge 34 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1b3ddc4
feat:indexoutofstock
htuzel Jan 10, 2025
fd6f0aa
- Cleaned up redundant code related to the `AlgoliaLocalizedProduct` …
htuzel Jan 10, 2025
a003010
Apply suggestions from code review
htuzel Jan 16, 2025
edcd392
fix: correct typo in preference setting for out of stock indexing
htuzel Jan 20, 2025
deeddea
fix: enhance product filtering for Algolia indexing
htuzel Jan 20, 2025
3ce475d
refactor: streamline Algolia data handling and improve test coverage
htuzel Jan 20, 2025
225e26d
fix: improve product filtering and indexing logic for Algolia
htuzel Jan 20, 2025
2ef8208
fix: update mock handling for Algolia record model in tests
htuzel Jan 20, 2025
00b71c7
test: enhance algolia product filtering tests for out-of-stock logic
htuzel Jan 20, 2025
135082f
Merge branch 'develop' into feature/SFCC-269
htuzel Jan 21, 2025
48cd8ab
fix: simplify availability status check in algoliaLocalizedProduct.js
htuzel Jan 21, 2025
ace7106
fix: standardize 'IndexOutOfStock' preference key across files
htuzel Jan 21, 2025
09aff99
fix: added back removed comment
htuzel Jan 27, 2025
50341fd
refactor: improve variant filtering with product filter module
htuzel Jan 27, 2025
2f3185e
test: add comprehensive test cases for master-level indexing with Ind…
htuzel Jan 27, 2025
ad7ea14
chore: increase Cypress page load timeout for more stable testing
htuzel Jan 27, 2025
437ccb3
chore: update Cypress test configuration
htuzel Jan 27, 2025
c411c27
chore: update Cypress CI workflow for browser testing
htuzel Jan 27, 2025
648ad10
fix: remove extra closing brace in algoliaProductIndex.js
htuzel Jan 27, 2025
dfe7048
chore: remove Cypress page load timeout configuration
htuzel Jan 27, 2025
5336413
refactor: improve product stock filtering and indexing logic
htuzel Jan 28, 2025
064e74a
refactor: clean up product stock availability method
htuzel Jan 28, 2025
b4cab2b
feat: enhance product indexing with stock availability filtering
htuzel Jan 28, 2025
663304d
refactor: remove unused stock-related imports in variant record gener…
htuzel Jan 28, 2025
07e9442
chore: restore Cypress page load timeout to 15 seconds
htuzel Jan 29, 2025
d05b4fa
Merge branch 'develop' into feature/SFCC-269
htuzel Jan 30, 2025
921e61c
fix: improve product stock availability indexing logic
htuzel Jan 30, 2025
626cb02
refactor: simplify stock availability check in localized product inde…
htuzel Jan 30, 2025
13c9a33
test: improve Cypress test stability for modal handling
htuzel Jan 30, 2025
d702d6f
refactor: optimize product indexing with stock availability filtering
htuzel Jan 31, 2025
4c141d9
Apply suggestions from code review
htuzel Feb 3, 2025
8ce35f7
feat: enhance product indexing with out-of-stock handling
htuzel Feb 4, 2025
e347eaf
fix: improve variant stock availability check in product indexing
htuzel Feb 4, 2025
2a614ec
chore: remove debug code and unused variable in product indexing
htuzel Feb 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,19 @@ jobs:
- name: Checkout Code
uses: actions/checkout@v3

- name: Install Dependencies for browser
run: |
sudo apt-get install -y \
libnss3 \
libgbm1 \
xvfb
htuzel marked this conversation as resolved.
Show resolved Hide resolved

- name: Run Cypress Tests
uses: cypress-io/github-action@v6
with:
install: npm ci
browser: electron
headless: true
headed: false
browser: chrome
config-file: cypress.config.js
env:
CYPRESS_SANDBOX_HOST: ${{ vars.SANDBOX_HOST }}
Expand Down
1 change: 1 addition & 0 deletions cartridges/bm_algolia/cartridge/controllers/AlgoliaBM.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function handleSettings() {
algoliaData.setPreference('EnableContentSearch', algoliaEnableContentSearch);
algoliaData.setPreference('EnableRecommend', algoliaEnableRecommend);
algoliaData.setPreference('EnablePricingLazyLoad', algoliaEnablePricingLazyLoad);
algoliaData.setPreference('IndexOutOfStock', params.IndexOutOfStock.submitted);
} catch (error) {
Logger.error(error);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,18 @@
</td>
</tr>

<iscomment> Algolia_IndexOutOfStock </iscomment>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually please put this checkbox above all the frontend related settings (below InStock threshold is the best place)

<tr>
<td class="table_detail w s" colspan="1">
<isprint value="${Resource.msg('algolia.label.preference.indexoutofstock', 'algolia', null)}" />
<i class="fa fa-info-circle dw-nc-text-info info-hover"></i>
<div class="tooltip">${Resource.msg('algolia.label.preference.indexoutofstock.help', 'algolia', null)}</div>
</td>
<td class="table_detail w e s">
<input type="checkbox" ${pdict.algoliaData.getPreference('IndexOutOfStock') ? "checked": ""} id="IndexOutOfStock" name="IndexOutOfStock" />
</td>
</tr>

<iscomment> Apply button </iscomment>
<tr>
<td class="w e s buttonspacing" align="right" colspan="2">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ algolia.label.preference.enablessr=Enable server-side rendering
algolia.label.preference.enablecontentsearch=Enable content search
algolia.label.preference.enablerecommend=Recommend
algolia.label.preference.enablePricingLazyLoad=Lazy Loading for prices
algolia.label.preference.indexoutofstock=Index out of stock products
algolia.label.preference.clientid=OCAPI Client ID
algolia.label.preference.clientpassword=OCAPI Client password
algolia.label.button.apply=Apply
Expand All @@ -43,7 +44,7 @@ algolia.label.preference.enablessr.help=Server-side rendering for SFRA's CLP (ca
algolia.label.preference.enablecontentsearch.help=Enable Content Search on the storefront
algolia.label.preference.enablerecommend.help=Enable Algolia Recommend on the SFRA storefront cartridge. See the documentation for additional setup steps
algolia.label.preference.enablePricingLazyLoad.help=When enabled, prices are fetched from SFCC when search results are displayed. Permits to display the most up-to-date promotions without having to index them.

algolia.label.preference.indexoutofstock.help=Index out of stock products, when disabled, only in-stock (ATS higher than the InStock Threshold) products are indexed.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
algolia.label.preference.indexoutofstock.help=Index out of stock products, when disabled, only in-stock (ATS higher than the InStock Threshold) products are indexed.
algolia.label.preference.indexoutofstock.help=Index out of stock products. When disabled, only in-stock (ATS higher than the InStock Threshold) products are indexed.


# v2 job report table
algolia.label.jobtype=job type:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,44 @@ function isInclude(product) {
return true;
}

module.exports.isInclude = isInclude;
/**
* Returns `true` if the product’s ATS >= threshold, false otherwise.
* @param {dw.catalog.Product} product - The SFCC product or variant to check
* @param {number} threshold - The min ATS to consider in-stock
* @returns {boolean}
*/
function isInStock(product, threshold) {
var availabilityModel = product.getAvailabilityModel();
if (!availabilityModel) {
return false;
}

// even if one variant is in stock, we consider the product as in stock
if (product.master || product.variationGroup) {
const variantsIt = product.variants.iterator();
while (variantsIt.hasNext()) {
let variant = variantsIt.next();
let variantAvailabilityModel = variant.getAvailabilityModel();
if (variantAvailabilityModel) {
let variantInvRecord = variantAvailabilityModel.getInventoryRecord();
if (variantInvRecord) {
let variantAtsValue = variantInvRecord.getATS().getValue();
if (variantAtsValue >= threshold) {
return true;
}
}
}
}
}

var invRecord = availabilityModel.getInventoryRecord();
var atsValue = invRecord ? invRecord.getATS().getValue() : 0;
return atsValue >= threshold;
}



module.exports = {
isInStock: isInStock,
isInclude: isInclude,
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ var productModelCustomizer = require('*/cartridge/scripts/algolia/customization/
var ObjectHelper = require('*/cartridge/scripts/algolia/helper/objectHelper');
var jobHelper = require('*/cartridge/scripts/algolia/helper/jobHelper');
var logger = require('*/cartridge/scripts/algolia/helper/jobHelper').getAlgoliaLogger();
var productFilter = require('*/cartridge/scripts/algolia/filters/productFilter');


var extendedProductAttributesConfig;
try {
Expand All @@ -28,6 +30,7 @@ try {
}

const ALGOLIA_IN_STOCK_THRESHOLD = algoliaData.getPreference('InStockThreshold');
const INDEX_OUT_OF_STOCK = algoliaData.getPreference('IndexOutOfStock');

/**
* Get the lowest promotional price for product
Expand Down Expand Up @@ -356,14 +359,15 @@ var aggregatedValueHandlers = {
return pricebooks;
},
in_stock: function (product) {
let availabilityModel = product.getAvailabilityModel();
let threshold = algoliaData.getPreference('InStockThreshold');
let indexOutOfStock = algoliaData.getPreference('IndexOutOfStock');
Comment on lines +362 to +363
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are already loaded once in the constants at the top of the file: ALGOLIA_IN_STOCK_THRESHOLD and INDEX_OUT_OF_STOCK, you can use them

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put this comment before seeing the explanation in the tests. I think it worth refactoring and passing them as a parameter than fetching the preference from this file in the end.


if (product.isMaster() || product.isVariationGroup()) {
return availabilityModel.availabilityStatus === 'IN_STOCK';
let inStock = productFilter.isInStock(product, threshold);

if (!inStock && !indexOutOfStock) {
return undefined;
}

let inventoryRecord = availabilityModel.getInventoryRecord();
let inStock = (inventoryRecord ? inventoryRecord.getATS().getValue() >= ALGOLIA_IN_STOCK_THRESHOLD : false);
return inStock;
},
image_groups: function (product) {
Expand Down Expand Up @@ -444,11 +448,21 @@ var aggregatedValueHandlers = {
const variantsIt = product.variants.iterator();
while (variantsIt.hasNext()) {
var variant = variantsIt.next();

let inStock = productFilter.isInStock(variant, ALGOLIA_IN_STOCK_THRESHOLD);

if (!inStock && !INDEX_OUT_OF_STOCK) {
continue;
}

var baseModel = { in_stock: inStock };

var localizedVariant = new algoliaLocalizedProduct({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that you have already checked if the product is in stock, you can optimize the build of the record by passing a baseModel with the in_stock value:

var baseModel = { in_stock: inStock };
new algoliaLocalizedProduct({ baseModel: baseModel

product: variant,
locale: request.getLocale(),
attributeList: parameters.variantAttributes,
isVariant: true,
baseModel: baseModel,
});
variants.push(localizedVariant);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ var fullRecordUpdate = false;

const VARIANT_LEVEL = 'variant-level';
const MASTER_LEVEL = 'master-level';
var ALGOLIA_IN_STOCK_THRESHOLD;
var INDEX_OUT_OF_STOCK;

/*
* Rough algorithm of chunk-oriented script module execution:
Expand Down Expand Up @@ -72,6 +74,9 @@ exports.beforeStep = function(parameters, stepExecution) {
CPObjectIterator = require('*/cartridge/scripts/algolia/helper/CPObjectIterator');
AlgoliaJobReport = require('*/cartridge/scripts/algolia/helper/AlgoliaJobReport');

ALGOLIA_IN_STOCK_THRESHOLD = algoliaData.getPreference('InStockThreshold');
INDEX_OUT_OF_STOCK = algoliaData.getPreference('IndexOutOfStock');

try {
extendedProductAttributesConfig = require('*/cartridge/configuration/productAttributesConfig.js');
logger.info('Configuration file "productAttributesConfig.js" loaded')
Expand Down Expand Up @@ -359,25 +364,40 @@ exports.process = function(cpObj, parameters, stepExecution) {
let indexName = algoliaData.calculateIndexName('products', locale);
let records = recordsPerLocale[locale];
processedVariantsToSend = records.length;

records.forEach(function(record) {
algoliaOperations.push(new jobHelper.AlgoliaOperation(baseIndexingOperation, record, indexName))
if (INDEX_OUT_OF_STOCK || record.in_stock) {
algoliaOperations.push(new jobHelper.AlgoliaOperation(baseIndexingOperation, record, indexName))
} else {
algoliaOperations.push(new jobHelper.AlgoliaOperation(deleteIndexingOperation, { objectID: record.objectID }, indexName));
}
});
}
} else {
// Master-level indexing
let baseModel = new AlgoliaLocalizedProduct({ product: product, locale: 'default', attributeList: nonLocalizedMasterAttributes });
for (let l = 0; l < siteLocales.size(); ++l) {
let locale = siteLocales[l];
let indexName = algoliaData.calculateIndexName('products', locale);
let localizedMaster = new AlgoliaLocalizedProduct({
product: product,
locale: locale,
attributeList: masterAttributes,
variantAttributes: variantAttributes,
baseModel: baseModel,
});
processedVariantsToSend = localizedMaster.variants ? localizedMaster.variants.length : 0;
algoliaOperations.push(new jobHelper.AlgoliaOperation(baseIndexingOperation, localizedMaster, indexName));
let inStock = productFilter.isInStock(product, ALGOLIA_IN_STOCK_THRESHOLD);
htuzel marked this conversation as resolved.
Show resolved Hide resolved
if (inStock || INDEX_OUT_OF_STOCK) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now you have removed the else condition entirely, but it's needed:
If the master product becomes out of stock, we want to delete it from the Algolia index.

let baseModel = new AlgoliaLocalizedProduct({ product: product, locale: 'default', attributeList: nonLocalizedMasterAttributes });
for (let l = 0; l < siteLocales.size(); ++l) {
let locale = siteLocales[l];
let indexName = algoliaData.calculateIndexName('products', locale);
let localizedMaster = new AlgoliaLocalizedProduct({
product: product,
locale: locale,
attributeList: masterAttributes,
variantAttributes: variantAttributes,
baseModel: baseModel,
});
processedVariantsToSend = localizedMaster.variants ? localizedMaster.variants.length : 0;
algoliaOperations.push(new jobHelper.AlgoliaOperation(baseIndexingOperation, localizedMaster, indexName));
}
} else {
// => product is out-of-stock and IndexOutOfStock=false => must delete from Algolia
for (let l = 0; l < siteLocales.size(); l++) {
let locale = siteLocales[l];
let indexName = algoliaData.calculateIndexName('products', locale);
algoliaOperations.push(new jobHelper.AlgoliaOperation(deleteIndexingOperation, { objectID: cpObj.productID }, indexName));
}
}
}

Expand All @@ -388,22 +408,31 @@ exports.process = function(cpObj, parameters, stepExecution) {
}

if (productFilter.isInclude(product)) {

// Pre-fetch a partial model containing all non-localized attributes, to avoid re-fetching them for each locale
htuzel marked this conversation as resolved.
Show resolved Hide resolved
var baseModel = new AlgoliaLocalizedProduct({ product: product, locale: 'default', attributeList: nonLocalizedAttributes, fullRecordUpdate: fullRecordUpdate });
for (let l = 0; l < siteLocales.size(); l++) {
let locale = siteLocales[l];
let indexName = algoliaData.calculateIndexName('products', locale);
let localizedProduct = new AlgoliaLocalizedProduct({ product: product, locale: locale, attributeList: attributesToSend, baseModel: baseModel, fullRecordUpdate: fullRecordUpdate });
algoliaOperations.push(new jobHelper.AlgoliaOperation(baseIndexingOperation, localizedProduct, indexName));
let inStock = productFilter.isInStock(product, ALGOLIA_IN_STOCK_THRESHOLD);
if (inStock || INDEX_OUT_OF_STOCK) {
// Pre-fetch a partial model containing all non-localized attributes, to avoid re-fetching them for each locale
var baseModel = new AlgoliaLocalizedProduct({ product: product, locale: 'default', attributeList: nonLocalizedAttributes, fullRecordUpdate: fullRecordUpdate });
for (let l = 0; l < siteLocales.size(); l++) {
let locale = siteLocales[l];
let indexName = algoliaData.calculateIndexName('products', locale);
let localizedProduct = new AlgoliaLocalizedProduct({ product: product, locale: locale, attributeList: attributesToSend, baseModel: baseModel, fullRecordUpdate: fullRecordUpdate });
algoliaOperations.push(new jobHelper.AlgoliaOperation(baseIndexingOperation, localizedProduct, indexName));
}
jobReport.processedItemsToSend++;
} else {
// => product is out-of-stock and IndexOutOfStock=false => must delete from Algolia
Comment on lines +422 to +423
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition is not what is documented:
You will end up here just if inStock is false
So if a product is not in stock but INDEX_OUT_OF_STOCK is true, it will be deleted!

It's supposed to be covered by your scenario 29 which you indicated as passed:

# In_stock in Master Level Model Job Will Run Update Type (Stock Change) Index out-of-stock products Product Stock Status Scenario result Result
29 False Variation Product model DeltaIndexJob ⬇️ true False In_stock false

Did you actually run the scenario?
I tested myself and the variant was removed from the index..

You also have a unit test for it but I see it's broken.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok my bad the condition is actually a || and not a &&, I probably made a mistake while testing, this works ok.

for (let l = 0; l < siteLocales.size(); l++) {
var locale = siteLocales[l];
var indexName = algoliaData.calculateIndexName('products', locale);
algoliaOperations.push(new jobHelper.AlgoliaOperation(deleteIndexingOperation, { objectID: cpObj.productID }, indexName));
}
jobReport.processedItemsToSend++;
}
jobReport.processedItemsToSend++;
}
} else {
for (let l = 0; l < siteLocales.size(); l++) {
var locale = siteLocales[l];
var indexName = algoliaData.calculateIndexName('products', locale);
algoliaOperations.push(new jobHelper.AlgoliaOperation(deleteIndexingOperation, { objectID: cpObj.productID }, indexName));
let localeIndexName = algoliaData.calculateIndexName('products', siteLocales[l]);
algoliaOperations.push(new jobHelper.AlgoliaOperation(deleteIndexingOperation, { objectID: cpObj.productID }, localeIndexName));
htuzel marked this conversation as resolved.
Show resolved Hide resolved
}
jobReport.processedItemsToSend++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ var extendedProductAttributesConfig;

const VARIANT_LEVEL = 'variant-level';
const MASTER_LEVEL = 'master-level';
var ALGOLIA_IN_STOCK_THRESHOLD;
var INDEX_OUT_OF_STOCK;

/*
* Rough algorithm of chunk-oriented script module execution:
Expand Down Expand Up @@ -64,6 +66,8 @@ exports.beforeStep = function(parameters, stepExecution) {
productFilter = require('*/cartridge/scripts/algolia/filters/productFilter');
algoliaProductConfig = require('*/cartridge/scripts/algolia/lib/algoliaProductConfig');
AlgoliaJobReport = require('*/cartridge/scripts/algolia/helper/AlgoliaJobReport');
ALGOLIA_IN_STOCK_THRESHOLD = algoliaData.getPreference('InStockThreshold');
INDEX_OUT_OF_STOCK = algoliaData.getPreference('IndexOutOfStock');

try {
extendedProductAttributesConfig = require('*/cartridge/configuration/productAttributesConfig.js');
Expand Down Expand Up @@ -270,7 +274,9 @@ exports.process = function(product, parameters, stepExecution) {
var records = recordsPerLocale[locale];
processedVariantsToSend = records.length;
records.forEach(function(record) {
algoliaOperations.push(new jobHelper.AlgoliaOperation(indexingOperation, record, indexName));
if (INDEX_OUT_OF_STOCK || record.in_stock) {
algoliaOperations.push(new jobHelper.AlgoliaOperation(indexingOperation, record, indexName));
}
});
}
} else {
Expand All @@ -289,8 +295,13 @@ exports.process = function(product, parameters, stepExecution) {
variantAttributes: variantAttributes,
baseModel: baseModel,
});
processedVariantsToSend = localizedMaster.variants ? localizedMaster.variants.length : 0;
algoliaOperations.push(new jobHelper.AlgoliaOperation(indexingOperation, localizedMaster, indexName));

if (!INDEX_OUT_OF_STOCK && (localizedMaster && localizedMaster.variants && (localizedMaster.variants.length === 0))) {
continue;
} else {
processedVariantsToSend = localizedMaster.variants ? localizedMaster.variants.length : 0;
algoliaOperations.push(new jobHelper.AlgoliaOperation(indexingOperation, localizedMaster, indexName));
}
}
}

Expand All @@ -301,6 +312,11 @@ exports.process = function(product, parameters, stepExecution) {
}

if (productFilter.isInclude(product)) {
const inStock = productFilter.isInStock(product, ALGOLIA_IN_STOCK_THRESHOLD);
if (!inStock && !INDEX_OUT_OF_STOCK) {
return [];
}

var algoliaOperations = [];

// Pre-fetch a partial model containing all non-localized attributes, to avoid re-fetching them for each locale
Expand Down
1 change: 1 addition & 0 deletions cypress.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ module.exports = defineConfig({
// Important: return the updated config
return config;
},
pageLoadTimeout: 15000,
},
});
2 changes: 2 additions & 0 deletions cypress/e2e/variation.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ describe('Algolia Search', () => {

// Handle the cookie consent pop-up
cy.get('.affirm').click()

cy.get('.modal-backdrop', { timeout: 4000 }).should('not.exist');
})

it('performs a search and displays results', () => {
Expand Down
10 changes: 10 additions & 0 deletions metadata/algolia/meta/system-objecttype-extensions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ Setting this preference replaces the first two segments, the final index name be
</value-definitions>
</attribute-definition>

<attribute-definition attribute-id="Algolia_IndexOutOfStock">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This preference has not been added to the Algolia group so it's not visible in the Custom Preferences of the site.

(side question: Do you know where I can see its value in that case?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

answer for the side question: No, it is not possible via standard UI, only possible via our custom UI

<display-name xml:lang="x-default">Index Out of Stock</display-name>
<description xml:lang="x-default">Index out of stock products</description>
<type>boolean</type>
<mandatory-flag>false</mandatory-flag>
<externally-managed-flag>false</externally-managed-flag>
<default-value>true</default-value>
</attribute-definition>

<attribute-definition attribute-id="Algolia_LocalesForIndexing">
<display-name xml:lang="x-default">Locales for indexing</display-name>
<description xml:lang="x-default">List of locales that will be used by the indexing jobs</description>
Expand Down Expand Up @@ -274,6 +283,7 @@ Setting this preference replaces the first two segments, the final index name be
<attribute attribute-id="Algolia_EnableContentSearch"/>
<attribute attribute-id="Algolia_EnableRecommend"/>
<attribute attribute-id="Algolia_EnablePricingLazyLoad"/>
<attribute attribute-id="Algolia_IndexOutOfStock"/>
</attribute-group>
</group-definitions>

Expand Down
Loading