The calculation will analyze Order ID and current Freight value:
If the order total is greater than $100, then Freight will be $19.95 flat.
Otherwise, Freight is $3.95.
The Order Form page will allow overriding the Freight value.
Switch to Visual Studio. If it is not open, exit the Designer, click on the project name in the generator, and press Develop. Open App_Code / Rules / OrdersBusinessRules.cs(vb) file.
This is how the method is implemented. You can copy the implementation into your own project. The method CalculateFreight takes nullable integer orderID and decimal freight, and returns a decimal value. It calls CalculateOrderDetailsTotal method to find the total price of order details. If Freight is equal to blank, 0, 3.95, or 19.95, then it will be returned as 19.95 for Total greater than $100, or 3.95 for Total under $100. If the conditions are not met, then Freight will not be affected.
C#:
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); } } public decimal CalculateFreight(int? orderID, decimal? freight) { decimal total = CalculateOrderDetailsTotal(orderID); if (!freight.HasValue || freight.Value == 0 || freight.Value == 3.95m || freight.Value == 19.95m) if (total > 100) return 19.95m; else return 3.95m; else return freight.Value; } } }
VB:
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 Public Function CalculateFreight(ByRef orderID As Nullable(Of Integer), ByRef freight As Nullable( Of Decimal)) As Decimal Dim total As Decimal = CalculateOrderDetailsTotal(orderID) If Not freight.HasValue Or freight.Value = 0 Or freight.Value = 3.95 Or freight.Value = 19.95 Then If total >= 100 Then Return 19.95 Else Return 3.95 End If Else Return freight.Value End If End Function End Class End Namespace
Go back to the Project Explorer, and select Orders from the Controllers list. Open Fields node, and double-click on Freight. Enter the following settings:
Property | Value |
The value of this field is calculated by a business rule expression | True |
Code Formula |
CalculateFreight(orderID, freight) |
Context Fields | OrderDetails |
Save the field, and regenerate the application. Edit an order, and change the Freight to “0”. When you tab away from the field, the freight will be recalculated.
If you change the order details so that the Subtotal is less than than $100, you will see Freight be recalculated to $3.95.
Let’s take a quick look at the Orders business rules class that was automatically created by the code
generator for us. You can see that we have a partial class OrdersBusinessRules with method
CalculateOrders adorned with attributes ControllerAction, which respond to Calculate action. The
method calculates Freight, Subtotal, and Total fields by calling CalculateOrderDetailsTotal and
CalculateFreight with orderID passed as an argument.
C#:
using System; using System.Data; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Web; using System.Web.Security; using MyCompany.Data; namespace MyCompany.Rules { public partial class OrdersBusinessRules : MyCompany.Data.BusinessRules { [ControllerAction("Orders", "Calculate", "Freight")] [ControllerAction("Orders", "Calculate", "Subtotal")] [ControllerAction("Orders", "Calculate", "Total")] public void CalculateOrders( int? orderID, string customerID, string customerCompanyName, int? employeeID, string employeeLastName, DateTime? orderDate, DateTime? requiredDate, DateTime? shippedDate, int? shipVia, string shipViaCompanyName, decimal? freight, string shipName, string shipAddress, string shipCity, string shipRegion, string shipPostalCode, string shipCountry, decimal? subtotal, decimal? total) { UpdateFieldValue("Freight", CalculateFreight(orderID, freight)); UpdateFieldValue("Subtotal", CalculateOrderDetailsTotal(orderID)); UpdateFieldValue("Total", CalculateOrderDetailsTotal(orderID) + freight); } [RowBuilder("Orders", RowKind.New)] public void BuildNewOrders() { UpdateFieldValue("OrderDate", DateTime.Now); } } }
VB:
Imports MyCompany.Data Imports System Imports System.Collections.Generic Imports System.Data Imports System.Linq Imports System.Text.RegularExpressions Imports System.Web Imports System.Web.Security Namespace MyCompany.Rules Partial Public Class OrdersBusinessRules Inherits MyCompany.Data.BusinessRules <ControllerAction("Orders", "Calculate", "Freight"), _ ControllerAction("Orders", "Calculate", "Subtotal"), _ ControllerAction("Orders", "Calculate", "Total")> _ Public Sub CalculateOrders( _ ByVal orderID As Nullable(Of Integer), _ ByVal customerID As String, _ ByVal customerCompanyName As String, _ ByVal employeeID As Nullable(Of Integer), _ ByVal employeeLastName As String, _ ByVal orderDate As Nullable(Of DateTime), _ ByVal requiredDate As Nullable(Of DateTime), _ ByVal shippedDate As Nullable(Of DateTime), _ ByVal shipVia As Nullable(Of Integer), _ ByVal shipViaCompanyName As String, _ ByVal freight As Nullable(Of Decimal), _ ByVal shipName As String, _ ByVal shipAddress As String, _ ByVal shipCity As String, _ ByVal shipRegion As String, _ ByVal shipPostalCode As String, _ ByVal shipCountry As String, _ ByVal subtotal As Nullable(Of Decimal), _ ByVal total As Nullable(Of Decimal)) UpdateFieldValue("Freight", CalculateFreight(orderID, freight)) UpdateFieldValue("Subtotal", CalculateOrderDetailsTotal(orderID)) UpdateFieldValue("Total", CalculateOrderDetailsTotal(orderID) + freight) End Sub <RowBuilder("Orders", RowKind.New)> _ Public Sub BuildNewOrders() UpdateFieldValue("OrderDate", DateTime.Now) End Sub End Class End Namespace