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
Friday, December 28, 2012PrintSubscribe
Web Transactions with Staging Tables

The most robust method to ensure separation between “draft” and “committed” data is physical segregation of draft data in dedicated staging tables. When data is ready to be committed, it is moved from draft tables to the primary database tables. For example, orders in the Northwind sample database are stored in Orders and OrderDetails – the primary tables. DraftOrders and DraftOrderDetails tables will be created in order to store draft orders.

Draft Orders and Order Details table schema.

A custom action in DraftOrders controller will copy the draft order and order details to the primary tables, and delete the draft data rows.

Adding the DraftOrders and DraftOrderDetails Tables

Start SQL Server Management Studio. In the Object Explorer window, right-click on Databases / Northwind node, and press New Query.

Creating a new query for Northwind database.

Paste the following script into the query window:

create table dbo.DraftOrders(
    OrderID int IDENTITY(1,1) not null,
    CustomerID nchar(5) null,
    EmployeeID int null,
    OrderDate datetime null,
    RequiredDate datetime null,
    ShippedDate datetime null,
    ShipVia int null,
    Freight money null,
    ShipName nvarchar(40) null,
    ShipAddress nvarchar(60) null,
    ShipCity nvarchar(15) null,
    ShipRegion nvarchar(15) null,
    ShipPostalCode nvarchar(10) null,
    ShipCountry nvarchar(15) null,
    PRIMARY KEY (OrderID)
)
go

alter table dbo.DraftOrders add foreign key(CustomerID)
references dbo.Customers (CustomerID)
go

alter table dbo.DraftOrders  add foreign key(EmployeeID)
references dbo.Employees (EmployeeID)
go

alter table dbo.DraftOrders  add foreign key(ShipVia)
references dbo.Shippers (ShipperID)
go

create table dbo.DraftOrderDetails(
    OrderID int,
    ProductID int,
    UnitPrice money default (0),
    Quantity smallint default (1),
    Discount real default (0),
    primary key (OrderID, ProductID)
)
go

alter table dbo.DraftOrderDetails add foreign key (OrderID)
references dbo.DraftOrders (OrderID)
go

alter table dbo.DraftOrderDetails add foreign key (ProductID)
references dbo.Products (ProductID)
go

This script will create DraftOrders and DraftOrderDetails tables with the same columns as the primary Orders and OrderDetails tables. It also recreates the relationships with lookup tables – Customers, Employees, Shippers, and Products.

Run the script by pressing Execute on the toolbar.

Creating Draft Order Form

Follow the Order Form Sample tutorial to create a draft order form. Make sure to use DraftOrders and DraftOrderDetails instead of Orders and OrderDetails when implementing the form.

Order Form created from the draft tables.

Creating “Submit Order” Action

The next step is to create an action that will move the draft order and draft order details into the original Orders and OrderDetails tables.

In the Project Designer, switch to the Controllers tab. Right-click on DraftOrders / Actions / ag2 (Form) node, and press New Action.

Creating a new action in the form of DraftOrders.

Assign the following values:

Property Value
Command Name Custom
Command Argument SubmitOrder
Header Text Submit Order

Press OK to save. Drop a100 – Custom, SubmitOrder | Submit Order node to the left side of the first action in ag2 to place it first in the group.

Dropping action 'a100' on the left side of 'a1'.     Action 'a100' placed first.

Handling the Action

Right-click on DraftOrders / Business Rules node, and press New Business Rule.

Creating a new business rule.

Assign these values:

Property Value
Type SQL
Command Name Custom
Command Argument SubmitOrder

In the Script property, enter the following:

begin transaction;

begin try
    -- move submitted order from DraftOrders to Orders
    insert into Orders (CustomerID, EmployeeID, OrderDate, 
                        RequiredDate, ShippedDate, ShipVia, 
                        Freight, ShipName, ShipAddress, 
                        ShipCity, ShipRegion, ShipPostalCode, 
                        ShipCountry)
    select CustomerID, EmployeeID, OrderDate, RequiredDate, 
            ShippedDate, ShipVia, Freight, ShipName, 
            ShipAddress, ShipCity, ShipRegion, ShipPostalCode, 
            ShipCountry
    from DraftOrders 
    where OrderID = @OrderID;

    -- find ID of committed order
    declare @NewOrderID int;
    select @NewOrderID = @@IDENTITY;

    -- move submitted order details from DraftOrderDetails to "Order Details"
    insert into "Order Details" (OrderID, ProductID, UnitPrice,
                                Quantity, Discount)
    select @NewOrderID, ProductID, UnitPrice,
            Quantity, Discount
    from DraftOrderDetails
    where OrderID = @OrderID;

    -- delete draft order and order details
    delete from DraftOrderDetails
    where OrderID = @OrderID;

    delete from DraftOrders
    where OrderID = @OrderID;

    commit transaction;

    -- refresh the page
    set @Result_NavigateUrl = 'OrderForm.aspx'
end try
begin catch
    rollback transaction;
    -- display error message
    declare @Error as nvarchar(500);
    select @Error = error_message();
    set @Result_ShowMessage = 'Order has not been submitted. ' + @Error;
end catch

Press OK to save.

Try testing the action – it will properly move the draft order and details into the Orders and OrderDetails tables. If any errors occur, the transaction will be rolled back and an error message will be displayed to the end user at the top of the web page.

Wednesday, December 26, 2012PrintSubscribe
Web Transactions with “Status” Field

A dedicated “Status” field in a database table is a simple and easy to implement method of separating “draft” and “committed” data. For example, orders stored in a database will be explicitly marked with a status of “Committed” if no changes are allowed to them. Orders still being composed will be marked with a status of “Draft”. The application must ignore draft data and have it visible only on the order entry page.

Adding the “Status” Column

Start SQL Server Management Studio. In the Object Explorer, right-click on Databases / Northwind and press New Query.

Creating a new query for Northwind database.

Paste in the following script to add the table column and mark all existing orders as “Committed”.

alter table Orders
add Status nvarchar(50) default 'Draft'
go

update Orders
set Status = 'Committed'
go

On the toolbar, press Execute to run the query.

Controlling Display of Draft Orders

Start the web application generator. Select the project name and click Settings. Press Business Logic Layer and enable shared business rules. Click Finish and regenerate the project.

Enabling shared business rules.

Start the Project Designer. In the Project Explorer, switch to the Controllers tab. Right-click on Orders controller node, and press Edit Handler in Visual Studio.

Using the context menu action to edit the handler in Visual Studio.

The shared business rule file will open in Visual Studio. Replace the file with 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
    {
        
        public SharedBusinessRules()
        {
        }

        protected override void EnumerateDynamicAccessControlRules(string controllerName)
        {
            if (Context.Request.UrlReferrer != null)
            {
                if (Context.Request.UrlReferrer.ToString().ToLower().Contains("orderform.aspx"))
                    RegisterAccessControlRule("OrderID", 
                        "select OrderID from Orders where Status = 'Draft'", 
                        AccessPermission.Allow);
                else
                    RegisterAccessControlRule("OrderID", 
                        "select OrderID from Orders where Status = 'Committed'", 
                        AccessPermission.Allow);
            }
        }
    }
}

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

        Public Sub New()
            MyBase.New()
        End Sub

        Protected Overrides Sub EnumerateDynamicAccessControlRules(controllerName As String)
            If Context.Request.UrlReferrer <> Nothing Then
                If Context.Request.UrlReferrer.ToString().ToLower().Contains("orderform.aspx") Then
                    RegisterAccessControlRule("OrderID",
                                            "select OrderID from Orders where Status = 'Draft'",
                                            AccessPermission.Allow)
                Else
                    RegisterAccessControlRule("OrderID",
                                            "select OrderID from Orders where Status = 'Committed'",
                                            AccessPermission.Allow)
                End If
            End If
        End Sub
    End Class
End Namespace

The implementation will conditionally register a dynamic access control rule that will apply to a view of any data controller with an OrderID data field. If the user is interacting with an application page ~/Pages/OrderForm.aspx, then only data that matches orders with a status of “Draft” is allowed. Otherwise, only data that matches orders with a status of “Committed” is included in the returned data set.

Adding “Submit Order” Action

In the Project Explorer, right-click on Orders / Actions / ag2 (Form) node, and press New Action.

Context menu option 'New Action' for action group 'ag2'.

Assign the following values:

Property Value
Command Name Custom
Command Argument SubmitOrder
Header Text Submit Order

Press OK to save the action. Drop Orders / Actions / ag2 (Form) / a101 – Custom, SubmitOrder | Submit Order node on the left side of a100 – Report | Order Report to place it first.

Dropping action 'a101' on the left side of 'a100'.     Action 'a101' has been placed first in the form.

Adding Business Rule

Right-click on Orders / Business Rules node, and press New Business Rule.

Creating a new business rule for Orders controller.

Assign these values:

Property Value
Type SQL
Command Name Custom
Command Argument SubmitOrder
Phase Execute
Script
update Orders
set Status = 'Committed'
where OrderID = @OrderID

set @Result_NavigateUrl = 'OrderForm.aspx'

The business rule will set Status column of the selected order to “Committed” and refresh the page loaded in the web browser. Press OK to save.

Testing the Results

On the toolbar, press Browse. Navigate to the Order Form page. Create a new order and return to the grid. Note that only a single draft order is listed.

A single draft order is displayed in the Order Form list.

Navigate to the Orders page. Note that the all of the orders are displayed except for the draft order.

Orders page only displays committed orders.

The draft order will also not be visible in any data controllers based on database views if they relate to orders. For example, page Reports | Order Subtotals will not display the new order. The dynamic access control rule explained above filters the order out.

Other views and reports will not display draft reports.

Go back to the Order Form page, and select the draft order. Click on the “Submit Order” button.

Clicking on the 'Submit Order' button in the Order Form.

The browser will refresh the page and display an empty list of orders.

The Order Form grid does not display any records.

The order will now be displayed on Orders page.

The committed order is now displayed on Orders page.

It will also be displayed on Order Subtotals page that can be found under the Reports option in the application navigation menu.

Committed order displayed on Order Subtotals page.

Thursday, November 29, 2012PrintSubscribe
Calculating Read-Only Fields with C# and Visual Basic

Let’s create a calculated field in the Employees controller that will combine First Name and Last Name fields.

Start the Project Designer. In the Project Explorer, switch to the Controllers tab. Right-click on Employees / Fields node, and press New Field option.

New Field context menu option for Employees controller in Code On Time web application generator.

Assign the following properties:

Property Value
Name FullName
Type String
Length 80
Allow Null Values true
The value is calculated by a business rule expression true
Label Full Name
Values of this field cannot be edited true

Press OK to save.

In the Project Explorer, drag Employees / Fields / FullName field node and drop it onto Employees / Views / createForm1 to add a data field.

Dropping FullName field node onto 'createForm1' view.     FullName data field created in 'createForm1' view.

Right-click on Employees / Fields / FullName node, and press Add Code Converter.

Add Code Converter context menu option on FullName field node in the Project Designer.

Double-click on Employees / Fields / FullName node, and change the Context Fields property:

Property Value
Context Fields FirstName, LastName

On the toolbar, press Browse to generate the web application and code business rule.

Right-click on Employees / Business Rules / FullName_Convertor and press Edit Rule in Visual Studio.

Edit Rule in Visual Studio context menu option for 'FullName_Converter' business rule node.

The business rule file will open in Visual Studio. Replace the default code with the following:

C#:

using System;
using MyCompany.Data;

namespace MyCompany.Rules
{
    public partial class EmployeesBusinessRules : MyCompany.Data.BusinessRules
    {
        
        /// <summary>
        /// Rule "FullName_Converter" implementation:
        /// This method will execute in any view before an action
        /// with a command name that matches "Calculate|Insert|Update".
        /// </summary>
        [Rule("r100")]
        public void r100Implementation(
                    int? employeeID, 
                    string lastName, 
                    string firstName, 
                    string title, 
                    string titleOfCourtesy, 
                    DateTime? birthDate, 
                    DateTime? hireDate, 
                    string address, 
                    string city, 
                    string region, 
                    string postalCode, 
                    string country, 
                    string homePhone, 
                    string extension, 
                    string notes, 
                    int? reportsTo, 
                    string reportsToLastName, 
                    string photoPath, 
                    string fullName)
        {
            if (!(String.IsNullOrEmpty(firstName)) && !(String.IsNullOrEmpty(lastName)))
                UpdateFieldValue("FullName", firstName + ' ' + lastName);
        }
    }
}

Visual Basic:

Imports MyCompany.Data
Imports System

Namespace MyCompany.Rules
    
    Partial Public Class EmployeesBusinessRules
        Inherits MyCompany.Data.BusinessRules
        
        ''' <summary>
        ''' Rule "FullName_Converter" implementation:
        ''' This method will execute in any view before an action
        ''' with a command name that matches "Calculate|Insert|Update".
        ''' </summary>
        <Rule("r100")>  _
        Public Sub r100Implementation( _
                    ByVal employeeID As Nullable(Of Integer),  _
                    ByVal lastName As String,  _
                    ByVal firstName As String,  _
                    ByVal title As String,  _
                    ByVal titleOfCourtesy As String,  _
                    ByVal birthDate As Nullable(Of DateTime),  _
                    ByVal hireDate As Nullable(Of DateTime),  _
                    ByVal address As String,  _
                    ByVal city As String,  _
                    ByVal region As String,  _
                    ByVal postalCode As String,  _
                    ByVal country As String,  _
                    ByVal homePhone As String,  _
                    ByVal extension As String,  _
                    ByVal notes As String,  _
                    ByVal reportsTo As Nullable(Of Integer),  _
                    ByVal reportsToLastName As String,  _
                    ByVal photoPath As String,  _
                    ByVal fullName As String)
            If (Not (String.IsNullOrEmpty(firstName)) AndAlso Not (String.IsNullOrEmpty(lastName))) Then
                UpdateFieldValue("FullName", firstName + " " + lastName)
            End If
        End Sub
    End Class
End Namespace

Save the file.

Switch back to the web application generator. On the toolbar, press Browse.

Navigate to the Employees page, and create a new employee. Type a value for Last Name and First Name.

Typing in First and Last Name into each respetive field on the New Employees form.

The Full Name field will be updated when the user presses Tab or shifts focus away from the field.

Tabbing away from First Name will update the Full Name calculated field.