Thursday, October 31, 2013

How to get Address Templating Working with Custom Transaction Addresses in Netsuite

How to set a Custom Shipping Address on a Transaction in Netsuite Using Suitescript

I have a situation where I want to use a specific address as the shipping address on a quotation. I don't want this address to be added to the customer record. It is a one time only address that should only be available on the quotation.

Simple enough right?

The Problem

This should be pretty straight forward using code like this

   1 var theRecord = nlapiLoadRecord('estimate', 123,  {recordmode: 'dynamic'});
   2 
   3 theRecord.setFieldValue('shipaddresslist', '');
   4 theRecord.setFieldValue('shipattention', 'Temp User 1');
   5 theRecord.setFieldValue('shipaddressee', 'Temp Company Ltd');
   6 theRecord.setFieldValue('shipphone', '999-888-7777');
   7 theRecord.setFieldValue('shipaddr1', '123 Test Street');
   8 theRecord.setFieldValue('shipaddr2', '123 Test Street 2');
   9 theRecord.setFieldValue('shipcity', 'Test');
  10 theRecord.setFieldValue('shipstate', 'Test State');
  11 theRecord.setFieldValue('shipzip', '10004');
  12 theRecord.setFieldValue('shipcountry', 'SE');
  13 theRecord.setFieldValue('shipoverride', 'F');
  14 theRecord.setFieldValue('shipisresidential', 'T');
  15 
  16 nlapiSubmitRecord(theRecord);
  17 

Unfortunately if you do that the data is properly set in the background but it is not rendered in the shipping address textarea.


In order to get the address to be rendered in the text area we have to create a custom string including line breaks like this:
1 theRecord.setFieldValue('shipaddress', 'Temp User 1\nTemp Company Ltd\n999-888-7777\n123 Test Street\n123 Test Street 2' );

This is a bit crazy since that breaks the address templating that is built in to Netsuite. Let's say that a Japanese address is supposed to be rendered with the field in a different order from a Swedish address. If we create the address string on our own we either have to replicate all the rules for every country directly in the code or just render the field in the same order for every country. This adds loads of coding work or increases the risk for parcels not getting to the customer.

We need a better solution where the built in address renderers are being used. I have asked Netsuite about this and they just refer to that this is by design.

The Solution

The only properly working way I found for fixing this is to use the address functionality on the customer record.

This is what I do
  1. Load the quotation record
  2. Load the customer record of the entity on the order
  3. Add a new address to the customer
  4. Copy the addrtext attribute on the new address
  5. Add the rendered address to the text area on the quotation
  6. Save the quotation record
This solution gives us a templated text string to set in the address field on the quotation.

Here is the full code for this.

 1 var theRecord = nlapiLoadRecord('estimate', 123,  {recordmode: 'dynamic'});
 2 
 3 var theCustomer = nlapiLoadRecord('customer', theRecord.getFieldValue('entity'),  {recordmode: 'dynamic'});
 4 
 5 theCustomer.selectNewLineItem('addressbook');
 6 
 7 theCustomer.setCurrentLineItemValue('addressbook','attention', 'Temp User 1');
 8 theCustomer.setCurrentLineItemValue('addressbook','addressee', 'Temp Company Ltd');
 9 theCustomer.setCurrentLineItemValue('addressbook','phone', '999-888-7777');
10 theCustomer.setCurrentLineItemValue('addressbook','addr1', '123 Test Street');
11 theCustomer.setCurrentLineItemValue('addressbook','addr2', '123 Test Street 2');
12 theCustomer.setCurrentLineItemValue('addressbook','city', 'Test');
13 theCustomer.setCurrentLineItemValue('addressbook','state', 'Test State');
14 theCustomer.setCurrentLineItemValue('addressbook','zip', '10004');
15 theCustomer.setCurrentLineItemValue('addressbook','country', 'SE');
16 theCustomer.setCurrentLineItemValue('addressbook','override', 'F');
17 theCustomer.setCurrentLineItemValue('addressbook','isresidential', 'T');
18 
19 var templatedAddress = theCustomer.getCurrentLineItemValue('addressbook','addrtext');
20 
21 theRecord.setFieldValue('shipaddresslist', '');
22 theRecord.setFieldValue('shipattention', 'Temp User 1');
23 theRecord.setFieldValue('shipaddressee', 'Temp Company Ltd');
24 theRecord.setFieldValue('shipphone', '999-888-7777');
25 theRecord.setFieldValue('shipaddr1', '123 Test Street');
26 theRecord.setFieldValue('shipaddr2', '123 Test Street 2');
27 theRecord.setFieldValue('shipcity', 'Test');
28 theRecord.setFieldValue('shipstate', 'Test State');
29 theRecord.setFieldValue('shipzip', '10004');
30 theRecord.setFieldValue('shipcountry', 'SE');
31 theRecord.setFieldValue('shipoverride', 'F');
32 theRecord.setFieldValue('shipisresidential', 'T');
33 theRecord.setFieldValue('shipaddress', templatedAddress );
34 
35 nlapiSubmitRecord(theRecord);

Now the address field looks like this:

Summary

This solution is acceptable because we only have to load the customer record and not waste time by having to submit the customer record and load it again to get the data. The drawback is that it gets pretty slow and we use up a few execution points extra.

Netsuite really need to fix this. It works fine using web services or if if you do it straight in the UI. Why shouldn't it work in Suitescript?

I hope this helped you. I know for sure that I couldn’t create the feature I am working on now without this solution.


No comments:

Post a Comment