Map Reduce script to “Send Email to the Customer when the item is back in stock and delete the record from customer record list”
/**
* @NApiVersion 2.x
* @NScriptType MapReduceScript
* @NModuleScope SameAccount
*/
/****************************************************************************
BP-21 In stock verification - PDP
Date: 14/07/2021
Author: Rosemol
Script Description : Send Email to the Customer when the item is back in stock and delete the record from customer record list
Date created : 14 July 2021
REVISION HISTORY
Revision 1.0 14/07/2021 md: Create
****************************************************************************/
define(
[
'N/email',
'N/runtime',
'N/search',
'N/error',
'N/log',
'N/record',
'N/render',
'N/file',
'./underscore.custom'
], function (
email,
runtime,
search,
error,
log,
record,
render,
file,
_
) {
var Utils = {
record: 'customrecord_back_in_stock',
getSku: function (values) {
var parent = values['GROUP(parent.CUSTRECORD_BACK_ITEM)'];
var child = values['GROUP(custrecord_back_item)'];
if (parent && parent.text !== '- None -') {
parent = parent.text;
// log.debug("parentsubsku",child.text.split(":")[1])
return child.text.split(":")[1];
} else {
return values['GROUP(custrecord_back_item)'].text;
}
},
baseUrl: function (site) {
if (site.value === Utils.getParameterByKey('custscript_bp_id')) {
return Utils.getParameterByKey('custscript_bp_url');
}
},
getParameterByKey: function getParameterByKey(key) {
var script = runtime.getCurrentScript();
return script.getParameter({ name: key });
},
renderHTML: function renderHTML(items, customer, site) {
try {
// log.debug('renderHTMLsgfg', { items: items, customer: customer, site: site })
var renderer = render.create();
renderer.addCustomDataSource({
format: render.DataSource.JSON,
alias: 'ITEMS',
data: JSON.stringify({ items: _.isArray(items) ? items : [items] })
});
renderer.addCustomDataSource({
format: render.DataSource.JSON,
alias: 'CUSTOMER',
data: JSON.stringify(customer)
});
renderer.addCustomDataSource({
format: render.DataSource.JSON,
alias: 'SITE',
data: JSON.stringify(site)
});
log.debug('renderer', renderer)
var templateFile = file.load({
id: Utils.getParameterByKey('custscript_template')
});
// log.debug('templateFile', templateFile)
var tplHtml = templateFile.getContents();
// log.debug('tplHtml', tplHtml)
renderer.templateContent = tplHtml;
// log.debug('tplHtmlrenderer', renderer)
return renderer.renderAsString();
} catch (e) {
log.error('renderHTML', e)
}
},
sendEmail: function sendEmail(items, customer, site) {
try {
// var body = 'Hello,\n' + "These items are now back in stock"
email.send({
author: Utils.getParameterByKey('custscript_email_author'),
recipients: customer.id,
subject: site.name + Utils.getParameterByKey('custscript_email_subject'),
body: Utils.renderHTML(items, customer, site),
relatedRecords: {
entityId: customer.id
}
});
} catch (e) {
log.error('sendEmail', e)
}
},
getWebstoreAvailableLocations: function getWebstoreAvailableLocations() {
// get all the locations that expose stock to the webstore
var locations = [];
var locationSearchObj = search.create({
type: 'location',
filters: [
['isinactive', 'is', 'F'],
'AND',
['makeinventoryavailablestore', 'is', 'T']
],
columns: [
search.createColumn({ name: "internalid", label: "Internal ID" })
]
});
var searchResultCount = locationSearchObj.runPaged().count;
log.debug("locationSearchObj result count", searchResultCount);
locationSearchObj.run().each(function (result) {
locations.push(result.getValue('internalid'));
return true;
});
// log.debug('locations', locations);
return locations.join(',');
}
};
function getInputData() {
var locationIds;
var isLocationsActivated = runtime.isFeatureInEffect({ feature: 'locations' });
// log.debug('isLocationsActivated', isLocationsActivated);
var filters = [
["isinactive", "is", "F"],
"AND",
["custrecord_back_sent", "is", "F"],
"AND",
["custrecord_back_site", "anyof", "3"],
"AND",
['custrecord_back_item.isonline', 'is', 'T'],
'AND',
["custrecord_back_item.locationquantityavailable", "isnotempty", ""]
];
var columns = [
search.createColumn({
name: "custrecord_back_customer",
summary: "GROUP",
label: "Customer"
}),
search.createColumn({
name: "custrecord_back_item",
summary: "GROUP",
label: "Item"
}),
search.createColumn({
name: "custrecord_back_site",
summary: "GROUP",
label: "Site"
}),
search.createColumn({
name: "custrecord_back_sent",
summary: "GROUP",
label: "Sent"
}),
search.createColumn({
name: "internalid",
summary: "GROUP",
label: "Internal ID"
}),
search.createColumn({
name: "custrecord_back_language",
summary: "GROUP",
label: "Language"
}),
search.createColumn({
name: "custrecord_back_locale",
summary: "GROUP",
label: "Locale"
}),
search.createColumn({
name: "displayname",
join: "CUSTRECORD_BACK_ITEM",
summary: "GROUP",
label: "Display Name"
}),
search.createColumn({
name: "storedisplayname",
join: "CUSTRECORD_BACK_ITEM",
summary: "GROUP",
label: "Store Display Name"
}),
search.createColumn({
name: "urlcomponent",
join: "CUSTRECORD_BACK_ITEM",
summary: "GROUP",
label: "URL Component"
}),
search.createColumn({
name: "parent",
join: "CUSTRECORD_BACK_ITEM",
summary: "GROUP",
label: "Parent"
}),
search.createColumn({
name: "internalid",
join: "CUSTRECORD_BACK_ITEM",
summary: "GROUP",
label: "Internal ID"
}),
search.createColumn({
name: "custrecord_back_item_parent",
summary: "GROUP",
label: "Item Parent"
}),
search.createColumn({
name: "urlcomponent",
join: "CUSTRECORD_BACK_ITEM_PARENT",
summary: "GROUP",
label: "URL Component"
}),
search.createColumn({
name: "custrecord_back_currency",
summary: "GROUP",
label: "Currency"
}),
search.createColumn({
name: "firstname",
join: "CUSTRECORD_BACK_CUSTOMER",
summary: "GROUP",
label: "First Name"
}),
search.createColumn({
name: "lastname",
join: "CUSTRECORD_BACK_CUSTOMER",
summary: "GROUP",
label: "Last Name"
}),
search.createColumn({
name: "custitem_item_image",
join: "CUSTRECORD_BACK_ITEM",
summary: "GROUP",
label: "Item_Image"
})
]
if (isLocationsActivated) {
locationIds = Utils.getWebstoreAvailableLocations();
log.debug('locationIds', locationIds);
filters.push(
'AND',
['custrecord_back_item.inventorylocation', 'anyof', locationIds],
'AND',
["sum(custrecord_back_item.locationquantityavailable)", "greaterthan", "0"]
);
columns.push(
search.createColumn({
name: "locationquantityavailable",
join: "CUSTRECORD_BACK_ITEM",
summary: "SUM",
label: "Location Available"
})
)
} else {
filters.push(
'AND',
["sum(custrecord_back_item.quantityavailable)", "greaterthan", "0"]
);
columns.push(
search.createColumn({
name: "quantityavailable",
join: "CUSTRECORD_BACK_ITEM",
summary: "SUM",
label: "Available"
})
)
}
var customrecord_back_in_stockSearchObj = search.create({
type: Utils.record,
filters: filters,
columns: columns
});
var searchResultCount = customrecord_back_in_stockSearchObj.runPaged().count;
log.debug("customrecord_back_in_stockSearchObj result count", searchResultCount);
return customrecord_back_in_stockSearchObj;
}
function map(mapContext) {
var data = JSON.parse(mapContext.value);
log.debug('datacheckkkkkkiiiiinnnnng', data)
var values = data.values;
var recordSubs = {
firstname: values['GROUP(firstname.CUSTRECORD_BACK_CUSTOMER)'],
lastname: values['GROUP(lastname.CUSTRECORD_BACK_CUSTOMER)'],
internalid: values['GROUP(internalid)'].value,
customerid: values['GROUP(custrecord_back_customer)'].value,
item: values['GROUP(custrecord_back_item)'],
currency: values['GROUP(custrecord_back_currency)'],
locale: values['GROUP(custrecord_back_locale)'],
language: values['GROUP(custrecord_back_language)'],
site: values['GROUP(custrecord_back_site)'],
email: values['GROUP(custrecord_back_email)'],
sent: values['GROUP(custrecord_back_sent)'],
displayname: values['GROUP(displayname.CUSTRECORD_BACK_ITEM)'],
storedisplayname: values['GROUP(storedisplayname.CUSTRECORD_BACK_ITEM)'],
urlcomponent: values['GROUP(urlcomponent.CUSTRECORD_BACK_ITEM)'],
parentItem: values['GROUP(custrecord_back_item_parent)'],
parentUrl: values['GROUP(urlcomponent.custrecord_back_item_parent)'],
sku: Utils.getSku(values),
imgURl: values['GROUP(custitem_item_image.CUSTRECORD_BACK_ITEM)']
};
mapContext.write(recordSubs.site.id + '|' + recordSubs.customerid, recordSubs);
}
function reduce(reduceContext) {
//send email for record
// log.debug('reduceContext', reduceContext);
var reduceValues = reduceContext.values;
var itemsBp = [];
var subscriptionsIds = [];
var bpDetails;
_.each(reduceContext.values, function(value) {
var current = JSON.parse(value);
log.debug('current', current);
var urlComponent = '';
var displayName = current.storedisplayname;
var imgURl = "http://bp.sca-jobinandjismi.ml/alphalifecare website Item Images/no_image_available.jpeg";
if (current.parentItem && current.parentItem.value && current.parentUrl) {
urlComponent = current.parentUrl === '- None -' ? Utils.baseUrl(current.site) + 'product/' + current.Item.value :
Utils.baseUrl(current.site) + '/' + current.urlcomponent
} else {
urlComponent = current.urlcomponent === '- None -' ?
Utils.baseUrl(current.site) + 'product/' + current.item.value :
Utils.baseUrl(current.site) + '/' + current.urlcomponent;
}
if (!displayName || (displayName === '- None -')) {
displayName = current.displayName;
}
if (!displayName || (displayName === '- None -')) {
displayName = current.sku;
}
if (current.imgURl != null && current.imgURl != '' && current.imgURl != "" && current.imgURl != undefined) {
var imgFile = file.load({
id: current.imgURl.value
});
imgURl = Utils.baseUrl(current.site) + '/alphalifecare website Item Images/' + encodeURIComponent(imgFile.name);
// log.debug('imgURl', imgURl);
}
if (current.site.value === Utils.getParameterByKey('custscript_bp_id')) {
bpDetails = current;
itemsBp.push({ //item
internalid: current.item,
sku: current.sku,
displayname: displayName,
urlcomponent: urlComponent,
imgURl: imgURl
});
}
log.debug('itemsBp', itemsBp);
subscriptionsIds.push(current.internalid);
});
if (itemsBp.length > 0) {
log.debug('itemsBp', {
itemsBp: itemsBp,
customer: { // customer
id: bpDetails.customerid,
firstname: bpDetails.firstname === '- None -' ? '' : bpDetails.firstname,
lastname: bpDetails.lastname === '- None -' ? '' : bpDetails.lastname
},
site: { //site
name: bpDetails.site.text,
baseUrl: Utils.baseUrl(bpDetails.site),
}
})
Utils.sendEmail(
itemsBp, { // customer
id: bpDetails.customerid,
firstname: bpDetails.firstname === '- None -' ? '' : bpDetails.firstname,
lastname: bpDetails.lastname === '- None -' ? '' : bpDetails.lastname
}, { //site
name: bpDetails.site.text,
baseUrl: Utils.baseUrl(bpDetails.site),
}
);
}
reduceContext.write('sentEmail', {
subscriptionId: subscriptionsIds
});
}
function summarize(summarizeContext) {
var errorMessage = '';
if (summarizeContext.inputSummary.error) {
errorMessage += summarizeContext.inputSummary.error + '\n';
log.error('Input Error', summarizeContext.inputSummary.error);
}
summarizeContext.mapSummary.errors.iterator().each(function(key, error) {
log.error('Map Error for key: ' + key, error);
errorMessage += 'Map Error for key: ' + key + '\n' + error + '\n';
});
summarizeContext.reduceSummary.errors.iterator().each(function(key, error) {
log.error('Reduce Error for key: ' + key, error);
errorMessage += 'Reduce Error for key: ' + key + '\n' + error + '\n';
});
// mark as sent if no errors
if (errorMessage === '') {
summarizeContext.output.iterator().each(function(key, value) {
value = JSON.parse(value);
_.each(value.subscriptionId, function(id) {
log.debug('update email sent for -->', JSON.stringify(id));
record.delete({
type: Utils.record,
id: id
})
// record.submitFields({
// type: Utils.record,
// id: id,
// values: {
// 'custrecord_back_sent': 'F'
// }
// });
});
return true;
});
}
}
return {
getInputData: getInputData,
map: map,
reduce: reduce,
summarize: summarize
};
});