When the billing schedule runs it auto generates invoices from sales order. When this happens - how can I create a link on the sales order that will allow me to load the corresponding invoice in code?
I need this so I can grab couple of field values from the invoice but I can't access the invoice directly from another entity which seems only related to sales order.
EDIT 1:
var fil = [];
fil[0] = new nlobjSearchFilter('createdfrom', null, 'is', nlapiGetRecordId())
var col = [];
col[0] = new nlobjSearchColumn('internalid');
var invoices = nlapiSearchRecord('invoice', null, fil, col);
nlapiLogExecution('DEBUG', 'field val', invoices);
Throws invalid operator or not in proper syntax: createdfrom.
Though adding a link on the Sales Order is a viable solution, it's not your only option. Alternatively, you could do a search for invoices where the createdfrom field is the internal ID of your Sales Order. Something like in SuiteScript 1.0:
var invoices = nlapiSearchRecord('invoice', null,
[['createdfrom', 'is', nlapiGetRecordId()]],
[/* create search columns for the fields you need off the invoice */]
) || [];
or in 2.0:
var invoices = search.create({
"type": search.Type.INVOICE,
"filters": [['createdfrom', 'is', context.currentRecord.id]],
"columns": [/* create search columns for the fields you need off the invoice */]
}).run().each(processResult);
This will get you a list of all the Invoices created from your Sales Order (which is likely only 1).
If you believe you need a link to the Invoice on the Sales Order, you could add the custom body field, then create a User Event on the Invoice record that populates this new field with its createdfrom value on the Before Submit event. But then what happens if your Sales Order gets paid via multiple Invoices?
Related
I'm having an issue pulling the value of a column in SuiteScript v1.0. The search is looking at Cash Sales and is producing the results I want in the UI, but I am unable to get the value of one column in SuiteScript. I suspect it is because either the value comes from the 'Created From' doc, or because it is a drop down list. Any help would be greatly appreciated.
The search looks at Cash Sales where the Dept/Sales Channel (NS id department) doesn't match the Dept/Sales Channel of the Sales Order. The results are:
Type
Document Number
Created From : Dept/Sales Channel
In the UI, it is doing exactly what I hoped. However, when I loop thru the results in my v1.0 SuiteScript, I'm getting a null value for Dept/Sales Channel:
results.forEachResult(function(res){
var id = res.getId();
var docid = res.getValue('tranid');
var dept = res.getValue('channel');
nlapiLogExecution('DEBUG', 'Found result - '+docid+' ('+id+') - '+dept+'.');
docid and id are correct, but dept ends up being null. I've tried 'channel', 'deptartment' and column[3].value with no luck. What am I doing wrong?
Based on how you formatted this: "Created From : Dept/Sales Channel", I assume it is a joined column.
If it is, you need to do it this way:
var dept = res.getValue('department', "createdfrom");
I am trying to somewhat mimic NetSuite's Landed Cost feature using NetSuite's customization options (SuiteBuilder,SuiteScript etc.) and then further extend the functionality according to my requirements.
For this I need to in script, get value of "LANDED COST CATEGORY" line field of item sublist in the Transaction records (like Bill, Purchase Order etc.) using saved search.
But in a saved search I was unable to find any Column/scriptId which would give me value of LANDED COST CATEGORY line field. We ARE able to get this value using record.load().getValue() but I need this value from multiple transaction records and using this approach may cause performance issues. So, please can you tell how we can access this value using saved search.
I don't believe Netsuite exposes that field in saved searches at this time. This is the records browser in Netsuite listing all of the available search columns for Transaction searches. The internal id for that column is landedcostcategory, and that doesn't show up on the list.
However, if your goal is to get this information in SuiteScript, then you can use the 'N/query' module. Pull up one of your Purchase Orders, open the Javascript console (Ctrl+Shift+J) and try this:
require(['N/query'], (query) => {
const suiteqlQuery = `SELECT
transaction as transaction_id,
BUILTIN.DF(transaction) as transaction_name,
BUILTIN.DF(item) as item_name,
item as item_id,
landedcostcategory as landedcostcategory_id,
BUILTIN.DF(landedcostcategory) as landedcostcategory_name
FROM
transactionline
WHERE
transaction='<internal id of your PO here>'`;
const results = query.runSuiteQL({query: suiteqlQuery}).asMappedResults();
console.log(JSON.stringify(results, null, 2));
/*
Example output for results:
[
{
"transaction_id": "12345",
"transaction_name": "Purchase Order #PO123456",
"item_name": "My Favorite iPod",
"item_id": 1234,
"landedcostcategory_id": 1,
"landedcostcategory_name": "Duties & Tariffs"
}
]
*/
})
So I was doing a simple custom search but somehow the tax rate is not showing. I am still new to NetSuite and I tried to find workarounds about this. Any suggestions?
var columns = new Array();
columns[0] = new nlobjSearchColumn('internalid');
columns[1] = new nlobjSearchColumn('name');
columns[2] = new nlobjSearchColumn('itemid');
columns[3] = new nlobjSearchColumn('rate');
columns[4] = new nlobjSearchColumn('taxtype')
var res = nlapiSearchRecord('salesTaxItem', null, null, columns);
wcache('res---> '+ JSON.stringify(res));
return;
not sure if it matters but the name should be 'salestaxitem' not 'salesTaxItem' Also do you know if you have any tax items or codes in your account?
If you are on a One World account you need to make sure you have access to the subisdiary that has tax items.
I see all the rates when I run your code in my account.
The Netsuite record browser has this to say about the rate field:
Enter the appropriate tax rate as a percentage. Example: 8% This percentage will be calculated when you select this tax item on transactions. This field is available only if the SuiteTax feature is disabled in your account.
I am fairly new to suitescript and would like to build a script that runs on a recurring schedule and only invoices based on item fulfillments (ie there is a one to one relationship between the invoice and item fulfillment but potentially a one to many relationship between the sales order and invoice/item fulfillments).
I am able to successfully run a script that transforms the sales order in total into an invoice - however this includes all items on sales order and not just the items that have been fulfilled (we have many situations in our business in which only partial fulfillment occurs and the order must then be closed out). At this point from my research I'm unable to find other examples of this script being successfully created. My initial idea is to somehow store the 'qtyfulfilled' on the sales order in an an array with the items and somehow create an invoice with this. However to me it seems that the transform function is the best way to retain a link between sales order and the invoice.
var invoice = record.transform({
fromType: record.Type.SALES_ORDER,
fromID: salesOrderId,
toType: record.Type.INVOICE,
isDynamic: true
});
This returns an invoice with all items from the sales order rather than just the fulfilled items.
EDIT:
I implemented a version of the code suggested where I just iterate over the lines of the sales order and replace each line quantity on the invoice with 'fulfilledquantity' - however I realized when the quantity is zero the invoice appears to be still storing that line at a zero value.
Downstream of the invoice script I'm passing the invoice record to our EDI provider via a NS integration. The invoices created via my script map into the EDI 810 (invoice record) with 0 quantity lines for the line items that werent fulfilled which cause errors in the EDI file.
I wrote the following to iterate through invoice lines after the quantity and remover the zero quantity lines but am getting the following error: "name":"USER_ERROR","message":"Please choose an item to add" -
for (var k = 0; k < lineCount; k++) {
var currentInvoiceLineQuantity = newInvoice.getSublistValue ({
sublistId: 'item',
fieldId: 'quantity',
line: k
});
if(currentInvoiceLineQuantity === 0){
newInvoice.removeSublistSubrecord({
sublistId: 'item',
fieldid: 'item',
line: k
});
k--;
lineCount--;
}
}
After you transform the sales order to an invoice, iterate through the lines and change the quantity to only invoice the amount that was fulfilled.
The sample below is from a legacy script written in SS1.0 but will translate pretty easily to SS2.0.
var lineCount = invoice.getLineItemCount('item');
for (var i = 1; i <= lineCount; i++) {
const quantity = invoice.getLineItemValue('item', 'quantity', i);
const remaining = invoice.getLineItemValue('item', 'quantityremaining', i);
invoice.setLineItemValue('item', 'quantity', i, quantity - remaining);
}
If you do this in an After Submit user event on Item Fulfillments you can transform the related Sales Order to an invoice and then walk backwards through the line times and delete the ones not on the fulfillment.
You should check quantities for the against the shipped quantities and you may need to have logic for billing any unfulfillable items ( I do that either the first fulfillment on an order or when there are no more lines to ship. )
Finally you may need to handle shipping charge logic to either charge the amount of shipping on each fulfillment or charge the fulfillment’s shipping up to the shipping charge on the original sales order.
I am creating a script that needs to get the contacts associated to a company. The script needs to work for both Customers and Vendors.
You can attach a Contact to a Customer or Vendor from the record screen and by doing this you can attach a Contact with an empty Company field.
I can use the sublist contactroles if it is a Customer record but that sublist is not available for the Vendor record.
Is there a way to get the contact records via search? So using the screenshot above can a search get the following contacts: Aiden Somerhalder, Alex Wolfe and Gerrom Test Contact.
I'd create a saved search of Vendors/Suppliers.
Add a filter to your result: contact : name is not empty
Add a column to your result: contact : name
Add a column to your result: contact : internalId
This should give you a set that your script can iterate through.
You should be able to create a vendor or customer search and the search should return the company/name or more details. Just select as a filter or column:
Contact fields... Company
Perhaps something like this (Running from within the record):
var filters = [];
var columns = [];
filters.push(new nlobjSearchFilter('internalidnumber', null, 'equalto', [nlapiGetRecordId()]));
columns.push(new nlobjSearchColumn('entityid', 'contact', null));
var results = nlapiSearchRecord(nlapiGetRecordType(), null, filters, columns);