Suite Coder is now Open Source

Source code of SuiteCoder has finally been published on Github. Suite Coder is a web app that runs on Google App Engine. To run your own version of SuiteCoder you don’t require any programming skills. You can easily deploy the source code on Google app engine and run it there free of cost. All the required steps to do so are listed here

Suitecoder UI is built using JQuery and Angular 1.2. Code Mirror JS component is used as code editor. With basic knowledge of HTML/JS, one can make useful UI/UX tweaks. Keywords list for the code completion (IntelliSense) can be modified from the file static/js/deferred.js .

For adding features like compatibility of SuiteScript 2.0, knowledge of Python in required.

10 year ago when I started working on NetSuite, I found very few resources about Suite Scripting which are powered by community. That motivated me to build tools like SuiteCoder and PHP Toolkit Docs. The response I get for these tools make me believe that there is much more need for community built tools for NetSuite developers. Let’s make this project a hub for Netsuite developers community where we can share our ideas and help each other to make these ideas a reality.

Tagged with: , ,
Posted in Netsuite

SuiteCoder: Of the community, By the community, For the community

The First version of SuiteCoder was launched about 6 years ago. It’s been a eventful journey in which I added several oft-requested features such as Rich Code Editor with Auto Complete and file versioning. The app has a diverse user-base ranging from freelance developers to ones associated with Fortune 500 companies.

Netsuite scripting has been evolving very rapidly. Unfortunately, I have not been able to update the app at the same pace lately. At this point, I believe the best way to move forward is to make SuiteCoder community driven. I will take the app open source shortly. This will help all of us to add new features (and improvements) to the app. Furthermore, once a community has formed, we can discuss and implement new tools to help Netsuite developers.

Since the SuiteCoder is based on Google App Engine, anybody will be able to run the app with full control on GAE platform, free of cost.

Happy SuiteCoding.

Tagged with: ,
Posted in Netsuite

Suitecoder just got more awesome

New version of Suite Coder has been released. Yay!!

Some salient features of this release are

  • New UI with better support for small screens.
  • Manage personal files. These files are not connected to any Netsuite account so you can access them anytime without Netsuite credentials
  • Unicode support. Now you can save files having unicode characters like © or ¥
  • Several minor bug fixes
Tagged with: , , , ,
Posted in Google App Engine, Programming & Development, Python

Setup Selenium Web driver on WAMP environment

Recently I configured Selenium web driver on multiple systems having WAMP environment. There’s an excellent tutorial for it here. However I had to do some additional configurations mentioned below.

Step 2.1 mentioned there is a bit tricky, you may have to try these

pear clear-cache

pear install -a -f phpunit/PHPUnit


pear install –force phpunit/PHPUnit_Selenium


Also make sure that cURL is working. You may have to replace your curl extension file

Also WAMP contains multiple php.ini files

  1. /wamp/bin/php/php5.x.x
  2. /wamp/bin/apache/apache2.x.x/bin

Make sure to enable cURL in both the files so that PHP CLI picks the cURL extension

Integrate Web Driver

Selenium Webdriver doesn’t support PHP. However there are several third party implementations. I prefer Download the repo and copy the lib folder in your tests folder. Here’s a sample file that you can use to verify your installation



class First extends PHPUnit_Framework_TestCase {

protected function setUp() {
$host = 'http://localhost:4444/wd/hub'; // this is the default
$capabilities = array(WebDriverCapabilityType::BROWSER_NAME => 'firefox');
$this->driver = RemoteWebDriver::create($host, $capabilities, 1000);

public function testLogin(){



Run command “phpunit first.php First”. This would open a firefox window and navigate to http://localhost/mysite/.

Extend the script using both the Selenium webdriver API and PHP Unit assertions.

Tagged with: , , , , , ,
Posted in PHP, Programming & Development

AWS PHP SDK logging using Guzzle

Recently I’ve been working on AWS PHP SDK. I found out that there is a simple code snippet to enable wire logging in the API

use Guzzle\Plugin\Log\LogPlugin;

// Create an Amazon S3 client
$s3Client = S3Client::factory();

// Add a debug log plugin

However according to FAQs on the AWS docs site, we have to create our own plugin for logging in a file. I had a look at the code and found that you just have to provide the 2nd parameter to getDebugPlugin function and it wil start logging in the file

// Create an Amazon S3 client
$s3Client = S3Client::factory();

$logPlugin = LogPlugin::getDebugPlugin(TRUE,
  //Don't provide this parameter to show the log in PHP output
  fopen(APPPATH . 'logs/wire.log', 'a')

Later if you want to stop the logging you have to use the following snippet.

//Remove this log plugin to the client
Tagged with: , , , ,
Posted in Amazon, Programming & Development

Using GetSelectValue in Netsuite PHP Toolkit

Nowadays I am working on porting one of my Suite Talk projects to the newer version of Netsuite PHP Toolkit.

In my previous version I use the getSelectValue operation using following code.

new nsComplexObject(
        array('recordType' => $record,'field' => $field)

I converted the code accordingly but the new toolkit was returning this error

No such operation ‘getSelectValue’

After some debugging I found that pageIndex is now a Required Attribute, so I had to add the following line

$request->pageIndex = 0;

Here’s the complete working code

$obj = new GetSelectValueFieldDescription();
$obj->recordType = $recordType;
$obj->field = $field;

$request = new getSelectValueRequest();
$request->fieldDescription = $obj;
$request->pageIndex = 0;

$getResponse = $service->getSelectValue($request);
Posted in Netsuite, Programming & Development

Integrating Netsuite PHP Toolkit in Yii

  • Download PHP Toolkit from here.
  • Copy the PHP Toolkit from the zip archive into protected/vendors folder
  • Make the Config variables global in NSconfig.php . i.e. add following code in beginning of the file
    global $nsendpoint;
    global $nshost;
    global $nsemail;
    global $nspassword;
    global $nsrole;
    global $nsaccount;
  • Create a new file in protected/models and name it as NSEntity.php. Below are its contents
    class NSEntity {
    	private $service;
    	public function __construct() {
    		Yii::$enableIncludePath = false;
    		Yii::import('application.vendors.PHPToolkit.NetSuiteService', true);
    		$this->service = new NetSuiteService();
    		if (!Yii::app()->session['nshost']) {
    			global $nshost,$nsaccount;
    			$params = new GetDataCenterUrlsRequest();
    			$params->account = $nsaccount;
    			$response = $this->service->getDataCenterUrls($params);
    			Yii::app()->session['nshost'] = $response->getDataCenterUrlsResult->dataCenterUrls->webservicesDomain;
    			$nshost = Yii::app()->session['nshost'];
    	function search($searchRequest, $searchId, $pageNum) {
    		$this->service->setSearchPreferences(false, 10);
    		if ($searchId && $pageNum) {
    			$req = new SearchMoreWithIdRequest();
    			$req->searchId = $searchId;
    			$req->pageIndex = $pageNum;
    			$searchResponse = $this->service->searchMoreWithId($req);
    		} else {
    			$searchResponse = $this->service->search($searchRequest);
    		$response = array();
    		if (!$searchResponse->searchResult->status->isSuccess) {
    			$response['status'] = FALSE;
    			$response['error'] = '';
    		} else {
    			$response['status'] = TRUE;
    			$response['recordCount'] = $searchResponse->searchResult->totalRecords;
    			$response['pageCount'] = $searchResponse->searchResult->totalPages;
    			$response['searchId'] = $searchResponse->searchResult->searchId;
    			$response['records'] = array();
    			foreach ($searchResponse->searchResult->recordList->record as $record) {
    				$response['records'][] = $this->map($record);
    		return $response;
    	function load($id, $type) {
    		if ($id) {
    			$request = new GetRequest();
    			$request->baseRef = new RecordRef();
    			$request->baseRef->type = $type;
    			$request->baseRef->internalId = $id;
    			$getResponse = $this->service->get($request);
    			if ($getResponse && $getResponse->readResponse->status->isSuccess) {
    				return array('status' => TRUE, 'record' => $this->map($getResponse->readResponse->record));
    			} else {
    				return array('status' => FALSE, 'msg' => $getResponse->readResponse->status->statusDetail[0]->message);
    	function map($record) {
    		return $record;
    	function getCustomField($record, $fieldName) {
    		foreach ($record->customFieldList->customField as $field)
    			if ($field->internalId == $fieldName)
    				return $field->value;
    		return '';
    	function update($record) {
    		$request = new UpdateRequest();
    		$request->record = $record;
    		$updateResponse = $this->service->update($request);
    		if ($updateResponse->writeResponse->status->isSuccess) {
    			return array('status' => TRUE);
    		} else {
    			return array('status' => FALSE, 'msg' => $updateResponse->writeResponse->status->statusDetail[0]->message);
  • Most of the magic lies in the constructor where Netsuite Service is intialized and and we get the dynamic Date Center URL, once for a session.
  • NSEntity.php serves as the base class for any entity that you want to use in the app. For e.g. here is a class for Items.
    class Item extends NSEntity {
    	public $record;
    	public function __construct() {
    	function map($record) {
    		$thumb = $this->getCustomField($record, 'custitem_internalimagethumb');
    		if ($thumb && $thumb->internalId)
    			$thumb = $thumb->internalId;
    		return array(
    			'type' => lcfirst(get_class($record))
    			, 'internal_id' => $record->internalId
    			, 'item_id' => $record->itemId
    			, 'image_thumb' => $thumb
    	function createSearchRequest($searchTerm) {
    		$itemIdSearchField = new SearchStringField();
    		$itemIdSearchField->operator = "contains";
    		$itemIdSearchField->searchValue = $searchTerm;
    		$search = new ItemSearchBasic();
    		$search->itemId = $itemIdSearchField;
    		$request = new SearchRequest();
    		$request->searchRecord = $search;
    		return $request;
Tagged with: ,
Posted in Computer And Internet, Netsuite, Programming & Development, Uncategorized

2012 in review

The stats helper monkeys prepared a 2012 annual report for this blog.

Here’s an excerpt:

600 people reached the top of Mt. Everest in 2012. This blog got about 7,800 views in 2012. If every person who reached the top of Mt. Everest viewed this blog, it would have taken 13 years to get that many views.

Click here to see the complete report.

Posted in Uncategorized

Netsuite PHP Toolkit Documentation

Recently Netsuite has uploaded the Netsuite PHP Toolkit version 2012_2. This version is very mature compared to its predecessors.

Now the code is distributed in different classes that makes it possible for IDEs and Documentation generators to parse it. So I decided to generate the documentation and upload it so that anyone can view it. So here the link

Hope it helps

Tagged with: , , ,
Posted in Netsuite, Programming & Development

New Data Centers for Netsuite Accounts

As of September, 2012 Netsuite has started hosting different accounts to different data centers. That means if you are developing SuitTalk Apps for multiple accounts then you have to make sure that you are using correct URL for these.

These two articles can help you make necessary changes in your code

Although Netsuite PHP Toolkit 2012_2 has built-in methods to get the URLs but if you are not using that then below is the Sample PHP class that can be used to access Netsuite Rest Roles Service

class AccountsGrabber {

private $curl;

public function __construct($email, $password) {
 $this->curl = curl_init();
 curl_setopt($this->curl, CURLOPT_HTTPHEADER, array(
 'Authorization: NLAuth nlauth_email=' . $email . ', nlauth_signature=' . $password

public function __destruct() {

public function getAccounts() {
 $url = '';
 curl_setopt($this->curl, CURLOPT_URL, $url);
 curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, TRUE);
 $result = curl_exec($this->curl);

return json_decode($result);
Tagged with:
Posted in Netsuite, Programming & Development
About me
A geek trying to make world a better place to live.

I work on LAMP Stack, SRE and resilience engineering. I also worked on Python, GAE and Netsuite Customization. Currently working @ Cloudways as Software Architect

Profile Links Linkedin | Github | Stackoverflow
Subscribe to this blog