Description
We need to create a script that sends an email to the customer who clicks on the “Notify when item is in stock” button when the item is back in stock. The Custom record created when the button is clicked will be removed after sending the email
/**
* @NApiVersion 2.x
* @NScriptType MapReduceScript
* @NModuleScope SameAccount
*/
/****************************************************************************
BP-21 In stock verification - PDP
Date: 14/07/2021
Author: Jobin & Jismi IT Services LLP
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')
});
var tplHtml = templateFile.getContents();
renderer.templateContent = tplHtml;
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;
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();
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;
return customrecord_back_in_stockSearchObj;
}
function map(mapContext) {
var data = JSON.parse(mapContext.value);
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);
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);
}
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
};
});