Wednesday, 24 May 2017

Steps to Hide the Print Button for a User having a Custom Customer Center Role when a Sales Order is Viewed on the Web Store Context

​For a custom Customer Center role having Fulfill Sales Order=None, when a user clicks See Orders in theCustomer Center > view any order > a Print button is displayed. To hide this Print button, here are the steps:

1. Create a user event script by navigating to Customization > Scripting > Scripts > New > User EventUser Event needs to be setup this way: 

Deployments 
Applies to: Sales Order 
Deployed: Yes 
Status: Released 

Scripts
Before Record Load: restrictPrintButtonOnWebStore <-- this is the name of the function 

Script :

function restrictPrintButtonOnWebStore(type, form){ 
        var currentContext = nlapiGetContext(); 
        if (currentContext.getExecutionContext() == 'webstore') { 
                nlapiLogExecution('Debug', 'context', currentContext.getExecutionContext()); 
                userRole = nlapiGetRole(); 
                nlapiLogExecution('Debug', 'nlapiGetRole()', userRole); 
                if(userRole == 1017){ 
                      var button = form.getButton('print'); 
                      button.setVisible(false); 
                } 
                 
        } 
}

Sunday, 7 May 2017

Netsuite Suitescript 2.0

Its been a while since suitescript 2.0 made an appearance into Netsuite with Version 2015 Release 2. Netsuite introduced a SuiteScript 2.0- a complete re-factor of the SuiteScript model driving towards a more modular based development approach. Recently, I was trying to have some hands on it and thought of sharing few keynotes based on my exploration.
Advantages to SuiteScript 2.0
  1. Modular Architecture
  2. Modern JavaScript Syntax and Behavior
  3. New and Improved API Functionality
  4. Asynchronous Client Side Processing (Promises)
  5. New Batch Processing Framework (Map/Reduce Script Type)
Lets see some examples:
Load a record


require(['N/record'], function(RECORDMODULE){

    var recordType = RECORDMODULE.Type.ACCOUNT; //The type of record to load.
    var recordID = 10011; //The internal ID of the existing record in NetSuite.
    var isDynamic = true; //Determines whether to load the record in dynamic mode.

    var loadedRecord = RECORDMODULE.load({
        type: recordType, 
        id: recordID,
        isDynamic: isDynamic,
    });
});


Create Search

We can use search.create to build out our search object or search.load to load a saved search. Then we can  invoke run on the resulting search object. Finally, we will process the results in two ways:
  1. Use the each method and a callback
  2. Use the getRange method to get a specific number of results

In the example below, I've imported N/search into my module as s and shown the usage of the each method.
  • Summary Search (Suitescript 2.0)
// Assuming N/search is imported as `s`
var demoSalesOrderSearch = s.create({
    type: 'salesorder'
    // Use the summary property of a Column to perform grouping/summarizing
    columns: [{
        name: 'salesrep',
        summary: s.Summary.GROUP
    },{
        name: 'internalid',
        summary: s.Summary.COUNT
    }],
    filters: [{
        name: 'mainline',
        operator: 'is',
        values: ['T']
    }]
});

demoSalesOrderSearch.run().each(function (result) {
    var repId = result.getValue({
        "name": "salesrep",
        "summary": s.Summary.GROUP
    });
    var repName = result.getText({
        "name": "salesrep",
        "summary": s.Summary.GROUP
    });
    var orderCount = parseInt(result.getValue({
            "name": "internalid",
            "summary": s.Summary.COUNT
    }), 10);

    log.debug({
        "title": "Order Count by Sales Rep",
        "details": repName + " has sold " + orderCount + " orders."
    });
});
  • Search with criteria search
require(['N/search'], function(SEARCHMODULE){
    
    var type = 'transaction';
    var columns = [];
    columns.push(SEARCHMODULE.createColumn({
        name: 'internalid'
    }));
    columns.push(SEARCHMODULE.createColumn({
        name: 'formulanumeric',
        formula: '{quantity}-{quantityshiprecv}'
    }));
    
    var salesOrdersArray = [1001,2001,3001,4001];
    var filters = [];
    filters.push(['type', 'anyof', 'SalesOrd']);
    filters.push('and');
    filters.push(['mainline', 'is', 'F']);
    filters.push('and');
    filters.push(['internalid', 'anyof', salesOrdersArray]);
        
    var mySearchObj = {};
    mySearchObj.type = type;
    mySearchObj.columns = columns;
    mySearchObj.filters = filters;
    
    var mySearch = SEARCHMODULE.create(mySearchObj);
    var resultset = mySearch.run();
    var results = resultset.getRange(0, 1000);
    for(var i in results){
        var result = results[i];
        var row = {};
        for(var k in result.columns){
            log.debug('Result is ' + result.getValue(result.columns[k])); //result 
        }
    }
});
  • From Saved search
require(['N/search'], function(SEARCHMODULE){
    var savedSearchId = 'customsearch_customsearch';
    var mySearch = SEARCHMODULE.load(savedSearchId);
    var resultset = mySearch.run();
    var results = resultset.getRange(0, 1000);
    for(var i in results){
        var result = results[i];
        for(var k in result.columns){
            log.debug('Result is ' + result.getValue(result.columns[k])); //result
        }
    }
});

If you want to explore more related to Suitescript 2.0 check out the below resources:



Tuesday, 25 April 2017

Common Netsuite Interview Questions II



1. Which Suitescript API has maximum governor limits?
·                      nlapiSetRecoveryPoint
·                      nlapiSubmitCSVImport
·                     nlobjJobManager.submit

2. What is the governor limits allowed for Restlets?
     5,000

3. Which Script has maximum governor limits
     Scheduled Script => 10,000

4. How can you overcome governance issue in case of long running process or scheduled jobs on a large set of data ?
      nlapiYieldScript()

5. What is the difference between record level script and form level script ?
A client script can be deployed in one of two ways: at the record level, or at the form level.
6. When you deploy a client script at the record level, you deploy it globally on one or more record types. The script runs on all forms associated with the record type. By contrast, with a form-level deployment, you attach the script to a custom form associated with a record type, and the script runs only when that form is used.
For example, you could use record-level deployment to configure a client script to run on the employee record type. With this approach, the script run whenever the employee record is used, regardless of which form is being used. With record-level deployment, it is also possible to limit the script by configuring it to be available only to certain audiences. With this approach, the script runs only when the form is used by people in certain roles, groups, or other classifications, as configured on the Audience subtab of the script deployment record. However, with record deployment, you cannot limit the script to only one form. The script behaves the same way on all forms associated with the record type.
By contrast, you could attach the client script to only one custom entry form for the employee record type. If a user then opened an employee record using the standard entry form, the script would not run. You can attach a client script to any custom entry form, custom transaction form, or custom address form. However, you cannot limit the audience for a form-level script.
Note that only client scripts can be deployed at the form level. All other entry point scripts can be deployed at the record level only.
7. What are the event types in a client script ?
    pageInit
    saveRecord
    validateField
    fieldChanged
    postSourcing
    lineInit
    validateLine
    recalc
    validateInsert
    validateDelete
8. What's the Difference Between xedit and edit User Event Types?
When the user event type argument is set to xedit, it means that the execution context for the script is inline edit or mass update. In other words, if a user has inline edited a field on a record (or if the record has been part of a mass update), the user event script will execute. In contrast, user event scripts set to execute when the type argument is set to edit will execute when the record is edited in all other contexts. The script will not execute based on an inline edit or mass update.

9. How Many User Events Can I Have on One Record?

There is no limit to the number of user event scripts you can execute on a particular record type. For example, you could have 10 beforeLoad, 9 beforeSubmit, and 15 afterSubmit executing functions on a Customer record. However, assigning this many executable functions to one record type is highly discouraged, as this could negatively affect user experience with that record type. In other words, if you have 10 beforeLoad scripts that must complete their execution before a record loads into the browser for the user, this may significantly increase the time it takes for the record to load. As a consequence, the user's experience working with the record will be negatively affected.

10. What are the event types in a User event script ?
      Before Load
      Before Submit
      After Submit



Thursday, 6 April 2017

Serialized Inventory Items on Order

Problem Statement:
I’m trying to generate a saved search of serialized inventory items on order. I created an item search using these filters:

Is Serialized item - true
On Order - is greater than 0 (Zero)

If I have the results returned with just basic information - i.e., name, on order number, and average cost, the report returns the correct number of items on order. However, if I add the serial number to the results columns, it shows all the serial numbers records we've ever had for that item type as on order.

Example: we have one of a particular type of machine on order, but we've had five of that same type of machine in the past. If I don't include serial number in the results columns, the report shows (correctly) that we have one of those machines on order. If I include the serial number in the results field (which obviously I want to do), it lists all six of those machines as on order and their individual serial numbers.

Solution :
If you are using an item saved search and receive purchase orders in full, please add the following fields:

Under Criteria > Standard:
a. Transaction Fields... > Status > Purchase Order:Pending Receipt
b. Transaction Fields... > Type > Purchase Order
c. Transaction Fields... > Transaction Serial/Lot Number > is not empty

Under Result > Columns:
a. Transaction Fields... > Transaction Serial/Lot Number


Thursday, 16 March 2017

Cash Sale with Status: Deposited but Need to Change Account

​​
This is a very common scenario where transaction posted wrongly to Undeposited Funds account and the Cash Sale shows Status: Deposited
Since the transaction was posted to Undeposited Funds account and user is unable to change the account.
here is a way this issue can be fixed.

Steps to resolve:
1.    Transactions > Bank > Make Deposits > List Edit the deposit.
2.    Uncheck the cash sale.
3.    Click Save.

The cash sale now displays Not Deposited status and the account can be changed in Edit mode.​