NetSuite: Issue turning a quote into a sales order - netsuite

I have two business requirements that are currently conflicting with each other. I added the following logic to the client-side order creation code, to restrict who could order by invoice:
if (type == 'create' && nlapiGetContext().getRoleCenter() == 'CUSTOMER') {
if(nlapiGetFieldValue('entity')){// shouldn't be here if no entity
var hasTerms = nlapiLookupField('customer', nlapiGetFieldValue('entity'), 'terms');
var neededFormId = hasTerms ? 135 : 134;
if (req && !req.getParameter('cf') && neededFormId != nlapiGetFieldValue('customform')) {
nlapiSetRedirectURL('RECORD', nlapiGetRecordType(), nlapiGetRecordId(), (type == 'create'), { cf: neededFormId });
}
}
}
However, for some reason, this has now broken the following needed use case: When I now click "Create Order" from a Quote, it creates it but with none of the items from the quote in the order any more. When I comment out the above logic , the "Create Order" button works fine. How can I get both? Can I somehow check if the order is being created as a result of an existing quote or not?

Have you tried getting the value of the 'createdfrom' field on the Page Init event? If you are creating standalone SO, this field will be blank.

Use "createdfrom" check as suggested by #rusty to avoid Quote converted SO to fall into your logic's trap.
However, you still may want to use the specific form, in that case you can write the logic in user event script to change the form.
If the purpose of the form is to ask for different fields which does not appear in the other form, you can try with a "beforeload user event script" which gives access to nlobjform and you can try changing the fields on the form.

Consider doing the checking when making the initial Quote form available to the client. Terms customers get the Terms quote form. Credit customers get a quote form that will always lead them to a Cash Sale.
Then just use Netsuite's inherent on the quote forms.
Cheers

Related

Conditionally Mandatory Field in Netsuite

Is there a way to make a field conditionally mandatory? If in a dropdown a user selects "Other", the next field should be mandatory, optional otherwise.
Thanks!!
Yes you could do that. You can write a client field change function and do something like this.
var field0=context.currentRecord.getText({fieldId: ‘field0'});
if(field0 === ‘Other’) {
context.currentRecord.getField({fieldId: ‘field1'}).isMandatory=true;
} else {
context.currentRecord.getField({fieldId:’field1’}).isMandatory=false
}
You could also make it possible via workflow as well. But for small validations and stuff it would be better if script is used rather than a workflow.
For small validations I find it best house a workflow rather than a script (contrary to the other answer). Most companies have admins and few have developers. Workflows should allow anyone to manage it.
In either case make sure you handle setting it to mandatory AND unsetting it. If a user selects other "accidentally" and then changes their option to something other than "other", the field should most likely no longer be mandatory

Set the line item value from a custom column using script #suitescript #Netsuite

I am trying to take the value from "custcol_po_cost" and put it into "porate".
I want this to happen when a quote is transformed into a sales order. This way the PO Rate can be stored in the quote. I am unsure where I have gone wrong, I am very new to this. I am also unsure of which Function I should use to make this happen.
function validateSOLineItem(type){
if(type == 'item'){
var amount = nlapiGetCurrentLineItemValue('item', 'custcol_po_cost');
nlapiSetCurrentLineItemValue('item', 'porate', amount);
}
}
If these fields are on both the sales order and quote form, they should automatically be transferred to the sales order when it is converted. You need to add the function call to the event you want to trigger it. I would guess either on source or after submit perhaps? If you need to populate a field that is not on the original quote form you will need to do a user event. Sorry, I might be misunderstanding what you are trying to do but if you can provide a little more detail I will sure try to help.
First off just from a teaching moment - validate line is a function built to identify any validation rules (data entry mistakes) and not allow the user to proceed until fixed. Because of this it returns a boolean of true/false to determine if the user can continue. The reason you can't click ok is because at no point does that return true.
That being said you should not use a validate line function. If this will forever be in the UI, with no chance of ever being from CSV or anything else, then you can use Client scripts or User Event. You can do Client side pageInit () or saveRecord () . In either of these you will want to do a for loop and iterate through your list to grab the value for each item.

Suitescript - Hiding line fields during Sales Order/Invoice entry

I'm wondering if anyone knows a way to HIDE certain fields (such as costs) from certain Netsuite roles if they are not permitted to see costs.
I can prevent users changing sell prices without the proper authority with nlapiDisableLineItemField during PostSourcing and validateline etc...
But with cost fields, I'd like to HIDE them if the user does not have COST access. I realize I can do this by creating a separate form that does not include costs, but if I can hide information via the script, it means less duplication of effort down the track with other things I have in mind.
You can use a beforeLoad userevent script to hide body level fields (but, it is not possible to do the same for line item field, as there isn't any API on nlobjform to allow that. For sublist/lineitem fields You will have to write a client script validations or remove the field from the form like you have been already doing as you mentioned in your question).
In you beforeload user event script you get access to form and then use something like below to hide body level fields.
function beforeLoadEntryFunction(type, form)
{
if(nlapiGetRole() === 'NON_ACCESSIBLE_ROLE_ID'){
form.getField(YOUR_BODY_FIELD_ID).setDisplayType('hidden');
}
}
Edit:
For sublist/lineitem fields create a client script with code as
function clientScriptEntryFunction(type, form)
{
if(nlapiGetRole() === 'NON_ACCESSIBLE_ROLE_ID'){
form.getField(YOUR_BODY_FIELD_ID).setDisplayType('hidden');
nlapiDisableLineItemField(SUBLIST_ID, LINE_FIELD_ID);
}
}
And in before load user event use form.setScript(YOUR_CLIENT_SCRIPT_ID) as you already have access to the form object.
Remember, client script should be a global client script
If your purpose is purely aesthetic, you can do a Client side onLoad script and hide the fields via jQuery, you can do a select by name which wouldn't change even on version upgrades.
The jQuery library is included on NetSuite.

NetSuite, prevent Quote to Sales Order (via Sales Order button) if prospect assigned vs customer

We allow sales to attach Prospects to an Opportunity and Quote, and once credit has qualified the prospect they promote the prospect to a customer. What we need to do is hide the "Sales Order" button on the quote, or disallow advancing the quote to a sales order.
I was hesitant to ask this- seems like it should be intuitive to figure out. I looked at the standard NetSuite button id's in NetSuite help but there wasn't one for "Sales Order". I've looked at validation logic but this isn't validation as the sales order button is shown when record is not in edit mode. If possible I'd like the solution to be form independent.
I'd be happy to hide the button or letting the user click the button and preventing them from creating the sales order. It might be more user friendly doing the latter because if the button is hidden sales will be calling asking why the button is not there.
For clarity here is an image:
I am assuming that when you are talking about "the Sales Order button", you mean this one:
I'm not sure if this is the best user experience, or if you have NetSuite development resources available to you, but here is one option:
Create a new User Event script that is deployed to the Sales Order (and any other Transaction record you may want this prevention on). Using the BeforeLoad event, you can check if the Entity on the Transaction is in the Prospect stage. If they are, then the script will throw an error, preventing the creation of the Transaction. Code to accomplish this:
function onBeforeLoad(type) {
var entityId = nlapiGetFieldValue('entity');
if ((type != 'create') || !entityId) { return; }
if(nlapiLookupField('customer', nlapiGetFieldValue('entity'), 'stage') === 'PROSPECT') {
throw nlapiCreateError('INVALID_REQUEST', 'You cannot create a Sales Order from a Quote placed for a Prospect');
}
}
I tested this code in a TSTDRV account, and it works as expected. You might alternatively be able to build a workflow that does the same thing without requiring you to write code, but I did not attempt this.
By using a User Event script, this code will be form independent as well as entry point independent, meaning that this code will execute if the Sales Order is being created through the UI, through some other script, through a web services integration (depending on your web services configuration), or through a CSV import (depending on your CSV import configuration).
To hide the option:
If you're referring to the dropdown list, you can create a script for context view/edit to do the following:
setFieldAndLabelVisibility("nl13", false);
Otherwise, replace nl13 with the value of the table or td element shown when you inspect element on the desired Sales Order link/icon.
--The ID in the example above is the table, button or label ID shown when you inspect element

Disabling Override in Address Box

I am open to doing this via Forms, Workflows, or Suitescript. None have worked for me so far.
On a transaction, a user can change the bill to or ship to address for a customer. We are having issues due to the users using the Override feature and not the normal "Address Line 1, City, State, Zip" lines. Therefore, we want to disable the override functionality.
I cannot find this on any forms. I have tried workflows - I have disabled it on Before Record Load, Before User Edit, and Before field edit. I could not hide nor disable the Override button in any of these cases. I also tried hiding/disabling the Address free form text box they type in after they hit Override. I did this in all of the above stages as well as After Field Edit for when the Override button is pushed. Lastly, I attempted to just make the address fields mandatory. To do this, I tried setting Address Line 1, City, State, Zip all mandatory and again I tried before record load, before user edit, and before field edit. None actually worked. The workflow in any case would say it fired on Before Record load but when I went to add or edit an address, it still worked.
Part of my confusion comes on what exactly an address is. While the user is doing this on the transaction level (Quote, Sales Order, or Invoice), technically the update stores on the Customer Level. I tried applying the same above workflows on the Customer level with no success.
I am about to try scripting against this, but don't feel very optimistic based on all of the above testing with Workflows.
Has anyone else tried to do any manipulation against the Address on the transaction level? How did you do that? Again, I am open to forms, workflows, or Scripts. If you did it outside of these, please explain.
EDIT:
I still need help with this. This problem is persisting. Has anyone found a way to disable the "Override" feature on a transaction but still allow the drop down?
This seems to work to disable the drop-down select list for the Address on a transaction. I only tested it on a sales order but the theory should apply to other transactions as well.
var DcDisableAddress = {
beforeLoad : function(type, form) {
if (type == 'edit') {
var shipSelect = form.getField('shipaddresslist');
if (shipSelect) {
shipSelect.setDisplayType('disabled');
}
}
}
}
Use below as custom code in your address form.
/**
*#NApiVersion 2.0
*#NScriptName
*#NScriptType ClientScript
*/
define(['N/currentRecord'],function(currentRecord) {
function pageInit(context) {
var field = context.currentRecord.getField({
fieldId: 'override'
});
field.isDisabled = true;
}
return {
pageInit: pageInit
};
});

Resources