The clients requires a restlet API to create an item receipt for a PO.
/**
* @NApiVersion 2.1
* @NScriptType Restlet
*/
/************************************************************************************************
* JOINF-1708 Create Restlet API for IR creation In NetSuite
*********************************************************************************************
*
* Author: Jobin and Jismi IT Services
* Date Created : 23-May-2023
* Instance: JOINF Sandbox
* Created By: Athul Krishna, Jobin and Jismi IT Services
* Description : API to create Item reciept in NetSuite
*
* REVISION HISTORY
* Revision 1.0 - 20 April 2023 - Create Restlet API for IR creation In NetSuite
***********************************************************************************************/
define(['N/https', 'N/record', 'N/search'],
/**
* @param{https} https
* @param{record} record
* @param{search} search
*/
(https, record, search) => {
/**
* Defines the function that is executed when a GET request is sent to a RESTlet.
* @param {Object} requestParams - Parameters from HTTP request URL; parameters passed as an Object (for all supported
* content types)
* @returns {string | Object} HTTP response body; returns a string when request Content-Type is 'text/plain'; returns an
* Object when request Content-Type is 'application/json' or 'application/xml'
* @since 2015.2
*/
const get = (requestParams) => {
}
/**
* Defines the function that is executed when a PUT request is sent to a RESTlet.
* @param {string | Object} requestBody - The HTTP request body; request body are passed as a string when request
* Content-Type is 'text/plain' or parsed into an Object when request Content-Type is 'application/json' (in which case
* the body must be a valid JSON)
* @returns {string | Object} HTTP response body; returns a string when request Content-Type is 'text/plain'; returns an
* Object when request Content-Type is 'application/json' or 'application/xml'
* @since 2015.2
*/
const put = (requestBody) => {
}
/**
* To generate the date in correct format
* @param {*} dateValu
* @returns
*/
function generateDate(dateValu){
let dateValue=new Date(dateValu)
let date=new Date(dateValu)
log.debug("Current",dateValue)
log.debug("Current Date",dateValue.getDate())
log.debug("CUrrent Month",dateValue.getMonth())
date.setDate(date.getDate()+1)
log.debug("date2",date);
return date;
}
/**
* To check whenther the purchase order can be received.
* @param {*} internalID
* @returns
*/
function checkingPOStatus(internalID){
try{
let purchaseorderSearchObj = search.create({
type: "purchaseorder",
filters:
[
["type","anyof","PurchOrd"],
"AND",
["internalid","anyof",internalID],
"AND",
["status","anyof","PurchOrd:E","PurchOrd:D","PurchOrd:B"]
],
columns:
[
search.createColumn({name: "tranid", label: "Document Number"})
]
});
var searchResultCount = purchaseorderSearchObj.runPaged().count;
log.debug("purchaseorderSearchObj result count",searchResultCount);
if(searchResultCount>0){
return true
}
else{
return false
}
}catch(e){
log.debug("error@checkingPOStatus",e);
return false;
}
}
/**
* Defines the function that is executed when a POST request is sent to a RESTlet.
* @param {string | Object} requestBody - The HTTP request body; request body is passed as a string when request
* Content-Type is 'text/plain' or parsed into an Object when request Content-Type is 'application/json' (in which case
* the body must be a valid JSON)
* @returns {string | Object} HTTP response body; returns a string when request Content-Type is 'text/plain'; returns an
* Object when request Content-Type is 'application/json' or 'application/xml'
* @since 2015.2
*/
const post = (requestBody) => {
try{
log.debug("requsetBody",requestBody.bodyfield);
//Checking if the bodyfield is empty
if(!requestBody?.bodyfield){
return JSON.stringify({
summary: {
message: "FAILED",
reason: "BODY_FIELD_MISSING",
error: ["Body field is empty"]
},
details: []
})
}
//Checking if the sublist is empty
if (!(requestBody?.sublist?.item && util.isArray(requestBody?.sublist?.item) && requestBody?.sublist?.item.length)){
return JSON.stringify({
summary: {
message: "FAILED",
reason: "SUBLIST_MISSING",
error: ["No Content in Sublist"]
},
details: []
});
}
let poID=requestBody.bodyfield.po_internal_id
log.debug("PoID",poID)
//Checking if the po_internal_id is empty
if(!poID){
return JSON.stringify({
summary: {
message: "FAILURE",
reason: "FIELD_IS_MANDATORY",
error: ["po_internal_id Field Is Mandatory"]
},
details: []
});
}
//Checking if the po_internal_id is a number
else if(poID && Number.isNaN(parseInt(poID))){
return JSON.stringify({
summary: {
message: "FAILURE",
reason: "NOT_A_NUMBER",
error: ["po_internal_id needs to a integer value"]
},
details: []
})
}
let poInternalIdFlag=checkingPOStatus(requestBody?.bodyfield?.po_internal_id)
if(!poInternalIdFlag){
return JSON.stringify({
summary: {
message: "FAILED",
reason: "CANNOT_RECIEVED",
error: ["The order is already recieved/ not able to recieve"]
},
details: []
});
}
const bodyFileds = [
{
fieldId: 'entity',
value: requestBody.bodyfield.vendor_int_id,
text: null,
isMandatory: true,
parameterName: "vendor_int_id",
isInteger: true
},
{
fieldId: 'subsidiary',
value: requestBody.bodyfield.subsidiary_int_id,
text: null,
isMandatory: false,
parameterName: "subsidiary_int_id",
isInteger: true
},
{
fieldId: 'trandate',
value: new Date(requestBody.bodyfield.receipt_date),
text: null,
isMandatory: false,
parameterName: "receipt_date",
isInteger: false
},
{
fieldId: 'memo',
value: requestBody.bodyfield.header_memo,
text: null,
isMandatory: false,
parameterName: "header_memo",
isInteger: false
},
]
for (let ele of bodyFileds) {
log.debug({title: ele.fieldId, details: ele.value})
if (!ele.value && !ele.text && ele.isMandatory) {
return JSON.stringify({
summary: {
message: "FAILURE",
reason: "FIELD_IS_MANDATORY",
error: [ele.fieldId + " Field Is Mandatory"]
},
details: []
})
}
else if(ele.isInteger && Number.isNaN(parseInt(ele.value)) && Number.isNaN(parseInt(ele.text))){
return JSON.stringify({
summary: {
message: "FAILURE",
reason: "NOT_A_NUMBER",
error: [ele.parameterName + "needs to a integer value"]
},
details: []
})
}
}
let irRecord=record.transform({
fromType: record.Type.PURCHASE_ORDER,
fromId: requestBody.bodyfield.po_internal_id,
toType: record.Type.ITEM_RECEIPT,
});
log.debug("transform",irRecord);
for (let ele of bodyFileds) {
if(ele.fieldId === 'trandate'){
irRecord.setValue({
fieldId: ele.fieldId,
value: generateDate(ele.value)
});
}
else if(ele.text){
irRecord.setText({
fieldId: ele.fieldId,
value: ele.text
});
}
else{
irRecord.setValue({
fieldId: ele.fieldId,
value: ele.value
});
}
}
let irInternalId;
if (requestBody?.sublist?.item && util.isArray(requestBody?.sublist?.item) && requestBody?.sublist?.item.length > 0) {
const fieldMap = [
{
fieldId: 'item',
jsonKey: 'line_item_int_id',
isValue: true,
isText: false,
isMandatory: true,
isInteger: true,
parameterName: 'line_item_int_id',
},
{
fieldId: 'location',
jsonKey: 'line_item_location',
isValue: true,
isText: false,
isMandatory: true,
isInteger: true,
parameterName: 'line_item_location',
},
{
fieldId: 'quantity',
jsonKey: 'line_item_quantity',
isValue: true,
isText: false,
isMandatory: true,
isInteger: true,
parameterName: 'line_item_quantity',
},
{
fieldId: 'custcol_orderref_containerno',
jsonKey: 'line_container_number',
isValue: true,
isText: false,
isMandatory: false,
isInteger: false,
parameterName: 'line_container_number',
},
{
fieldId: 'cseg_saleschannel',
jsonKey: 'cseg_saleschannel',
isValue: true,
isText: false,
isMandatory: false,
isInteger: true,
parameterName: 'cseg_saleschannel',
},
{
fieldId: 'cseg_geography',
jsonKey: 'cseg_geography',
isValue: true,
isText: false,
isMandatory: false,
isInteger: true,
parameterName: 'cseg_geography',
},
{
fieldId: 'custcol_jj_tracker_link_key',
jsonKey: 'line_linkkey',
isValue: true,
isText: false,
isMandatory: false,
isInteger: false,
parameterName: 'line_linkkey',
},
]
for (let ele of requestBody.sublist.item) {
for (let field of fieldMap) {
if(!ele[field.jsonKey] && field.isMandatory){
return JSON.stringify({
summary: {
message: "FAILURE",
reason: "FIELD_IS_MANDATORY",
error: [field.parameterName + " Field Is Mandatory"]
},
details: []
})
}
else if(ele[field.jsonKey] && field.isInteger && Number.isNaN(parseInt(ele[field.jsonKey]))){
return JSON.stringify({
summary: {
message: "FAILURE",
reason: "NOT_A_NUMBER",
error: [field.parameterName + " Field Should Have An Intger Value"]
},
details: []
})
}
}
}
let itemLineCount=irRecord.getLineCount({sublistId: "item"});
let itemArray=requestBody.sublist.item;
let recordCreationFlag=0;
for(let i=0;i<itemLineCount;i++){
let itemFlag=0;
let item=irRecord.getSublistValue({
sublistId: "item",
fieldId: "item",
line: i
})
for(let j=0;j<itemArray.length;j++){
recordCreationFlag=recordCreationFlag+1;
let itemArrayItem=itemArray[j].line_item_int_id
if(item==itemArrayItem){
itemFlag=itemFlag+1;
irRecord.setSublistValue({
sublistId: "item",
fieldId: "location",
value: itemArray[j].line_item_location,
line: i
})
irRecord.setSublistValue({
sublistId: "item",
fieldId: "quantity",
value: itemArray[j].line_item_quantity,
line: i
})
irRecord.setSublistValue({
sublistId: "item",
fieldId: "custcol_orderref_containerno",
value: itemArray[j].line_container_number,
line: i
})
if(itemArray[j].cseg_geography){
irRecord.setSublistValue({
sublistId: "item",
fieldId: "cseg_geography",
value: itemArray[j].cseg_geography,
line: i
})
}
if(itemArray[j].cseg_saleschannel){
irRecord.setSublistValue({
sublistId: "item",
fieldId: "cseg_saleschannel",
value: itemArray[j].cseg_saleschannel,
line: i
})
}
if(itemArray[j].line_linkkey){
irRecord.setSublistValue({
sublistId: "item",
fieldId: "custcol_jj_tracker_link_key",
value: itemArray[j].line_linkkey,
line: i
})
}
}
}
if(itemFlag<=0){
irRecord.setSublistValue({
sublistId: 'item',
fieldId: 'itemreceive',
value: false,
line: i
});
}
}
if(recordCreationFlag>0){
irInternalId= irRecord.save({
enableSourcing: true,
ignoreMandatoryFields: true
});
}else{
return JSON.stringify({
summary: {
message: "FAILURE",
reason: "NOT_RECIVED_ANY_ITEM",
error: ["Couldnot receive any item in the request"]
},
details: []
})
}
}
return JSON.stringify({
summary: {
message: "SUCCESS",
reason: "RECORD_CREATED",
error: []
},
details: [{
internalId: irInternalId
//internalID:"Success"
}
]
})
}
catch(e){
log.debug("Error@Post",e)
return JSON.stringify({
summary: {
message: "FAILED",
reason: e.name,
error: [e.message]
},
details: []
});
}
}
/**
* Defines the function that is executed when a DELETE request is sent to a RESTlet.
* @param {Object} requestParams - Parameters from HTTP request URL; parameters are passed as an Object (for all supported
* content types)
* @returns {string | Object} HTTP response body; returns a string when request Content-Type is 'text/plain'; returns an
* Object when request Content-Type is 'application/json' or 'application/xml'
* @since 2015.2
*/
const doDelete = (requestParams) => {
}
return {get, put, post, delete: doDelete}
});