Using SuiteScript to populate a transfer order - netsuite

Current issue is that i can't commit a line item. Do i need to add more fields even though item is the only one required?
function OLDcreateTO() //(request, response)
{
for ( var i = 1; i < lines + 1 ; i++ )
{
nlapiLogExecution('DEBUG','<Before Load Script> type: '+type,"line # " + i);
arrayName[i] = PORecord.getLineItemValue('item', 'item', i );
nlapiLogExecution('DEBUG','<Before Load Script> type: '+type, arrayName[i]);
}
nlapiLogExecution('DEBUG','<Before Load Script> type: '+type, lines + ' lines');
var TOrecord = nlapiCreateRecord ('transferorder');
var TOrecordID = TOrecord.getId();
TOrecord.setFieldValue('customform',128);
//subsidiaries CC bedford id is 2
TOrecord.setFieldValue('subsidiary',2);
//testing for location and transfer location, 144 & 145
TOrecord.setFieldValue('location',144);
TOrecord.setFieldValue('transferlocation',145);
nlapiLogExecution('DEBUG','<Before Load Script> type: '+type, 'break 4');
// add new lines to a sublist
nlapiSelectNewLineItem('item');
// set the item and location values on the currently selected line
nlapiSetCurrentLineItemValue('item', 'item', arrayName[1]);
nlapiSetCurrentLineItemValue('item', 'location', 6);
// commit the line to the database
nlapiCommitLineItem('item');
nlapiLogExecution('DEBUG','<Before Load Script> type: '+type, 'break 5');
var TOResult = nlapiSubmitRecord(TOrecord, true, true);
var TOTranID= nlapiLookupField('transferorder', TOResult, 'tranid');
nlapiLogExecution('DEBUG','<Before Load Script> type: '+type, 'break 6');
var poURL = nlapiResolveURL('RECORD', 'transferorder', TOResult);
nlapiSetRedirectURL('RECORD','transferorder', TOResult);
}
So I am trying to have the items of a purchase order populate the items field on a new transfer order via a button on the PO. From there the user can make any changes they want to the record before submitting it and creating the TO. The main issue is I don't know how to populate a blank TO from script. I have it redirect there via a url string, but I'm sure there is a better way to do it.
In summary.
-User clicks "create TO" button on a PO
-takes user to the "create TO" page where all the items (and some various info) is pre populated depending on the PO.
-User edits the record and then submits it.
suitescript 1.0
//create_to_button
var newId ;
var newType ;
function beforeload(type)
{
if(nlapiGetContext().getRole() == '3')
{
if(type =='view' || type == 'edit')
{
newId = nlapiGetRecordId();
newType = nlapiGetRecordType();
if(newType == 'purchaseorder')
{
var strURL = "https://system.na2.netsuite.com/app/accounting/transactions/trnfrord.nl"
var scriptbutton = 'window.open(' + String.fromCharCode(39) + strURL + String.fromCharCode(39) + ')' ;
//nlapiLogExecution('DEBUG','<Before Load Script> type: '+type, 'URL: '+strURL + '&id=' + newId);
form.addButton('custpage_createpo', 'Create TO', scriptbutton);
}
}
}
}
function loadTO() //(request, response)
{
nlapiLogExecution('DEBUG','<Before Load Script> type: '+type, 'hello');
nlapiLoadRecord(newType, newId);
}
Any ideas or advice is appreciated.
-Brandon

If you know the TO will be saved you would open a Suitelet that will populate the TO. Save it and redirect to the new TO using nlapiSetRedirect with a url from nlapiResolveURL.
If the TO might not be saved then add some parameters to the tasklink url that you are already using and add your population logic to the TO's client side init function. You may need to add some custom fields to the TO with a beforeLoad user event script to provide the info the client script needs. (Your client script can look at query string parameters too but depending on what you are doing the server side lookups may be faster).

Related

SuiteScript New NetSuite UI InlineHTML elements not available in Javascript

On the new NetSuite UI, when creating a Project Task from the Project Subtab, the script does not seem to load as expected.
On before load of my script I add an inlineHTML field to the form and insert them html.
for(var key in fieldIds) {
var html = "<span class='smallgraytextnolink uir-label'>"+
"<span class='smallgraytextnolink labelSpanEdit'>"+
"<a class='smallgraytextnolink'>"+originalField.label + "</a>"+
"</span>"+
"</span>"+
"<div id='" + fieldIds[key] + "_div'></div>";
var theField = form.addField("custpage_"+fieldIds[key]+"_canvasfield", "inlinehtml", "Redacted");
nlapiSetFieldValue("custpage_"+fieldIds[key]+"_canvasfield", html);
}
On client side, PageInit I use
var field = document.querySelector("#" + id + "_div");
to try and select the div element added into the inlineHTML, but unfortunately this returns null.
This all works in the old NetSuite UI.
If that worked in the past then it was a bug.
The way to set the value of an added field in the beforeLoad user event in which it is created is via its defaultvalue:
form.addField({
id:'custpage_lint_results',
type:ui.FieldType.INLINEHTML,
label:'Lint Results',
container:'custgrp_lint'
}).defaultValue = '<div id="lint_results"></div>';
or in SS1:
var msg = form.addField('custpage_ra_reject', 'inlinehtml');
msg.setLayoutType('outsideabove', 'startrow');
msg.setDefaultValue('<div id="lint_results"></div>');
In the pageInit you may have to fully qualify the document element. I've had some friction with this in the past though not recently:
var field = window.document.querySelector("#" + id + "_div");
Finally you may need to wait.
I haven't had any issues with querying an id set in an Inline Html field in the then() of a promise that is called from a pageInit but I have sometimes done the following in a pageInit because of what you are seeing:
function pageInit(){
var elem = null;
function doStart(){
elem = document.querySelector('#elemFromUE');
if(!elem) setTimeout(doStart, 200);
}
doStart();
...
}

Getting users job title in Sharepoint List

So I have a SP Online list, that every user can submit his entries. I have a default column of "created by", where the user, that submited the entry is listed. I'd like to have 2 other columns, to get users Department and Job Title copied automatically from users account. How can I do this?
Method 1:
You can use the JSOM to set the Department/JobTitle. Because we don't sure where your user from(AD or some else )
First of all you need to load the “SP.UserProfiles.js, SP.Runtime.js and SP.js” js files on your SharePoint page, use following code snippet to load these files,
$(document).ready(function () {
var scriptbase = _spPageContextInfo.webAbsoluteUrl + "/_layouts/15/";
$.getScript(scriptbase + "SP.Runtime.js",
function () {
$.getScript(scriptbase + "SP.js",
function () {
$.getScript(scriptbase + "SP.UserProfiles.js", GetUserInformation);
});
});
});
var userProfileProperties;
function GetUserInformation() {
// Get the current client context.
var clientContext = SP.ClientContext.get_current();
//Get Instance of People Manager Class
var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);
var targetUser = "domain\\userId";
userProfileProperties = peopleManager.getPropertiesFor(targetUser);
//Execute the Query.
clientContext.load(userProfileProperties);
clientContext.executeQueryAsync(onSuccess, onFail); }
function onSuccess () {
// get user information from userProfileProperties and set to your target column.
userProfileProperties.get_userProfileProperties()['Department'];
userProfileProperties.get_userProfileProperties()['SPS-JobTitle'];
// To do: list item replace operation
}
function onFail (sender, args) {
alert("Error: " + args.get_message());
}
Reference:https://msdn.microsoft.com/en-us/library/office/jj679700.aspx
Method 2: Workflow
When user add/edit a item,we trigger the workflow to copy the user's department/JobTitle to target column
Reference for get the Department/Jobtitle.
https://sharepoint.stackexchange.com/questions/97971/get-current-user-information-and-add-to-email-action-in-workflow

RangeError Maximum call stack size exceeded on Creating Sales Order

We are developing a client script that will auto update the rate or unit price (*this is a custom column), but it throws an error and I think its because if we change the rate it will auto update the unit price and after the unit price has been updated it will update the rate also, so on and so on until it reach the maximum call stack, We are looking for any workaround for this not to happen, please see my code below. Thanks
function fieldChanged(type, name, linenum)
{
var context = nlapiGetContext();
var user = context.getUser();
var execution = context.getExecutionContext();
try {
switch (name) {
case "custcol_cqwst_po_uprice":
if (execution == "userinterface") {
var qty = nlapiGetCurrentLineItemValue('item', 'quantity');
var taxCode = nlapiGetCurrentLineItemValue('item', 'taxcode');
if (!isNullOrEmpty(taxCode) && !isNullOrEmpty(qty)) {
var taxRate = nlapiGetCurrentLineItemValue('item', 'taxrate1');
var unitprice = nlapiGetCurrentLineItemValue('item', 'custcol_cqwst_po_uprice');
var vatRate = 1 + ((taxRate.replace('%', '')) / 100);
var unitRate = unitprice / vatRate;
nlapiSetCurrentLineItemValue('item', 'rate', unitRate);
}
}
break;
//case "taxcode":
//break;
case "rate":
if (execution == "userinterface") {
var qty = nlapiGetCurrentLineItemValue('item', 'quantity');
var taxCode = nlapiGetCurrentLineItemValue('item', 'taxcode');
if (!isNullOrEmpty(taxCode) && !isNullOrEmpty(qty)) {
var taxRate = nlapiGetCurrentLineItemValue('item', 'taxrate1');
var rate = nlapiGetCurrentLineItemValue('item', 'rate');
var vatRate = 1 + ((taxRate.replace('%', '')) / 100);
var unitPrice = rate * vatRate;
nlapiSetCurrentLineItemValue('item', 'custcol_cqwst_po_uprice', unitPrice);
nlapiLogExecution('debug', "Rate Value", "Rate: " + rate + " Vat Rate: " + vatRate + " Unit Price: " + unitPrice + " Execution: " + execution);
}
}
break;
}
}
catch (ex) {
alert("A scripting problem occurred during the onFieldChange event please inform an administrator quoting the following error: " + ((ex instanceof nlobjError) ? ex.getCode() + '\n' + ex.getDetails() : ex.toString()));
}
}
nlapiSetCurrentLineItemValues() has a fourth paramater called firefieldchanged which can be set to false to prevent exactly this issue
Using the Fire Field Changed Parameter
When creating scripts that provide the ability to watch a field for a
change, and then write back to the field that changed, a risk of
creating an infinite loop exists as follows:
The Client script watches for fieldA to change.
fieldA changes.
The script writes to fieldA, causing the Field Changed event to fire,
returning the code to step 2, and this loop repeats indefinitely.
To prevent this looping behavior, you can set the optional
firefieldchanged parameter in your client scripts.
The firefieldchanged parameter is available for all write functions.
If set to true, the parameter causes any field changed events to fire
as normal. This is the default setting. If set to false, field changed
events are NOT fired.
https://system.netsuite.com/app/help/helpcenter.nl?fid=section_N3042487.html#bridgehead_N3050839

How to create Purchase Order in Netsuite with ScriptSuite?

I am new to Netsuite and I was asked to perform a script that was launched from an application programmed in java. The script with a function to generate a Purchase Order in Netsuite and other function to list the Purchase Order created earlier. It turns out that for this I am using the api SuiteScript but when creating the Purchase Order run the java application and launches the script but it gives the following error:
Aug 03, 2015 2:49:00 PM com.gargoylesoftware.htmlunit.WebClient printContentIfNecessary
INFO: {"error": {"code": "user_error", "message": "Please enter value (s) for: Vendor"}}
Javascript function to create is:
function CreatePurchase_Orders(datain){
var output = '';
nlapiLogExecution('DEBUG','createRecord','ingreso la consulta' ) ;
nlapiLogExecution('DEBUG','createRecord', 'Ingresa: '+ datain);
//var msg = validateTimeBills(datain);
var msg = null;
if (msg){
var err = new Object();
err.status = "failed";
err.message= msg;
return err;
}
var Purchase_Orders = datain.Purchase_Order;
nlapiLogExecution('DEBUG','createRecord', 'obtuvo el objeto: '+ Purchase_Orders);
for (var Purchase_Orderobject in Purchase_Orders){
var Purchase_Order = Purchase_Orders[Purchase_Orderobject];
var transdate = Purchase_Order.Transdate;
var Form = Purchase_Order.Form;
var Vendor = Purchase_Order.Vendor;
var Currency = Purchase_Order.Currency;
var Item = Purchase_Order.Item;
nlapiLogExecution('DEBUG','campos','transdate: '+ transdate+'/Form: '+Form + ' /Vendor: ' + Vendor + ' /Currency: ' + Currency
+ ' /Item: ' + Item);
var Purchase_Order = nlapiCreateRecord('purchaseorder');
var nlobjAssistant = nlapiCreateAssistant ( 'asistente' , false ) ;
var Purchase_Orderid = 1;//nlapiSubmitRecord( Purchase_Order , true, true);
if(Purchase_Order){
nlapiLogExecution('DEBUG', 'Purchase_Order ' + Purchase_Orderid + ' successfully created', '');
nlapiLogExecution('DEBUG', 'createRecord', 'creo el record');
}
Purchase_Order.setFieldValue('transdate', transdate);
Purchase_Order.setFieldValue('inpt_customform1', Form);
Purchase_Order.setFieldValue('vendor', Vendor);
Purchase_Order.setFieldValue('inpt_currency7', Currency);
Purchase_Order.setFieldValue('inpt_item', Item);
Purchase_Order.setFieldText('quantity_formattedValue', '1');
Purchase_Order.setFieldText('rate_formattedValue', '1');
Purchase_Order.setFieldText('amount_formattedValue', '1');
Purchase_Order.setFieldText('inpt_taxcode', 'VAT_MX:UNDEF_MX');
Purchase_Order.setFieldText('grossamt_formattedValue', '1');
Purchase_Order.setFieldText('tax1amt_formattedValue', '0');
Purchase_Order.setFieldText('expectedreceiptdate', '24/6/2015');
//var Purchase_Orderid = 1;//nlapiSubmitRecord( Purchase_Order , true, true);
var submitRecord = nlapiSubmitRecord(Purchase_Order);//,true);
nlapiLogExecution('DEBUG', 'submirRecord ' + submitRecord);
}
var mesg = new Object();
mesg.status = "OK";
mesg.message= nlobjAssistant.getAllFields();
return mesg;
}
And the function code in Java is:
WebClient client = new WebClient(BrowserVersion.FIREFOX_31);
client.getOptions().setJavaScriptEnabled(false);
client.getOptions().setThrowExceptionOnScriptError(false);
WebRequest requestSettings = new WebRequest(new URL(url),HttpMethod.POST);
requestSettings.setAdditionalHeader("Host", "rest.na1.netsuite.com");
requestSettings.setAdditionalHeader("User-Agent", "SuiteScript-Call");
requestSettings.setAdditionalHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
requestSettings.setAdditionalHeader("Accept-Language", " es-cl,es;q=0.8,en-us;q=0.5,en;q=0.3");
requestSettings.setAdditionalHeader("Accept-Encoding", "gzip, deflate");
requestSettings.setAdditionalHeader("Content-Type", "application/json");
requestSettings.setAdditionalHeader("Pragma", "no-cache");
requestSettings.setAdditionalHeader("Cache-Control", "no-cache");
requestSettings.setAdditionalHeader("Referer", "http://localhost:8084");
requestSettings.setAdditionalHeader("Cookie", "");
requestSettings.setAdditionalHeader("Connection", "keep-alive");
requestSettings.setAdditionalHeader("Authorization", "NLAuth nlauth_account=" + account + ", nlauth_email=" + mail + ", nlauth_signature=" + pass + ", nlauth_role=" + role + "");
Gson gson = new Gson();
//objeto llenado estaticamente de forma momentanea, se debe leer desde archivo externo
Purchase_Order purchaseOrder = new Purchase_Order("25/06/2015","formTest","vendorTest","CurrencyTest","itemTest");
String cuerpo = gson.toJson(purchaseOrder);
System.out.println(cuerpo);
// Set the request parameters
requestSettings.setRequestBody(cuerpo);
Page page = client.getPage(requestSettings);
WebResponse response = page.getWebResponse();
String json = response.getContentAsString();
System.out.println(json);
With this javascript function you should create me a record Purchase Order but I can not find the error and the solution if someone could please help me I would appreciate it a lot.
PS: if you have to create a customized form could tell me how?
thanks!
Here are some points :
As your error message says Please enter value (s) for: Vendor, you're missing the value for vendor field, which is mandatory. In your piece of code you're passing wrong internalid value for vendor. You should use entity instead of vendor
Purchase_Order.setFieldValue('entity', Vendor); // where vendor is the internal id of the vendor record
For setting custom form you can use
Purchase_Order.setFieldValue('customform', Form); // where Form is the id of the custom form
I also noticed that you're setting some values in purchase order which I suspect are to be a kind of custom one. If that is the case, then your custom field internal id should be prefixed with custbody.
For all the standard fields internal id you can refer to the Suite script Records Browser.

How do I pass multiple datasets to my view in sailsjs?

I want to be able to pass multiple data sets to my view. Here is how I am currently doing it in my controller:
transactions: function (req, res) {
var queryexpenses = 'select * from expense order by name';
Expense.query(queryexpenses, function (err, expense) {
this.expenses = expense;
});
if (req.param('filter')) {
var where = 'where fk_expense = ' + req.param('expensefilter');
where += ' and datePosted > "' + req.param('yearfilter') + '-01-01" ';
where += ' and datePosted < "' + req.param('yearfilter') + '-12-31" ';
} else {
var where = 'where fk_expense IS NULL';
}
var query = 'select * from accounting ' + where + ' order by description';
Accounting.query(query, function (err, trans) {
this.transactions = trans;
});
var total = 0;
_.each(this.transactions, function (element, index, list) {
// format dates
element.datePosted = dateFormat(element.datePosted, 'dd/mm/yyyy');
var tmp0 = element.amount
var tmp1 = tmp0.replace(/ /g, '');
var tmp2 = parseFloat(tmp1);
total += tmp2;
});
this.total = total.toFixed(2);
return res.view();
}
This is the only way I am able to accomplish what Im trying to do but there are problems which I believe are caused by me putting the query objects in the "this" scope. The first problem is the page will crash after server restart on first reload. The second problem is everything seems to happen one step behind. What I mean is if I issue commands on the UI (eg submit a form) nothing will happen unless I take the same action twice.
So how do I pass multiple sets of data to my views without scoping them in "this"?
res.view({
corndogs: [{name: 'Hank the Corndog'}, {name: 'Lenny the Corndog'}]
});
Here is the relevant docs page: http://sailsjs.org/#!documentation/views
Also, it looks like you're not taking full advantage of Waterline for making SQL queries.

Resources