31 January 2011

Siebel: Script Libraries

Siebel 8 (or ST engine to be more specific) has a elegant way of calling business service methods. Script libraries provide the ability to call functions on a business service directly, no more is the need for building property sets and setting the parameters!

If you have not already used script libraries, do take a look. The reduced coding implies lesser mistakes, debugging time and easier maintenance! The simple demo below illustrates the usage.

Step 1:
Create the target business service 'COG Test Script Lib'. A custom function 'Echo' is defined here.

Service_PreInvokeMethod:

function Service_PreInvokeMethod (MethodName, Inputs, Outputs)

{

return (CancelOperation);

}

Echo:
function Echo (MyString)

{

return "Echoed: " + MyString;

}



Step 2:
Create the caller service 'COG Test Script Lib Call'. There is only one method here - 'Service_PreInvokeMethod', and the following code has to be input:

function Service_PreInvokeMethod (MethodName, Inputs, Outputs) {

var bsTest = TheApplication().GetService("COG Test Script Lib");

Outputs.SetProperty("Output", bsTest.Echo("abc"));

bsTest = null;

return (CancelOperation);

}



Compare this to the approach in earlier versions. In most probability you will be coding something like:

function Service_PreInvokeMethod (MethodName, Inputs, Outputs)

{

var bsTest = TheApplication().GetService("COG Test Script Lib");

var psIn = TheApplication().NewPropertySet();

var psOut = TheApplication().NewPropertySet();

psIn.SetProperty("MyString", "abc");

bsTest.InvokeMethod(psIn, psOut);

Outputs.SetProperty("Output", psOut.GetProperty("ReturnString"));

psOut = null;

psIn = null;

bsTest = null;

return (CancelOperation);

}


And, don't forget to add a line or two in the target service 'COG Test Script Lib' to set required properties in the output propertyset. Now, a simple 'bsTest.Echo("abc")' does the job. Isn't life simpler?

24 January 2011

Siebel: Prototype in eScript

I had mentioned about using prototypes in one of the previous posts, here's a drilldown into how things work.
Tucked away in a remote corner in the eScript reference of the Siebel Bookshelf is a single paragraph referring to prototypes. Common to javascript developers, prototype is not something that we bother about too often. Prototypes provide a highly reusable way of extending out of the box objects, with an optimal memory usage as a bonus.

How do we use Prototypes?
The best way to understand will be through an example. Let us consider a problem where we need to add x days to the given date and get the next working day (!= Saturday or Sunday).
We go about this problem by extending the Date object to support a new functionality - add x days and retrieve the next working day. For simplicity sake we keep the definition of prototype and the actual call together, however they may be located in different objects as well.
To demo the prototype define custom business service 'COG Get Working Day' in Siebel Tools or Client. Paste the following code in relevant sections:
(declarations)


Date.prototype.AddDaysToGetWrkDay = AddDaysToGetWrkDay;

AddDaysToGetWrkDay


function AddDaysToGetWrkDay(iDays, Outputs)

{

var iDateNew; var iOneDay = 24 * 60 * 60 * 1000; // day in milliseconds -
(hrs/day * min * sec * ms)
this.setMilliseconds(iDays * iOneDay);
if
(this.getDay() == 0 this.getDay() == 6) { // if sunday or saturday

this.AddDaysToGetWrkDay(1); // add one more day and check whether that falls
on working day

}

return this;

}

Service_PreInvokeMethod
function Service_PreInvokeMethod (MethodName, Inputs, Outputs)
{
try {
var dSomeDate = new Date("1/28/2011");
dSomeDate.AddDaysToGetWrkDay(1);
Outputs.SetProperty("New Date", dSomeDate);
return (CancelOperation);
}
catch(e){
throw(e);
}
finally {
dSomeDate = null;
}
}


When executed through simulator (or a call from placed from another service), the service returns the next working day - in the above example 31-Jan-2011. Read on to find out how.


Code Explanation

  1. 'Date.prototype.AddDaysToGetWrkDay = AddDaysToGetWrkDay' is the statement that tells the execution engine that there is a new prototype for Date object, and the extended functionality is provided by the function (or object) called 'AddDaysToGetWrkDay'. This is not synonymous with calling a function since there is no actual execution at this point. It is equivalent to a declaration.
  2. Next, define the function 'AddDaysToGetWrkDay'. This will act on the provided date object, which is referenced using 'this'. All it does is to add the given number of days to the date, check whether the new date falls on a Saturday or Sunday, continue adding more days if that is the case, and return the final date. Recursion is used to keep on adding days until it is not required.
  3. 'Service_PreInvokeMethod' just calls the extended function 'AddDaysToGetWrkDay' against the date object. When the actual call is made, the scripting engine looks at the Date object itself to check whether such a method is present, and then consults the prototype. Since such a prototype exists and points to a function, the function is executed to return the result

Note that the prototype itself may be defined only once, and the functionality is available thereon. Though this example is simple at its best, it does demonstrate how prototypes can be used to extend the objects.

Conclusion

Keep in mind the following:

  • Prototypes share the same memory space. Multiple invocations do not mean multiple copies
  • Prototypes can also be added later. Dynamic invocation can mean that you don't need to do everything in one place and at once
  • A prototype can also be extended further. For example, I can very well define another which says 'AddDaysToGetWrkDay.prototype.ExcludeDay' to selectively exclude certain days. For example, myDate.AddDaysToGetWrkDay(21).ExcludeDay("Tuesday") can return the working day 21 days from the given date, but which is not a Tuesday
  • From the above point you can observe that the methods can be executed in a 'chained' manner, which gives us a scalable solution that is easy to maintain (remember my OO reference in an earlier post?)
  • Use prototypes for reusable functions, that is when they yield better results

So, how do you want to use prototypes in your application?

17 January 2011

Siebel: Custom Functions for TheApplication

If you want to reuse code in Siebel, one of the common practices is to put it away in the business service and invoke those methods. This method, though is invaluable for complex operations, will become a painful process for simple things. When I say painful, it applies in some measure for both developers and the execution engine, reasons outlined below:
  1. Additional business service objects have to be created during execution, this may put some overhead in terms of performance (business service caching kept aside for now)
  2. Invoking most of the business services out there involves creation of property sets and calling them in a "proper" way. With the increased lines of code comes the increased complexity
  3. Developers have to "know" about the business service. This is a big problem in the longer term since code again gets littered everywhere inspite of the same functionality in a service
    There is a way to solve some of the above issues for simple reusable code (at least partially) - custom methods on TheApplication object. This uses a simple fact - all functions written in the application object will be available in any entity and method. Let us illustrate this with an example.

Problem: I need to get the description of a specified LOV. Though developers swear by LookupValue (and other Lookup) functions, there is little one can do about the 30 (or 50) char limit imposed by the data model. It is common to use Description (or some such field) for this purpose, but the code reuse is limited.

Solution: Write a LookupDesc function in the application object. Just edit the 'Siebel Life Sciences' (or any application) that is being used by your object manager. Create a new function called 'LookupDesc' and paste this code:

function LookupDesc(Type, Value)
{
try {
var sDesc = "";
var boLOV = TheApplication().GetBusObject("List Of Values");
var bcLOV = boLOV.GetBusComp("List Of Values");
with (bcLOV) {
ClearToQuery();
SetViewMode(AllView);
ActivateField("Description");
SetSearchExpr("[Type]='" + Type + "' AND [Value] = '" + Value + "'");
ExecuteQuery(ForwardOnly);
if (FirstRecord()) sDesc = GetFieldValue("Description");
} //with
return(sDesc);
}
catch(e) {
throw(e);
}
finally {
bcLOV = null;
boLOV = null;
}
}

Now, invoking the above function is by using a single line in applet, bc or a business service -

TheApplication().LookupDesc("MY_TYPE", "My Value")

This is also available in ScriptAssist against TheApplication, to make others aware of this function ofcourse!
A note of caution though - don't overdo this. I would recommend keeping the code here simple and tight, and to those functions where lot of reuse is foreseen.

30 December 2010

Siebel: User Defined Objects

Ever missed all the OOP goodness in Siebel? Although not used frequently, user defined objects provide you with some degree of control with hiding complexities in scripting. No, this will not help you attain OO nirvana - but you can start doing things with the custom objects and prototyping (another post for another day) to:

  • Hide complexity
  • Provide scalability
  • Save memory while doing the above

Here’s a simple example that demonstrates use of user-defined objects. To test, you simply copy the code in a new client business service and you are all set.
First the Service_PreInvoke method:

function Service_PreInvokeMethod (MethodName, Inputs, Outputs)
{
var qryBC;

qryBC = new GetRecord("Contact", "Contact", "[Id] = '0-1'", "First Name", "Last Name");
Outputs.SetProperty("First Name", qryBC.Values[3]);

Outputs.SetProperty("Last Name", qryBC.Values[4]);

return (CancelOperation);

qryBC = null;
}

Next comes the constructor:

function GetRecord ()
{
try {
var arrValue = new Array();
var iCount;

if (arguments.length < 4) TheApplication().RaiseErrorText("I need minimum four arguments - BO name, BC
name, SearchExpr and at least one field name.");

var bo = TheApplication().GetBusObject(arguments[0]);
var bc = bo.GetBusComp(arguments[1]);
with (bc){
ClearToQuery();
SetViewMode(AllView);

SetSearchExpr(arguments[2]);
for (iCount = 3; iCount < arguments.length; iCount++){
ActivateField(arguments[iCount]);
}
ExecuteQuery(ForwardOnly);
}

if (bc.FirstRecord()) {
for (iCount = 3; iCount < arguments.length; iCount++){
arrValue[iCount] = bc.GetFieldValue(arguments[iCount]);
}
}
this.Values = arrValue;
} // try

catch(e){
throw(e);
}

finally{
arrValue = null;
bc = null;
bo = null;
}
}

Now, the explanation:
Purpose:

Provide ability to query any given BO / BC and retrieve the specified field values

How did we do that:

First, we create an object called “qryBC”, which becomes instance of a class “GetRecord” when the constructor “GetRecord()” is executed. Since this is the very first exposure to the class/object concept, we are letting the constructor do all the work rather than splitting it up. At this time we also pass the arguments to the object, whereby the constructor will query and return you the results. For simplicity in further processing, we return an array with the query results. Note the use of ‘this’ in the constructor and the reference to the set values when retrieving results in PreInvoke method.

Never understood why OO beats procedural programming you say? You need to depend your friend Google to find out what you missed.(cross posted elsewhere)

28 December 2010

CRM 2011!

It is that time of the year folks - time when you, I and every IT guy worth his salt tends to get clobbered with analyst talk. This is all about the past year - how they prophesized just right, and how the world is converting to paradise or is getting destroyed in the nuclear winter next year. Since I too am finding myself putting together hard-to-comprehend words one too many times, I thought this is something ought to be addressed pronto (before you sink too deep in the holiday mood that is). Since CRM is what I am doing all the time (it is actually Siebel application development, but it feels liberating to be more generic), this is a short list of what I think should happen to CRM in 2011.

  1. Fusion should come out of its wraps
    Inspite of Elison's jab at the implementable state of Oracle Fusion apps, I quite look forward to it. In the process, I also look forward to throwing out all the experience of developing lousy scripts using eScript/Siebel VB, half-baked COM interfacing programs, workflows with a clunky interface and all the configuration fun that can be had in any version of Siebel apps post v7. I will miss dismissing customer requests with a hard-hitting statement - "the functionality is tagged to SRF, and cannot be changed now". 2011 is a good year to brave up to J2EE, ODI, WebCenter, WebLogic and other hotchpotch. This is number one solely because I am associated with Siebel for too long a time.
  2. SaaS triumps in Large Enterprises
    Yes, I know this has been said since the inception of SFDC and the glorious just-dream-forces unleashed upon us. But it is not hard to listen when businesses (not IT) is shouting at you about why they should be spending so much on CapEx and ongoing maintenance including upgrades. So there will be a slew of studies on SaaS take-over, hybrid architectures and how many millions one saved while firing the software and the dream-teams which were keeping them afloat. Well, this cannot happen in next year alone but will enable me to brag about how it came true to a certain extent at the end of 2011.
  3. Mobile to the Rescue!
    Mobile phones with their ubiquity and affordability, should wield greater power over deciding the CRM strategy. How many of us wants to navigate the shiny website of Airtel when the transactions can be done through mcheck? CRM will get more focussed in the mobile space, true for developed and developing countries alike. App development, here I come!
  4. Social CRM will bring down companies to their knees
    Well, I sort of made it up - companies don't have knees. Service companies especially will struggle to keep an eye on what is going on, and would have to resort to several IT adventures before they can get things right. A piece of copied advice - it is not about IT guys (a.k.a 'dont blame me'), set your focus on what you want to do when customers are talking all good or bad about you.
  5. Paul Greenberg should be crowned the undisputed thought-leader of CRM
    I really like his way of writing - the book and the blog, even with my zero knowledge of baseball. Though I feel he vastly over-rates the power of getting Social, being a undisputed leader will push to the fore-front his genial thoughts on maintaining good customer relationship.

27 December 2010

Siebel: Importing data from files

I am back after a not-so-brief hiatus, and am back hopefully for good :). Here I am with yet another utility - this time something that will help you to import data from files into Siebel, with zero coding required from your end. ‘COG File Import Service’ as it is known, will hopefully simplify your life a bit.

Contrary to popular (and let me add, buggy) excel macros / VB COM programs that are available to load data to Siebel, this is a business service that can be imported to Tools / Client. But at the same time it does not offer as much flexibility, given below are a few things that make this tool stand apart.

Why another tool?
File import is nothing new to Siebel developers. But why use another tool when there are dime-a-dozen you say? Thus goes the story:

  • The first thing that hits you - most of the tools to load Siebel data have inconsistent interfaces, and may require some amount of ‘getting-used-to’
  • External objects or platforms are required to actually see what is going on, and hopefully to change the behavior. For example, you need Excel or Visual Basic software, or have a dependency on Windows platform to execute the code. And all that can be done, provided you understand what has been written there
  • Customers might have their own restrictions in connecting to production systems using third party software and utilities

The Mechanism


COG Import Service is just a business service that can be applied to Siebel v7.5+, but has only been tested with 7.7 and 8.1. The service works with CSV/delimited files and has two distinct ways to handle them:

  1. Simple Update - This is just a wrapper to the OOB CSV reader service, with a couple of enhancements thrown in
  2. Update - A more sophisticated updater, which can do a few more things than what CSV reader can do

The steps involved in both methods are simple:

  1. Read file (all at once)
  2. Map fields to provided content
  3. Use a data map, if specified
  4. Update

Where they differ is in the way they process files.



When to use which method?


.. Simple Update

  • Uses the 'CSV Reader Business Service', and hence needs an integration object (IO) to be available for the input data
  • When the processing is simple and there is no need for processing more than one component/entity (in other words, entity and its children) at one time
  • Processing should be fast
  • Any errors should roll-back all transactions

.. Update

  • Can be used with or without involving IO
  • Delimited with be comma or something else
  • Process entity and one child with one operation


How to Use?


Import the attached XML into Siebel Tools and compile to SRF, or imported into the Client (Site Map > Business Service Administration). Parameters to the service specify the parameters that are needed for a successful run. The file formats/structure has been documented in the service itself.



License


None, you can use it or throw it away. Use it at your own risk, unintentional bugs are all but risks of the trade.

You can watch this space (at your own risk, of course) for new versions - improvements or bug fixes.

26 September 2010

Fusion - at last

Well, the moment we have been waiting for is here - Oracle Fusion CRM finally finds the light of the day (so as to speak) in the recent Oracle Open World. This is a new technology framework folks, put on your best armour and start preparing for all new things coming your way. You can start with http://www.oracle.com/fusion! No, no downloads yet - you should satisfy yourself with the latest sales pitch. Alternately, you can take your frustration to the Siebel 8.3 Statement of Direction (available on support.oracle.com).