Tuesday, March 30, 2010

Type Specs and Predefaults

There are many times when you need to constrain an applet by type. I will explain a declarative technique for doing so in three general situations. In all of these cases, we want to constrain the applet to only show records of a particular type and we want new records to predefault to that type.

Single Valued - Pick Applet: Lets say you have two different type of contacts, 'X Type' and 'Y Type'. I want to be able to pick the 'X Type' contact for an account and the 'Y Type' contact for an account into two different account fields (one for each). I will need to create two new pick lists:

Name: PickList X Type Contact
Business Component: Contact
Long List: Y
Bounded: Y
Type Field: Type
Type Value: X Type

Name: PickList Y Type Contact
Business Component: Contact
Long List: Y
Bounded: Y
Type Field: Type
Type Value: Y Type

On the Account, for the field 'X Contact' set the picklist to 'PickList X Type Contact', set the pick map appropriately, expose a contact pick applet on the account field, etc., and do the same for the account field 'Y Contact'. When the pick applet opens, it will only show Contacts with the respective type field and new contacts created within this pick applet will have there type predefaulted. This is the only way you can declaratively get a predefault of different types. Picklist objects are very "thin" so having a lot of them with different type specs or search specs does not really result in a lot of maintenance overhead. You can even use the same pick applet for both fields.

Multi Valued - MVG/Associate Applet: When the Contacts you wish to add to your hypothetical account are multi valued instead of single valued, a pick list will not help you. Instead you need to use the Type Field/Value on the Multi Value Link. So on the Account, let say you have a Contact MV Link called 'Z Contacts'. Set the properties thus:

Type Field: Type
Type Value: Z Type

This will predefault new contact created within the Associate applet to 'Z Type'. You will also need to add a Search Spec to the Associate applet to constrain the records to 'Z Type'. It is important to do both in this scenario as the MV Link Type spec alone will not update the type of existing records.

Standard List/Form Applet: When constraining and predefaulting a value on a regular applet as opposed to a popup applet, you need to leverage Aspect user properties. These were new properties documented after 7.7 I think and bookshelf does a decent job of documenting them. Basically you need to do the following for each applet representing each different type respectively:
  • Applet class is either CSSFrameListBase or CSSFrameBase
  • Create an Applet User Property:
    Name: Default Aspect
    Value: X Type
  • Create a Field user property on the Contact BC, Type field:
    Name: Aspect Default Value: X Type
    Value: X Type
The Default Aspect property value must match the Field Aspect Default Value expression after the colon (in this case X Type). This confiuration will predefault new records to be a particular type but will not constrain the records that appear. If you need to constrain the records as well, you can add a standard search spec either to the applet or if it is a child applet, to the link.

Customized Version Control - Tertiary

In a previous post, I discussed how to implement binary or bimodal version control. This means that there are two states, Active and Inactive. This is useful for objects like quotes where you really just need to know which is the most recent. In other situations, especially involving complex meta data, the timing of deploying the new version is critical and therefore requires the entire data structure to be completed before deploying. This requires a third mode, a Pending or In Progress status and an Activation step. You see this in Siebel already in Assignment Manager where Rules need to be Activated. You also see this in Data Validation Manager (DVM), which I actually was able to mimic.


In DVM admin, creating a new record puts the status as 'In Progress'. Pressing the 'Activate' button changes the status of this record to 'Active' and the status of any other records with this name to 'Outdated'. This is all enabled by the specialized class of the FINS Validation Rule Set business component, CSSFABCValidation. I was able to create a custom BC and set the class to this custom value, and mimic this versioning behavior. The other setup steps for a binary versioning setup are still required, including setting up the sequence and version field for that BC, and setting up BC User Props 'Active Field' and 'Revision Field'. There are some additional BC user properties that are necessary to make this work.


Status Field. This is undocumented as far as I can see but the value of this property identifies the BC field holding the status value of the version. This is the field that will hold the values 'Active', 'In Progress' and 'Outdated'


Name Field. The value of this property identifies the BC field holding the logical key of the versioned data structure, typically the name or a unique number that will remain the same across all versions of a structure.


If this data structure has child records, insure that Deep Copy and Deep Delete properties are setup correctly

Monday, March 29, 2010

Dynamic Drilldowns - No Default Drilldown

When configuring a dynamic drilldown, there is a Siebel limitation that the destination view on the default drilldown object be accessible. So if the else condition occurs, or if the default drilldown object is explicitly referenced by the dynamic drilldown destination, then the view used in the drilldown object must exist in the current user's responsibility.

But what if you don't want anything to happen when the else condition occurs, or when Siebel reverts to the default condition. In this case you can specify the view housing the applet you are working on, without specifying any sourcec/destination fields or BC. This way when the default condition occurs, the system drills you down to the same view, but because no source/destination is set, no additional query is executed. WHat this looks like visually in the UI is a blue hyperlink field that when clicked, nothing happens.

Let's see how this is configured. In this scenario, we will need three Drilldown Object records:

Name: Account
Hyperlink Field: Account
View: Contact List View

Name: Custom Type X
View: Custom Account Detail View X
Source Field: Account Id
Business Component: Account

Name: Custom Type Y
View: Custom Account Detail View Y
Source Field: Account Id
Business Component: Account

For the first Drilldown Object record, Account, Navigate to Dynamic Drilldown Destinations, and create the following records:

Name: Custom Type X
Field: Contact Type
Value: X
Destination Drilldown Object: Custom Type X

Name: Custom Type Y
Field: Contact Type
Value: Y
Destination Drilldown Object: Custom Type Y

This configuration will navigate the user to the view 'Custom Account Detail View Y' if the field 'Contact Type' = 'Y' and to the view 'Custom Account Detail View X' if the field 'Contact Type' = 'X', otherwise the drilldown will do nothing.

NOTE: One think to keep in mind when doing this is that since the default link is meant to be self-referential, this only makes sense if the applet is leveraged in a single view. If the applet is used in multiple views, then the default drilldown will actually navigate you away from the view you were on.

Dynamic Drilldowns - Theory and Instructions

After doing a search on supportweb to help a coworker today, I realized the documentation on this functionality was especially... unclear. So let me try to make it more so.

This is an area that changed between siebel 2k and 7 and I actually think the 2k configuration steps were more clear. Anyhow, the order of operations Siebel uses to determine the dynamic drilldown is
  1. Lookup the Drilldown object by Hyperlink Field (There should only be one for any field)
  2. Resolve the dynamic drilldown object Field / Value pairs to determine the correct Destination Drilldown Object
  3. Use the correct Destination Drilldown Object to determine the View and source/destination fields/BC properties from the linked Drilldown Object record.
  4. Navigate to the view
One way to think of the Dynamic drilldown object in Tools is like an If/Else statement. Siebel checks the conditions of the field / value pairs, and navigates to that drilldown object if a match is found. If no condition matches, the else, then the destination view of the current Drilldown Object record is used. This implies that Only the Drilldown Object with the Hyperlink field specified should have dynamic drilldown object records. The other drilldown object records representing different view destination views should not have dynamic drilldown object records configured. It is also not strictly necessary that there be a Dynamic Drilldown Object condition that explicitly specifies it's parent Drilldown Object as the Parent Drilldown Object will always satisfy the else anyway. If for clarity's sake it is considered desireable to see this configuration though, it does not hurt.

Here is an example for a dynamic drilldown on a contact list applet that drills down to two different account views based on a contact type field.

Navigate to Applet, Drilldown Object, Create the following records:

Name: Account
Hyperlink Field: Account
View: Custom Account Detail View X
Source Field: Account Id
Business Component: Account

Name: Custom Type Y
View: Custom Account Detail View Y
Source Field: Account Id
Business Component: Account

For the first Drilldown Object record, Account, Navigate to Dynamic Drilldown Destinations, and create the following record:

Name: Custom Type Y
Field: Contact Type
Value: Y
Destination Drilldown Object: Custom Type Y

This configuration will navigate the user to the view 'Custom Account Detail View Y' if the field 'Contact Type' = 'Y' and to the view 'Custom Account Detail View X' if the field 'Contact Type' is anything else, including the value 'X'.

Wednesday, March 17, 2010

Using a Sequence

Sequences have a lot of use in added logical order to a complex structure. Typically you have a master/parent record at the top of a view, and you need to have numbered child records. Each parent record would have a unique set of numbered children. Sequences can also be used for version control. Here are the steps to making a sequence BC:

Create a BC of class CSSSequence whose name is a concatenation of the source BC name plus '.Version (Sequence)' where Version is the name of the source BC field holding the sequence value. So for example, 'Quote.Version (Sequence)' would be a BC name. In addition set the Sort Spec to Sequence (DESCENDING) and the Table to the same table as the source BC. Create he following fields in the new sequence BC:

Name = Sequence
Column =
Type = DTYPE_INTEGER

Also create fields for the logical key field making the sequence unique. Usually Name or Id or some unique Number. This is how the system finds the next sequence: looks at the source BC with this field value, finds the maximum sequence value and adds one.

Create a link between the Base BC and the Sequence BC, with the Source Field and Destination fields holding the same value. Again this is the logical key indicating when the sequence should reset. Typically Name or Id or a unique Number.

Add the new sequence BC to the Business Object where the sequence will be used linked by the newly created link.

Customized Version Control - Binary

As of at least 7.8 you can now implement your own forms of version control for custom objects. Bookshelf provides some specifications for BC User properties in the Developer's Reference, User Properties, Business Component User Properties:

Revision Condition
Revision Copy
Revision Field

Using these with the Vanilla method, Revise, allows you to achieve funcitonality similar to what you see in a quote. To implement, create a custom minibutton on an applet and set the method to be 'Revise'.

On the BC the applet is based on, create a User Property

name = Revision Field
value = Version

Where version is the name of a BC field storing a sequence. Create a sequence BC and link for the source BC.

Revision Condition is an optional user propery that allows to to disable the Revise button under certain conditions. Here is an example if you only wanted the button enabled when the Status = 'Active'. You can have as many of these as you like and the system will interpret an AND condition between each of them.

Name = Revision Condition 1
Value = "Status", "Active"

Pressing the Revise button will make the current record Read Only, and create an editable copy. The copy is immediately 'Active' and the revised original is immediately old. This functionality can be combined with the user property Active Field to make control the editability of these records. To do that, create or identify a flag field on the BC; I'll use Edit Flag as my example. Create a new BC user property:

Name = Active Field
Value = Edit Flag

Now when you create the revision, the new Active copy is editable and the old copy is read only, or archived.

This is a binary way to look at archiving which may be useful in many instances (Quotes obviously), but there are other times when a tertiary state is needed. That is you may want to tweek the settings of the new version before activating it, leaving the previous version active until ready to activate the revision. That will be the subject of another post.

Monday, March 15, 2010

Picklist Pre Default Field

I just got an opportunity to use this undocumented user property for the first time and thought it useful to explain how it is used. Let's say you have an object like a Service Request where you have a pick applet that allows the creation of a record in another object, like a contact. In addition you have constrained the SR Contact to only show contacts for the already selected SR Account. When you create a new contact in the Pick Applet, you presumeably want the Account to be predefaulted to the SR Account since you have it constrained to be so, but Siebel does not do this automatically.

The trick is getting the Contact field to predefault to a field on the Service Request, in this case, Account. To do this, create new User Properties on the Contact BC:

Name: Picklist Pre Default Field 1
Value: "Account Id", "'Service Request.Account Id', 'Action.Account Id'"

Name: Picklist Pre Default Field 2
Value: "Account", "'Service Request.Account', 'Action.Account'"

Name: Picklist Pre Default Field 3
Value: "Account Location", "'Service Request.Account Location', 'Action.Account Location'"

The value expression is the field on the target BC to set (Contact in this case), followed by a comma separated list of Source BC.Field pairs enclosed in quotes. Notice the quotes. Entire expression enclosed in double quotes, and each BC.Field pair enclosed in single quotes. I made sure that the fields on the Source BC had the link spec checked just in case.

I am using a 1:M Account:Contact relationship in this example so I am not sure whether this works when Account:Contact is M:M. Additional testing would be necessary. Also this is an undocumented user property as of 8.0 so not sure whether it will work on all BC classes but I tried it on Contact and it definately worked there.

Detail Tabs from Aggregate Views

Problem: In vanilla Siebel, every aggregate view is mainly a list applet over a form applet where the Name field (or some other logical key field) is a drilldown that when actioned, takes the user to a Master Detail view where they can then navigate to different Detail tabs. The initial Aggregate view does not have the view tabs exposed. This means that the User always has to click twice to get to the desired view.

Solution: Change the View Web Template to 'View Parent List With Tabs' for every view set up as an Aggregate view. This template has both the dropdown in the upper right corner to change the visibility view, and the detail tab bar. So from a view based on this template I can change the view from My to All for instance, select a record from the top list applet, and click directly on the detail tab in question.

Why: In call center environment's especially, the application should be optimized for a minimum number of clicks to minimize average handle time. This eliminates one click.

Hello World

I had an epiphany last night that the best way to market my 10 plus years as a Siebel Architect is to teach others how to do some of the things I have picked up along the way, and in the process build a network.  So this blog will be a how to, a repository of 'cool' stuff, and a sermon on design philosophy all rolled into one.  Its audience is aimed to be technical, to understand basic Siebel and IT jargon.

I wish I had been doing this all along as 10 years worth of client implementations and upgrades have taught me a lot, most of which I have since forgotten.  I know that using Siebel, and now Oracle's, support documentation is painful at best.  Bookshelf is organized as a specification, but frequently when you want to do something, you need to make changes to many objects, and there is no subject oriented instructions out there unless you get lucky and find one on Metalink/supportweb.  So hopefully this will serve as another repository of answers.

Regarding comments, I make no promises that I will follow them closely and answer questions, though that position may evolve as I figure out how to make this blog work for me.