Business Rules/Logic

Labels
AJAX(112) App Studio(9) Apple(1) Application Builder(245) Application Factory(207) ASP.NET(95) ASP.NET 3.5(45) ASP.NET Code Generator(72) ASP.NET Membership(28) Azure(18) Barcode(2) Barcodes(3) BLOB(18) Business Rules(1) Business Rules/Logic(140) BYOD(13) Caching(2) Calendar(5) Charts(29) Cloud(14) Cloud On Time(2) Cloud On Time for Windows 7(2) Code Generator(54) Collaboration(11) command line(1) Conflict Detection(1) Content Management System(12) COT Tools for Excel(26) CRUD(1) Custom Actions(1) Data Aquarium Framework(122) Data Sheet(9) Data Sources(22) Database Lookups(50) Deployment(22) Designer(178) Device(1) DotNetNuke(12) EASE(20) Email(6) Features(101) Firebird(1) Form Builder(14) Globalization and Localization(6) How To(1) Hypermedia(2) Inline Editing(1) Installation(5) JavaScript(20) Kiosk(1) Low Code(3) Mac(1) Many-To-Many(4) Maps(6) Master/Detail(36) Microservices(4) Mobile(63) Mode Builder(3) Model Builder(3) MySQL(10) Native Apps(5) News(18) OAuth(9) OAuth Scopes(1) OAuth2(13) Offline(20) Offline Apps(4) Offline Sync(5) Oracle(11) PKCE(2) Postgre SQL(1) PostgreSQL(2) PWA(2) QR codes(2) Rapid Application Development(5) Reading Pane(2) Release Notes(184) Reports(48) REST(29) RESTful(29) RESTful Workshop(15) RFID tags(1) SaaS(7) Security(81) SharePoint(12) SPA(6) SQL Anywhere(3) SQL Server(26) SSO(1) Stored Procedure(4) Teamwork(15) Tips and Tricks(87) Tools for Excel(3) Touch UI(93) Transactions(5) Tutorials(183) Universal Windows Platform(3) User Interface(338) Video Tutorial(37) Web 2.0(100) Web App Generator(101) Web Application Generator(607) Web Form Builder(40) Web.Config(9) Workflow(28)
Archive
Blog
Business Rules/Logic
Saturday, March 31, 2012PrintSubscribe
“Soft” Filtering With Business Rules

Code On Time web applications offer impressive adaptive filtering and search capabilities that require zero programming. Consider the following screen shot from the Northwind sample.

A complex filter defined at runtime by an application user

Application user has selected specific categories,

User-defined category filter

specific suppliers,

User-defined supplier filter

a range of prices,

User-defined unit price filter

and specific values of product units on order.

User-defined 'units on order' filter

A user can remove the filter at will by either clicking on individual filter elements or dismissing the entire filter.

User can remove the filter at will by either clicking on individual filter elements or dismissing the entire filter

An application developer can also configure a filter based on arbitrary conditions at runtime. The filter can be constructed just before the data is retrieved from the database.  Users will see the filter as if they have selected all options on their own. End users can always cancel or adjust the “soft” filter to reveal more data rows.

This may be useful when a specific data row has to be brought to the application user’s attention.  “Soft” filtering will work even better when combined with the auto highlight first row or auto select first row features.

Enable shared business rules in your web application and enter the following code.

C#:

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using MyCompany.Data;

namespace MyCompany.Rules
{
    public partial class SharedBusinessRules : MyCompany.Data.BusinessRules
    {
        [ControllerAction("Orders", "grid1", "Select", ActionPhase.Before)]
        public void AssignOrdersFilter()
        {
            if (!IsTagged("Filtered"))
            {
                AddTag("Filtered");
                DateTime startDate = new DateTime(1998, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                DateTime endDate = new DateTime(1998, 6, 1, 23, 59, 59, DateTimeKind.Utc);
                AssignFilter(
                    new FilterValue("OrderDate",
                        RowFilterOperation.Between, startDate, endDate),
                    new FilterValue("EmployeeLastName",
                        RowFilterOperation.Equal, "Callahan"),
                    new FilterValue("ShipViaCompanyName",
                        RowFilterOperation.Includes, "Speedy Express", "United Package"),
                    new FilterValue("Freight", 
                        RowFilterOperation.Between, 10, 30)
                );
                Result.ShowViewMessage("A \"soft\" filter has been applied to this list.");
            }
        }
    }
}

Visual Basic:

Imports MyCompany.Data
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq

Namespace MyCompany.Rules
    Partial Public Class SharedBusinessRules
        Inherits MyCompany.Data.BusinessRules

        <ControllerAction("Orders", "grid1", "Select", ActionPhase.Before)> _
        Public Sub AssignOrdersFilter()
            If Not IsTagged("Filtered") Then
                AddTag("Filtered")
                Dim startDate As DateTime = New DateTime(1998, 1, 1, 0, 0, 0, DateTimeKind.Utc)
                Dim endDate As DateTime = New DateTime(1998, 6, 1, 23, 59, 59, 
DateTimeKind.Utc) AssignFilter( New FilterValue("OrderDate", RowFilterOperation.Between, startDate, endDate), New FilterValue("EmployeeLastName", RowFilterOperation.Equal, "Callahan"), New FilterValue("ShipViaCompanyName", RowFilterOperation.Includes, "Speedy Express", "United Package"), New FilterValue("Freight", RowFilterOperation.Between, 10, 30) ) Result.ShowViewMessage("A ""soft"" filter has been applied to this list.") End If End Sub End Class End Namespace

Save the code file and navigate to the page Orders. The method AssignOrdersFilter will be invoked when the data is about to be retrieved. The method will apply a filter one time only in the lifecycle of the page instance displayed in the web browser to prevent interference with application user actions.

Notice that we are filtering by UTC dates to ensure that Microsoft.NET will not try to compensate for the time difference between the server and the web browser.

In the end, the method will display a view-level message rendered just above the grid view informing the app user about the “soft”- filter.

A list of orders with the 'soft' filtered applied in the business rules method

Select data view Customers/ Orders / container1 / view in the Project Explorer.

Data view selected in the Project Explorer

If you enable Search On Start in the data view properties then the Orders page will open up with the search bar pre-filled with filter values and no data will be displayed. Users will have to click Search to initiate the retrieval of data.

'Soft' filter will be displayed in the search bar if the data view property 'Search on Start' is turned on

If you have enabled automatic selection or highlighting of the first row in the properties of the page data view then the view will perform the first action in the context menu of the first data row or simulate a click in the first row. This sort of behavior will happen even if you do not “soft” filter the data.

You can also coincide the selection or highlighting of the first row with the assignment of a “soft” filter in business rules  by calling Result.SelectFirstRow or Result.HightlightFirstRow right after the call of ShowViewMessage method.

For example, this is the effect of Result.HighlightFirstRow method call.

The effect of calling AssignFilter and HighlightFirstRow methods in the business rules prior to data selection

Developers should use access control rules or filter expressions when the application business logic does not permit cancellation of data filters at will by the application users.

Saturday, March 31, 2012PrintSubscribe
Shared Business Rules

The core framework of your application always tries to create a class with the name YourProjectNamespace.Rules.SharedBusinessRules whenever it receives a request to process data on the server. The framework interacts with the class instance in order to determine if any custom business logic is implemented in the application. This happens when data is selected, updated, inserted, deleted, and when custom actions are requested.

The name YourProjectNamespace in the namespace entered in the project settings. The default namespace is MyCompany.

Project namespace configuration in the line-of-business application created with Code OnTime web application generator

You can enable shared business rules if you select Settings of your project and choose the Business Logic Layer option. Toggle the check box in the Shared Business Rules section, click Finish button to save the changes.

Enabling shared business rules in a Code On Time web application

If you generate the app then the class file SharedBusinessRules.cs(vb) will be created either in ~/App_Code/Rules folder on in the ~/Rules folder of the application class library. This depends on the type of your projects.

'SharedBusinessRules' code file in the Solution Explorer of a 'Web Site Factory' project

Class SharedBusinessRules provides a convenient placeholder for the business logic that may apply to all data controllers of your web application.

Enter the following code in the code file of shared business rules.

C#:

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using MyCompany.Data;

namespace MyCompany.Rules
{
    public partial class SharedBusinessRules : MyCompany.Data.BusinessRules
    {
        [ControllerAction("", "grid1", "Select", ActionPhase.Before)]
        protected void TellTheUserWhatJustHappened()
        {
            if (!IsTagged("UserIsInformed"))
            {
                Result.ShowMessage(
                    "You just have requested data from '{0}' controller", 
                    ControllerName);
                AddTag("UserIsInformed");
            }
        }
    }
}

Visual Basic:

Imports MyCompany.Data
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq

Namespace MyCompany.Rules

    Partial Public Class SharedBusinessRules
        Inherits MyCompany.Data.BusinessRules

        <ControllerAction("", "grid1", "Select", ActionPhase.Before)>
        Protected Sub TellTheUserWhatJustHappened()
            If (Not IsTagged("UserIsInformed")) Then
                Result.ShowMessage(
                    "You just have requested data from '{0}' controller",
                    ControllerName)
                AddTag("UserIsInformed")
            End If
        End Sub

    End Class
End Namespace

Save the file and navigate to any page of your web application that contains data. Here is what you will see at the top of the page if you view the Suppliers in the Northwind sample.

The message from the shared business rule method TellTheUserWhatJustHappened displays a message at the top of the page when data is selected for the first time

If you continue sorting, filter, and paging the suppliers then the message will continue to be displayed at the top. If you start editing or select a supplier then the message from the child view will popup.

The message from the shared business rules is displayed when the child products are selected for the first time

We are using IsTagged and AddTag methods to display the messages once in the lifecycle of the page instance in the browser window. If the data view on the page is not tagged then the message is displayed and the tag UserIsInformed is assigned to it.

The message will eventually disappear as soon as user invokes available data view actions.

Method TellTheUserWhatJustHappened is called every time the data is selected. This happens when the data is sorted, paged, changed, or if a filter is applied. Data view tagging ensures that the message will be sent to the client one time only.

If you navigate away from the page and come back using the Back button of your web browser then the tag is restored and no message will be displayed. If you click ahead and arrive to a non-historical version of the page then the data view tags will be blank and the message will show up once when the first attempt to select data is executed on the server.

The business logic implemented in this shared business rules example will be engaged for all data pages of your web application whenever the grid1 view of any controller requires data. This applies to an application with a single data page and will also be true in the application with three hundred data pages.

If you have existing controller-specific business rules, then make sure that their base class is changed from BusinessRules to SharedBusinessRules. If you create new controller-specific business rules, then the code generator will automatically specify the SharedBusinessRules class as their base.

Sunday, March 18, 2012PrintSubscribe
Total and Subtotal: Business Rule for Subtotal

The Subtotal field is now present in the application. The field does not reflect changes when new order items are entered. We will add a business rule to the Orders controller and add a code expression for Subtotal. This code expression will use the rule to calculate the subtotal.

In the Project Explorer, switch to Controllers tab. Double-click on the Orders controller. In the Handler field, type:

OrdersBusinessRules

Adding 'OrdersBusinessRules' Handler to 'Orders' Controller

Press OK to save the controller, exit the Designer, and Generate the project. The business rule placeholder file will be created.

When generation is complete, click on the project name in the web application generator and press Develop. Microsoft Visual Studio or Visual Web Developer will open. In the Solution Explorer on the right side of the screen, double-click on App_Code /Rules / OrdersBusinessRules.cs(vb).

OrdersBusinessRules.cs Rule file in OrderForm project

Paste in the following code:

C#:

using MyCompany.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace MyCompany.Rules
{
    public partial class OrdersBusinessRules : MyCompany.Data.BusinessRules
    {
        public decimal CalculateOrderDetailsTotal(int? orderID)
        {
            using (SqlText calc = new SqlText(@"select sum(unitprice * 
                    quantity * (1 - discount)) from 
                    [Order Details] where OrderID= @OrderID"))
            {
                calc.AddParameter("@OrderID", orderID);
                object total = calc.ExecuteScalar();
                if (DBNull.Value.Equals(total))
                    return 0;
                else
                    return Convert.ToDecimal(total);
            }
        }
    }
}

VB:

Imports MyCompany.Data
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Namespace MyCompany.Rules

    Partial Public Class OrdersBusinessRules
        Inherits MyCompany.Data.BusinessRules
        Public Function CalculateOrderDetailsTotal(
                            ByRef orderID As Nullable(Of Integer)) As Decimal
            Using calc As SqlText = New SqlText(
                    "select sum(unitprice * quantity * (1 - discount)) " +
                    "from [Order Details] where OrderID=@OrderID")
                calc.AddParameter("@OrderID", orderID)
                Dim total As Object = calc.ExecuteScalar()
                If DBNull.Value.Equals(total) Then
                    Return 0
                Else
                    Return Convert.ToDecimal(total)
                End If
            End Using
        End Function
    End Class
End Namespace

This function uses SqlText utility class to create an instance of a query connected to the project’s database.
This simple query selects a sum of UnitPrice multiplied by Quantity multiplied by one minus the
Discount.

Note that SqlText utility class is generated as a part of the code base of your application. It uses the
default database connection string and ADO.NET to execute the query.

Save the file, and switch back to the application generator. Select the project name, and press Design. In the Project Explorer, switch to Controllers. Double-click on Orders / Fields / Subtotal. Make the following changes:

Property Text
The value of this field is calculated by a business rule expression True
Code Formula
CalculateOrderDetailsTotal(orderID)
Context Fields OrderDetails

Code Formula for 'Subtotal' field
'Context Fields' property of Orders / Fields / Subtotal

Press OK to save the field. The Subtotal field on the Order Form will now update to reflect any changes made to the order details.