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.​

How to Record a Cash Back from a Deposit in Netsuite


You can record cash received back from a deposit when you create the deposit slip in NetSuite. Enter the amount received on the Cash Back subtab on the Deposit page.

To record cash back from a deposit:

  1. Go to Transactions > Bank > Make Deposits (Administrator).
  2. Create a deposit. For more information, see Making Deposits.
  3. Click the Cash Back subtab.
    1. In the Amount field, enter the amount of cash you got back.
    2. Select the account the deposit comes from.
    3. Select a department, class or location.
    4. Enter an optional memo.
  4. Click Add.
    Repeat the steps above for any other cash items you received from deposits.
  5. Click Save.​

Friday 24 February 2017

Upload a file in to Filecabinet using Webservice

First we need to browse the file using asp:FileUpload control. 
Here is the code :-

 <div>
     <asp:FileUpload ID="fileupload" runat="server" />         
     <asp:Button ID="btnUpload" runat="server" Text="UPLoad"  onclick="btnUpload_Click" />
</div>

Then in the code behind of the button click event we need to write the following code to get the file information:-

//Getting the file path
string path = System.IO.Path.GetFullPathfileupload.PostedFile.FileName;
//getting the file name
string filename = System.IO.Path.GetFileName(fileupload.FileName);                  
//Getting the file content                    
byte[] fileContent = System.IO.File.ReadAllBytes(path);                    
lblSummary.Text = "Upload status: File uploaded!";
//calling the function to add the file to the file cabinet  
AddFile(filename, fileContent); 

In  AddFile(filename, fileContent) we need to search the specific folder in the file cabinet through suitetalk.
Code to search for the specific folder in the file cabinet :

//Contains details on the status of the operation and a reference to the updated 
//record.WriteResponse writeResp = null; 
// To implement a search for Folder through suitetalk , 
//we need to work with FolderSearch and FolderSearchBasic classes.
FolderSearch fldSearch = new FolderSearch();
FolderSearchBasic fldSrearchBasic = new FolderSearchBasic(); 
SearchStringField searchFolder = null;
              
//Name of the folder that we want to search                 
string searchValue = "Demo";                 
//Filtering by the folder name                 
searchFolder = new SearchStringField();
searchFolder.@operator =SearchStringFieldOperator.@is;
//Search operator
searchFolder.operatorSpecified = true;
searchFolder.searchValue = searchValue;
//searchValue is name of the folder "Demo"
fldSrearchBasic.name =searchFolder ;
fldSearch.basic = fldSrearchBasic;
// Search by isActive field which is a boolean
SearchBooleanField isActive = new SearchBooleanField();                 
isActive.searchValue = true;
isActive.searchValueSpecified = true;
// Invoke search() web services operation
SearchResult response = nsService.search(fldSearch); 

Once the search is successful we need to fetch the information from the search result to add the file to the specific folder in filecabinet.


//Now stroring the search result in an array
Record[] arrRecord = (Record[])response.recordList;
// Process response
if (response.status.isSuccess){
lblSummary.Text = "search is successful";
Folder fldr = (Folder)arrRecord[0];
//Getting a specific folder from the search
string fldrId = fldr.internalId;
//Fetching the required folder's internal ID
RecordRef refId = new RecordRef();    
refId.internalId = fldrId;
//Storing the folder id
//File object created to get all the file information 
File objFile = new File(); 
objFile.name = filename; //setting the file name 
objFile.folder = refId;  //setting the folder information  
objFile.content = fileContent; //settig the file content     
writeResp = nsService.add(objFile); //adding file to the file cabinet  
}else{           
          lblSummary.Text = "search not found"; 
          return;   
}









Thursday 2 February 2017

Hide/Remove the Create Deposit Button on Sales Orders

To hide the Create Deposit button from the sales order form perform the following steps:

--Navigate to Customization > Forms > Transaction Forms
--Click Edit beside Customer Sales Order form
--Click on Actions > Standard Actions subtab
--Uncheck Show field beside Create Deposit
--Save

The Create Deposit button should be removed from the sales orders.

Apply an existing Customer Deposit to an existing Sales Order

Problem:

User pulls up an existing Customer Deposit on edit mode and tries to apply the deposit to an existing sales order. On the Customer Deposit record > Sales Order dropdown, the order is not showing as a selection.

Solution:

1. Edit the sales order and change the form to "Standard Sales Order", "Standard Sales Order – Invoice" or any forms customized from any of these Sales Order forms.

2. For "Standard Sales Order" or any forms customized from this form, on the Billing tab of the sales order record, any of the below should be set:
Terms should be selected

- No Terms or Payment Method is selected
Create Deposit button is only available if the sales order is converted to an invoice. The form used should not be a cash sale type and payment method should not be set on the sales order.