Requirement:
Over a seven-day period, we have issued email alerts to customers to recognize the sales order is ready for distribution.
We are not checking the partial item fulfillment situation of the sales order in the present functionality.
When several item fulfilment records are created from the same sales order, the consumer becomes confused as to which items are ready to ship.
For differentiating the partial item fulfilment scenario, the script must be updated as well as the new logic.
Solution:
/**
* @NApiVersion 2.1
* @NScriptType MapReduceScript
*/
/************************************************************************************************
* * Corp Design, Inc| CDU-858 | Email sending functionality for IF creation before 7 days
*************************************************************************************************
*
* Author: Jobin & Jismi IT Services LLP
*
* Date Created : 01.04.2022
*
* REVISION HISTORY
*
***********************************************************************************************//
define(['N/email', 'N/file', 'N/http', 'N/https', 'N/record', 'N/search'],
/**
* @param{email} email
* @param{file} file
* @param{http} http
* @param{https} https
* @param{record} record
* @param{search} search
*/
(email, file, http, https, record, search) => {
function fetchIFusingSearch(){
try{
var itemfulfillmentSearchObj = search.create({
type: "itemfulfillment",
filters:
[
["type","anyof","ItemShip"],
"AND",
["status","anyof","ItemShip:B","ItemShip:A"],
"AND",
["createdfrom.shipmethod","anyof","912"],
"AND",
["createdfrom.type","anyof","SalesOrd"],
"AND",
["formulanumeric: CEIL({today}-{datecreated})","equalto","8"],
"AND",
["cogs","is","F"],
"AND",
["shipping","is","F"],
"AND",
["taxline","is","F"]
],
columns:
[
search.createColumn({name: "internalid", label: "Internal ID"}),
search.createColumn({name: "item", label: "Item"}),
search.createColumn({name: "quantity", label: "Quantity"}),
search.createColumn({name: "location", label: "Location"}),
search.createColumn({name: "createdfrom", label: "Created From"}),
search.createColumn({
name: "formulatext",
formula: "NVL(NVL({customer.custentity_jj_operationmail}, {customer.custentity_jj_accountingmail}), {customermain.email})",
label: "Formula (Text)"
}),
search.createColumn({name: "otherrefnum", label: "PO/Check Number"}),
search.createColumn({
name: "tranid",
join: "createdFrom",
label: "Document Number"
}),
search.createColumn({
name: "internalid",
join: "customer",
label: "Internal ID"
})
]
});
var searchResultCount = itemfulfillmentSearchObj.runPaged().count;
log.debug("itemfulfillmentSearchObj result count",searchResultCount);
var ifArray = [], custEmail, po;
if (searchResultCount>0) {
itemfulfillmentSearchObj.run().each(function (result) {
var ifObj = {};
ifObj.id = result.getValue({name: "internalid", label: "Internal ID"})
ifObj.item = result.getText({name: "item", label: "Item"})
ifObj.qty = result.getValue({name: "quantity", label: "Quantity"})
ifObj.loc = result.getText({name: "location", label: "Location"})
ifObj.soInternalId = result.getValue({name: "createdfrom", label: "Created From"})
ifObj.soDocNum = result.getValue({
name: "tranid",
join: "createdFrom",
label: "Document Number"
})
ifObj.customer = result.getValue({
name: "internalid",
join: "customerMain",
label: "Internal ID"
})
custEmail = result.getValue({
name: "formulatext",
formula: "NVL(NVL({customer.custentity_jj_operationmail}, {customer.custentity_jj_accountingmail}), {customermain.email})",
label: "Formula (Text)"
})
if (custEmail)
ifObj.custEmail = custEmail;
else
ifObj.custEmail = false;
po = result.getValue({name: "otherrefnum", label: "PO/Check Number"})
if (po)
ifObj.po = po;
else
ifObj.po = false;
ifArray.push(ifObj)
return true;
});
return ifArray;
}
else
return [];
}catch (e) {
log.debug("Error@fetchIFusingSearch", e)
return [];
}
}
const getInputData = (inputContext) => {
try{
//fetch the IF using saved search
let ifArray = fetchIFusingSearch();
return ifArray;
}catch (e) {
log.debug("Error@getInputData", e)
return [];
}
}
const map = (mapContext) => {
try{
let resultObject=JSON.parse(mapContext.value);
var IFid = resultObject.id;
mapContext.write({
key:IFid,
value:resultObject
})
}catch (e) {
log.debug("Error@map", e)
}
}
const reduce = (reduceContext) => {
try{
let dataIF = reduceContext.values.map(JSON.parse);
log.debug("dataIF",dataIF)
//create Table for email body
//table header
var table ='<table style="border: 1px solid black;"><tr style="border: 1px solid black;"><th style="border: 1px solid black; background-color:#808080;">Item Name</th><th style="border: 1px solid black; background-color:#808080;">Quantity</th><th style="border: 1px solid black; background-color:#808080;">Location</th></tr>';
for(let i=0;i < dataIF.length;i++) {
table+= '<tr style="border: 1px solid black;"><td style="border: 1px solid black;">'+ dataIF[i].item+'</td><td style="border: 1px solid black;">'+ dataIF[i].qty+'</td><td style="border: 1px solid black;">'+ dataIF[i].loc+'</td></tr>';
}
table+='</table>';
let customer = dataIF[0].customer;
let soNum = dataIF[0].soDocNum;
let soId = dataIF[0].soInternalId;
let recipientEmail = dataIF[0].custEmail;
let po = dataIF[0].po;
// let recURLHyperLink = 'https://tstdrv2571125.app.netsuite.com/app/accounting/transactions/salesord.nl?id=' +soId;
// let url= "<a href= "+recURLHyperLink+">"+soNum+"</a>"
let emailBody ='We would appreciate if you could please come pickup your order '+soNum+' within the next 24 hours, otherwise, we might have to cancel your order and restock the items. In the future, if you could mark your orders with a PICKUP date it would help us greatly. '+'<br><br>' +'Effective October 1st'.bold()+', 2020-Orders already PICKED and READY for pickup can’t be changed without a replacement PO an RMA, please contact your customer service specialist if you have any question.' +'<br><br>'+ table +'<br><br>'+ 'Have a great day!'+'<br><br>'+'CorpDesign'+'<br><br>'+'info@corpdesign.com';
let subject;
if (po)
subject = 'Your order PO#: '+po+'/'+soNum+' has been sitting on our docks for over a week now';
else
subject = 'Your order '+soNum+' has been sitting on our docks for over a week now';
//send email to the customer
// log.debug("cust", customer)
if (recipientEmail) {
email.send({
author: //author,
recipients: //recipientEmail
body: emailBody,
subject: subject
relatedRecords: {
entityId: parseInt(customer)
}
});
}
}catch (e) {
log.debug("Error@reduceContext", e)
}
}
const summarize = (summaryContext) => {
}
return {getInputData, map, reduce, summarize}
});