Skip to Content
Technical Articles

Embedding decisions with SAP Business Rules Services

If you are working remotely, and consuming a lot of these fast food apps to quickly get something to eat, you’re probably being flooded with a bunch of good offers such as free delivery, 2×1, 50% discounts, extra toppings or even free or extra meals.

With so many apps and restaurants in the market place that seems to be one of the many strategies to keep the customer attached and win visibility over the competition.

The offers are pretty dynamic: sometimes they only apply for specific restaurants, meal types, or for a very short time-frame, so best offers go for those customers watching the notifications.

The challenge for the restaurants might actually live on how to define and maintain the offer’s matrix and their rules, and be able to quickly react whenever it’s required, changing the rules without touching the core ERP, for instance.

I’m going to explore here how to leverage the SAP Business Rules Services on the Business Technology Platform to support partners and customers on that process.

In order to speed things up, I will take advantage of the latest prototype we have built (see it here), and extend the workflow we implemented for that pizza shop. So if you want to implement what I’m about to show here, I recommend you to go there and take a look on what we implemented before.

Otherwise, if you’re just curious, keep the reading. Enjoy!

The Use Case

The pizza shop manager, in this case, wants to implement a simple rule to give away some products. If the customer’s order matches the criteria, which is based on the delivery address, the pizza flavor and the channel used to place the order (social network chatbot, web page chat, or web form), then specific products will be added to the order for free.

The giveaways are free extra beverage, pizza or topping, depending on the matched criteria.

It might be the case that the restaurant wants to add something expensive to that list, so let’s also add a criteria that will help deciding whether or not the offer is subject to manager’s approval.

Setting up the rules

You can access the Business Rules Services through this tile on the Workflow cockpit:

https://<cf_org>.cockpit.workflowmanagement.cfapps.<cf_region>.hana.ondemand.com/cp.portal/site#Shell-home

Note 1: follow this tutorial to get the services up and running on your BTP trial account.
Note 2: import this file to your projects so you can see all the components mentioned here.

You will see the Pizza Offer project added to the list of projects. Here’s the place to define the rules:

https://<cf_org>.cockpit.workflowmanagement.cfapps.<cf_region>.hana.ondemand.com/comsapbpmrule.ruleeditor/index.html#//Projects

Once you have the project, you will be able to structure the Data Objects required by the Rule Services to run the business rules. That data structure will be further used as the input and the results of the decision process.

In our case, the input is:

  • the Order details, comprised by the Pizza Flavor, Address and Channel, as their are part of the criteria to decide what will be the give away.

and for the results:

  • the Offer details, such as offer type, offer ID and its description – this is the actual product we will offer; and
  • the OfferList, which will contain all the available products to offer.

As mentioned before, we also want to provide offer approval, so there’s one more data object we need to define which is:

  • the Offer Approval, comprised by the criteria to decide whether or not the offer needs to go thorough the user approval.

Below you will find them:

As we have defined all the data objects required to run our decision engine, it’s time to configure the rules that will consume them. If you select the tab “Rules“, you will be able to define the rules that will choose the correct offer based on the order’s input, and whether or not it needs approval:

Let’s first check the Decision Table for the DetermineOfferRules rule:

  • Customers from Málaga, ordering a Margherita using the web chat will get an extra pizza of the same flavor;
  • Those from Parla, ordering a Pepperoni using the website will get an extra cheese topping; and
  • People in Madrid, hungry for a Cheese Pizza ordering from the chatbot will get an extra beverage.

The other rule I have defined is to decide whether the approval is needed:

Notice this is a single if/then/else rule, no need of a decision table. So, if the free product is a pizza, please ask manager’s approval before releasing it to the kitchen. Notice that here I’m only implementing whether it requires approval or not, afterwards I will show how to consume it in the workflow.

Rules are packed into Rulesets so they can be consumed through the Rule Services, once they are deployed:

The first rule set above contains the rules that will serve to determine the offer:

The second will contain the approval rule:

We finally define the Rule Services. This is what we deploy to be consumed by the workflow (or any other application):

For each service we have to define what’s the input data and the results, in other words, the Vocabulary. You will choose the inputs and result from the object data defined few steps before, in this case we expect the input payload with the order data for the decision table, and the service will respond with the offer details:

For the approval’s service we need the offer details as the input (remember we want to decide whether the manager’s offer approval is required) and the result will be true/false, it is, the object data Offer Approval:

Now we just need to release the project version and deploy both services:

Note: if you don’t see the service ID and version code, click the gear icon and make them visible.

 

Testing the business rules services

Time to test both services with your favorite REST client tool. I’m using Insomnia.

You will also find the cURL followed by the pictures below so you just need to replace with your service token and change the service ID/version.

Follow this tutorial to learn how to create the service keys, authenticate and consume the Business Rules API.

Testing the Offer Determination service:

curl --request POST \
  --url https://bpmruleruntime.cfapps.eu10.hana.ondemand.com/rules-service/rest/v2/rule-services \
  --header 'Authorization: Bearer <your_service_token>' \
  --header 'Content-Type: application/json' \
  --data '{
  	"RuleServiceId": "5195fecc6a634212a497b98b4895a2d3",
      "RuleServiceVersion": "000000000001000000",
  "Vocabulary": [
    {
      "Order": {
        "Channel": "chatbot",
        "Address": "28007",
        "Pizza": "PZ00001"
      }
    }
  ]
}'

 

Testing the Offer Approval service:

curl --request POST \
  --url https://bpmruleruntime.cfapps.eu10.hana.ondemand.com/rules-service/rest/v2/rule-services \
  --header 'Authorization: Bearer <your_service_token>' \
  --header 'Content-Type: application/json' \
  --data '{
  	"RuleServiceId": "5398e9324eba40d5a0a4d6b44a83f9c9",
      "RuleServiceVersion": "000000000001000000",
  "Vocabulary": [
    {
      "Offer": {
        "OfferType": "Pizza"
      }
    }
  ]
}'

At this point we know the services are working as designed, so let’s now embed them into our workflow.

Adding the Business Rules to the workflow

As mentioned before, I enhanced the workflow we built for the pizza shop (check our previous blog post). I just added the tasks highlighted in red below, to determine the offer and to check whether the approval is required or not. You can download the full project from this branch (or just the workflow definition, if you wish) and import it to your workspace on the SAP Business Application Studio:

Prepare Rules Payload – this is a script task that prepares the payload required to call the offer determination service:

  var channel = $.context.channel;
  var prodID = $.context.orderData.ProductID;
  var postCode = $.context.orderData.Address;

  /************ Prepare Input Payload to Execute Rules ****************/
  var Vocabulary = [{
      "Order": {
        "Channel": channel,
        "Address": postCode,
        "Pizza": prodID
      }
    }];
  var rulesPayload = {
"RuleServiceId": "5195fecc6a634212a497b98b4895a2d3",
      "RuleServiceVersion": "000000000001000000",
  	"Vocabulary": Vocabulary
  };
  $.context.rulesPayload = rulesPayload;

Determine Offer – this is the service task that will actually call the business rule service to determine the offer based on the order data, it is, the payload prepared on the preceding task. You can download the destination here.

Enrich Context – this is a script task that gets the response from the previous Determine Offer call, formats the data to the context (so we can bind it to the approval form, for instance) and also prepares the payload to call the next service Approval Required:

var offerInfo = [];
var offer = {};

if ($.context.offer.OffersInfo.Result.length > 0){
    var assignedOffer = $.context.offer.OffersInfo.Result[0].Offer;

    if (assignedOffer.length > 0) {
        for (var i = 0; i < assignedOffer.length; i++) {
            offer = assignedOffer[i];
            offer.ProdDesc = offer.OfferDescription;
            offer.OfferType = offer.OfferType;
            offerInfo.push(offer);
        }
    } else {
        offer = assignedOffer;
        offer.ProdDesc = offer.OfferDescription;
        offer.OfferType = offer.OfferType;
        offerInfo.push(offer);
    }
} else {
    offer.ProdDesc = "None";
    offer.OfferType = "None";
    offerInfo.push(offer);
}

$.context.offer.OffersInfo = offerInfo;

/************ Prepare Input Payload to Execute Rules (APPROVAL) ****************/
var VocabularyApproval = [{
    "Offer": {
        "OfferType": offer.OfferType
    }
}];
var rulesPayloadApproval = {
"RuleServiceId": "5398e9324eba40d5a0a4d6b44a83f9c9",
    "RuleServiceVersion": "000000000001000000",
"Vocabulary": VocabularyApproval
};
$.context.rulesPayloadApproval = rulesPayloadApproval;

Approval Required? – this is the service task that will call the business rule service to check whether the offer needs manager approval:

Enrich Approval Context – this is the script task that gets the response from the previous Approval Required? call and formats the data to the context so we can consume it on the following sequence flow to determine whether or not we it needs to go through the approval form:

if ($.context.autoApproved.Result.length > 0){
    $.context.approvalNeeded = $.context.autoApproved.Result[0].OfferApproval.ApprovalNeeded;
}

 

Ok, all good – let’s now build, deploy and run it:

You will find the whole sample here, in this repository.

That’s all, hope you have enjoyed.

Stay tuned!

Be the first to leave a comment
You must be Logged on to comment or reply to a post.