Saturday, December 22, 2012

How to add number of Hours to a Date Field


I am back with a very basic requirement which might looks very easy, but the solution might not be that easy to implement.

Requirement:
I have a Service Request form applet where I have following fields exposed on the UI:
  • Severity - LOV field values: a) 1-Critical b) 2-High c) 3-Medium d) 4-Low
  • Commit Date - Date Time field
Depending upon the Severity, being set by the user, system need to stamp the "Commit Date" field which is based on the calculation as per below table
If Severity Equals
Then SLA Hour =
Set Commit Date to [Created Date] + SLA Hour
1-Critical
10
[Created Date] + 10 Hours
2-High
20
[Created Date] + 20 Hours
3-Medium
30
[Created Date] + 30 Hours
4-Low
40
[Created Date] + 40 Hours
All this needs to happen whenever user changes the value for “Severity” field.

You can think of various ways to achieve this:
  1. The famous old method says extract the Year, Month, Date, Hours, Minutes and Seconds out of the “Created Date” field, get the SLA Hour depending upon the “Severity” value and do the calculation (add SLA Hour to the "Hours" variable ) and then combine the parts to get the date back. But the Problem with this method is, you need to be very careful with the calculation because while adding the "Hours" get exceeded by 24, then you need to increase the date by 1 and if then again adding 1 Day to the date reaches the month limit, you need to increase the month by 1 and so on ........................ problem, problem, problem :|
  2. I was also thinking to first convert the "Created Date" variable into "Seconds", then add the ("SLA Hour" * 60 * 60) to it and re-convert it back to Date. But didn't find the required function/methods available OOB for this in eScript. So, I dropped this idea as well.
So, the only tricky part here is how to get the number of “Hours” get added to a Date and after some of the experiment I was able to achieve it with some simple and easy method.

Here you go:
  1. Get the master data setup in the LOV:
  2. Create two calculated fields:
    Name
    Calculated
    Calc Value
    Type
    SLA Hour
    True
    LookupValue("SLA", [Severity])
    DTYPE_NUMBER
    Temp Commit Date
    True
    [Created] + ([SLA Hour]/24)
    DTYPE_DATETIME
  3. Check the “Immediate Post Changes” = True for field “Severity"
  4. Create a Business Component User Property:
Name       :           On Field Update Set
Value       :           "Severity", "Commit Date", "[Temp Commit Date]"

That’s it. Make sure you have the “Immediate Post Changes” checked for “Severity” and be careful about the “Type” for the two calculated field created, otherwise it won’t work.





Sunday, January 22, 2012

Understanding EAI Transaction Service

Recently I got the chance to work on a EAI requirement which requires the use of business service:  "EAI Transaction Service"

This post might help you if you are hearing this business service for the first time.

First of all, let me tell you what was the requirement for which I used this business service and later will tell you how it works.

Requirement
We have integration between a third-party system which keeps the Quotes, created in Siebel. So whenever a Quote record is UPDATED, it should also get reflect in the third-party system. The synchronous transaction is being send via real-time Web Service call at the WriteRecord event of Quote BC. The requirement was, while sending the updated Quote XML to the other system, check for the web service response. If the response = "Success", it is fine, but if response = "Failed", then revert back the changes done by user on the UI. So lets suppose user has changed 3-4 fields on Quote list applet and saved the record, and while integration call, system receives the respone = "Failed", then system has to revert back the values of these 3-4 fields.

Now, let us see how EAI Transaction Service help in this scenario:

I will not discuss the integration details but just the technical details related to EAI Transaction Service. Please assume that we already have a function: "SendToInterface()" created which will take care of sending the Quote XML to the other system. Now, here is what you need to do:

1. BusComp Server Script -> General -> Declarations:


var svcEAITransService = TheApplication().GetService("EAI Transaction Service");
var psInp = TheApplication().NewPropertySet();
var psOut = TheApplication().NewPropertySet();

2. BusComp_PreWriteRecord:


function BusComp_PreWriteRecord ()
{
svcEAITransService.InvokeMethod("BeginTransaction", psInp, psOut);
return (ContinueOperation);
}

3. BusComp_WriteRecord()


var strResult = SendToInterface();
psInp.Reset();
psOut.Reset();
if (strResult == "Failed")
psInp.SetProperty("Is Abort", "True");
svcEAITransService.InvokeMethod("EndTransaction", psInp, psOut);
this.InvokeMethod("RefreshRecord");




So, from the point you invoke "BeginTransaction" method, system keeps a check-point for you, till the time you invoke "EndTransaction" method. And as soon as EndTransaction get executed, the data gets commit actually to the database. 

Points to ponder:
  1. If BeginTransaction method has been executed, then execution of EndTransaction method is MUST for getting the data commit into the database. If for any reason, it not get executed or thin-client session get closed, data will never go to database.
  2. In the same session, the updated value is available for the Business Component and if you do a GetFieldValue in the current instance or try to fetch value via Integration Object, you will get the updated value.
  3. In case you have a Workflow Policy based on some field you have updated, it will only get trigger after the event of execution of method: EndTransaction.


Query
Somebody might come back and ask why should even I use this business service, why don't I just call the "SendToInterface()" function in PreWriteRecord event itself and check for the web service response right there? If success, then let the WriteRecord event fire else prompt a message using RaiseErrorText?

Clarification
Well, the above statement might sounds correct, but keep in mind EAI Siebel Adapter will run a separate query to fetch the data in SiebelMessage, so unless and until, the WriteRecord event fires (in the current session) it won't be able to get the updated values in SiebelMessage.

Hope this helps.



Friday, August 19, 2011

How to update Child BC records on update of Parent BC record?

Siebel provides various ways of achieving the same solution, but you need to do the analysis beforehand to pick the right one. Recently I got one basic requirement that:

As soon as the Opportunity Sales Stage gets "Approved", all the Activities (Child of Opportunity) status should automatically set to "Approved".
Any Siebel Geek can offer multiple ways to achieve this solution:
1. Write a small script on "WriteRecord" event of the Opportunity business component.

2. People against scripting will not like Point#1 above and they might suggest to create a Workflow process with an Update operation on Action business component. And call this Workflow process in WriteRecord event of Opportunity or by Runtime event or by Workflow Policy.

3. Trigger a Workflow Policy when Opportunity Sales Stage = "Approved" which will call a WF Policy action with a program of type DB Operation.

I found another way of achieving the same solution (scriptless) and want to share with you. Using Data Validation Manager (DVM), you can achieve this as well. If you know how to update a field (SetFieldValue) using DVM, you might know what I am talking about.

Solution Details: 1. Navigate to Administration - Data Validation -> Rule Sets view.
2. Create a new record with the following data:

Name : Set Activity Approved
Business Component : Opportunity
Business Object : Opportunity

3. Drilldown on Rule Set Name.
4. Create new record under Rules view.

Sequence# : 1
Name : Set Status to Approve
Expression : [Status]="Approved"
Business Component : Action
Apply To : All Records
Return Code : Select any return code from the pick applet

5. Navigate to "Action" sub-view under the "Rules" view.
6. Create new record in Action applet:

Sequence# : 1
Type : Business Component
Business Component : Action
7. Create new record in "Field Values" applet
Field : Status
Value : Approved

8. Navigate to Administration - Data Validation -> Rule Sets view again and Activate the Rule set you just created.

9. Status changes to "Active".
10. Navigate to Administration - Runtime Events -> Action Sets view.
11. Create a new record:


Name : Activity Approved
Active : True
12. Create new action record:

Name : Call DVM
Action Type : BusService
Sequence : 1
Active : True
Business Service Name : Data Validation Manager
Business Service Method : Validate
Business Service Contect : "Rule Set Name", "Set Activity Approved", "Enable Log", "Y"
13. Navigate to Administration - Runtime Events -> Events view.
14. Create new record:

Sequence : -1
Object Type : BusComp
Object Name : Opportunity
Event : WriteRecord
Conditional Expression : [Sales Stage]="Approved"
Action Set Name : Activity Approved

15. Reload the runtime events.

You are done.

Now this is the time to test the solution:
1. Navigate to Opportunity -> Activities View.
2. Change the Sales Stage to "Approved".

3. See the change in activities status.