Defining an Impact Rule
A scenario analysis template must define at least one impact rule, so that there is information to use when making the recommendation. Typically, with a supply chain problem, it is useful to consider both cost and time impacts.
After analyzing impacts, the system can move to the recommendation process.
How an Impact Rule Is Used
For each call to the scenario analysis API, the system does the following:
-
For each impact rule in the template:
-
Iterate through all the scenarios generated in this run, except for the invalid scenarios which have already been removed.
-
For each possibility, use the impact rule to set the value of one impact parameter, typically time or cost.
Notice that the system performs the iteration over the possibilities and impact rules. Your impact rule simply updates a value in a snapshot.
-
-
Generate a report object, which contains all the results.
No coding is needed to create the report object; this step is handled entirely by the scenario analysis module.
Template Syntax
The following template fragment shows where to include impact rules:
"impact": {
"name": "KPIs for out of stock scenarios",
"rules": [
{
"description": "Time to get the inventory",
"name": "Time impact",
"type": "Python",
"expression": "TimeImpact.py.calculateTimeImpact",
"parameters": [
"supplierId",
"productId"
]
},...
Formally:
-
The impact object is a top-level property of the template. For this object:
-
name—Specifies a generic name for all the impact rules within this object.
-
rules—Specifies an array of objects, each of which describes one impact rule.
-
-
Within the rules array, each object has the following properties:
-
description—Describes the rule.
-
name—Provides a name for the rule.
-
type—Specifies how this rule is implemented. Use one of the following values for this property: "Python", "ObjectScript", "SQL", "BPL"
-
expression—Specifies the code to execute when using this rule. The syntax used depends on the value of the type property:
-
For "Python", use syntax of the form "PythonFilename.py.FunctionName" or "PythonFilename.py.ClassName.MethodName"
-
For "ObjectScript", use syntax of the form "##class(Package.Class).MethodName()"
-
For "SQL", use syntax of the form "SQLFilename.sql"
-
For "BPL", use the logical name of the BPL: "MyBPLName"
-
-
parameters—Specifies an array of parameters to pass to the given code, in the same order expected by that code. The context object provides the values for these parameters.
-
Implementing in Python
To implement an impact rule in Python, create a Python function as follows:
-
The function must accept arguments as follows:
-
All the values specified in parameters array, in that order.
-
Two additional arguments at the end (samRunContext and snapshot).
-
-
The function must return a value that represents the impact, given the inputs.
For example (with artificial line breaks):
import sys
import iris
def calculateTimeImpact(supplierId, productId, samRunContext, snapshot):
iris.cls("SC.Core.Analytics.SAM.Util.SAMLogger").LogInfo(samRunContext,
snapshot.uid,
"Calculating time impact for supplier " + supplierId + " and product " + productId)
query = "SELECT leadTime FROM SC_Data.ProductSupplier WHERE supplierId = ? AND productId =?"
params = [supplierId, productId]
result = snapshot.Query(query, params)
if not result._Next():
iris.cls("SC.Core.Analytics.SAM.Util.SAMLogger").LogError(samRunContext,
snapshot.uid,
"Some error occurred while fetching lead time from ProductSupplier table")
return sys.float_info.max
time = result._Get('leadTime')
iris.cls("SC.Core.Analytics.SAM.Util.SAMLogger").LogInfo(samRunContext,
snapshot.uid,
"Time impact for supplier " + supplierId + " and product " + productId + " is: " + str(time) + " days")
return time
Implementing in ObjectScript
To implement an impact rule in ObjectScript, create a class method as follows:
-
The method must be defined as a class method, not an instance method.
-
The method must accept arguments as follows:
-
All the values specified in parameters array, in that order.
-
Two additional arguments at the end (samRunContext and snapshot).
-
-
The method must return a value that represents the impact, given the inputs.
For example (with artificial line breaks for readability):
ClassMethod CalculateCostImpact(originLocationId As %String,
destinationLocationId As %String,
productId As %String,
quantity As %String,
samRunContext As %DynamicObject,
snapshot As SC.Core.Analytics.SAM.Data.Internal.Snapshot) As %String
{
do ##class(SC.Core.Analytics.SAM.Util.SAMLogger).LogInfo(samRunContext,
snapshot.uid,
"Calculating cost for moving inventory from "_originLocationId_" to "_destinationLocationId)
set params = ##class(%DynamicArray).%New()
set query = "SELECT unitCost FROM SC_Data.ShippingCost WHERE originLocationId = ? AND destinationLocationId = ? AND productId = ?"
do params.%Push(originLocationId)
do params.%Push(destinationLocationId)
do params.%Push(productId)
set result = snapshot.Query(query, params)
if result.%SQLCODE < 0 {
do ##class(SC.Core.Analytics.SAM.Util.SAMLogger).LogError(samRunContext,
snapshot.uid,
"Error while running Cost Impact: "_result.%Message)
return $$$ERROR($$$SQLCode, result.SQLCODE, result.%Message)
}
do result.%Next()
set unitCost = result.%Get("unitCost")
do ##class(SC.Core.Analytics.SAM.Util.SAMLogger).LogInfo(samRunContext,
snapshot.uid,
"Cost Impact: "_(unitCost * quantity)_" for moving inventory from "_originLocationId_" to "_destinationLocationId)
return unitCost * quantity
}
Implementing in SQL
To implement an impact rule in SQL, create a .sql file containing one SQL SELECT statement as follows:
-
The statement must accept all the parameters provided by the parameters array, in that order.
-
The statement must select one field containing a single value, which is the impact, given the inputs.
Implementing in BPL
To implement an impact rule in BPL, create a BPL business process as follows:
-
The business process request class must be SC.Core.BP.Message.ImpactRequest. This class has three properties, automatically set by the scenario analysis module:
-
snapshotId, which is the ID of the snapshot to which this data belongs.
-
parameters, which is a list of parameters, provided by the parameters array of the template, in that order.
The parameters property provides the %Collection.ListOfDTOpens in a new tab methods; use those methods to access individual parameters.
-
samRunContext, which is the samRunContext as a %DynamicObjectOpens in a new tab.
-
-
The response class must be SC.Core.BP.Message.ImpactResponse.
-
The process must set the impactResult property of the response.
Checklist
-
Create the Python function, method, SQL, or BPL
-
If you use BPL, add it to the Supply Chain production and enable it.
-
Within this code, log any errors as well as any intermediate steps that are useful for debugging.
-
Make sure that this code is located appropriately so that it can be found when you use the template.
-
Update the template as shown above.