Relate/link vendor bill to purchase order in Netsuite - netsuite

I have created vendor bill with nlapiCreateRecord, I can see the Bill record in the system with all items I want, but I can't relate it / link it to specific Purchase Order natively. When I'm using nlapiTransformRecord I'm deleting all records first from the PO and I'm adding new line items from CSV, but the native link/relationship between PO and Vendor Bill is missing. Here is my code created for the Bill Import from CSV:
function BillImport() {
var fromrecord;
var fromid;
var torecord;
var record;
var qty;
fromrecord = 'purchaseorder';
fromid = 23664;
torecord = 'vendorbill';
var loadedBillFile = nlapiLoadFile(5034);
var loadedBillString = loadedBillFile.getValue();
var BillLines = loadedBillString.split('\r\n'); //split on newlines
record = nlapiTransformRecord(fromrecord, fromid, torecord);
//trecord.setFieldValue('location', 1);
//trecord.setFieldValue('tranid', 'TEST!');
//var record = nlapiCreateRecord('vendorbill');
for (var j = record.getLineItemCount('item'); j>=1; j--)
{
record.removeLineItem('item',j);
}
for (var i = 1; i < BillLines.length; i++) {
var cols = BillLines[i].split(';');
var dsplit = cols[4].split(".");
var date = new Date(dsplit[2],dsplit[1],dsplit[0]);
currentDate = date.getMonth() + '/' + date.getDate() + '/' + date.getFullYear();
var entity = cols[0]; // OK HEAD
var currency = cols[1]; // OK LINE
var taxcode = cols[2]; // SKIP
var tranid = cols[3]; // OK HEAD
var trandate = currentDate; // OK HEAD FORMAT 11/3/2016
var location = 21;//cols[5]; // OK HEAD (ID of Location)
var item = cols[6]; // OK LINE
var quantity = cols[7];
var rate = parseFloat(cols[8]); // FLOAT
var amount = parseFloat(cols[9]);
var po = cols[10];
record.selectNewLineItem('item');
// Head Level
record.setFieldValue('createdfromstatus','');
record.setFieldValue('entity', entity);
record.setFieldValue('tranid', tranid);
record.setFieldValue('trandate', trandate);
record.setFieldValue('location', location);
// Line Level
record.setCurrentLineItemValue('item','item', item);
record.setCurrentLineItemValue('item','quantity', quantity);
record.setCurrentLineItemValue('item','rate', rate);
record.setCurrentLineItemValue('item','amount', amount);
//record.setCurrentLineItemValue('item','orderdoc', po);
//record.setCurrentLineItemValue('item','podocnum', po);
record.commitLineItem('item');
}
var id = nlapiSubmitRecord(record, true);
//trecord.setLineItemValue('item', 'amount', 1, 3 );
//var idl = nlapiSubmitRecord(trecord, true);
}
Here is the example CSV file:
Entity;Currency;Taxcode;Tranid;TranDate;Location;Item;Quantity;Rate;Amount;PO Internal ID
2449;USD;0.00 ;224676;11.3.2016;21;885;1;10;50;23664
2449;USD;0.00 ;224676;11.3.2016;21;870;2;10;120;23664
2449;USD;0.00 ;224676;11.3.2016;21;890;3;3;45;23664
2449;USD;0.00 ;224676;11.3.2016;21;948;4;4,66;38,5;23664
2449;USD;0.00 ;224676;11.3.2016;21;886;5;19,54;720;23664
I'm

If you don't want it to transform into a Vendor Bill (probably to avoid the PO from changing status) then you will need to create a custom relationship. You do this by:
Create a custom field on the Vendor Bill form of type "List/Record" and have the it be of "Transaction" type and check "Record is Parent". Save the Custom Field.
Go back to the custom field and edit it. Go to the display tab and select a "Parent Subtab", I usually select "Related Records". Save.
Now you just need to create a new Vendor Bill from scratch and save the record id of the PO in the Vendor Bill using the new custom field. Leave the "Created From" field blank, otherwise you would be linking them natively. The Bill should be listed under the "Related Records" tab or whichever subtab you selected on the PO.

Vendor bill import via CSV method is doable but you can bill the Purchase Order completely and not partially i.e. if you try to import a bill mentioning any referenced Purchase Order's link in it, it'll create a bill for all the remaining unbilled quantities of the Purchase Order rather than the quantity you have mentioned.
Actually if you mention any quantity AND Purchase Order link BOTH in the CSV file then it will throw an error.
Below is the part I found from the SuiteAnswers with answer id as 10020.
Refer the supporting image here

Related

Fill duedate field based on value of terms field

Is it possible to fill the duedate field based on the terms field? For example, I have a date in the duedate field, but I want to extend it based on the terms field. How can I do it? Through Suitescript or workflow?
The code is incomplete because I don’t know if I’m on the right path.
(NB: It is a user event)
function beforeLoad(context) {
}
function beforeSubmit(context) {
}
function afterSubmit(context) {
var dataEntrega = context.currentRecord
currentRecordRecord.getValue({
fieldId: 'duedate'
})
var dataCondicoes = context.currentRecord
currentRecord.getValue({
fieldId: 'terms'
})
}
return {
beforeLoad: beforeLoad,
beforeSubmit: beforeSubmit,
afterSubmit: afterSubmit
}
Why do you need to script this? I believe the due date is calculated based on the terms out of the box, no need for scripting
The following code should work. Depending on your needs I recommend adding some limitations to when this logic is executed. For example you can only execute based on if the transaction/record mode is create/copy (decide if you want to include edit or not). You can also check the status of the transaction, and only execute if the status is not partially paid/paid in full...
function afterSubmit(context) {
//load record
var curRec = context.newRecord; //can substitute "context.oldRecord", or "currentRecord.get();"
//get current due date
var transDueDate = curRec.getValue({fieldId: 'duedate'});
//get the terms, this will likely come as an internal id. use getText if you want the text.
var transTerms = curRec.getValue({fieldId: 'terms'});
//empty string to hold terms as a number of days
var addtlDays;
//transform the internal id to terms as a number of days
switch (transTerms){
case 1: // Ex: 1 = internal id for term "Net 15"
addtlDays = 15;
break;
case 2: // Ex: 2 = internal id for term "Net 30"
addtlDays = 30;
break;
//add additional case statements as needed
default:
addtlDays = 0;
}
//calculuate the new due date
var d = new Date(transDueDate);
var newDueDate = d.setDate(d.getDate() + addtlDays);
//set the new due date
curRec.setValue({
fieldId: 'duedate',
value: newDueDate,
ignoreFieldChange: true //optional, default is false
});
}

billing schedule record creation on netsuite

I have written a script which creates a billing schedule record for items on the creation of sales order using afterSubmit() user event script.
The billing schedule record gets created for every item,but it also should be set in line level field 'billing schedule' of the sales order.details in attachment
var rec =nlapiCreateRecord('billingschedule');
var res = itemname.substring(0, 40);
rec.setFieldValue('name',res);
rec.setFieldValue('initialamount',itemamount);
rec.setFieldValue('numberremaining','5');
rec.setFieldText('frequency','Daily');
var sub = nlapiSubmitRecord(rec,true);
if(sub!=null)
{
nlapiSetLineItemValue('item','billingschedule',i+1,sub);
}
You need to load the record in afterSubmit, otherwise it's read-only.
var salesOrderId = nlapiGetRecordId();
var soRec = nlapiLoadRecord('salesorder', salesOrderId);
// DO YOUR BILLING SCHEDULE CREATION LINE WORK
var soLines = soRec.getLineItemCount('item');
// SS1 indexes start at 1
for (var x = 1; x <= soLines; x++) {
var rec =nlapiCreateRecord('billingschedule');
var res = itemname.substring(0, 40);
rec.setFieldValue('name',res);
rec.setFieldValue('initialamount',itemamount);
rec.setFieldValue('numberremaining','5');
rec.setFieldText('frequency','Daily');
var sub = nlapiSubmitRecord(rec,true);
if(sub!=null) {
soRec.setLineItemValue('item','billingschedule', x, sub);
}
}
// Submit the record to save the values
nlapiSubmitRecord(soRec);

SuiteScript Auto Populate Department Line Item Fields

Code Portion Click Here
I am trying to populate the Department line item field as per the Department Transaction Body Field, please assist to check if my codes are right.. i am new to suitescript.
var itemDepartment = nlapiGetFieldValue('department');
var nlapiSetCurrentLineItemValue = nlapiSetCurrentLineItemValue('item', 'department_display', itemDepartment);
It keeps stating that department_display is not an internal ID.
Please advise.
Thank you.
Can you try setting text instead,if it is a client script.
The id of the department column field is 'department'
var itemDepartment = nlapiGetFieldText('department');
nlapiSetCurrentLineItemText('item', 'department', itemDepartment);
The id of the department column field is also department, same as the header field.
Therefore, the second line of you snippet should be:
nlapiSetCurrentLineItemValue('item','department',itemDepartment);
EDIT
As per the comment below, please find below the full code snippet to populate lines department from the customer on before submit:
function onBeforeSubmit(type) {
if (type == 'create' || type == 'edit') {
var customerId = nlapiGetFieldValue('entity');
var itemDepartment = nlapiLookupField('customer',customerId, 'custentity_department');
var itemCount = nlapiGetLineItemCount('item');
for (var i = 1; i <= itemCount; i++) {
nlapiSetLineItemValue('item', 'department', i, itemDepartment);
}
}
}
Also, as a side note, you don't have to load the whole record in order to get a field value. You should use nlapiLookupField instead. It's much faster, safer and less api usage.

Column Value in search api

I want to get the value from a Item sublist of Sales Order record.
But unable to get it. Though I can get the value of entity fields of the SO record.
Below is the snippet of the code:
var filters = new Array();
filters[0] = new nlobjSearchFilter("mainline",null,"is","T");
var column=new Array();
column[0] = new nlobjSearchColumn("trandate");
column[1] = new nlobjSearchColumn("item");
column[2] = new nlobjSearchColumn("cust_col_1");
var result = nlapiSearchRecord('salesorder', null, filters, column);
for(var i = 0; i<result.length; i++)
{
var col = result[i].getAllColumns();
var date = result[i].getFieldValue("trandate"); //I get this
var item_id = result[i].getLineItemValue("item", "item", i+1); // I don't get this
var cust_col = result[i].getLineItemValue("item", "cust_col_1", i+1); //I don't get this
}
I think I am defining the columns wrong.
This part
var item_id = result[i].getLineItemValue("item", "item", i+1); // I don't get this
var cust_col = result[i].getLineItemValue("item", "cust_col_1", i+1); //I don't get this
is also wrong, you use this syntax if you have loaded the record but for search results you just use
result[i].getValue('cust_col_1")
By specifying the filter new nlobjSearchFilter("mainline",null,"is","T"), you're basically telling the search that you don't want any line item data. This means that you will be unable to read any column data, custom or otherwise.
The mainline filter parameter has basically three options, 'F' means you want the line item details. 'T' means you just want the header data. Leaving this filter out will return one row for the header information and one row for each line item on the transaction.

How to get all subsidiaries showing in UI by RESTlet in Netsuite?

i could get all names, types, labels and available options for fields except subsidiary.
There are two options for subsidiary in Netsuite UI. But when i try to get by code, i could get only one subsidiary which was referred in Employee creation.
This is the code snippet.
function getFields(datain) {
var record = nlapiCreateRecord ( datain . recordtype );
var fields = record.getAllFields();
var requiredFields = {};
fields.forEach(function(fieldName){
var field = record.getField(fieldName);
if(field.mandatory === true) {
var id = field.getName();
var field_details = {}
field_details['Type'] = field.getType();
field_details['Label'] = field.getLabel();
if(field.getType() == 'select' || field.getType() == 'multiselect') {
var Options = field.getSelectOptions();
var selectOptions = {};
for(var i in Options) {
var opt_id = Options[i].getId();
selectOptions[opt_id] = Options[i].getText()
}
field_details['Options'] = selectOptions;
}
requiredFields[id]=field_details;
}
});
return requiredFields;
}
How to get all subsidiaries available in lead , customer or contact creation?
Subsidiaries are retrieved based on subsidiaries set in roles not on employee creation. Here before i have selected only one subsidiary in role.
If we select all subsidiaries for the appropriate role, we can get all subsidiaries which were selected in the role.

Resources