Jira Code: AN-15
The objective is to develop a custom page to receive the purchase orders as the desired actions are not supported in the NetSuite default PO receive pages. The page allows the user to select the purchase orders to receive. Once the user submits the page it create the item receipt with the inventory details along with auto-generated lot numbers for the entire quantity for the item receipt.
Client Script : AN-15 JJ CS Receive Order
/**
* @NApiVersion 2.x
* @NScriptType ClientScript
* @NModuleScope SameAccount
*/
/*******************************************************************************
* CLIENTNAME:Aurora Naturals
* AN-15
* Auto Generate LOT Numbers
* **************************************************************************
* Date : 28-01-2019
*
* Author: Jobin & Jismi IT Services LLP
* Script Description : This script is to define the button action of 'Receive Order' button and to define the field change action
* Date created :28-01-2019
*
* REVISION HISTORY
*
* Revision 1.0 ${28-01-2019} nd : created
* 1.1 ${28-01-2019} nd :updated
* 1.2 ${26-02-2019} nd :updated
******************************************************************************/
define(['N/record','N/url','N/currentRecord','N/https','N/search'],
function(record,url,currentRecord,https,search) {
/**
* Function to be executed after page is initialized.
*
* @param {Object} scriptContext
* @param {Record} scriptContext.currentRecord - Current form record
* @param {string} scriptContext.mode - The mode in which the record is being accessed (create, copy, or edit)
*
* @since 2015.2
*/
function pageInit(scriptContext) {
}
/**
* Function to be executed when field is changed.
*
* @param {Object} scriptContext
* @param {Record} scriptContext.currentRecord - Current form record
* @param {string} scriptContext.sublistId - Sublist name
* @param {string} scriptContext.fieldId - Field name
* @param {number} scriptContext.lineNum - Line number. Will be undefined if not a sublist or matrix field
* @param {number} scriptContext.columnNum - Line number. Will be undefined if not a matrix field
*
* @since 2015.2
*/
function fieldChanged(scriptContext) {
try {
var currentRec = scriptContext.currentRecord;
//Changing the sublist based on the Location and Page index selection
if(scriptContext.fieldId == 'custpage_vendor' || scriptContext.fieldId == 'custpage_pageid')
{
var vendorValue = currentRec.getValue({
fieldId : 'custpage_vendor'
});
var pageIndex = currentRec.getValue({
fieldId : 'custpage_pageid'
});
if(pageIndex != null && pageIndex != '' && pageIndex != undefined){
var pageId = parseInt(pageIndex.split('_')[1]);
}
else{
pageId=0;
}
get_url = url.resolveScript({
scriptId: "customscript_an15_jj_al_receiveorders",
deploymentId: "customdeploy_an15_jj_al_receiveorders",
parameters:{
'vendorValue':vendorValue
}
});
get_url += '&vendorValue=' + vendorValue + '&pageindex=' + pageId;
if (window.onbeforeunload) {
window.onbeforeunload = function() {
null;
};
}
window.location.href = get_url;
}
//(UPDATED ON 26-02-19)field change action of select column to find if the PO is in the mentioned location and display alert.
if(scriptContext.fieldId == 'custpage_select_po'){
var numLines = currentRec.getLineCount({
sublistId: 'cust_polist'
});
for(var j = 0; j < numLines; j++){
var selectFieldValue = currentRec.getSublistValue({
sublistId: 'cust_polist',
fieldId: 'custpage_select_po',
line: j
});
if(selectFieldValue == true){
var poId = currentRec.getSublistValue({
sublistId: 'cust_polist',
fieldId: 'cust_internalid',
line: j
});
var binLookup = search.lookupFields({
type: search.Type.PURCHASE_ORDER,
id: poId,
columns: ['location']
});
var PO_location = binLookup.location[0].value
if(PO_location != 9){
alert('This item is lot controlled and must be received into the QA Inspection location. Please contact the P.O. creator or your administrator.')
currentRec.setCurrentSublistValue({
sublistId: 'cust_polist',
fieldId: 'custpage_select_po',
line: j,
value: false
});
}
}
}
}
} catch (e) {
console.log(e.name,e.message);
}
}
function receiveOrder(scriptContext){
try{
var poId_array=[]
var itemR_arr=[]
var record = currentRecord.get();
var numLines = record.getLineCount({
sublistId: 'cust_polist'
});
for(var j = 0; j < numLines; j++){
var selectFieldValue = record.getSublistValue({
sublistId: 'cust_polist',
fieldId: 'custpage_select_po',
line: j
});
if(selectFieldValue == true){
var poId = record.getSublistValue({
sublistId: 'cust_polist',
fieldId: 'cust_internalid',
line: j
});
poId_array.push(poId)
}
}
//julian date
var julianDate = Math.floor((new Date().getTime() - new Date("01/01/"+new Date().getFullYear()).getTime())/(1000*60*60*24)+1)
// date code
var jDate = leftPad(julianDate,3)
var str_jDsate= jDate.toString();
//year code
var year = new Date().getFullYear().toString().substr(-2)
var str_year =year.toString();
var jDate_param = str_year.concat(str_jDsate)
var poId_array_encode = encodeURI(poId_array)
var output = url.resolveScript({
scriptId: 'customscript_an15_jj_sl_potoir',
deploymentId: 'customdeploy_an15_jj_sl_potoir',
params:{
'poId':poId_array_encode,
'dateCode':jDate_param
}
});
var response=https.get({
url: output
});
var obj = JSON.parse(response.body);
var itemR_arr = encodeURIComponent(obj.arr_IR)
var ponum_arr = encodeURIComponent(obj.arr_po)
var ir_tranidArr = encodeURIComponent(obj.itemreceipt)
if(obj.id == 'Completed'){
window.location.reload();
}
if (window.onbeforeunload) {
window.onbeforeunload = function() {
null;
};
}
var output_link = url.resolveScript({
scriptId: 'customscript_an19_jj_sl_display_itemrece',
deploymentId: 'customdeploy_an19_jj_sl_display_itemrece',
params:{
'itemReceiptId':itemR_arr,
'poId':ponum_arr,
'tranidIR':ir_tranidArr,
// 'po_noIR':noIR_puchaseOrder
}
});
window.open(output_link);
//padding zero to make it 3 digit
function leftPad(number, targetLength) {
var output = number + '';
while (output.length < targetLength) {
output = '0' + output;
}
return output;
}
}catch(err){
console.log('error @ receiveOrder',err)
}
}
return {
pageInit: pageInit,
fieldChanged: fieldChanged,
receiveOrder: receiveOrder
};
});
Suitelet 1: AN-15 JJ SL Receive Orders
/**
* @NApiVersion 2.x
* @NScriptType Suitelet
* @NModuleScope SameAccount
*/
/*******************************************************************************
* CLIENTNAME:Aurora Naturals
* AN-15
* Auto Generate LOT Numbers
* **************************************************************************
* Date : 28-01-2019
*
* Author: Jobin & Jismi IT Services LLP
* Script Description : This script is to display the POs to be receipted
* Date created :28-01-2019
*
* REVISION HISTORY
*
* Revision 1.0 ${28-01-2019} nd : created
*
*
******************************************************************************/
define(['N/ui/serverWidget','N/search'],
function(serverWidget,search) {
var PAGE_SIZE=10;
/**
* Definition of the Suitelet script trigger point.
*
* @param {Object} context
* @param {ServerRequest} context.request - Encapsulation of the incoming request
* @param {ServerResponse} context.response - Encapsulation of the Suitelet response
* @Since 2015.2
*/
function onRequest(context) {
try{
var form = serverWidget.createForm({
title: 'Receive Orders'
});
form.clientScriptFileId = 12468;
var pageId = assignDefaultValue(context.request.parameters.pageindex, 0);
var vendorId = context.request.parameters.vendorValue;
var vendorName = form.addField({
id: 'custpage_vendor',
type: serverWidget.FieldType.SELECT,
label: 'Vendor',
source: 'vendor'
});
vendorName.defaultValue = vendorId;
var sublist1 = form.addSublist({
id : 'cust_polist',
type : serverWidget.SublistType.LIST,
label : 'Purchase Order List'
});
//add checkbox field to select the PO
sublist1.addField({
id: 'custpage_select_po',
type: serverWidget.FieldType.CHECKBOX,
label: 'Select'
});
//add Pagination Fields
var selectOptions = form.addField({
id: 'custpage_pageid',
type: serverWidget.FieldType.SELECT,
label: 'Page Index'
});
//receive button
sublist1.addButton({
id : 'buttonId',
label : 'Lot Number',
functionName:'receiveOrder'
});
sublist1.addField({
id : 'cust_type',
type : serverWidget.FieldType.TEXT,
label : 'Transaction Type'
});
sublist1.addField({
id : 'cust_date',
type : serverWidget.FieldType.TEXT,
label : 'Date'
});
sublist1.addField({
id : 'cust_ponmber',
type : serverWidget.FieldType.TEXT,
label : 'PO#'
});
sublist1.addField({
id : 'cust_vendorname',
type : serverWidget.FieldType.TEXT,
label : 'Vendor Name'
});
sublist1.addField({
id : 'cust_billto',
type : serverWidget.FieldType.TEXT,
label : 'Bill To'
});
sublist1.addField({
id : 'cust_ordertot',
type : serverWidget.FieldType.TEXT,
label : 'Order Total'
});
//hidden field for internal id
sublist1.addField({
id : 'cust_internalid',
type : serverWidget.FieldType.TEXT,
label : 'Id'
}).updateDisplayType({
displayType: serverWidget.FieldDisplayType.HIDDEN
});
// Run search and determine page count
var retrieveSearch = runSearch(PAGE_SIZE,vendorId);
//getting the total count
var len=retrieveSearch.count;
var pageCount = parseFloat(retrieveSearch.count / PAGE_SIZE);
// Set pageId to correct value if out of index
if (!pageId || pageId == '' || pageId < 0)
pageId = 0;
else if (pageId >= pageCount)
pageId = pageCount - 1;
var recordLength=len;
if (recordLength < 10) {
PAGE_SIZE = recordLength;
}
if(recordLength==0)
{
PAGE_SIZE = 1;
}
//setting the page index
for (var i = 0; i < pageCount; i++) {
if (i == pageId) {
if(parseInt(pageCount)==i)
{
selectOptions.addSelectOption({
value : 'pageid_' + i,
text : ((i * PAGE_SIZE) + 1) + ' - '
+ recordLength,
isSelected : true
});
}
else
{
selectOptions.addSelectOption({
value : 'pageid_' + i,
text : ((i * PAGE_SIZE) + 1) + ' - '
+ ((i + 1) * PAGE_SIZE),
isSelected : true
});
}
} else {
if(parseInt(pageCount)==i)
{
selectOptions.addSelectOption({
value : 'pageid_' + i,
text : ((i * PAGE_SIZE) + 1) + ' - '
+ recordLength
});
}
else
{
selectOptions.addSelectOption({
value : 'pageid_' + i,
text : ((i * PAGE_SIZE) + 1) + ' - '
+ ((i + 1) * PAGE_SIZE)
});
}
}
}
if (pageId >= 0 && pageCount != 0) {
// Get subset of data to be shown on page
var addResults = fetchSearchResult(retrieveSearch, pageId);
var j=0;
// Set data returned to columns
addResults.forEach(function (result) {
//set values to sublist
sublist1.setSublistValue({
id : "cust_type",
line : j,
value : result.type
});
sublist1.setSublistValue({
id : "cust_date",
line : j,
value : result.date
});
sublist1.setSublistValue({
id : "cust_ponmber",
line : j,
value : result.poNmber
});
sublist1.setSublistValue({
id : "cust_vendorname",
line : j,
value : result.vendor
});
sublist1.setSublistValue({
id : "cust_billto",
line : j,
value : result.billto
});
sublist1.setSublistValue({
id : "cust_ordertot",
line : j,
value : result.total
});
sublist1.setSublistValue({
id : "cust_internalid",
line : j,
value : result.internailId
});
j++;
});
}
context.response.writePage(form);
}catch(err){
log.error('error',err)
}
}
return {
onRequest: onRequest
};
//creating the search for PO
function runSearch(searchPageSize,vendorId) {
try{
var filterArr=[]
filterArr.push(["type","anyof","PurchOrd"])
filterArr.push("AND")
filterArr.push(["status","anyof","PurchOrd:B","PurchOrd:E","PurchOrd:D"])
filterArr.push("AND")
filterArr.push(["mainline","is","T"])
if(vendorId != "" && vendorId != null && vendorId != undefined && vendorId !='- None -' && vendorId != " "){
filterArr.push("AND");
filterArr.push(["vendor.internalidnumber","equalto",vendorId])
}
var purchaseorderSearchObj = search.create({
type: "purchaseorder",
filters:filterArr,
columns:
[
search.createColumn({name: "type", label: "Type"}),
search.createColumn({name: "trandate", label: "Date"}),
search.createColumn({name: "tranid", label: "Document Number"}),
search.createColumn({
name: "formulatext",
formula: "CONCAT({vendor.entityid}, {vendor.altname})",
label: "Vendor "
}),
search.createColumn({name: "billaddress", label: "Billing Address"}),
search.createColumn({name: "total", label: "Amount (Transaction Total)"}),
search.createColumn({name: "internalid", label: "Internal ID"})
]
});
return purchaseorderSearchObj.runPaged({
pageSize : searchPageSize
});
}catch(err){
log.error('error @ runSearch',err)
}
}
//getting data based on the range
function fetchSearchResult(pagedData, pageIndex) {
try{
var searchPage = pagedData.fetch({
index : pageIndex
});
var results = new Array();
//fetching values from saved search results
searchPage.data.forEach(function (result) {
var type = assignDefaultValue(result.getText({
name: 'type'
}),null);
var date= assignDefaultValue(result.getValue({
name: 'trandate'
}),null);
var poNmber= assignDefaultValue(result.getValue({
name: 'tranid'
}),null);
var vendor = assignDefaultValue(result.getValue({
name: "formulatext",
formula: "CONCAT({vendor.entityid}, {vendor.altname})"
}),null);
var billto = assignDefaultValue(result.getValue({
name: "billaddress"
}),null);
var total = assignDefaultValue(result.getValue({
name: "total"
}),null);
var internailId = assignDefaultValue(result.getValue({
name: "internalid"
}),null);
results.push({
"type" : type,
"date" : date,
"poNmber" : poNmber,
"vendor":vendor,
"billto":billto,
"total":total,
"internailId":internailId
});
});
return results;
}catch(er){
log.error('error @ fetchSearchResult',er)
}
}
//To check whether a value exists in parameter
function checkForParameter(parameter, parameterName) {
if (parameter != "" && parameter != null && parameter != undefined && parameter != "null" && parameter != "undefined" && parameter != " ") {
return true;
} else {
if (parameterName)
return false;
}
}
//To assign a default value if the it is empty
function assignDefaultValue(value, defaultValue) {
if (checkForParameter(value))
return value;
else
return defaultValue;
}
});
Suitelet 2 : AN-15 JJ SL Transform PO to Item receipt
/**
* @NApiVersion 2.x
* @NScriptType Suitelet
* @NModuleScope SameAccount
*/
/*******************************************************************************
* CLIENTNAME:Aurora Naturals
* AN-15
* Auto Generate LOT Numbers
* **************************************************************************
* Date : 29-01-2019
*
* Author: Jobin & Jismi IT Services LLP
* Script Description : This script is to transform the selected POs to Item receipt records
* (Runs in background)
* Date created : 29-01-2019
*
* REVISION HISTORY
*
* Revision 1.0 ${29-01-2019} nd : created
* 1.1 ${08-02-2019} nd :updated
* 1.2 ${23-02-2019} nd : updated
*
******************************************************************************/
define(['N/ui/serverWidget','N/search','N/record'],
function(serverWidget,search,record) {
/**
* Definition of the Suitelet script trigger point.
*
* @param {Object} context
* @param {ServerRequest} context.request - Encapsulation of the incoming request
* @param {ServerResponse} context.response - Encapsulation of the Suitelet response
* @Since 2015.2
*/
function onRequest(context) {
try{
var final_arr=[];
var arrayId=[];
var arr_po_docNum=[];
var error_PO=[];
var array_loc=[];
var array_filteredPO=[];
var form = serverWidget.createForm({
title: 'Receive Orders'
});
form.clientScriptFileId = 12468;
var poId = context.request.parameters.poId;
var date_code = context.request.parameters.dateCode;
arrayId = poId.split(',');
//to find the location
// for(var c=0;c<arrayId.length;c++){
// var binLookup = search.lookupFields({
// type: search.Type.PURCHASE_ORDER,
// id: arrayId[c],
// columns: ['location']
// });
//
// var PO_location = binLookup.location[0].value
// //search for bin from location
// var binSearchObj = search.create({
// type: "bin",
// filters:
// [
// ["location","anyof",PO_location]
// ],
// columns:
// [
// search.createColumn({
// name: "binnumber",
// sort: search.Sort.ASC,
// label: "Bin Number"
// }),
// search.createColumn({name: "location", label: "Location"})
//
// ]
// });
// var searchBin = binSearchObj.run().getRange({
// start: 0,
// end: 100
// });
// for(var b=0;b<searchBin.length;b++){
// var bin_nm = searchBin[b].getValue({
// name: "binnumber"
// });
//
// var loc = searchBin[b].getValue({
// name: "location"
// });
//
// if(bin_nm == 'QAInspection')
// array_loc.push(loc)
// }
//
// }
var purchaseorderSearchObj = search.create({
type: "purchaseorder",
filters:
[
["type","anyof","PurchOrd"],
"AND",
["item.type","noneof","NonInvtPart"],
"AND",
["location","anyof",array_loc],
"AND",
["internalid","anyof",arrayId],
],
columns:
[
search.createColumn({
name: "internalid",
summary: "GROUP",
sort: search.Sort.ASC,
label: "Internal ID"
}),
search.createColumn({
name: "itemid",
join: "item",
summary: "COUNT",
label: "Name"
}),
search.createColumn({
name: "tranid",
summary: "GROUP",
label: "Document Number"
})
]
});
var searchResultCount = purchaseorderSearchObj.runPaged().count;
var searchResult_count = purchaseorderSearchObj.run().getRange({
start: 0,
end: 100
});
var itemCOunt=null;
var itemCOunt_sum = 0;
for (var z = 0; z<searchResult_count.length; z++) {
internal_id=searchResult_count[z].getValue({
name: "internalid",
summary: "GROUP"
});
array_filteredPO.push(internal_id)
itemCOunt = searchResult_count[z].getValue({
name: "itemid",
join: "item",
summary: "COUNT"
});
itemCOunt_sum=parseInt(itemCOunt)+parseInt(itemCOunt_sum)
po_docNum = searchResult_count[z].getValue({
name: "tranid",
summary: "GROUP"
});
arr_po_docNum.push(po_docNum)
}
// final_arr = diff(arrayId,array_filteredPO)
var strObj = createIR(search,itemCOunt_sum,record,date_code,array_filteredPO,arr_po_docNum,arrayId);
context.response.write(JSON.stringify(strObj));
}catch(err){
log.error('error',err)
}
}
return {
onRequest: onRequest
};
//to get the index from custom list for id code
function createIR(search,itemCOunt_sum,record,date_code,array_filteredPO,arr_po_docNum,arrayId){
var index_Arr =[]
var fieldLookUp = search.lookupFields({
type: 'customrecord_an15_jj_autogenlotnmbr',
id: '1',
columns: ['custrecord_an15_jj_index']
});
var index= fieldLookUp.custrecord_an15_jj_index;
//calculate the new index and submit
var newIndex=parseInt(index)+parseInt(itemCOunt_sum);
try{
var id = record.submitFields({
type: 'customrecord_an15_jj_autogenlotnmbr',
id: 1,
values: {
custrecord_an15_jj_index: newIndex
}
});
}catch(errors){
if(errors.message=='Record has been changed'){
createIR(search,itemCOunt_sum,record,date_code,array_filteredPO);
}
}
for(i = index;i < newIndex;i++){
index_Arr.push(i)
}
var customlist1SearchObj = search.create({
type: "customlist1",
filters:
[
["internalid","anyof",index_Arr]
],
columns:
[
search.createColumn({name: "name", label: "Name"}),
search.createColumn({
name: "internalid",
sort: search.Sort.ASC,
label: "Internal ID"
})
]
});
var searchResult= customlist1SearchObj.run().getRange({
start: 0,
end: 100
});
var final_codeArr=[];
var currIndex=0;
for (var j = 0; j<searchResult.length; j++) {
var code = searchResult[j].getValue({
name: "name"
});
var str_code = code.toString();
var final_code = date_code.concat(str_code)
final_codeArr.push(final_code);
}
var array_IR=[];
var array_IR_name=[];
for(var p=0;p<array_filteredPO.length;p++){
// to transform PO to Item Receipt
var newRecord = record.transform({
fromType: record.Type.PURCHASE_ORDER,
fromId: array_filteredPO[p],
toType: record.Type.ITEM_RECEIPT,
isDynamic: true,
});
//set line items
var lineCount = newRecord.getLineCount({
sublistId: 'item'
});
for(var n=0;n<lineCount;n++){
newRecord.selectLine({sublistId: 'item', line:n });//select item line
var qty = newRecord.getCurrentSublistValue({
sublistId: 'item',
fieldId: 'quantity'
});
var itm= newRecord.getCurrentSublistValue({
sublistId: 'item',
fieldId: 'item'
});
var itemSearchObj = search.create({
type: "item",
filters:
[
["internalidnumber","equalto",itm]
],
columns:
[
search.createColumn({name: "type", label: "Type"})
]
});
var searchResult1 = itemSearchObj.run().getRange({
start: 0,
end: 100
});
for (var k = 0; k<searchResult1.length; k++) {
var type = searchResult1[k].getText({
name: "type"
});
}
if((type =='NonInvtPart')||(type =='Non-inventory Item')){
continue;
}else{
// // set inventory detail
subrecordInvDetail = newRecord.getCurrentSublistSubrecord({
sublistId: 'item',
fieldId: 'inventorydetail'
});
subrecordInvDetail.selectNewLine({//select inventory detail(sub record) line
sublistId: 'inventoryassignment'
});
subrecordInvDetail.setCurrentSublistValue({
sublistId: 'inventoryassignment',
fieldId: 'receiptinventorynumber',
value: final_codeArr[currIndex]
});
currIndex=currIndex+1;
subrecordInvDetail.setCurrentSublistValue({
sublistId: 'inventoryassignment',
fieldId: 'binnumber',
value: 6
});
subrecordInvDetail.setCurrentSublistValue({
sublistId: 'inventoryassignment',
fieldId: 'quantity',
value:qty
});
subrecordInvDetail.commitLine({
sublistId: 'inventoryassignment'
});
newRecord.commitLine({
sublistId: 'item'
});
}
}
var recordId=newRecord.save();
//updated to push the id of item receipt so that it can be listed a seperate SL
var fieldLookUp = search.lookupFields({
type: search.Type.ITEM_RECEIPT,
id: recordId,
columns: ['tranid']
});
var IR_name =fieldLookUp.tranid
array_IR_name.push(IR_name)
array_IR.push(recordId)
}
var strObj = {
id:'Completed',
arr_IR:array_IR,
arr_po:arr_po_docNum,
itemreceipt:array_IR_name,
// noIR_PO:final_arr
};
return strObj;
}
//diff function
function diff(a1, a2) {
return a1.concat(a2).filter(function(val, index, arr){
return arr.indexOf(val) === arr.lastIndexOf(val);
});
}
});