NetSuite: Retrieve a value from a popup/subrecord - netsuite

Thanks for clicking in.
On the Customer record within the Address subtab I have a sublist with addresses.
On each line there's a button for edit. (See first picture)
Clicking edit will bring up a popup window with some fields that can not be seen in Field Explorer. It is one of these fields I would really like to retrieve the value from. (See second picture)
See the third picture to see how the record of the field I want to retrieve looks.
I've tried to both load the customer record and to use lookupFields. But the field I want can't be accessed through just the customer record. Looking at the field record it says that it is for record of type Address. But it says it's a subrecord in record browser, and I don't really know how to access it.
Do I need to create a search in order to get to it? Or is a better way to use SuiteQL?
I'm still a bit new to NetSuite and haven't really done anything with SuiteQL yet.
So any help and guidance is very much appreciated.
Address Sublist
Popup
Field

There are different options.
When you loaded the customer record, you should load the address sublistrecord to access that value.
define(['N/record'], function(record) {
var myRecord = record.load({
type: record.Type.CUSTOMER,
id: INTERNALID_OF_YOUR_CUSTOMER
})
for (var line = 0; line < myRecord.getLineCount({ sublistId: 'addressbook' }); line++) {
var address = myRecord.getSublistSubrecord({ sublistId: 'addressbook', line: line, fieldId: 'addressbookaddress' })
var accountNo = address.getValue({ fieldId: FIELDID_OF_YOUR_CUSTOM_FIELD })
}
})
Use the N/search module
define(['N/search'], function(search) {
var mySearch = search.create({
type: search.Type.CUSTOMER,
columns: [
'internalid',
'entityid',
'companyname',
{ join: 'Address', name: 'city' },
{ join: 'Address', name: FIELDID_OF_YOUR_CUSTOM_FIELD },
],
filters: [ 'internalid', search.Operator.IS, INTERNALID_OF_YOUR_CUSTOMER ]
})
mySearch.run().each(function(result) {
...DO SOMETHING
return true;
})
})

You need to load the subrecord for getting the values of address.You can use API recordObj.getCurrentSublistSubrecord.
Here is the code how i have used to get the values:-
1- First load the customer record in script.
var customerObj = record.load({
type: record.Type.CUSTOMER,
id: customerRecordId,
isDynamic:true
});
var addressSubrecord = customerObj.getCurrentSublistSubrecord({
sublistId: 'addressbook',
fieldId: 'addressbookaddress'
});
addressSubrecord.getValue({
fieldId: 'addr1',
value: linedata1.address1
});
addressSubrecord.getText({
fieldId: 'country'
});
addressSubrecord.getValue({
fieldId: 'addr2'
});
addressSubrecord.getValue({
fieldId: 'zip'
});
2-Put inside for loop if it is according to line using API and add line as well.
var numLines = objRecord.getLineCount({
sublistId: 'addressbook'
});
You can get all the data using their field id.

Related

NetSuite Invoice from Case

Hoping some one may be able to help me out with this error I am receiving... I am working a custom button on the case record that will create an invoice using fields from the case. I have a custom field that is a multi select of all items that can be needed as part of a case. Not all cases require an item, so I will code in logic or workflow to prevent the button from showing up if an item isn't selected and also lock editing and mark the case status as invoiced with a stage of closed once invoice has been created from the record. My problem is that when testing the suitelet I am getting an error when trying to set the subsidiary field and also department. Here is my error: ["type":"error.SuiteScriptError"."name":"INVALID_FLD_VALUE", "message":"You have entered an Invalid Field Value 2 for the following field: subsidiary"
The customer I am testing with is assigned the subsidiary with a internal Id of 2
Below is a portion of my code, I've tried removing quotes in sub value and also trying to set the subsidiary value using the current record.getValue. both throw the same error
function onRequest(context) {
var custom_id = context.request.parameters.custom_id;
var currentRecord = record.load({
type: record.Type.SUPPORT_CASE,
id: custom_id
});
var newRecord = record.create({
type: record.Type.INVOICE,
isDynamic: true
});
newRecord.setValue({
fieldId: 'customform',
value: 122
});
newRecord.setValue({
fieldId: 'entity',
value: currentRecord.getValue('entity')
});
newRecord.setValue({
fieldId: 'otherrefnum',
value: currentRecord.getValue('casenumber')
});
newRecord.setValue({
fieldId: 'subsidiary', value: '2'
});
newRecord.setValue({
fieldId: 'department',
value: '17'
});
newRecord.selectNewLine({
sublistId: 'item'
});
newRecord.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'item',
//value: 46
value: currentRecord.getValue('custevent_multi_select_work_orders')
});
newRecord.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'quantity',
value: '1'
});
}
Any help much appreciated!
Errors I found:
There is a typo when you are loading the Support Case Record. It should be SUPPORT_CASE
var currentRecord = record.load({
type: record.Type.SUPPORT_CASE,
id: custom_id
});
There are many typos like an inverted comma here, hope you look into it
newRecord.setValue({
fieldId: 'customform',
value: 122'
});
Regarding your main Subsidiary issue, you are passing value (2) using Inverted Commas. Try passing it without those
newRecord.setValue({
fieldId: 'subsidiary',
value: 2
});
OR
newRecord.setValue({
fieldId: 'subsidiary',
value: Number(2)
});
Use inverted commas only to pass String value. For Numerical value, don't use them.
Try these changes and let me know if the problem still persist, there are many possibilities to this error!
I know this isn't exactly what you need, but it is fully functioning and you can make customizations/pick-and-choose parts to use. It's a custom function I've used in the past to create a Sales Order from a Case Record. Best of luck!
/**
* case_createSOButton.js
* #NApiVersion 2.x
* #NScriptType ClientScript
*/
define (['N/record', 'N/currentRecord'],
function (record, currentRecord){
//NetSiuite requires the existence of 1 of their functions
function pageInit(context) {
var currentRecord = context.currentRecord;
}
//Button function to create a Sales order and indicate on the Case record the new Sales Order record
//in the UI on the Script record add this function name to the "Buttons" section
function createSO(){
log.audit('function started', 'Cases - Service Case CS createSO');
var caseRecord = currentRecord.get();
//if record is in create mode than do not allow creation of a Sales Order
//mode property is not available, so base it off of id properrty. ids dont exist until record is saved
var caseId = caseRecord.id;
if (!caseId){
alert('You cannot create a Sales Order while creating a new Case.\nPlease save the Case, then try again.');
return;
}
//if sales order already exists, do not allow creation of a new SO
var associatedSO = caseRecord.getValue({fieldId: 'custevent_case_associated_sales_orde'});
if (associatedSO){
alert('Cannot create a Sales Order since "Associated Sales Order" already exists.');
return;
}
//gather info from user
var memo = prompt("What's the reason for the charge?\nThe text below will be copied onto the Sales Order \"Memo\" field.");
//if user clicks cancel, do not continue
if (memo == null){
return;
}
var description = prompt("Enter a description for the Service Work Item.");
//if user clicks cancel, do not continue
if (description == null){
return;
}
var amount = prompt("Enter an amount for the Service Work Item.\nPlease only enter #s, no letters, decimal/cents optional.");
//if user clicks cancel or there's no # value found, do not continue
var hasNumber = /\d/; //validation for confirming the amount variable is a number
hasNumber = hasNumber.test(amount);
if (amount == null){
return;
}
if(hasNumber == false){
alert('No numbers found in entry, please try again.');
return;
}
alert('Please wait for the process to complete before closing this page.');
//declare static values
var customform = 199;
var subsidiary = 2;
var status = 3;
var specialist = 62736;
var channel = 181;
var totalKW = 0;
var lenderPoints = 0;
var today = new Date();
var itemId = 3566;
var lender = 10;
var loanProduct = 37;
//load customer to gather values
var entity = caseRecord.getValue({fieldId: 'company'});
var customerRec = record.load({type: record.Type.CUSTOMER, id: entity});
var location = customerRec.getValue({fieldId: 'custentity_customer_market'})|| null;
var job = caseRecord.getValue({fieldId: 'custevent_case_associated_project'});
//load associated project to gather values
var projectRec = record.load({type: record.Type.JOB, id: job});
var projectMgr = projectRec.getValue({fieldId: 'custentity_project_manager_customer'})|| null;
var engineer = projectRec.getValue({fieldId: 'custentity31'})|| null;
var installMgr = projectRec.getValue({fieldId: 'custentity_install_manager'})|| null;
var state = projectRec.getValue({fieldId: 'custentity_csegmarke'})|| null;
var region = projectRec.getValue({fieldId: 'custentity_cseg2'})|| null;
var market = projectRec.getValue({fieldId: 'custentity_cseg3'})|| null;
//create SO record, set values
var newSORec = record.create({type: record.Type.SALES_ORDER, isDynamic: true});
newSORec.setValue({fieldId: 'customform', value: customform, ignoreFieldChange: false});
newSORec.setValue({fieldId: 'entity', value: entity});
newSORec.setValue({fieldId: 'job', value: job});
newSORec.setValue({fieldId: 'custbody_sostatus', value: status});
newSORec.setValue({fieldId: 'custbody_total', value: totalKW});
newSORec.setValue({fieldId: 'custbody13', value: lenderPoints});
newSORec.setValue({fieldId: 'custbody_fundingissues', value: memo});
newSORec.setValue({fieldId: 'subsidiary', value: subsidiary});
newSORec.setValue({fieldId: 'custbody_finance_specialist', value: specialist});
newSORec.setValue({fieldId: 'saleseffectivedate', value: today});
newSORec.setValue({fieldId: 'custbody_cseglende', value: lender});
newSORec.setValue({fieldId: 'custbody_csegloan', value: loanProduct});
newSORec.setValue({fieldId: 'custbody_project_manager', value: projectMgr});
newSORec.setValue({fieldId: 'custbody_engineer', value: engineer});
newSORec.setValue({fieldId: 'custbody_installmgr', value: installMgr});
newSORec.setValue({fieldId: 'class', value: channel, forceSyncSourcing: true});
newSORec.setValue({fieldId: 'custbody_csegmarke', value: state, forceSyncSourcing: true});
newSORec.setValue({fieldId: 'custbody_cseg2', value: region, forceSyncSourcing: true});
newSORec.setValue({fieldId: 'custbody_cseg3', value: market, forceSyncSourcing: true});
newSORec.setValue({fieldId: 'location', value: location, forceSyncSourcing: true});
//set default line item(s)
newSORec.selectLine({sublistId: 'item', line: 0});
newSORec.setCurrentSublistValue({sublistId: 'item', fieldId: 'item', value: itemId, ignoreFieldChange: false});
newSORec.setCurrentSublistValue({sublistId: 'item', fieldId: 'description', value: description, ignoreFieldChange: false});
newSORec.setCurrentSublistValue({sublistId: 'item', fieldId: 'rate', value: parseInt(amount), ignoreFieldChange: false});
newSORec.commitLine({sublistId: 'item'});
//save new SO
var newSORecId = newSORec.save({enableSourcing: true, ignoreMandatoryFields: false});
//add SO Rec to Case
record.submitFields({
type: record.Type.SUPPORT_CASE,
id: caseRecord.id,
values: {
custevent_case_associated_sales_orde: newSORecId
},
options: {
//enableSourcing: false, //default is true
ignoreMandatoryFields : true //default is false
}
});
//alert user when SO is created and open in a new tab
alert("The new Sales Order will open in a new tab. \n*Reminder - to save this record if you've made changes.");
var url = 'https://1234567.app.netsuite.com/app/accounting/transactions/salesord.nl?id='+newSORecId
window.open(url, '_blank');
log.audit('function end', 'Cases - Service Case CS createSO');
}//end of create SO funciton
return {
pageInit: pageInit,
createSO: createSO
}
}
);

NetSuite Client Script 2.0 to Disable Expiry Date Sublist Field on Inventory Detail record

I'm trying to disable the display type of expiry date field on inventory details. The current client script is working for 1st line only or 0 index. I'm trying to completely disable this field for all lines while adding inventory details.
This is my script please tell me what I missed here.
Thanks
function lineInit(scriptContext) {
try {
var currentRecord = scriptContext.currentRecord;
var sublistId = scriptContext.sublistId;
if (sublistId !== 'item') return;
var selectedLine = currentRecord.getCurrentSublistIndex({
sublistId: 'item'
});
log.debug({ title: 'selectedLine', details: JSON.stringify(selectedLine) });
var inventoryDetail = currentRecord.getCurrentSublistSubrecord({
sublistId: "item",
fieldId: "inventorydetail"
});
var expiryDate = inventoryDetail.getCurrentSublistField({
sublistId: "inventoryassignment",
fieldId: "expirationdate"
});
expiryDate.isDisabled = true;
} catch (error) {
log.debug({ title: 'Catch Error', details: error });
}
}
you need to traverse the loop using
var numLines = objRecord.getLineCount({
sublistId: 'item'
});
for the inventory detail sublist (summary) similarly as we do for item sublist then only it will set all the expiry dates to disabled , you have just taken the index "selectedLine" and printed in the log

How do I set the value for Serial/Lot Number on an Inventory Detail Subrecord?

I have tried everything to get this working but no matter what I do, I always get the following error from NetSuite:
error code: USER_ERROR error message: {"type":"error.SuiteScriptError","name":"USER_ERROR","message":"Please enter value(s) for: Serial/Lot Number","stack":["anonymous(N/serverRecordService)"...
This occurs when I try to commit the line.
What I am attempting to do (in a RESTlet) is programatically create a Work Order Completion (WOC) for an existing Work Order (WO). I have it working for the first operation. However, for the final operation, which requires an Inventory Detail, I am getting the error. Here is my code (I have removed error checking, etc for better clarity):
/**
* #NApiVersion 2.x
* #NScriptType restlet
*/
define(['N/runtime', 'N/error', 'N/record', 'N/search'], function(runtime, error, record, search) {
return {
get : function(datain) {
var wo = record.load({
type: record.Type.WORK_ORDER,
id: datain.woid
});
var woc = record.transform({
fromType: record.Type.WORK_ORDER,
fromId: datain.woid,
toType: record.Type.WORK_ORDER_COMPLETION,
isDynamic: true,
defaultValues: {
isbackflush: 'F',
}
});
woc.setText({
fieldId: "startoperation",
text: "20"
});
woc.setText({
fieldId: "endoperation",
text: "20"
});
woc.setText({
fieldId: "completedquantity",
text: "230"
});
var invdetail = woc.getSubrecord({
fieldId: "inventorydetail"
});
invdetail.selectNewLine({
sublistId: "inventoryassignment",
});
invdetail.setCurrentSublistValue({
sublistId: "inventoryassignment",
fieldId: "binnumber",
value: 29
});
invdetail.setCurrentSublistValue({
sublistId: "inventoryassignment",
fieldId: "quantity",
value: 230
});
invdetail.setCurrentSublistText({
sublistId: "inventoryassignment",
fieldId: "issueinventorynumber",
text: "abc"
});
invdetail.commitLine({
sublistId: "inventoryassignment",
});
woc.save();
var results = {
woc: woc
};
return JSON.stringify(results);
}
}
});
I have tried everything I can think of. Using setCurrentSublistValue() and setCurrentSublistText(), setting the value to an existing lot, new lot, etc, etc.
However, no matter what I do, NS always responds with the "Please enter value(s) for: Serial/Lot Number" error as if it is not set.
Thoughts, ideas, suggestions???
Thanks!
Try using receiptinventorynumber for your fieldId.
invdetail.setCurrentSublistValue({
sublistId: 'inventoryassignment',
fieldId: 'receiptinventorynumber',
value: 'lotNumber'
});
invdetail.commitLine({sublistId: 'inventoryassignment'});

Keep getting an error when trying to submit an Inbound Shipment via Netsuite Restlet

I keep getting the following error when trying to create a new Inbound Shipment record (new in Netsuite).
{"type":"error.SuiteScriptError","name":"USER_ERROR","message":"Please enter value(s) for: Item","stack":["anonymous(N/recordService)","<anonymous>(/SuiteScripts/KK_Sandbox_Scripts_SD/RestLets/InboundShipment.js:132)","<anonymous>(/SuiteScripts/KK_Sandbox_Scripts_SD/RestLets/InboundShipment.js:99)","doPost(/SuiteScripts/KK_Sandbox_Scripts_SD/RestLets/InboundShipment.js:34)"],"cause":{"type":"internal error","code":"USER_ERROR","details":"Please enter value(s) for: Item","userEvent":null,"stackTrace":["anonymous(N/recordService)","<anonymous>(/SuiteScripts/KK_Sandbox_Scripts_SD/RestLets/InboundShipment.js:132)","<anonymous>(/SuiteScripts/KK_Sandbox_Scripts_SD/RestLets/InboundShipment.js:99)","doPost(/SuiteScripts/KK_Sandbox_Scripts_SD/RestLets/InboundShipment.js:34)"],"notifyOff":false},"id":"","notifyOff":false}
Here is the code I have to set the record. I have verified that the sublist id is "items" and the fieldId is "itemid", but when I try to add the line, I get the above error.
function doPost(restletBody){
log.debug('Called from POST', restletBody);
var success = [],
errors = [];
restletBody.data.forEach(function(e)
{
try
{
log.debug('Called from POST', e.id);
//Create a new record
var rec =
r.create({
type: "inboundshipment",
isDynamic: true,
defaultValues: null
}).setValue({
fieldId: "externalid",
value: e.id,
ignoreFieldChange: false
});
var i = 1;
e.lineitems.items.forEach(function(item)
{
log.debug("Inside Line Items", item.itemid + " " + item.purchaseorder);
rec.selectNewLine({sublistId:"items"});
var field = rec.getSublistFields({
sublistId: 'items'
});
rec.setCurrentSublistValue({
sublistId: "items",
fieldId: "purchaseorder",
value: item.purchaseorder,
ignoreFieldChange: true
});
rec.setCurrentSublistValue({
sublistId: "items",
fieldId: "itemid",
value: item.itemid,
ignoreFieldChange: true
});
log.debug("Inside Line Items", "ITEM Added " + item.itemid );
rec.commitLine({sublistId:"items"});
log.debug("Inside Line Items", "Line Committed" );
++i;
});
rec.save();
}
catch(err)
{
var msg = '';
log.debug("There was an error", err);
}
})
return "";
}
I have tried changing the itemid to shipmentitem and id, and it doesn't work. Before, I was getting an error for PO, too, and it was because the name was wrong, but I fixed that (I believe) for the item.
One thing that might be affecting it (not sure) is that the PO list filters the item list. once the user selects the PO in the UI, it will filter the item list to only items on that PO. I have double-checked that the item I am trying to submit belongs to the PO I am trying to submit, but still receiving an error. Any ideas?
According to the NetSuite Record Browser, the field should be 'shipmentitem'.
rec.setCurrentSublistValue({
sublistId: "items",
fieldId: "shipmentitem",
value: item.itemid,
ignoreFieldChange: true
});
EDIT: Updated to reflect that the fieldname should be 'shipmentitem' as #shawleigh17 discovered so future users find the correct answer.
all you need is a PO line unique Id (line field id: lineuniquekey) of each from original PO/POs and transaction Id. This id you will set for shipmentitem sublist field of Inbound Shipment record.
objRecord.setCurrentSublistValue({
sublistId: 'items',
fieldId: 'purchaseorder',
value: objParam.purchaseOrderId,
forceSyncSourcing: true
});
objRecord.setCurrentSublistValue({
sublistId: 'items',
fieldId: 'shipmentitem',
value: objParam.lineUniqueIdFromPO,
forceSyncSourcing: true
});
and of course, do not forget to set quantity for quantityexpected

How to set an address on customer using SuiteScript 2.0

I'm trying to set an address on a customer record. I've grasped that the address is a subrecord of a customer sublist and I believe I'm able to set fields on said subrecord, but I'm unable to get the changes to save. How can one set address information on a Customer using SuiteScript 2.0?
Current code:
customer.selectNewLine({
sublistId: 'addressbook'
});
var addressSubrecord = customer.getCurrentSublistSubrecord({
sublistId: 'addressbook',
fieldId: 'addressbookaddress'
});
subrecordAddressDetail.setValue({
fieldId: 'addr1',
value: 'Test Street'
});
subrecordAddressDetail.setValue({
fieldId: 'country',
value: 'US'
});
customer.commitLine({
sublistId: 'addressbook'
});
I've also tried adding customer.save() after .commitList, but I get the error Record has changed when I try to do so.
The part I was missing was that you need to save the parent record for any changes to a subrecord of a sublist to take effect. I was unable to save said parent record because I had made changes to that record and saved them previously which caused the Record has already changed error.
Generally addresses can be added to customer records by:
Selecting a line in the addressbook sublist.
Retrieving the address subrecord of the currently selected line.
Updating the subrecord.
Committing the selected line in the addressbook sublist.
Saving the parent record.
For example this will update the first address for a given customer or create it if it doesn't already exist:
function updateAddress(customer, address) {
var currentAddressCount = customer.getLineCount({
'sublistId': 'addressbook'
});
if (currentAddressCount === 0){
customer.selectNewLine({
sublistId: 'addressbook'
});
} else {
customer.selectLine({
sublistId: 'addressbook',
line: 0
});
}
var addressSubrecord = customer.getCurrentSublistSubrecord({
sublistId: 'addressbook',
fieldId: 'addressbookaddress'
});
// Set all required values here.
addressSubrecord.setValue({
fieldId: 'addr1',
value: address.line_one
})
customer.commitLine({
sublistId: 'addressbook'
});
customer.save()
}
I think you need to treat the address as a proper record. Therefore, after you retrieve it, set its values and then commit it separately. Something along these lines:
customer.selectNewLine({
sublistId: 'addressbook'
});
var addressSubrecord = customer.getCurrentSublistSubrecord({
sublistId: 'addressbook',
fieldId: 'addressbookaddress'
});
addressSubrecord.setValue({
fieldId: 'addr1',
value: 'Test Street'
});
addressSubrecord.setValue({
fieldId: 'country',
value: 'US'
});
addressSubrecord.save()
customer.commitLine({ //probably not necessary since address is already updated
sublistId: 'addressbook'
});

Resources