Add ApplyDebit, InvalidAccount, and CheckBalance Rules

The rules you add in this section work together as follows:

When a Debit event is asserted into the Rete network, TIBCO BusinessEvents® Extreme checks rules with the Debit event in their scope.

It’s important to understand how conflict resolution and run to completion (RTC) cycles work. If you understand what triggers rules to execute, and why a rule may not execute, you can design rules more effectively. For a reminder, carefully reread Understanding Conflict Resolution and Run to Completion Cycles in TIBCO BusinessEvents® Extreme Application Architect’s Guide.

[Note]

See Run-time Inferencing Behavior in TIBCO BusinessEvents® Extreme Application Architect’s Guide.

If you have completed the section called “Add the DuplicateAccountCheck Rule” and the section called “Add the CreateAccount Rule”, you will be familiar with adding rules. This section shows the source code for the three rules you will add.

The main purpose for showing the form view is so you can compare it with the source view when creating your own rule.

Example 2.1. ApplyDebit Rule Source View Code

     		// $Revision: 1.1.4.7 $
/**
 * @description Debit the matching account by the specified amount.
 */
rule Rules.ApplyDebit {
    attribute {
        priority = 1;
        forwardChain = true;
    }
    declare {
        
        Events.Debit debit;
        Concepts.Account account;
    }
    when {
        Account.lookupByIdentifier("write", debit.identifier) != null;
        account.status != "Disabled";
        Instance.isModified(account) == false;
    }
    then {
        //
        //    Remove all old history objects for this account older than 2 minutes
        //
        Object results = History.lookupByAccount("read", "ascending", account.identifier, null);
        DateTime now = DateTime.now();
        Concepts.History history = Query.next(results);
        Double debitSum = 0;

        while (history != null)
        {
            if ((DateTime.getTimeInMillis(now) - DateTime.getTimeInMillis(history.at)) > 120000)
            {
            	System.debugOut(
            		"INFO: Removing expired history for " 
            		+ account.identifier
            		+ ".  History amount is "
            		+ history.amount);    
                Instance.deleteInstance(history);
                history = Query.next(results);
                continue;
            }
            debitSum = debitSum + history.amount;
            history = Query.next(results);
        }

        //
        //    Create a history object and debit the account
        //
        history = Concepts.History.History(
            "", 
            debit.amount,
            DateTime.now(),
            account.identifier);

        //
        //    Update the recent debit sum for this account
        //
        account.recentDebitBalance = debitSum + debit.amount;

        //
        //    Maximum debit is current balance
        //
        long newBalance = account.balance - debit.amount;
        long debitAmount = debit.amount;

        if (newBalance > 0)
        {
            account.balance = newBalance;
        }
        else
        {
            debitAmount = account.balance;
            account.balance = 0;
        }

        System.debugOut(
            "INFO: Debited account " 
            + account.identifier 
            + " by $" 
            + debitAmount
            + ".  New balance is $"
            + account.balance);    
    }
}

     	

Example 2.2. InvalidAccount Rule Source View Code

     		// $Revision: 1.1.4.4 $
/**
 * @description Reports account not found message for debit
 */
rule Rules.InvalidAccount {
    attribute {
        priority = 10;
        forwardChain = true;
    }
    declare {
        
        Events.AccountOperations accountoperations;
    }
    when {
        Account.lookupByIdentifier("none", accountoperations.identifier) == null;
    }
    then {
        System.debugOut("WARNING: Account " + accountoperations.identifier + " not found.");

        //
        //    All done
        //
        Event.consumeEvent(accountoperations);
    }
}

     	

Example 2.3. CheckBalance Rule Source View Code

// $Revision: 1.1.4.3 $
/**
 * @description Disable an account with zero balance.
 */
rule Rules.CheckBalance {
    attribute {
        priority = 4;
        forwardChain = true;
    }
    declare 
    {    
        Events.Debit debitevent;
        Concepts.Account account;
    }
    when 
    {
        account.balance == 0;
        account.status != "Disabled";
    }
    then {
        //
        //    Disable the account
        //
        account.status = "Disabled";

        System.debugOut("WARNING: " 
            + account.identifier 
            + " account balance is zero.");
    }
}