Business Rules sample (console) (Delphi)

The Business Rules sample demonstrates how Business Rules Scripting can be used to validate changes made by client applications at the server level, before committing the changes to the back-end database. The benefit of putting change validation in the middle tier is that rules can be changed and updated on the fly without having to deploy new versions of the client applications and deal with the possibility that some users have not yet updated to the latest client version.

Getting Started

The sample is located in C:\Users\Public\Documents\RemObjects Samples\Data Abstract for Delphi\Commands (Console).

To build it, you will need Delphi Rad Studio, and like all the samples provided with Data Abstract for Delphi you will need to be running Relativity Server with the DASamples Domain and the Simple Schema available.

Included with the sample is a uLogSupport class which has a LogTable procedure that takes an instance of TDADataTable and creates a nicely formatted string representation of the table that it then prints to the Console which can be useful for debugging purposes. (An example of its output can be seen at the end of this document)

Running the Sample

When run the sample sets up a connection to an instance of Relativity Server and logs in (Step 1). It then retrieves a single row from the "ClientsWithScripting" table which will be used in the following steps and prints it to the console (Step 2).

The following steps modify the data in some way and then attempt to apply that change to the server. The change is tested by the server which will return an exception if it fails to match the conditions and the contents of the exception message will be printed to the console. (Step 3-5)

Examining the Code

All of the client code can be found in the uBusinessRules source file and the business rules are in the schema attached to the table as discussed below. The "ClientsWithScripting" schema table used in this sample is comprised of 4 fields.

In terms of this sample the main code of interest are the business rules themselves. The sample uses a DA SQL statement to retrieve the top record from the table when when it retrieves data from the server which will be used to attempt modifications to the server data.

The Business Rules

The Business Rules are located on the server in a schema and allow you to add business logic that can be used to validate data or enforce access restrictions. The rules are written as small blocks of EcmaScript, otherwise known as JavaScript, that are triggered on certain events for instance on processing an error, after applying a delta change, before getting data and so on. To learn more about business rules, how to add/edit them and the events available check out the articles Business Rules Scripting, Business Rules Scripting API and Business Rules Scripting Events.

Here we are interested in the rules that are assigned to the "ClientsWithScripting" table. If you open Relativity Server Admin Tool and connect to the instance of Relativity Server you're using. Navigate to the "DASamples" domain and select the "Simple" schema and press the "Open in Schema Modeler" button.

In Schema Modeler navigate to the "ClientsWithScripting" table, expand the tree and click on "Scripts" node. This will display a page which contains the business rules used in this sample (duplicated below) which you can modify to test if you desire.

The beforeProcessDeltaChange event is trigged each time a change is received from a client application, but before the change has been processed. It takes four arguments that are:

  • a Delta object that holds all of the changes.
  • a Delta Change object that holds information about a single delta change and contains the old and new values
  • wasRefreshed a bool this indicates if the record was refreshed
  • canRemove a bool to indicate if the record is currently allowed to be removed

There are 5 validation rules to cover all of the conditions used in this sample. If none of them generate a fail message, then the function returns and the changes are applied to the table. The fail message will not be returned until all of the delta changes have been processed.

// From the Schema
// Called before each change is applied to the database
function beforeProcessDeltaChange(delta, change, wasRefreshed, canRemove)
{
    var msg = "";
    var client = "ClientID=" + change.newValues['Id'];


    // Delete rule
    if (change.isDelete) {
        client = "ClientID=" + change.oldValues['Id'];
        msg = "Business Rule: #CLIENT: Deleting clients is prohibited!"
        .replace("#CLIENT", client);
        fail(msg);
    }

    // Discount rule. Min check
    var newDiscountValue = Math.round(100*change.newValues['Discount']);
    if (newDiscountValue < 0) {
        msg = "Business Rule: #CLIENT: Discount cannot be less than zero! Current value is: #VAL %"
        .replace("#CLIENT", client)
        .replace("#VAL", newDiscountValue);
        fail(msg);
    }

    // Discount rule. Max check
    if (newDiscountValue > 60) {
        msg = "Business Rule: #CLIENT: Discount cannot be greater than 60%! Current value is: #VAL %"
        .replace("#CLIENT", client)
        .replace("#VAL", newDiscountValue);
        fail(msg);
    }

    // Birthdate rule. Min check
    var minDate = new Date(1940, 1, 1, 0, 0, 0, 0);
    var newBirthdateValue = change.newValues['Birthdate'];
    if (minDate > newBirthdateValue) {
        msg = "Business Rule: #CLIENT: Birthdate cannot be less than 1940! Current value is: #VAL"
        .replace("#CLIENT", client)
        .replace("#VAL", newBirthdateValue);
        fail(msg);
    }

    // Birthdate rule. Max check
    var maxDate = new Date();
    if (maxDate < newBirthdateValue) {
        msg = "Business Rule: #CLIENT: Birthdate cannot be in future! Current value is: #VAL"
        .replace("#CLIENT", client)
        .replace("#VAL", newBirthdateValue);
        fail(msg);
    }

Example Output

This is an example of the output you will see when the sample is run. As you can see in each step a number of attempts are made to satisfy the Business Rule, initially going outside the bounds and printing the exception raise, before then satisfying the rule.

BusinessRules

:Business Rules sample has been started.
Target URL is http://localhost:7099/bin
RO DataAbstract layer is configured.

STEP 1: Login to DataService

Connecting to Relativity server: http://localhost:7099/bin
Login string is :
  User Id="simple";Password="simple";Domain="DASamples";Schema="Simple"
Login has been successfull. Going further...



STEP 2. Select the data (single client row) ...

Table: ClientsWithScripting (1 rows from 1)
--------------------------------------------------------------------------
| Id          | Name                      | Discount        | Birthdate  |
--------------------------------------------------------------------------
| 18          | Brian L. Rowles           |                 | 19/09/1968 |
--------------------------------------------------------------------------



STEP 3. Check the Client Discount Business Rule. Value must be in range [0%..60%]

a) Try to violate rule by setting discount to negative value ...

One or more updates failed to apply on the server.

18: Script failed in beforeProcessDeltaChange: Business Rule: ClientID=18: Discount cannot be less than zero! Current value is: -100 %


b) Try to violate rule and set too high discount  (more than 60%) ...

One or more updates failed to apply on the server.

18: Script failed in beforeProcessDeltaChange: Business Rule: ClientID=18: Discount cannot be greater than 60%! Current value is: 61 %


c) Finally, try to set discount that satisfy business rule ...

Table: ClientsWithScripting (1 rows from 1)
--------------------------------------------------------------------------
| Id          | Name                      | Discount        | Birthdate  |
--------------------------------------------------------------------------
| 18          | Brian L. Rowles           | 0.5             | 19/09/1968 |
--------------------------------------------------------------------------



STEP 4. Check the Client Birthdate Business Rule. Value must not be in future and be more than 1940

a) Try to violate rule by setting value beyound 1940 ...

One or more updates failed to apply on the server.

18: Script failed in beforeProcessDeltaChange: Business Rule: ClientID=18: Birthdate cannot be less than 1940! Current value is: 01/01/1935 00:00:00


b) Try to set value to date in future ...

One or more updates failed to apply on the server.

18: Script failed in beforeProcessDeltaChange: Business Rule: ClientID=18: Birthdate cannot be in future! Current value is: 01/01/2025 00:00:00


c) Try to set value that satisfy business rule (1955 year) ...

Table: ClientsWithScripting (1 rows from 1)
--------------------------------------------------------------------------
| Id          | Name                      | Discount        | Birthdate  |
--------------------------------------------------------------------------
| 18          | Brian L. Rowles           | 0.5             | 01/01/1955 |
--------------------------------------------------------------------------



STEP 5. Try to violate Business Rule and remove client row ...

One or more updates failed to apply on the server.

18: Script failed in beforeProcessDeltaChange: Business Rule: ClientID=18: Deleting clients is prohibited!
Done!
Cleanup!

Press Return to exit...