I am trying to create a payment record from invoice record with following code.
/**
*#NApiVersion 2.0
*#NScriptType mapreducescript
*#NModuleScope SameAccount
*/
define(
[
'N/log',
'N/error',
'N/record',
],
(record,log) => {
function invoice() {
var invRec = record.transform({
fromType: record.Type.INVOICE,
fromId: 44701349,
toType: record.Type.PAYMENT,
isDynamic: true,
defaultValues: { customform: 12 }
});
invRec.setValue({
fieldId: 'undepfunds',
value: 'Return Magic Fix Account (Inactive FY22 P04)',
ignoreFieldChange: true
});
invRec.setValue({
fieldId: 'memo',
value: 'Rounding Written Off',
ignoreFieldChange: true
});
return{
invRec
}
}
return {
record: invoice
};
});
I tried to run it in script debugger but getting
I am trying to transform a PO into an Item Receipt using a Restlet accessed through a rest api call.
So I have the following Restlet script which I based on the NetSuite example.
/**
*#NApiVersion 2.x
*#NScriptType Restlet
*/
define(['N/record', 'N/error'],
function(record, error) {
function _get(context) {
transformPurchaseOrder(context);
}
function transformPurchaseOrder(context) {
const fromRecord = 'purchaseorder';
const fromId = context.poId;
const toRecord = 'itemreceipt';
const trecord = record.transform({
fromType: fromRecord,
fromId: fromId,
toType: toRecord,
});
trecord.setSublistValue({
sublistId: 'item',
fieldId: 'quantity',
line: 1,
value: '2'
});
const idl = trecord.save({
enableSourcing: true
});
}
return {
get: _get,
}
});
But when I run it and pass in the PO id, I get...
error: {
code: 'UNEXPECTED_ERROR',
message: '{"type":"error.SuiteScriptError","name":"UNEXPECTED_ERROR","message":null,"stack":["anonymous(N/serverRecordService)","transformPurchaseOrder(/SuiteScripts/Integration/po_to_item_receipt.js:21)","_get(/SuiteScripts/Integration/po_to_item_receipt.js:8)"],"cause":{"type":"internal error","code":"UNEXPECTED_ERROR","details":null,"userEvent":null,"stackTrace":["anonymous(N/serverRecordService)","transformPurchaseOrder(/SuiteScripts/Integration/po_to_item_receipt.js:21)","_get(/SuiteScripts/Integration/po_to_item_receipt.js:8)"],"notifyOff":false},"id":"","notifyOff":false,"userFacing":false}'
}
If I remove trecord.setSublistValue, and run it again, I get the following error.
{
error: {
code: 'USER_ERROR',
message: '{"type":"error.SuiteScriptError","name":"USER_ERROR","message":"Please configure the inventory detail in line 1 of the item list.","stack":["anonymous(N/serverRecordService)","transformPurchaseOrder(/SuiteScripts/Integration/po_to_item_receipt.js:21)","_get(/SuiteScripts/Integration/po_to_item_receipt.js:8)"],"cause":{"type":"internal error","code":"USER_ERROR","details":"Please configure the inventory detail in line 1 of the item list.","userEvent":null,"stackTrace":["anonymous(N/serverRecordService)","transformPurchaseOrder(/SuiteScripts/Integration/po_to_item_receipt.js:21)","_get(/SuiteScripts/Integration/po_to_item_receipt.js:8)"],"notifyOff":false},"id":"","notifyOff":false,"userFacing":false}'
}
}
But as this is the first time I have ever used netSuite, I don't know what is required to configure the inventory detail in line 1 of the item list. I also don't know if there is a way for me to view more details about the error.
Based on the comments below, I tried a version where I loaded dynamically.
`
define([`N/record`, `N/error`], function (record, error) {
function _get(context) {
transformPurchaseOrder(context);
}
function transformPurchaseOrder(context) {
const fromRecord = `purchaseorder`;
const fromId = context.poId;
const toRecord = `itemreceipt`;
const trecord = record.transform({
fromType: fromRecord,
fromId: fromId,
toType: toRecord,
isDynamic: true,
});
const inventoryDetail = trecord.getCurrentSublistSubrecord({
sublistId: `item`,
fieldId: `inventorydetail`,
});
log.debug({
title: `INVENTORY DETAIL &&&&&`,
details: inventoryDetail,
});
inventoryDetail.setValue({
fieldId: `quantity`,
value: `1`,
});
inventoryDetail.setValue({
fieldId: `totalquantity`,
value: `1`,
});
inventoryDetail.setValue({
fieldId: `issueinventorynumber`,
value: `lmrlmrlmr`,
});
inventoryDetail.setCurrentSublistValue({
sublistId: `inventoryassignment`,
fieldId: `issueinventorynumber`,
value: `lmrlmrlmr`,
});
inventoryDetail.setCurrentSublistValue({
sublistId: `inventoryassignment`,
fieldId: `issueinventorynumber_display`,
value: `lmrlmrlmr`,
});
inventoryDetail.setCurrentSublistValue({
sublistId: `inventoryassignment`,
fieldId: `quantity`,
value: `1`,
});
trecord.setCurrentSublistValue({
sublistId: `item`,
fieldId: `quantity`,
value: `1`,
});
const idl = trecord.save({
enableSourcing: true,
ignoreMandatoryFields: true,
});
}
return {
get: _get,
};
});`
With this version, I get UNEXPECTED_ERROR on trecord.getCurrentSublistSubrecord({.
And this is the equivalent non-dynamic version
define([`N/record`, `N/error`], function (record, error) {
function _get(context) {
transformPurchaseOrder(context);
}
function transformPurchaseOrder(context) {
const fromRecord = `purchaseorder`;
const fromId = context.poId;
const toRecord = `itemreceipt`;
const trecord = record.transform({
fromType: fromRecord,
fromId: fromId,
toType: toRecord,
});
const inventoryDetail = trecord.getSublistSubrecord({
sublistId: `item`,
fieldId: `inventorydetail`,
line: 0,
});
inventoryDetail.setValue({
fieldId: `quantity`,
value: `1`,
});
inventoryDetail.setValue({
fieldId: `totalquantity`,
value: `1`,
});
inventoryDetail.setValue({
fieldId: `issueinventorynumber`,
value: `lmrlmrlmr`,
});
inventoryDetail.setSublistValue({
sublistId: `inventoryassignment`,
fieldId: `issueinventorynumber`,
line: 0,
value: `lmrlmrlmr`,
});
inventoryDetail.setSublistValue({
sublistId: `inventoryassignment`,
fieldId: `issueinventorynumber_display`,
line: 0,
value: `lmrlmrlmr`,
});
inventoryDetail.setSublistValue({
sublistId: `inventoryassignment`,
fieldId: `quantity`,
line: 0,
value: `1`,
});
log.debug({
title: `INVENTORY DETAIL &&&&&`,
details: inventoryDetail,
});
trecord.setSublistValue({
sublistId: `item`,
fieldId: `quantity`,
line: 0,
value: `1`,
});
const idl = trecord.save({
enableSourcing: true,
ignoreMandatoryFields: true,
});
}
return {
get: _get,
};
});
Which works except for the fact that it adds a new inventoryassignment line instead of editing currentLine as shown below. And the error I get is "message":"Please enter value(s) for: Serial/Lot Number" so I assume that means I have to set that field in in the currentLine object.
{
type: `inventorydetail`,
isDynamic: false,
fields: {
itemdescription: `Descr`,
nlloc: `0`,
nlsub: `1`,
ignoreqtyvalidation: `F`,
trandate: `1/18/2023`,
_eml_nkey_: `xxxxxxx`,
type: `inventorydetail`,
subrecord_parent_tran_type: `ItemRcpt`,
nsapiCT: `xxxxx`,
sys_id: `xxxxx`,
nluser: `13080`,
nldept: `0`,
subrecord_transform_from_parent_id: `xxxxx`,
subrecord_transform_from_parent_tran_type: `PurchOrd`,
tolocationusesbins: `F`,
item: `13760`,
quantity: `1`,
sys_parentid: `4168409225838594`,
templatestored: `F`,
entryformquerystring: `orderline=1&item=13760&unit=1&quantity=1&subrecord_transform_from_parent_id=1075097&trandate=1/18/2023&location=713&uitype=MOH_BIN_FIELD_OPTIONAL&wavefulfillment=&subrecord_transform_from_parent_tran_type=purchord&subrecord_parent_tran_type=itemrcpt`,
nlrole: `3`,
uitype: `MOH_BIN_FIELD_OPTIONAL`,
baserecordtype: `inventorydetail`,
baseunitquantity: `1`,
totalquantity: `1`,
orderline: `1`,
haslines: `F`,
unit: `1`,
tolocation: `-1`,
customform: `-10820`,
location: `713232`,
conversionrate: `1`,
issueinventorynumber: `lmrlmrlmr`,
},
sublists: {
inventoryassignment: {
currentline: {
basequantityavailable: ``,
binnumber: ``,
binnumber_display: ``,
existingexpdate: ``,
existinginventorynumber: ``,
expirationdate: ``,
internalid: `-1`,
inventorydetail: `-1`,
inventorystatus: ``,
inventorystatus_display: ``,
issueinventorynumber: ``,
issueinventorynumber_display: ``,
lotquantityavailable: ``,
numberedrecordid: ``,
packcarton: ``,
pickcarton: ``,
quantity: ``,
quantityavailable: ``,
quantitystaged: ``,
receiptinventorynumber: ``,
sequencenumber: ``,
sys_id: `-xxxxx`,
sys_parentid: `-xxxxx`,
tobinnumber: ``,
tobinnumber_display: ``,
toinventorystatus: ``,
toinventorystatus_display: ``,
totalquantityavailable: ``,
'#': `1`,
},
'line 1': {
issueinventorynumber: `lmrlmrlmr`,
issueinventorynumber_display: `lmrlmrlmr`,
quantity: `1`,
sys_id: `-xxxxx`,
sys_parentid: `-xxxxxx`,
},
},
},
};
Im trying to create a Sales Order on netsuite, but im getting the fallowing error:
"error.SuiteScriptError","name":"TRANS_AMTS_UNBALNCD","message":"The transaction is not balanced! values + fees + shipping 0, total value: 90"
Here is the Code:
var salesOrder = record.transform({
fromType: 'customer',
fromId: '10807',
toType: 'salesorder',
isDynamic: true
});
salesOrder.selectNewLine({
sublistId: 'item'
});
salesOrder.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'item',
line: 1,
value: 1175
});
salesOrder.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'quantity',
value: '1'
});
salesOrder.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'rate',
value:45
});
salesOrder.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'amount',
value: 90
});
salesOrder.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'taxcode',
value: 5
});
salesOrder.commitLine({
sublistId: 'item'
});
salesOrder.save({
enableSourcing: false,
ignoreMandatoryFields: true
})
amount = quantity * rate
With the code that you're showing, you have one line item with a quantity of 1 and a rate of 45, but the amount you've specified is 90. You either need to change the amount to 45 or change the quantity to 2, or change the rate to 45.
Or don't specify the amount at all and NetSuite will do the calculation for you. I usually either specify an amount or a rate but not both.
I am creating this script to write the invoice in NetSuite. However, when I send the data this error appears: "The approval status field should only be used when the approval routing preference is selected."
PS: in the interface the same error occurs when trying to save.
Can you help me? Here's the code:
/**
* #NApiVersion 2.x
* #NScriptType restlet
* #author Adriano Barbosa
* #since 2019.2
*/
define(['N/record', 'N/file', 'N/log', 'N/search'], function (record, file, log, search) {
function vpc_contas_receber(context) {
if ( context.cnpj_forn ) {
var id_forn;
search.create({ type: "customer",
filters: [
[ "custentity_enl_cnpjcpf", "is", context.cnpj_forn ]
],
columns: [
search.createColumn({ name: "internalid", label: "ID interna" })
]
}).run().each(function(result) {
id_forn = result.id;
return true;
});
if ( !id_forn ) {
log.debug({ title: 'Erro', details: 'Fornecedor ' + context.cnpj_forn + ' não localizado!' });
return { status: 'Erro', mensagem: 'Fornecedor ' + context.cnpj_forn + ' não localizado!' }
} else if ( context.nf ) {
var id_nf_existe, nf_existe, num_fat;
search.create({ type: "invoice",
filters: [
[ "type", "anyof", "CustInvc" ], "AND",
[ "custbody_enl_fiscaldocnumber", "is", context.nf ]
],
columns: [
search.createColumn({ name: "custbody_enl_fiscaldocnumber", label: "Número da Nota Fiscal" }),
search.createColumn({ name: "formulatext", formula: "SUBSTR({tranid}, 0)", label: "nº fatura" })
]
}).run().each(function(result) {
id_nf_existe = result.id;
nf_existe = result.getValue({ name: 'custbody_enl_fiscaldocnumber' });
num_fat = result.getValue({ name: 'formulatext' });
});
if ( nf_existe ) {
log.debug({ title: 'NF ' + nf_existe + ' já cadastrada!', details: 'VPC: ' + id_nf_existe + '; ' + 'Nº Fatura: ' + num_fat });
return {
status: 'NF ' + nf_existe + ' já cadastrada!',
mensagem: 'VPC: ' + id_nf_existe + '; ' + 'Nº Fatura: ' + num_fat
}
} else {
vpc = record.create({ type: 'invoice', isDynamic: true })
.setValue({ fieldId: 'entity', value: id_forn })
.setValue({ fieldId: 'memo', value: context.obs })
.setValue({ fieldId: 'location', value: 1 })
.selectNewLine({ sublistId: 'item' })
.setCurrentSublistValue({ sublistId: 'item', fieldId: 'item', value: 27901 })
.setCurrentSublistValue({ sublistId: 'item', fieldId: 'rate', value: context.valor })
.commitLine({ sublistId: 'item' })/*
.setValue({ fieldId: 'custbody_rsc_dtvencboleto', value: new Date(context.venc_blt) })*/
.setValue({ fieldId: 'custbody_enl_operationtypeid', value: 15 })
.setValue({ fieldId: 'custbody_enl_order_documenttype', value: 7 })
.setValue({ fieldId: 'custbody_enl_fiscaldocnumber', value: context.nf })/*
.save({ enableSourcing: true, ignoreMandatoryFields: true })*/
if ( context.venc_blt ) {
var venc_blt = new Date(context.venc_blt);
venc_blt.setDate(venc_blt.getDate());
vpc.setValue({ fieldId: 'custbody_rsc_dtvencboleto', value: venc_blt });
}
var id_vpc = vpc.save({ enableSourcing: true, ignoreMandatoryFields: true });
try {
var bodyObject = {};
var load_id_vpc = record.load({ type: 'invoice', id: id_vpc });
bodyObject['id_vpc'] = id_vpc;
bodyObject['doc_vpc'] = load_id_vpc.getValue({ fieldId: 'tranid' });
bodyObject['memo'] = load_id_vpc.getValue({ fieldId: 'memo' }) || '';
bodyObject['valor'] = load_id_vpc.getSublistValue({ sublistId: 'item', fieldId: 'rate', line: 0 }).toFixed(2);
bodyObject['nf'] = load_id_vpc.getValue({ fieldId: 'custbody_enl_fiscaldocnumber' });
bodyObject['venc_blt'] = load_id_vpc.getValue({ fieldId: 'custbody_rsc_dtvencboleto' });
log.debug({ title: 'VPC["Contas a Receber"] cadastrado com sucesso!', details: bodyObject });
return { 'status': 'Sucesso!', 'infoVPC': bodyObject }
} catch (e) {
log.debug({ title: 'Erro', details: e });
return { status: 'Erro!', mensagem: e }
}
}
}
}
// forn = search.create({ type: "vendor",
// filters: [
// [ "custentity_enl_cnpjcpf", "is", context.fornecedor ]
// ],
// columns: [
// search.createColumn({ name: "internalid", label: "ID interna" })
// ]
// }).run().getRange({ start: 0, end: 1 })
}
return { 'post': vpc_contas_receber }
});
As the message indicates:
to use the Approval Status field, you must activate Approval Routing for invoices.
To do so, go to Setup -> Accounting -> Accounting Preferences -> Tab "Approval Routing" and check the Transactions(s) on which you want to manage approvals. This will make the "Approval Status" available for use.
I'm trying to access the json data in the format liike below...
{"subscriptions":
"recmachcustrecord2": [{
"custrecord_acceptable_min_shelf_life": "60",
"custrecord_item": {
"internalid": "399",
"name": "ABS2002-PACK"
}
}, {
"custrecord_acceptable_min_shelf_life": "60",
"custrecord_item": {
"internalid": "400",
"name": "ABS2003-PACK"
}
}]
}
I have written like
var subrec = salesRepRec.getSublistSubrecord({
sublistId: 'recmachcustrecord2',
fieldId: 'custrecord_item',
line: 0
});
{"type":"error.SuiteScriptError","name":"FIELD_1_IS_NOT_A_SUBRECORD_FIELD","message":"Field custrecord_item is not a subrecord field.","stack":["anonymous(N/serverRecordService)","onAfterSubmit(/SuiteScripts/cus.js:23)"],"cause":{"type":"internal error","code":"FIELD_1_IS_NOT_A_SUBRECORD_FIELD","details":"Field custrecord_item is not a subrecord field.","userEvent":"aftersubmit","stackTrace":["anonymous(N/serverRecordService)","onAfterSubmit(/SuiteScripts/cus.js:23)"],"notifyOff":false},"id":"","notifyOff":false,"userFacing":false}
mainly i want access the "internalid": "400",
"name": "ABS2003-PACK" these fields.
how can i access the using the suite script 2.0
Thanks in Advance!
AFAIK NetSuite does not allows creating a custom sublist subrecord. Although in you case, you only need to fetch internalid and itemid from the subrecord which can be achieved as below
{
custrecord_item: {
internalId: salesRepRec.getSublistValue({ sublistId: 'recmachcustrecord2', fieldId: 'custrecord_item', line: 0 }),
name: salesRepRec.getSublistText({ sublistId: 'recmachcustrecord2', fieldId: 'custrecord_item', line: 0 })
}
}