In this article, we'll do a scriptless PreSetFieldValue validation as an alternative solution to field-level validation. Clearly, PreSetFieldValue is not always the best fit for user input validations. But when you've been given no choice, here is a declarative and scalable solution to consider.
We'll be using a well-known stack: RunTime Events (RTE) + Data Validation Manager (DVM). And I'll also show you some tricks to work around the limitations.
The first challenge is to fetch a new field value. As you know at the PreSetFieldValue event BusComp holds an original value. Here is a couple of Siebel Support articles explaining the problem:
The solution is in the implicit parameter that runtime event passes by to a business service. And this parameter is [PreSetFieldValue]. Separate thanks to Jason for the hint!
Parameter | Description |
---|---|
Object Name | The name of the object experiencing the event |
Event Type | The type of object (BusComp, Applet, Application) |
ActionSet | The name of the action set |
EventId | The ROW_ID of the event |
Sub Event | The content of the Sub Event field (method, field, view name) |
Action | The name of the action |
Event Name | The name of the event such as PreWriteRecord, InvokeMethod etc |
Context | The content of the Business Service Context field. Alex has a great article on how to take an advantage of it. |
Business Component Name | An active BucComp name. Only available when [Object Type] = "Applet" or "BusComp" |
PreSetFieldValue | A new field value. Only available when [Event] = "PreSetFieldValue" |
There are probably other event-specific parameters out there |
Next problem is that the DVM business service can't handle implicit RTE parameters. I presume since DVM business service handles the Context parameter natively, it probably replaces the implicit inputs PropertySet with the new one constructed from the Context parameter.
Anyway, it shouldn't stop us. We can call another BS that accepts RTE parameters and converts them into profile attributes(PA) and then we can use the PA in the DVM rule. Feel free to create your generic BS which converts input parameter(s) into profile attribute(s) or use [User Registration] business service.
Imagine you've been asked to ensure [Account.Close Reason] is provided when you set [Account.Status] = 'Closed' and presumably locking the record.
So, let's start with creating a Runtime ActionSet "Account Close Reason Validation" with two actions as below:
Sequence | Action Type | Business Service Name | Business Service Method | Business Service Context |
---|---|---|---|---|
1 | BusService | User Registration | SetProfileAttr | |
2 | BusService | Data Validation Manager | Validate | RuleSet,Account Close Reason Validation |
Now we can create a Runtime Event:
Object Type | Object Name | Event | Subevent | Action Set Name |
---|---|---|---|---|
BusComp | Account | PreSetFieldValue | Status | Account Close Reason Validation |
And finally a DVM RuleSet with one rule:
Name | Stop On Error | Immediate Display | Rule Expression |
---|---|---|---|
Account Close Reason Validation | Y | Y | GetProfileAttr("PreSetFieldValue") <> "Closed" OR [Close Reason] IS NOT NULL |
Done! Another scriptless solution in your toolbox!
P.S.: Beware that GetPofileAttr function always returns string. To retrieve other data types, please use type specific functions.
If you ever had a requirement to constrain an assocoation applet, you might be familiar with one of the methods:
To be honest, I always felt guilty using above methods and kept looking for a more declarative way. And finally found it.
Let's say you need to constrain a [Contact Assoc Applet] with Opportunity's primary organisation => so you'll assoc only contacts which are from the same org as your opportunity.
First thing you'll need to do is to change an applet class to be CSSSWEFrameSIAAssocList.
Now create a couple of applet user properties:
User Property | Value | Description |
---|---|---|
BC Field Search LHS | [Primary Organization Id] = | Left (static) part of spec. A field mentioned here is from assoc applet's BC. |
Parent BC Constraint Field | Primary Organization Id | Right (dynamic) part of spec is a field name from your list applet's parent BC (Opportunity) |
Applet is ready to be compiled and tested!
As a result Siebel will construct a named search spec as shown in a log below:
... Named search [Associate Constraint Search]: [Primary Organization Id] ='2-9EZ5U1'
Afterword
As I already mentioned, these UserProps are part of a specific class, which means you can't use it together with other useful UserProprs from different classes (for example, Override Visibility)
Also keep in mind that you are now bond to parent BC field name. Association applet will fail, if used in the context, where parent BC doesn't have a referenced field.