23Creating Validation Rules for Customizable Products
Creating Validation Rules for Customizable Products
This chapter covers product validation. It includes the following topics:
About Validation for Customizable Products
The Product Validation view:
Allows you to validate configurable products using the provided Simple Expression business service.
Provides the infrastructure for validating products using custom validation business services that that you create.
The product ships with one validation business service, named VORD CPVE Simple Validation, which validates the components that make up a customizable product by using validation expressions.
The Product Validation service can be run in the following ways:
When the user selects Verify from the Line Item menu of the Quote or Order screens.
When the user clicks the Verify button within the Siebel Product Configurator user interface.
When the user selects Save or Done.
When the user verifies from the Quote or Order screen, the Product Validation service is run in conjunction with other verification services. The messages it generates appear with the messages from those services.
The messages from the Product Validation business service do not prevent the user from continuing, past the messages.
The Product Validation provides two key benefits:
It provides the architecture to create custom validation business services that are processed in conjunction with all other customizable product behavior. Depending on how the custom service is written, it could use rules written in an administration applet, or it may have the validation logic hard-coded into the script.
It fires only when called by clicking the Done, Save, or Verify button, so it makes batch validation possible in a configuration session. Product validation rules are not fired every time the selection changes, as configuration constraints are.
Scenario for Product Validation Using Custom Validation Services
This scenario describes one hypothetical way that product validation can be used. You may use it differently, depending on your business model.
An automotive wholesaler buys cars with many factory-installed options and configures them by adding wholesaler-installed options.
Some factory-installed options are not compatible with some wholesaler-installed options. The wholesaler must create requires and excludes rules such as:
Wholesaler-installed rear spoiler requires factory-installed V-6 engine.
Factory-installed sunroof excludes wholesaler-installed roof rack.
These are similar to the requires and excludes rules defined in Siebel Product Configurator. However, the wholesaler cannot use Siebel Product Configurator to configure these products, because the wholesaler only controls some of the components in the configuration.
For example, if you created a rule in Siebel Product Configurator saying that sunroof excludes roof-rack, Siebel Product Configurator would remove the sunroof when a user adds a roof rack. However, the wholesaler does not have control of the sunroof, and needs a rule saying that the roof rack cannot be installed if there is a sunroof.
To solve this problem using product validation, the wholesaler:
Uses the Pricing Administration screen, then the Attribute Adjustments view to create dynamic matrix tables of allowable combinations, as shown in the following two tables.
Table Allowable Combinations of Rear Spoiler and Engine
Rear Spoiler | Engine Type |
---|---|
Y |
6 |
Y |
6T |
N |
* |
Table Allowable Combinations of Sunroof and Roof Rack
Sunroof | Roof Rack |
---|---|
Y |
N |
N |
Y |
N |
N |
Write a validation business service for each of these matrices. The services reference the matrix to determine whether a combination that the end user selects is valid.
In the Product Validation view, add these business services and add the messages that are displayed to the user if the rules are violated. There is no limit to the number of business services that you can add for one validation.
Activating Workflows for Product Validation
Product validation is based on Siebel Workflows. You must activate these workflows before using the feature. For information about activating workflows, see Siebel Business Process Framework: Workflow Guide.
Activate the following workflows:
VORD Validate (Order)
VORD Validate (Quote)
Setting Up Product Validation Using the Simple Expression Business Service
To perform product validation using the simple expression business service, which is provided with the product, perform the following tasks:
Creating the Customizable Product for Validation
Validation rules only work on products that have been defined as components of a product with components. They use the Instance ID of the product with components as the key to retrieve products to validate.
As the first step in creating validation rules, define a product with components whose components include all the products that the rules will apply to. For more information, see Designing Products with Components.
Creating the Messages for Product Validation
You must use the Administration - Application screen, then the Message Types view to define the error messages that the product validation rule will display.
For more information about defining messages, see Siebel Order Management Infrastructure Guide.
To create the messages for product validation
Navigate to the Administration - Order Management screen, then the Message Types view.
In the All Message Types list, add a new record for each message and complete the necessary fields. Some fields are described in the following table.
Field | Comments |
---|---|
Name |
Enter a name for the message record. When you add rules in the Simple Validation Expression Rules list, this name will be used to link the rule to a message. |
Group |
If you are using the validation service VORD CPVE Simple Validation, which ships with the product, as the group, you must enter Simple Expression Rule. |
Full Text |
Enter the error message that is displayed by the application.
Note: Only the Full Text field is used by the product validation engine. The Short Text field is ignored.
|
Adding the Validation Services Record
The Validation Services record contains the name of the validation business service to call.
This task is a step in Setting Up Product Validation Using the Simple Expression Business Service.
To add the Validation Services record
Navigate to the Administration - Product screen, then the Products view.
Click the Product Validation view tab.
In the link bar of Product Validation view, click Validation Services.
Add one or more new records to the Validation Services list and complete the necessary fields. Some fields are described in the following table.
Field | Comments |
---|---|
Sequence |
Enter a number that controls the order in which the validation services are executed. You can create an unlimited number of validation services. |
Business Service |
Select the business service used to execute this rule. In this case, select VORD CPVE Simple Validation, the provided product validation business service that ships with the product. |
Rule Type |
Select a rule type. The options are as follows:
In this case, you must select Complex or All for use with the VORD CPVE Simple Validation business service. |
Creating Product Validation Expression Rules
The Product Validation Expression list allows you to create rules based on expressions that are true or false. If the expression is true, the application displays the error message that you select in the Message field.
This list allows you to create a number of different types of expressions. You may create only one type of expression in each rule.
For example, you can use the Search Expression field to create an expression in Siebel Query Language, such as [Quantity] > 2. If the value in the Quantity field is greater than 2, this expression evaluates as true, and the error message is displayed.
To create product validation rules
Navigate to the Administration - Product screen, then the Products view.
Click the Product Validation view tab.
In the link bar of Product Validation view, click Product Validation Expression Rules.
Add new records to the Product Validation Expression Rules list and complete the necessary fields.
The following table includes some sample simple expression rules that you could use to validate network ordering. The first six columns contain the values you enter in each record, and the last column contains an explanation of what this rule does. For more information about network ordering, see Siebel Order Management Guide Addendum for Industry Applications.
Table Samples of Simple Expression Rules
Seq | Error Text | Search Expression | Aggregate Function | Group By Fields | Having Expression | Explanation |
---|---|---|---|---|---|---|
1 |
[Count] [Product]s are missing Service Addresses |
([Network Element Type] = "Network Node" AND [Service Address] = "") |
Count |
[Product Name] | [Count]>0 |
Validates that all Nodes have a Service Address. |
2 |
[Count] [Product] are missing a "Service Address" and/or a "To Service Address " |
([Network Element Type] = "Network Connection" AND (([Service Address] = "") OR ([To Service Address] = ""))) |
Count |
[Product Name] | [Count]>0 |
Validates that all Connections have a Service Address associated with each end of the connection. |
3 |
[Product] at [Service Address] must have a different "To Service Address " |
([Network Element Type] = "Network Connection" AND ([Service Address] = [To Service Address])) |
Validates that the Addresses for each end of a connection are different. | |||
4 |
[Count] [Product] are missing a From Node and/or To Node |
([Network Element Type] = "Network Connection" AND ([Node] = "" OR [To Node] = "")) |
Count |
[Product Name] | [Count]>0 | Validates that all connections have a node associated with each end of the connection. |
In addition to the fields described in the previous table, use the Message field to select a message associated with the expression.
After this is setup, whenever a customizable product is validated, for each item in that current instance of the product, each expression rule is processed once. If any expression matches the current row, then the message associated with that rule is displayed.
Setting Up Product Validation Using Custom Validation Services
To create product validation rules, perform the following tasks:
Creating the Customizable Product for Validation
Validation rules only work on products that have been defined as components of a product with components. They use the Instance ID of the customizable product as the key to retrieve products to validate.
As the first step in creating validation rules, define a product with components whose components include all the products that the rules will apply to. For more information, see Designing Products with Components.
Creating Messages for Product Validation
If your custom business service uses Universal Messaging Service, you must use the Administration - Application screen, then the Message Types view to define the error messages that the product validation rule will display.
For more information about defining messages, see Siebel Order Management Infrastructure Guide.
To create the messages for product validation
Navigate to the Administration - Application screen, then the Message Types view.
In the All Message Types list, add a new record for each message and complete the necessary fields. Some fields are described in the following table.
Field | Comments |
---|---|
Name |
Enter a name for the message record. When you add rules in the Simple Validation Expression Rules list, this name will be used to link the rule to a message. |
Group |
If you are writing a custom validation service, give the group the name that you will call in the validation service. |
Full Text |
Enter the error message that is displayed by the application.
Note: Only the Full Text field is used by the product validation engine. The Short Text field is ignored.
|
Creating a Custom Business Service for Product Validation
You can create your own business services to solve specialized business problems, such as the problem described in Scenario for Product Validation Using Custom Validation Services.
This business service must follow the guidelines described in About Creating Custom Rule Checkers.
For more information about creating business services, see Siebel eScript Language Reference and Siebel VB Language Reference.
Adding the Validation Services Record
The Validation Services record contains the name of the validation business service to call. In this case, you use it to call the custom business service that you created.
To create validation services
Navigate to the Administration - Product screen, then the Products view.
Click the Product Validation view tab.
In the link bar of Product Validation view, click Validation Services.
Add one or more new records to the Validation Services list and complete the necessary fields. Some fields are described in the following table.
Field | Comments |
---|---|
Sequence |
Enter a number that controls the order in which the validation services are executed. You can create an unlimited number of validation services. |
Business Service |
Select the custom business service that you created to execute this rule. |
Rule Type |
Select a rule type. Options are:
The option you select depends on the custom validation service. |
About Creating Custom Rule Checkers
The Compound Product Validation Engine business service invokes a number of different rules checker business services. Two rules checkers are provided with the product, but a customer can build custom rules checker business services that comply with the following API specification.
The following rule checkers are provided with the product:
PreValidate. Returns the list of field names and attribute names used by the rules checker. The list of required fields and attributes may be influenced by the Parameters passed to the rule. For more information, see PreValidate Method.
Validate. Implements the logic of the specific rule and validates the contents of the Projected Asset cache. It returns rules violations. For more information, see Validate Method.
PreValidate Method
The PreValidate method determines the list of fields and attributes that the rules checker requires and returns them to the Compound Product Validation Engine. It may optionally use the product Id to retrieve product specific data related to the rule, or other parameters that may influence the list of fields and attributes.
Example
The Port Over-Subscription Checker business service checks that the sum of the bandwidths of the connections going into or out of a node does not exceed the bandwidth of the node. The checker has two parameters that specify the name of the Bandwidth attribute of the Node product and the name of the bandwidth of the Connection product. The rules checker requires the Network Element Type, Product Name, Node and To Node fields and the Bandwidth attributes to evaluate the rule. The method returns a property set of type Field and a property set of type Attribute containing the list of fields and attributes required by the rules checker.
function PreValidate (Inputs, Outputs) { // Retrieve input arguments var productId = Inputs.GetProperty("Product Id"); var parameter; // Retrieve the rules checker specific parameters // These parameter for (var i = 0; i < Inputs.GetChildCount(); i++) { var child = Inputs.GetChild(i); switch (child.GetType()) { case 'Parameter': parameter = child; break; default: throw "Unknown argument: " + child.GetType(); break; } } if (parameter == undefined) { throw "Missing input argument 'Parameter'"; } var connectionAttrib = parameter.GetProperty("Connection Attribute"); var nodeAttrib = parameter.GetProperty("Node Attribute"); // Define the fields used by this rules checker var field = TheApplication().NewPropertySet(); field.SetType("Field"); field.SetProperty("Network Element Type", ""); field.SetProperty("Product Name", ""); field.SetProperty("Node", ""); field.SetProperty("To Node", ""); // Define the attributes used by this rules checker var attribute = TheApplication().NewPropertySet(); attribute.SetType("Attribute"); attribute.SetProperty(connectionAttrib, ""); attribute.SetProperty(nodeAttrib, ""); // Return the required fields and attributes Outputs.AddChild(attribute); Outputs.AddChild(field); }
Validate Method
The Validate method implements the logic of the rules checker and returns rules violations. It may optionally use the Product Id to retrieve product specific data related to the rule, or other parameters that may influence the logic of the rule. It then queries the Projected Asset Cache using the supplied Asset Cache Key for rule violations and returns an error string for each to the Compound Product Validation Engine.
Example
The Port Over-Subscription Checker business service checks that the sum of the bandwidths of the connections going into or out of a node does not exceed the bandwidth of the node. The checker has two parameters that specify the name of the Bandwidth attribute of the Node product and the name of the bandwidth of the Connection product. The Validate method first queries the Projected Asset Cache using the Asset Cache Key passed as an input argument for all Network Node components and sorts the output by Node name. It then queries the Projected Asset cache for the sum of the bandwidth attribute for all Network Connection components grouped by the Node field. Finally, it queries the Projected Asset cache for the sum of the bandwidth attribute for all Network Connection components grouped by the To Node field. Using the results from the three queries, the Validate method then calculates the sum of the sum of the bandwidths of the connections going into or out of each node and constructs an error message string for each instance where the bandwidth of the node is exceeded. The error strings are returned in the Rule Violation output argument.
function Validate (Inputs, Outputs) { // Retrieve input arguments var productId = Inputs.GetProperty("Product Id"); var product = Inputs.GetProperty("Product"); var assetCacheKey = Inputs.GetProperty("Asset Cache Key"); var parameter; // Retrieve rules checker specific parameters for (var i = 0; i < Inputs.GetChildCount(); i++) { var child = Inputs.GetChild(i); switch (child.GetType()) { case 'Parameter': parameter = child; break; default: throw "Unknown argument: " + child.GetType(); break; } } if (parameter == undefined) { throw "Missing input argument 'Parameter'"; } var connectionAttrib = parameter.GetProperty("Connection Attribute"); var nodeAttrib = parameter.GetProperty("Node Attribute"); // Queries the Projected Asset Cache to retrieve a list of nodes sorted by node // name. var assetCacheSvc = TheApplication().GetService("VORD Projected Asset Cache"); var svcInputs = TheApplication().NewPropertySet(); var svcOutputs = TheApplication().NewPropertySet(); svcInputs.SetProperty("Asset Cache Key", assetCacheKey); svcInputs.SetProperty("Search Expression", "([Network Element Type] = \"Network Node\")"); var sortByField = TheApplication().NewPropertySet(); sortByField.SetType("Sort By Field"); sortByField.SetProperty("Node", "ASC"); svcInputs.AddChild(sortByField); assetCacheSvc.InvokeMethod("Query", svcInputs, svcOutputs); // Retrieves the result from the output of the Query method var nodePropSet; for (var i = 0; i < svcOutputs.GetChildCount(); i++) { var child = svcOutputs.GetChild(i); switch (child.GetType()) { case 'Result': nodePropSet = child; break; default: throw "Unknown argument: " + child.GetType(); break; } } if (nodePropSet == undefined) { throw "Missing output argument 'Result'"; } // Since a single query cannot get the bandwidth of connections into and out of // a node, the code retrieves this using two queries, one for connections // going in and one for connections going out. This maximizes the use of high // performance C++ code in the projected asset cache and minimizes the work // done by this script. // Get the bandwidth going into each node from the projected asset cache var assetCacheSvc = TheApplication().GetService("VORD Projected Asset Cache"); // Set up the inputs to the Query method var svcInputs = TheApplication().NewPropertySet(); var svcOutputs = TheApplication().NewPropertySet(); svcInputs.SetProperty("Asset Cache Key", assetCacheKey); svcInputs.SetProperty("Search Expression", "([Network Element Type] = \"Network Connection\")"); svcInputs.SetProperty("Aggregate Field", connectionAttrib); svcInputs.SetProperty("Aggregate Function", "Sum"); var groupByField = TheApplication().NewPropertySet(); groupByField.SetType("Group By Field"); groupByField.SetProperty("Node", ""); svcInputs.AddChild(groupByField); var sortByField = TheApplication().NewPropertySet(); sortByField.SetType("Sort By Field"); sortByField.SetProperty("Node", "ASC"); svcInputs.AddChild(sortByField); // Invoke the Projected Asset Cache Query method assetCacheSvc.InvokeMethod("Query", svcInputs, svcOutputs); // Get the Query result var nodeFromPropSet; for (var i = 0; i < svcOutputs.GetChildCount(); i++) { var child = svcOutputs.GetChild(i); switch (child.GetType()) { case 'Result': nodeFromPropSet = child; break; default: throw "Unknown argument: " + child.GetType(); break; } } if (nodeFromPropSet == undefined) { throw "Missing output argument 'Result'"; } // Get the bandwidth going out of each node from the projected asset cache var assetCacheSvc = TheApplication().GetService("VORD Projected Asset Cache"); ar svcInputs = TheApplication().NewPropertySet(); ar svcOutputs = TheApplication().NewPropertySet(); // Set up the inputs to the Query method svcInputs.SetProperty("Asset Cache Key", assetCacheKey); svcInputs.SetProperty("Search Expression", "([Network Element Type] = \"Network Connection\")"); svcInputs.SetProperty("Aggregate Field", connectionAttrib); svcInputs.SetProperty("Aggregate Function", "Sum"); var groupByField = TheApplication().NewPropertySet(); groupByField.SetType("Group By Field"); groupByField.SetProperty("To Node", ""); svcInputs.AddChild(groupByField); var sortByField = TheApplication().NewPropertySet(); sortByField.SetType("Sort By Field"); sortByField.SetProperty("To Node", "ASC"); svcInputs.AddChild(sortByField); // Invoke the Projected Asset Cache Query method assetCacheSvc.InvokeMethod("Query", svcInputs, svcOutputs); // Get the Query result var nodeToPropSet; for (var i = 0; i < svcOutputs.GetChildCount(); i++) { var child = svcOutputs.GetChild(i); switch (child.GetType()) { case 'Result': nodeToPropSet = child; break; default: throw "Unknown argument: " + child.GetType(); break; } } if (nodeToPropSet == undefined) { throw "Missing output argument 'Result'"; } // Create a property set for the errors var ruleViolation = TheApplication().NewPropertySet(); ruleViolation.SetType("Rule Violation"); // Check whether each node is over-loaded var nodeFromIndex = 0; var nodeToIndex = 0; for (var i = 0; i < nodePropSet.GetChildCount(); i++) { // Get details for the current node var thisNode = nodePropSet.GetChild(i); var thisNodeName = thisNode.GetProperty("Node"); var thisNodeBandwidth = parseInt(thisNode.GetProperty(nodeAttrib)); var thisNodeProduct = thisNode.GetProperty("Product Name"); // Find the current node in the 'total from' property set var fromNodeBandwidth = 0; if (nodeFromPropSet.GetChild(nodeFromIndex).GetProperty("Node") == thisNodeName) { fromNodeBandwidth = parseInt(nodeFromPropSet.GetChild(nodeFromIndex).GetProperty("Sum")); nodeFromIndex++; } // Find the current node in the 'total to' property set var toNodeBandwidth = 0; if (nodeToPropSet.GetChild(nodeToIndex).GetProperty("To Node") == thisNodeName) { toNodeBandwidth = parseInt(nodeToPropSet.GetChild(nodeToIndex).GetProperty("Sum")); nodeToIndex++; } // Raise an error if the bandwidth of the connections exceeds that of the node if (thisNodeBandwidth < (fromNodeBandwidth + toNodeBandwidth)) { ruleViolation.SetProperty(thisNodeProduct + " '" + thisNodeName + "' is overloaded (" + (fromNodeBandwidth + toNodeBandwidth) + " > " + thisNodeBandwidth + ")", ""); } } // Return any errors Outputs.AddChild(ruleViolation); }