We have one custom record setup which is intended to request new photos from the photographer whenever the items related to that record get new inventory.
An alert email should be sent when an item that was out of stock when the photo request was created comes back into stock so that the photographer can know to prioritize that item.
/**
* @NApiVersion 2.x
* @NScriptType MapReduceScript
* @NModuleScope SameAccount
*/
/*******************************************************************************
*
* Script Description: Script will Sent Email Notification to the Photographer for the items whose stock replenoshed today. Scheduled to run on a per day basis and summary Email is sent.
* Date created : 08-11-2021
*
******************************************************************************/
define( [ 'N/task', 'N/runtime', 'N/search', 'N/record', 'N/encode', 'N/email', 'N/file' ],
function ( task, runtime, search, record, encode, email, file )
{
const PRIORITY = "custrecord_vv_priority";
var BACK_INSTOCK_ARRAY = new Array();
function getInputData ()
{
try
{
var customrecord_vv_add_photo_requestSearchObj = search.create( {
type: "customrecord_vv_add_photo_request",
filters:
[
[ "custrecord_vv_status_addphotoreq", "anyof", "1" ]
],
columns:
[
search.createColumn( {
name: "custrecord_vv_source_code",
summary: "GROUP",
label: "Item"
} ),
search.createColumn( {
name: "custrecord_vv_priority",
summary: "GROUP",
label: "Priority"
} ),
search.createColumn( {
name: "custrecord_vv_new_label",
summary: "GROUP",
label: "New Label"
} ),
search.createColumn( {
name: "internalid",
summary: "GROUP",
label: "Internal ID"
} ),
search.createColumn( {
name: "locationquantityonhand",
join: "CUSTRECORD_VV_SOURCE_CODE",
summary: "SUM",
label: "Location On Hand"
} ),
search.createColumn( {
name: "custrecord_vv_stock_level",
summary: "GROUP",
label: "Stock Level"
} )
]
} );
//Declare variables
var searchPageRanges, itemID, pritemStockStatus, isNewLabelRequest, prRecId, qtyOnhand, stockLevel;
var itemRecordsArray = [];
try
{
searchPageRanges = customrecord_vv_add_photo_requestSearchObj.runPaged( {
pageSize: 1000
} );
} catch ( err )
{
return [];
}
if ( searchPageRanges.pageRanges.length < 1 )
return [];
var pageRangeLength = searchPageRanges.pageRanges.length;
for ( var pageIndex = 0; pageIndex < pageRangeLength; pageIndex++ )
searchPageRanges.fetch( {
index: pageIndex
} ).data.forEach( function ( result )
{
itemID = result.getValue( result.columns[ 0 ] );
pritemStockStatus = result.getValue( result.columns[ 1 ] );
isNewLabelRequest = result.getValue( result.columns[ 2 ] );
prRecId = result.getValue( result.columns[ 3 ] );
qtyOnhand = result.getValue( result.columns[ 4 ] );
stockLevel = result.getValue( result.columns[ 5 ] );
var customRecordObj = {};
customRecordObj.itemID = itemID
customRecordObj.prRecId = prRecId
customRecordObj.pritemStockStatus = pritemStockStatus
customRecordObj.isNewLabelRequest = isNewLabelRequest
customRecordObj.qtyOnhand = qtyOnhand
customRecordObj.stockLevel = stockLevel
itemRecordsArray.push( customRecordObj );
return true;
} );
//log.debug( "itemRecordsArray", itemRecordsArray )
var scriptObj = runtime.getCurrentScript();
log.debug( 'Remaining governance units @getInputData: ' + scriptObj.getRemainingUsage() );
return itemRecordsArray;
} catch ( er )
{
log.debug( 'er', er.message )
}
}
function reduce ( params )
{
try
{
var processData = JSON.parse( params.values[ 0 ] );
var Array = []
if ( processData.qtyOnhand > 0 )
{
//Urgent
record.submitFields( {
type: 'customrecord_vv_add_photo_request',
id: processData.prRecId,
values: {
'custrecord_vv_priority': 1,
'custrecord_vv_stock_level': processData.qtyOnhand
}
} );
//log.debug( "BACK_INSTOCK_ARRAY", BACK_INSTOCK_ARRAY )
}
else
{
//No Stock
record.submitFields( {
type: 'customrecord_vv_add_photo_request',
id: processData.prRecId,
values: {
'custrecord_vv_priority': 2,
'custrecord_vv_stock_level': 0
}
} );
}
params.write( {
key: "BACK_INSTOCK_ARRAY",
value: BACK_INSTOCK_ARRAY
} )
var scriptObj = runtime.getCurrentScript();
log.debug( 'Remaining governance units @reduce: ' + scriptObj.getRemainingUsage() );
} catch ( err )
{
log.debug( "err", err.message )
}
}
function summarize ( summary )
{
try
{
log.debug( "Entered summarize", "Entered summarize" )
var customrecord_vv_add_photo_requestSearchObj = search.create( {
type: "customrecord_vv_add_photo_request",
filters:
[
[ "isinactive", "is", "F" ],
"AND",
[ "custrecord_vv_status_addphotoreq", "anyof", "1" ],
"AND",
[ "systemnotes.field", "anyof", "CUSTRECORD_VV_STOCK_LEVEL" ],
"AND",
[ "systemnotes.date", "on", "today" ],
"AND",
[ "systemnotes.newvalue", "isnot", "0" ],
"AND",
[ "systemnotes.oldvalue", "is", "0" ],
"AND",
[ "custrecord_vv_priority", "anyof", "1" ],
"AND",
[ "custrecord_vv_source_code.quantityonhand", "greaterthan", "0" ]
],
columns:
[
search.createColumn( { name: "custrecord_vv_source_code", label: "Item" } ),
search.createColumn( {
name: "formulatext",
formula: "'<a href=https://386782-sb2.app.netsuite.com/app/common/item/item.nl?id=' || {custrecord_vv_source_code.id} || ' target=_blank>View Item Record </a>'",
label: "Formula (Text)"
} ),
search.createColumn( {
name: "formulatext",
formula: "'<a href=https://386782-sb2.app.netsuite.com/app/common/custom/custrecordentry.nl?rectype=1701&id=' || {internalid} || ' target=_blank>View PR Record </a>'",
label: "Formula (Text)"
} )
]
} );
var testArray = []
customrecord_vv_add_photo_requestSearchObj.run().each( function ( result )
{
var testObj = {}
var itemname = result.getText( customrecord_vv_add_photo_requestSearchObj.columns[ 0 ] )
var itemlink = result.getValue( customrecord_vv_add_photo_requestSearchObj.columns[ 1 ] )
var prlink = result.getValue( customrecord_vv_add_photo_requestSearchObj.columns[ 1 ] )
testObj.itemlink = itemlink
testObj.itemname = itemname
testObj.prlink = prlink
testArray.push( testObj )
return true;
} );
log.debug( "testArray", testArray )
//build the HTML table header
var msgHTML = '<table width=100%" class="listtable listborder uir-list-table" style="position: relative;" ><tr class="uir-machine-headerrow">';
msgHTML += '<td class="listheadertdleft listheadertextb uir-column-large">ITEM</td>'
msgHTML += '<td class="listheadertdleft listheadertextb uir-column-large">LINK TO ITEM RECORD</td>'
msgHTML += '<td class="listheadertdleft listheadertextb uir-column-large">LINK TO PHOTO REQUEST</td>'
//spin through results and draw html table row/cell elements
for ( var i = 0; i < testArray.length; i++ )
{
var msgRow = ( i % 2 ) ? 'even' : 'odd';
msgHTML += '</tr><tr class="uir-list-row-tr uir-list-row-' + msgRow + '">';
msgHTML += '<td class="uir-list-row-cell listtext">' + testArray[ i ].itemname + '</td>';
msgHTML += '<td class="uir-list-row-cell listtext">' + testArray[ i ].itemlink + '</td>';
msgHTML += '<td class="uir-list-row-cell listtext">' + testArray[ i ].prlink + '</td>';
}
msgHTML += '</tr></table>'
//3988 - Employee name Andrew
email.send( {
author: -5,
recipients: 6367,
subject: 'Items Back in Stock Alert',
body: '<BR />Hi ,<BR/> <BR/>This email is to notify you that the items listed below with outstanding photo requests now have new inventory.' + '<BR/> <BR/>' + msgHTML + '<br />'
} )
var scriptObj = runtime.getCurrentScript();
log.debug( 'Remaining governance units @summarize: ' + scriptObj.getRemainingUsage() );
} catch ( e )
{
log.debug( 'error@summarize', e )
log.error( 'error@summarize', e )
}
}
return {
getInputData: getInputData,
reduce: reduce,
summarize: summarize
};
} );