Salesforce Commerce Cloud – known as ‘Demandware’ until the recent acquisition by Salesforce – is used by major global retail brands including Adidas, Burton, Puma, and Lacoste. It is a highly scalable, cloud-based software-as-a-service (SaaS) ecommerce solution. It offers best-in-class features and functionality developed and refined over many years to provide a highly optimised ecommerce experience.
The basic proposition of the platform is that, by offering ecommerce as a SaaS solution, it frees your business from the demands of managing a technical roadmap – or figuring out how to stay ahead of the curve when it comes to best practice ecommerce features.
Salesforce Commerce Cloud uses XML files for maintaining Pricebook and inventory. During the testing/development phase – when the system connectors are not working – feeding the inventory/price to the store – you need to provide the inventory/pricebook manually. Instead of worrying about creating an XML, you can use the below code to generate the pricebook and inventory.
Pricebook generator
Generates a pricebook.xml. You can define the pricebook in the file.
What you need
- Some knowledge of Node.js or JS
- Nodejs installed on your system
- Import/Export permission on SFCC Dev/Demo environment
- Names of the pricebooks (Sales/List)
- CSV file with Product & Pricing information
The Code
//fill this up var pricebook = ' '; /// the pricebook id...should be something like brandname-pricebook-sale-list var currency = 'USD' // replace with the right currency - has to be 3 chars var inputPricebook = ' ' // filename of the CSV of product-price mapping - make sure it is in the same directory as this file. var outputXML = 'pricebook.xml' // rename the output XML file var headerChecker = 0 // = 1 if there is a file header var defaultPrice = 203 const parse = require('csv-parse'); //install first using npm var fs = require('fs'); var wstream = fs.createWriteStream(outputXML); wstream.write('<?xml version="1.0" encoding="UTF-8"?>'+ '<pricebooks xmlns="http://www.demandware.com/xml/impex/pricebook/2006-10-31">'+ '<pricebook>\n<header pricebook-id="'+pricebook+'">'+ '<currency>'+currency+'</currency>'+ '<online-flag>true</online-flag>'+ '</header>\n<price-tables>'); var lineReader = require('readline').createInterface({ input: require('fs').createReadStream(inputPricebook) }); var counter = 0; //create a function that starts reading the file line by line... and stores the details in an object. async function getLineValues(){ var objOfProducts = {}; var bigArray = []; // this guy will contain the line in an array format lineReader.on('line', await function (line) { if(headerChecker != 0){ //setthevalues: bigArray = CSVtoArray(line); var productId = bigArray[0]; var price = bigArray[1]?bigArray[1]:defaultPrice; //this checks if there is a value. If there is no value, it puts the default value. productString += '<price-table product-id="'+productId+'">\n' +'<amount quantity="1">'+price+'</amount>\n' +'</price-table>\n\n' } headerChecker++; console.log('Processed: ' +headerChecker + ' lines'); }) .on('close', async function(){ await wstream.write(productString + '</price-tables>\n</pricebook>\n</pricebooks>'); wstream.close(); }); } getLineValues(); // trigger the function /* ========DO NOT TOUCH THIS FUNCTION ==================*/ function CSVtoArray(text) { var re_valid = /^\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*(?:,\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*)*$/; var re_value = /(?!\s*$)\s*(?:'([^'\\]*(?:\\[\S\s][^'\\]*)*)'|"([^"\\]*(?:\\[\S\s][^"\\]*)*)"|([^,'"\s\\]*(?:\s+[^,'"\s\\]+)*))\s*(?:,|$)/g; // Return NULL if input string is not well formed CSV string. if (!re_valid.test(text)) return null; var a = []; // Initialize array to receive values. text.replace(re_value, // "Walk" the string using replace with callback. function(m0, m1, m2, m3) { // Remove backslash from \' in single quoted values. if (m1 !== undefined) a.push(m1.replace(/\\'/g, "'")); // Remove backslash from \" in double quoted values. else if (m2 !== undefined) a.push(m2.replace(/\\"/g, '"')); else if (m3 !== undefined) a.push(m3); return ''; // Return empty string. }); // Handle special case of empty last value. if (/,\s*$/.test(text)) a.push(''); return a; };
Getting the Salesforce Pricebook
The following steps should simplify affairs. This is aimed at a beginner level:
- Install nodejs if you haven’t already (if you’re using Mac, please use Homebrew to install nodejs – I find it easier to manage using Brew).
- Create a new directory in Terminal/Powershell.
mkdir pricebook
cd pricebook - Hopefully, you have a CSV that contains the product-id and the price of the product. (if you have two prices in the same CSV, break it up into different CSV. Excel should do the trick). Final file should have only:
Product-id, price - Type ‘npm install csv-parse’ to install the csv-parse library
- Wait for the installation to complete
- Create a new file & open it:
touch pricebookgen.js
edit pricebookgen.js - Fill up the first section.
- Save the file
- Run the script:
node pricebookgen.js - Verify the output
After verification, you can open SFCC Business Manager and upload the file through the Import/Export File option under Product & Catalog Section in the Merchant Menu. Import the pricebook. Check for errors.
You can verify that the prices are working by viewing the pricebook directly.
That’s all! If you are facing issues, please feel free to reach out to me with your questions. Comment here or DM me.
Thank you for reading. I’ll be making more SFCC oriented quick-wins and training articles here, so please subscribe!