/**
* @NApiVersion 2.1
* @NScriptType MapReduceScript
*/
define(['N/record', 'N/search'],
/**
* @param{record} record
* @param{search} search
*/
(record, search) => {
function searchSerolized(item) {
try {
var JJ_invtDetailSearch = search.create({
type: "inventorydetail",
filters:
[
["item.internalid", "anyof", item],
"AND",
["expirationdate", "after", "today"],
"AND",
["itemcount", "greaterthan", "0"],
"AND",
["quantity", "greaterthan", "0"],
"AND",
["inventorynumber.quantityavailable", "greaterthan", "0"]
],
columns:
[
search.createColumn({
name: "inventorynumber",
label: " Number"
}),
search.createColumn({ name: "quantity", label: "Quantity" }),
search.createColumn({
name: "expirationdate",
sort: search.Sort.ASC,
label: "Expiration Date"
}),
search.createColumn({
name: "quantityavailable",
join: "inventoryNumber",
label: "Available"
}),
search.createColumn({
name: "internalid",
join: "item",
label: "Internal ID"
})
]
});
var searchResultCount = JJ_invtDetailSearch.runPaged().count;
log.debug("searchResultCount", searchResultCount)
if (searchResultCount > 0) {
let lotNumber;
JJ_invtDetailSearch.run().each(function (result) {
lotNumber = result.getText({
name: "inventorynumber",
label: " Number"
});
return true
});
return lotNumber
}
}
catch (err) {
log.error("error@searchSerialized")
}
}
/**
* 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 salesorderSearchObj = search.create({
type: "salesorder",
filters:
[
["mainline", "is", "T"],
"AND",
["type", "anyof", "SalesOrd"],
"AND",
["employee", "anyof", "@ALL@"],
"AND",
["unitstype", "anyof", "@ALL@"],
"AND",
["customer.entityid", "haskeywords", "SHOPIFY"],
"AND",
["systemnotes.name", "anyof", "3"],
"AND",
["status","anyof","SalesOrd:B"],
"AND",
["internalid","noneof","6783768"]
],
columns:
[
search.createColumn({ name: "internalid", label: "Internal ID" }),
search.createColumn({ name: "trandate", label: "Date" }),
search.createColumn({ name: "location", label: "Location" })
]
});
let searchResultCount = salesorderSearchObj.runPaged().count;
log.debug("searchResultCount........",searchResultCount)
if (searchResultCount > 0) {
return salesorderSearchObj
}
else {
return {}
}
}
catch (err) {
log.error("error@GetInputData", err)
return {}
}
}
/**
* 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 dataObj = reduceContext.values.map(JSON.parse)
log.debug("dataObj", dataObj)
let soId = dataObj[0].id;
let dateValue = dataObj[0].values["trandate"]
let location = dataObj[0].values["location"].value
let objRecord = record.transform({
fromType: 'salesorder',
fromId: soId,
toType: record.Type.ITEM_FULFILLMENT,
isDynamic: true,
});
objRecord.setText({
fieldId: 'trandate',
text: dateValue
});
let line_count = objRecord.getLineCount({
sublistId: 'item'
});
for (let i = 0; i < line_count; i++) {
objRecord.selectLine({
sublistId: 'item',
line: i
});
let item_id_from_itemline = objRecord.getCurrentSublistValue({
sublistId: 'item',
fieldId: 'quantityremaining',
});
objRecord.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'location',
value: location
})
let isInventory = objRecord.getCurrentSublistValue({
sublistId: 'item',
fieldId: 'inventorydetailavail',
})
if (isInventory == 'T' || isInventory == true) {
let invdetail = objRecord.getCurrentSublistSubrecord({
sublistId: 'item',
fieldId: 'inventorydetail'
});
let item = objRecord.getCurrentSublistValue({
sublistId: 'item',
fieldId: 'item'
});
let data = searchSerolized(item);
invdetail.selectNewLine({
sublistId: 'inventoryassignment'
});
invdetail.setCurrentSublistText({
sublistId: 'inventoryassignment',
fieldId: 'receiptinventorynumber',
text: data
});
invdetail.setCurrentSublistValue({
sublistId: 'inventoryassignment',
fieldId: 'quantity',
value: item_id_from_itemline
});
invdetail.commitLine({
sublistId: 'inventoryassignment'
});
objRecord.commitLine({
sublistId: 'item'
});
}
}
objRecord.save()
let invoiceRecord = record.transform({
fromType: 'salesorder',
fromId: soId,
toType: record.Type.INVOICE,
isDynamic: true,
});
invoiceRecord.setText({
fieldId: 'trandate',
text: dateValue
});
invoiceRecord.setValue({
fieldId: 'location',
value: location
});
invoiceRecord.save();
}
catch (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) => {
}
return { getInputData, reduce, summarize }
});