/**
* @NApiVersion 2.1
* @NScriptType MapReduceScript
*/
define([‘N/runtime’, ‘N/record’, ‘N/cache’, ‘N/search’, ‘N/file’],
/**
* @param{runtime} runtime
* @param{record} record
* @param{cache} cache
* @param{search} search
*/
(runtime, record, cache, search, file) => {
/**
* 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 globalArray = [];
let taxObj = {};
let scriptCache = cache.getCache({ name: ‘globalArrayCache’ });
scriptCache.put({
key: ‘globalArray’,
value: JSON.stringify(globalArray),
ttl: 3600
});
let taxgroupSearchObj = search.create({
type: “taxgroup”,
columns:
[
search.createColumn({ name: “internalid”, label: “Name” }),
search.createColumn({ name: “rate”, label: “Rate” })
]
});
taxgroupSearchObj.run().each(function (result) {
let taxGroupId = result.getValue({ name: ‘internalid’ });
let taxRate = result.getValue({ name: ‘rate’ });
taxObj[taxGroupId] = taxRate;
return true;
});
let taxgroupCache = cache.getCache({ name: ‘taxgroupSearchObjCache’ });
taxgroupCache.put({
key: ‘taxgroupSearchObj’,
value: JSON.stringify(taxObj),
ttl: 3600
});
let salesOrderIds = [];
let csvFile = file.load({
id: ‘SuiteScripts/Jobin and Jismi IT Services/AHAP-3493 Update Tax Rates for Open Sales Orders/SingleSO.csv’
});
let fileContent = csvFile.getContents();
let lines = fileContent.split(/r?n/);
lines.forEach(line => {
let trimmed = line.trim();
if (trimmed && !isNaN(trimmed)) {
salesOrderIds.push(trimmed);
}
});
log.debug(‘Parsed Sales Order IDs from CSV’, salesOrderIds);
return salesOrderIds;
} catch (e) {
log.debug(“error @getInputData”, getInputData);
}
}
/**
* 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 {
let scriptCache = cache.getCache({ name: ‘globalArrayCache’ });
let globalArray = JSON.parse(scriptCache.get({ key: ‘globalArray’ }));
let salesOrder = JSON.parse(reduceContext.values[0]);
let taxgroupCache = cache.getCache({ name: ‘taxgroupSearchObjCache’ });
let taxObj = JSON.parse(taxgroupCache.get({ key: ‘taxgroupSearchObj’ }));
let rec = record.load({
type: ‘salesorder’,
id: salesOrder,
});
let recId = rec.id;
let j = 0;
for (let i = 0; i < rec.getLineCount({ sublistId: ‘item’ }); i++) {
let taxName = rec.getSublistValue({
sublistId: ‘item’,
fieldId: ‘taxcode’,
line: i
});
log.debug(“taxName”, taxName);
let taxRate1 = rec.getSublistValue({
sublistId: ‘item’,
fieldId: ‘taxrate1’,
line: i
});
log.debug(“taxRate1”, taxRate1);
let rateFromTaxObj = taxObj[taxName];
if (rateFromTaxObj !== undefined) {
let rateFromObj = parseFloat(rateFromTaxObj.replace(‘%’, ”).trim()) || 0;
let rateFromLine = parseFloat(taxRate1) || 0;
if (rateFromObj !== rateFromLine) {
// rec.setSublistValue({
// sublistId: ‘item’,
// fieldId: ‘taxcode’,
// line: i,
// value: ”
// });
// rec.setSublistValue({
// sublistId: ‘item’,
// fieldId: ‘taxcode’,
// line: i,
// value: taxName
// });
j++;
}
}
}
if (j > 0) {
globalArray.push(recId);
}
// rec.save({
// ignoreMandatoryFields: true
// });
scriptCache.put({
key: ‘globalArray’,
value: JSON.stringify(globalArray),
ttl: 3600
});
} catch (e) {
log.debug(“error @reduce”, e);
}
}
/**
* 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) => {
try {
let scriptCache = cache.getCache({ name: ‘globalArrayCache’ });
let globalArray = JSON.parse(scriptCache.get({ key: ‘globalArray’ }));
log.debug(“globalArray”, globalArray);
log.audit({
title: ‘Global Array Contents’,
details: globalArray.join(‘, ‘)
});
let taxGroupCache = cache.getCache({ name: ‘taxgroupSearchObjCache’ });
let taxGroupObj = JSON.parse(taxGroupCache.get({ key: ‘taxgroupSearchObj’ }));
log.debug(“taxGroupObj”, taxGroupObj)
} catch (e) {
log.debug(“error @summarize”, e);
}
}
return { getInputData, reduce, summarize }
});