This article is relevant if you need to craft a standalone NetSuite Vendor Bill and you want to link it to a respective Purchase Order.
Background
While subject to a separate article, during a client implementation of a consignment sales flow, we sought to couple the specific sale of an item to the creation of a related vendor bill. In this case, since the items were serialized, we knew exactly where we acquired the item by looking it up via its related item receipt.
The goal thus was to constitute a vendor bill and bind it to the purchase order. However, we did not seek to use the SuiteScript “record.transform” option due to the way that the sales transactions could reference more than one item across different respective purchase orders.
Note, in my 2015 article, Learn the SuiteScript Pattern to Generate Target Purchase Orders from Sales Orders, I discuss another SuiteScript 1.0 pattern. In addition, my 2020 article, NetSuite Vendor Bill Created From Purchase Order References, helps illustrate how Vendor Bills can reference Purchase Orders.
SuiteScript Pattern to Link Vendor Bill Lines to Purchases Orders
It turns it is indeed possible to craft a NetSuite standalone vendor bill and link it to a purchase order using SuiteScript. Our consultants, Sylvain M. and Elie C. produced the handiwork. The approach uses the built-in orderdoc and orderline references in the vendor bill item sublist.
Here is the code pattern:
billRec.selectLine ( {sublistId: 'item', line: i } ); billRec.setCurrentSublistValue ( { sublistId: 'item', fieldId: 'orderdoc', value: poReference } ); billRec.setCurrentSublistValue ( { sublistId: 'item', fieldId: 'orderline', value: poLineId } ); billRec.commitLine ( {sublistId:'item'} );
There are a couple of considerations to account for:
- On Create: you can only link on the creation of the vendor bill, not on its update. However, we did not test if we could update the vendor bill and add newly created lines to bind to the purchase order.
- Orderline Index: To get the orderline index, you will need some lookup code. Else you may receive an error, “You cannot add an item and purchase order combination that does not exist to a Vendor Bill.”
Call the following function to get the PO Line:
var poLine = PO.findSublistLineWithValue({sublistId: "item", fieldId: "item", value: data.itemId});
Then get the Orderline value using the PO Line as an index pointer:
var orderLine = PO.getSublistValue({sublistId: "item", fieldId: "line", line: poLine});
Note, the term “line” is ambiguous because it both exists as a field and is also used to reference the array index.
Remember, NetSuite is Designed to be Adapted
Having strong software development and database pattern knowledge is quite handy when working with the NetSuite platform. Indeed, the platform has its own nuances to accomplish objectives — after working with NetSuite for 12+ years, our team continues to deepen their expertise.
Our clients are very pleased with productivity possibilities to extend NetSuite’s capacities to streamline their business and accounting operations. Let’s always remember that we are working with software — it can be powerfully enhanced to help generate more revenue and lower cost.
If you found this article relevant, feel free to sign up for notifications to new articles as I post them. If you are ready to streamline your business operations and suspect that a NetSuite enhancement will make a difference, let’s have a conversation.
Hi, We are trying to create a vendor bill from existing purchase order using suitescript N/record module. Following is the code:
var vendorBill = recordModule.create({
type: recordModule.Type.VENDOR_BILL,
isDynamic: true,
defaultValues: {
entity: supplierId
}
});
vendorBill.selectNewLine(‘item’);
vendorBill.setCurrentSublistValue(‘item’, ‘orderdoc’, poId);
vendorBill.setCurrentSublistValue(‘item’, ‘orderline’, poLineId);
vendorBill.commitLine(‘item’);
vendorBill.save({
enableSourcing: false,
ignoreMandatoryFields: true
});
This above code is written in a restlet and when we invoke it from postman, we get :
{
“type”: “error.SuiteScriptError”,
“name”: “YOU_CANNOT_ADD_MULTIPLE_VENDORS_ANDOR_CURRENCIES_TO_A_SINGLE_VENDOR_BILL”,
“message”: “You cannot add multiple vendors and/or currencies to a single Vendor Bill.”,
“id”: “”,
“stack”: [
“anonymous(N/serverRecordService)”,
“postBill(/SuiteScripts/new_post_transaction.js:1402)”,
“doPost(/SuiteScripts/new_post_transaction.js:641)”
],
“cause”: {
“type”: “internal error”,
“code”: “YOU_CANNOT_ADD_MULTIPLE_VENDORS_ANDOR_CURRENCIES_TO_A_SINGLE_VENDOR_BILL”,
“details”: “You cannot add multiple vendors and/or currencies to a single Vendor Bill.”,
“userEvent”: null,
“stackTrace”: [
“anonymous(N/serverRecordService)”,
“postBill(/SuiteScripts/new_post_transaction.js:1402)”,
“doPost(/SuiteScripts/new_post_transaction.js:641)”
],
“notifyOff”: false
},
“notifyOff”: false,
“userFacing”: false
}
Please help.
Hello Prashant,
It looks like you are trying to cross currency boundaries on a transaction. You will need to invent a workaround. Our account clearing model may be able to assist. See this article:
https://blog.prolecto.com/2018/09/02/how-to-cross-netsuite-foreign-currency-boundaries-with-the-account-clearing-model/
Marty
I just did this exact thing except I consolidated a vendor bill from a list of PO items on the inbound shipment (custom NS bundle) record. This needed a UE, CS, and Suitelet script to work; quite the adventure.
Typically, inbound shipments create one bill per PO whereas my solution allows for a consolidated bill for each vendor in the shipment.
Hi Craig,
That’s interesting and valuable that you needed all that code to work together. I worry about any solution that should be all server side requiring some client side script and would love to learn more. We find the Inbound Shipment Record difficult to work with and we always exercise caution when working with clients.
Marty
There are three scripts in the solution:
1. UE script to add a button to the Shipment record linking to a function in a CS. The button is what the user presses when they want to create a consolidated bill rather than one per PO
2. CS script to redirect the user to a Suitelet
3. The Suitelet provides the UI/fields etc and business logic to create the consolidated vendor bill based on data from the inbound shipment record and any information added by the user in the Suitelet fields.
I wanted to hook into the save button on the inbound shipment bill page but that’s not a scriptable record which is why I had to add a new button and Suitelet/UI.
Interestingly, I am finding it a struggle to link the Vendor Bill with an Inbound Shipment. It appears there is one field on the bill (“inboundshipmentvalue”) that shows the internal ID of the shipment but setting that field gives the error: “message”: “Items you have requested in the record have been deleted since you retrieved the form”
I’ll share the knowledge here once I’ve figured it out incase it’s useful to others.