0

Requirement: I want to update the value of a custom attribute (name: badges) (type: enum-of-strings) for a Product via code. I want to set the value "bestSeller" as selected. How should I do that update because the code below is not working?

Screenshot of the Custom Attribute in Business Manager

Code snippet:

function updateBestSeller() {
var ProductMgr = require('dw/catalog/ProductMgr');
var Site = require('dw/system/Site');
var UUIDUtils = require('dw/util/UUIDUtils');
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var currentSite = Site.getCurrent();
var bestSellerOrderUnits = Object.hasOwnProperty.call(currentSite.preferences.custom, 'bestSellerOrderUnits') ? currentSite.getCustomPreferenceValue('bestSellerOrderUnits') : 0;
try {
        Transaction.wrap(function () {
            var count = 1;
            var products = ProductMgr.queryAllSiteProducts();sni
            var HashSet = require('dw/util/HashSet');
             var badges = new HashSet();
            if (products.count > 0) {
                while (products.hasNext() && count < 5) {
                    var product = products.next();
                        var badges = [];
                        badges.push('bestSeller');
                        if (Object.hasOwnProperty.call(product.custom, 'badges')) {
                            product.custom.badges = badges
                        }
                        count++;
                        Logger.debug('{0}',product.ID);
                }
            }
            products.close();
        });
} catch (ex) {
    Logger.error(ex.toString());
    return new Status(Status.ERROR, 'ERROR', 'UPDATE failed');
}
return new Status(Status.OK, 'OK', 'UPDATE successful');

}

sholsinger
  • 3,028
  • 2
  • 23
  • 40
BalMukund
  • 1
  • 1

1 Answers1

2

I think what is probably happening here is that your attempt to validate that a product has a badges key in the product.custom attribute collection is failing. This prevents the update from occurring.

I suggest removing the condition around the following line: product.custom.badges = badges;

If that line were to not execute, then the update to the database would never occur.

The way custom attributes work is that they will never exist until a value is set for that attribute for a given persistent object. (eg: Product) So checking to see if it exists via something like: 'badges' in product.custom (which is the recommended way) will often be false even when the custom attribute definition exists because many products have never had a badge value set. Once an object has had a value set to a particular custom attribute even if it is now set to null then it will exist.

Additionally, there are some other issues with the code that may be causing problems. One example is defining the badges variable twice within the same scope. Another example is sni that is placed at the end of the line where you define the products variable. This is likely causing an error in your code. Finally, it is a good practice to avoid the use of the queryAllSiteProducts method if you can. An alternative may be to use the ProductSearchModel instead; This may not always meet your need, but it is a good idea to rule it out before resorting to queryAllSiteProducts for performance reasons.

Something else to consider is that if badges currently has any selected values, you'll be overwriting those values with the code you have today. Consider setting badges initially to [] then check to see if there is a value for that product by doing:

if ('badges' in product.custom && !empty(product.custom.badges) {
  badges = product.custom.badges;
}
sholsinger
  • 3,028
  • 2
  • 23
  • 40