The changes in the IR will reflect on G/L Impact, Balance Sheet, and related Item Fulfillment records.
The script is powered by a saved search in UI which enlists the item receipts.
/**
* @NApiVersion 2.1
* @NScriptType MapReduceScript
* @NModuleScope SameAccount
*/
define(['N/record', 'N/search', 'N/file', 'N/format', 'N/email'],
/**
* @param{record} record
* @param{search} search
* @param{file} file
* @param{format} format
* @param{email} email
*/
(record, search, file, format, email) => {
const SEARCH_ID = "customsearch_jj_ir_clear_lc_tgus556";
/**
* Defines the function that is executed at the beginning of the map/reduce process and generates the input data.
* @param {Object} inputContext
* @param {boolean} inputContext.isRestarted - Indicates whether the current invocation of this function is the first
* invocation (if true, the current invocation is not the first invocation and this function has been restarted)
* @param {Object} inputContext.ObjectRef - Object that references the input data
* @typedef {Object} ObjectRef
* @property {string|number} ObjectRef.id - Internal ID of the record instance that contains the input data
* @property {string} ObjectRef.type - Type of the record instance that contains the input data
* @returns {Array|Object|Search|ObjectRef|File|Query} The input data to use in the map/reduce process
* @since 2015.2
*/
const getInputData = (inputContext) => {
try {
let irArrayObj = searchItemReciptsIds()
log.debug('Get Input Data - irArrayObj', irArrayObj);
return irArrayObj;
} catch (Err) {
log.debug('error@getInputData', Err);
log.error('error@getInputData', Err);
}
}
/**
* Defines the function that is executed when the reduce entry point is triggered. This entry point is triggered
* automatically when the associated map stage is complete. This function is applied to each group in the provided context.
* @param {Object} reduceContext - Data collection containing the groups to process in the reduce stage. This parameter is
* provided automatically based on the results of the map stage.
* @param {Iterator} reduceContext.errors - Serialized errors that were thrown during previous attempts to execute the
* reduce function on the current group
* @param {number} reduceContext.executionNo - Number of times the reduce function has been executed on the current group
* @param {boolean} reduceContext.isRestarted - Indicates whether the current invocation of this function is the first
* invocation (if true, the current invocation is not the first invocation and this function has been restarted)
* @param {string} reduceContext.key - Key to be processed during the reduce stage
* @param {List<String>} reduceContext.values - All values associated with a unique key that was passed to the reduce stage
* for processing
* @since 2015.2
*/
const reduce = (reduceContext) => {
try {
log.debug("reduceContext", reduceContext)
let irRecValue = JSON.parse(reduceContext.values);
if (!isEmpty(irRecValue)) {
let irRecordId = irRecValue.irRecId
log.debug("irRecordId", irRecordId);
if (!isEmpty(irRecordId)) {
clearLandedCostforItemReceipts(irRecordId)
}
}
} catch (Err) {
log.debug('error@reduce', Err);
log.error('error@reduce', Err);
}
}
/**
* Defines the function that is executed when the summarize entry point is triggered. This entry point is triggered
* automatically when the associated reduce stage is complete. This function is applied to the entire result set.
* @param {Object} summaryContext - Statistics about the execution of a map/reduce script
* @param {number} summaryContext.concurrency - Maximum concurrency number when executing parallel tasks for the map/reduce
* script
* @param {Date} summaryContext.dateCreated - The date and time when the map/reduce script began running
* @param {boolean} summaryContext.isRestarted - Indicates whether the current invocation of this function is the first
* invocation (if true, the current invocation is not the first invocation and this function has been restarted)
* @param {Iterator} summaryContext.output - Serialized keys and values that were saved as output during the reduce stage
* @param {number} summaryContext.seconds - Total seconds elapsed when running the map/reduce script
* @param {number} summaryContext.usage - Total number of governance usage units consumed when running the map/reduce
* script
* @param {number} summaryContext.yields - Total number of yields when running the map/reduce script
* @param {Object} summaryContext.inputSummary - Statistics about the input stage
* @param {Object} summaryContext.mapSummary - Statistics about the map stage
* @param {Object} summaryContext.reduceSummary - Statistics about the reduce stage
* @since 2015.2
*/
const summarize = (summaryContext) => {
// Summarize added to find the Map/Reduce script excution end time.
}
/**
* Description - Perform Item Receipts Search for Clearing Landed Cost
* @returns irRecordsArray: Array
*/
function searchItemReciptsIds() {
try {
let itemReceiptSearchObj = search.load({ id: SEARCH_ID }); // SEARCH NAME: Item Receipts Search for Clearing Landed Cost JJ TGUS-556
//Declare variables
let irPageRanges, irRecId
let irRecordsArray = [];
try {
irPageRanges = itemReceiptSearchObj.runPaged({
pageSize: 1000
});
} catch (err) {
return [];
}
if (irPageRanges.pageRanges.length < 1)
return [];
let pageRangeLength = irPageRanges.pageRanges.length;
for (let pageIndex = 0; pageIndex < pageRangeLength; pageIndex++)
irPageRanges.fetch({
index: pageIndex
}).data.forEach(function (result) {
irRecId = result.getValue(result.columns[0]);
let itemRecordsObj = {};
itemRecordsObj.irRecId = irRecId
irRecordsArray.push(itemRecordsObj);
return true;
});
log.debug("irRecordsArray", irRecordsArray);
return irRecordsArray;
}
catch (err) {
log.debug("err@searchMerchGroup", err)
return [];
}
}
/**
* Description - Clear landed cost values configured in line level of ir record
* @param {integer} irRecId - internal id of the ir record
*/
function clearLandedCostforItemReceipts(irRecId) {
try {
if (irRecId ) {
let irRecObj = record.load({
type: record.Type.ITEM_RECEIPT,
id: irRecId,
isDynamic: true,
});
let irLineCount = irRecObj.getLineCount({ sublistId: 'item' });
log.debug("irLineCount", irLineCount);
for (let index = 0; index < irLineCount; index++) {
irRecObj.selectLine({
sublistId: 'item',
line: index
});
irRecObj.removeCurrentSublistSubrecord({
sublistId: 'item',
fieldId: 'landedcost'
});
irRecObj.commitLine({
sublistId: 'item'
});
}
let recordId = irRecObj.save({
enableSourcing: true,
ignoreMandatoryFields: true
});
log.debug("recordId", recordId)
}
} catch (Err) {
log.debug("Err@clearLandedCostforItemReceipts", Err)
log.error("Err@clearLandedCostforItemReceipts", Err)
}
}
function isEmpty(value) {
let isEmptyObject = function (a) {
if (typeof a.length === 'undefined') { // it's an Object, not an Array
let hasNonempty = Object.keys(a).some(function nonEmpty(element) {
return !isEmpty(a[element]);
});
return hasNonempty ? false : isEmptyObject(Object.keys(a));
}
return !a.some(function nonEmpty(element) { // check if array is really not empty as JS thinks
return !isEmpty(element); // at least one element should be non-empty
});
};
return (
value == false
|| typeof value === 'undefined'
|| value == null
|| (typeof value === 'object' && isEmptyObject(value))
);
}
return { getInputData, reduce, summarize }
});