Implementing Service Layer’s Script Engine: It’s been a while since the Service Layer has been enhanced with a new feature called Script Engine, released together with the SAP Business One, version for SAP HANA 9.2 PL04. I’m sure you have already read the relevant blog posts talking about it from Trinidad here and Andy Bai here, as well as the SAP Note 2343691 – Service Layer supports script engine.

As you’ve learned in those posts, there are many benefits of using script engine such as better performance, as it reduces the calls from your application to the Service Layer; re-use of server-side customizations; and the implementation of global transaction for several operations.

Now that you are already familiar with the feature, let me guide you through two very simple examples on how to implement it:

Example A – Creating a Sales Order

So, here is the scenario: before creating a Sales Order, you want to validate whether the customer already exists in the system. If it doesn’t exist, then create it before the sales order, if it already does, just create the sales order. In a world without Script Engine (before 9.2 PL04), your application would have to do at least two requests to the Service Layer (GET BusinessPartners(id), and POST Orders). Since 9.2 PL04, you can do a single request to your own custom script (at the script engine level) in the Service Layer and it will threat other calls internally.

In this example I’m interested in demonstrate the use of global transactions and how to call a Service Layer entity from a custom script, using the script engine feature.

Here is all you’ll need: one javascript and one xml, packed together in a zip file.

The steps required to accomplish this development is described below:

  1. Create a javaScript file which will threat a POST request and perform two calls: one GET request to validate the business partner and a POST request to add the sales order to the given business partner;
  2. Create an xml file with the ARD extension, where you’ll basically reference your javaScript file as part of the Service Layer, as well as some other data such as partner name and namespace so that Business One can install it in the right place during the deployment of your script;
  3. Create a zip file containing both ARD and JS files above;
  4. Run the deployment of this script by importing the zip file using the Extension Manager; and
  5. Test the new script calling it from a REST client.

Let’s now run it step-by-step.

1. Create a javaScript file, name it as you wish using the js extension, in this case it will be SalesOrders.js. Just open your favorite IDE and write the code below, note that it is fully commented:

// required to handle http calls var http = require('HttpModule.js'); // required to call SL entities/actions var ServiceLayerContext = require('ServiceLayerContext.js'); function POST() { var ret = {}; // Instantiates SL context var slContext = new ServiceLayerContext(); // Gets the body of the request var salesOrderData = http.request.getJsonObj(); // Starting point for the Global Transaction slContext.startTransaction(); //Gets Business Partner data var res = slContext.BusinessPartners.get(salesOrderData.CardCode); //If it doesn't exist then create it if (res.status != 200){ var res = slContext.BusinessPartners.add( { "CardCode": salesOrderData.CardCode, "CardName": "BP created using SL Script Engine", "CardType": "C" } ); // If there's any problem creating Business Partner, // roll back and throw the exception if (!res.isOK()) { slContext.rollbackTransaction(); throw http.ScriptException(http.HttpStatus.HTTP_BAD_REQUEST, res.getErrMsg()); } } // This is to store and send back business partner details ret.BusinessPartnerDetail = res; //Create Sales Order var res = slContext.Orders.add(salesOrderData); // If there's any problem creating the Sales Order, // roll back and throw the exception if (!res.isOK()) { slContext.rollbackTransaction(); throw http.ScriptException(http.HttpStatus.HTTP_BAD_REQUEST, res.getErrMsg()); } // This is to store and send back sales order details ret.SalesOrderDetail = res; //Everything went smooth then commit! slContext.commitTransaction(); /* SET HTTP RESPONSE */ http.response.setContentType(http.ContentType.APPLICATION_JSON); http.response.setStatus(http.HttpStatus.HTTP_OK); http.response.setContent(ret); http.response.send(); }

2. Now create an XML file, give it the same name as the previous javascript just changing the extension to ard, in this case SalesOrders.ard. Fill in the Partner Namespace, Partner Name, Script name and File Name, as you can see below:

Note that this will define the URL you will call in your application, it is https://:50000/b1s/v1/script//