יום שישי, 26 באוגוסט 2011

Generating Data to UI mappings in Siebel just got easier!

This is one of those tasks which is fairly simple to do. However, can be very time consuming considering you have to generate a mapping for an entire/multiple repositories. We've all have had to do this at some point, not enjoying it one bit!

Well, here is a code that will save you some time and your sanity :).

The below code generates a screen to Applet, and an Applet to BC mapping which can be then exported to excel.


Screen to Applet - 


select scr.name "Screen Name"
      ,nvl(nvl(ptabi.tab_text, scri.viewbar_text), scr.viewbar_text) "Screen"
      ,scrv.sequence "View Seq"
      ,vw.name "View Name"
      ,vwi.title "View"
      ,vw.busobj_name "Business Object"
      ,vwti.item_num "Item Num"
      ,ap.name "Applet Name"
      ,api.title "Applet"
      ,ap.buscomp_name "Business Component"
from   siebel.s_repository rep
       inner join siebel.s_screen scr on scr.repository_id = rep.row_id
       left outer join siebel.s_screen_intl scri on scri.screen_id = scr.row_id and scri.repository_id = rep.row_id and scri.name = 'ENU-STD'
       inner join siebel.s_screen_view scrv on scrv.screen_id = scr.row_id and scrv.repository_id = rep.row_id
       inner join siebel.s_application appl on rep.row_id = appl.repository_id
       left outer join siebel.s_page_tab ptab on ptab.application_id = appl.row_id and ptab.repository_id = rep.row_id and ptab.screen_name = scr.name
       left outer join siebel.s_page_tab_intl ptabi on ptabi.page_tab_id = ptab.row_id and ptabi.repository_id = rep.row_id and ptabi.name = 'ENU-STD'
       inner join siebel.s_view vw on vw.name = scrv.view_name and vw.repository_id = rep.row_id
       left outer join siebel.s_view_intl vwi on vwi.view_id = vw.row_id and vwi.repository_id = rep.row_id and vwi.name = 'ENU-STD'
       inner join siebel.s_view_web_tmpl vwt on vwt.view_id = vw.row_id and vwt.repository_id = rep.row_id
       left outer join siebel.s_view_wtmpl_it vwti on vwti.view_web_tmpl_id = vwt.row_id and vwti.repository_id = rep.row_id
       inner join siebel.s_applet ap on ap.name = vwti.applet_name and ap.repository_id = rep.row_id
       left outer join siebel.s_applet_intl api on api.applet_id = ap.row_id and api.repository_id = rep.row_id and api.name = 'ENU-STD'
where  rep.name = 'Siebel Repository'
and    appl.name = 'Siebel Power Communications'
and    nvl(rep.inactive_flg,'N') = 'N'
and    nvl(scr.inactive_flg,'N') = 'N'
and    nvl(scri.inactive_flg,'N') = 'N'
and    nvl(scrv.inactive_flg,'N') = 'N'
and    nvl(vw.inactive_flg,'N') = 'N'
and    nvl(vwi.inactive_flg,'N') = 'N'
and    nvl(vwt.inactive_flg,'N') = 'N'
and    nvl(vwti.inactive_flg,'N') = 'N'
and    nvl(ap.inactive_flg,'N') = 'N'
and    nvl(api.inactive_flg,'N') = 'N'
union
select scr.name "Screen Name"
      ,nvl(nvl(ptabi.tab_text, scri.viewbar_text), scr.viewbar_text) "Screen"
      ,scrv.sequence "View Seq"
      ,vw.name "View Name"
      ,vwi.title "View"
      ,vw.busobj_name "Business Object"
      ,vwti.item_num "Item Num"
      ,apta.name "Applet Name"
      ,api.title "Applet"
      ,apta.buscomp_name "Business Component"
from   siebel.s_repository rep
       inner join siebel.s_screen scr on scr.repository_id = rep.row_id
       left outer join siebel.s_screen_intl scri on scri.screen_id = scr.row_id and scri.repository_id = rep.row_id and scri.name = 'ENU-STD'
       inner join siebel.s_screen_view scrv on scrv.screen_id = scr.row_id and scrv.repository_id = rep.row_id
       inner join siebel.s_application appl on rep.row_id = appl.repository_id
       left outer join siebel.s_page_tab ptab on ptab.application_id = appl.row_id and ptab.repository_id = rep.row_id and ptab.screen_name = scr.name
       left outer join siebel.s_page_tab_intl ptabi on ptabi.page_tab_id = ptab.row_id and ptabi.repository_id = rep.row_id and ptabi.name = 'ENU-STD'
       inner join siebel.s_view vw on vw.name = scrv.view_name and vw.repository_id = rep.row_id
       left outer join siebel.s_view_intl vwi on vwi.view_id = vw.row_id and vwi.repository_id = rep.row_id and vwi.name = 'ENU-STD'
       inner join siebel.s_view_web_tmpl vwt on vwt.view_id = vw.row_id and vwt.repository_id = rep.row_id
       left outer join siebel.s_view_wtmpl_it vwti on vwti.view_web_tmpl_id = vwt.row_id and vwti.repository_id = rep.row_id
       inner join siebel.s_applet ap on ap.name = vwti.applet_name and ap.repository_id = rep.row_id
       inner join siebel.s_applet_toggle apt on apt.applet_id = ap.row_id and apt.repository_id = rep.row_id
       inner join siebel.s_applet apta on apta.name = apt.applet_name and apta.repository_id = rep.row_id
       left outer join siebel.s_applet_intl api on api.applet_id = apta.row_id and apta.repository_id = rep.row_id and api.name = 'ENU-STD'
where  rep.name = 'Siebel Repository'
and    appl.name = 'Siebel Power Communications'
and    nvl(rep.inactive_flg,'N') = 'N'
and    nvl(scr.inactive_flg,'N') = 'N'
and    nvl(scri.inactive_flg,'N') = 'N'
and    nvl(scrv.inactive_flg,'N') = 'N'
and    nvl(vw.inactive_flg,'N') = 'N'
and    nvl(vwi.inactive_flg,'N') = 'N'
and    nvl(vwt.inactive_flg,'N') = 'N'
and    nvl(vwti.inactive_flg,'N') = 'N'
and    nvl(ap.inactive_flg,'N') = 'N'
and    nvl(api.inactive_flg,'N') = 'N'
order by "Screen"
        ,"View Seq"
        ,"View Name"
        ,"Item Num"
        ,"Applet Name"


Output looks like -








Applet to BC mapping -

select  "Applet Name"
,"BC Name"
,"BC Field"
,"Required"
,"Calculated"
,"Calculated Value"
,"Join Name"
,"Table"
,"Column"
,"Data Type"
,"Length"
,"Multi-valued"
,"MV Link"
,"Pick List"
,"LOV Name"
,min("Caption") "Caption"
,"Display Order"
from (
select ap.name "Applet Name"
      ,bc.name "BC Name"
      ,fld.name "BC Field"
      ,fld.required "Required"
      ,fld.calculated "Calculated"
      ,fld.calcval "Calculated Value"
      ,fld.join_name "Join Name"
      ,(case when fld.mvlink_name is null then nvl(nvl(jotab.name, fld.join_name), case when fld.calculated = 'Y' then null else bc.table_name end) else null end) "Table"
      ,fld.col_name "Column"
      ,fld.type "Data Type"
      ,(case when fld.prec_num is null then to_char(fld.textlen)
             else to_char(fld.prec_num) || to_char(case when fld.scale is null or fld.scale = 0 then '' else ',' || fld.scale end)
        end) "Length"
      ,fld.multi_valued "Multi-valued"
      ,fld.mvlink_name "MV Link"
      ,pl.name "Pick List"
      ,pl.type_value "LOV Name"
      ,coi.caption "Caption"
      ,co.sequence "Display Order"
from   siebel.s_control co
       inner join siebel.s_control_intl coi on coi.control_id = co.row_id and coi.name = 'ENU-STD'
       inner join siebel.s_applet ap on co.applet_id = ap.row_id
       inner join siebel.s_buscomp bc on ap.buscomp_name = bc.name
       inner join siebel.s_field fld on fld.name = co.field_name and fld.buscomp_id = bc.row_id
       inner join siebel.s_repository rep on bc.repository_id = rep.row_id
       left outer join siebel.s_join jo on jo.buscomp_id = fld.buscomp_id and fld.join_name = jo.name
       left outer join siebel.s_table jotab on jotab.name = jo.dest_tbl_name and jotab.repository_id = rep.row_id
       left outer join siebel.s_picklist pl on fld.picklist_name = pl.name and pl.repository_id = rep.row_id
where  rep.name = 'Siebel Repository'
and    ap.repository_id = rep.row_id
and    co.repository_id = rep.row_id
and    bc.repository_id = rep.row_id
and    fld.repository_id = rep.row_id
and    nvl(co.inactive_flg,'N') = 'N'
and    nvl(ap.inactive_flg,'N') = 'N'
and    nvl(bc.inactive_flg,'N') = 'N'
and    nvl(fld.inactive_flg,'N') = 'N'
and    nvl(rep.inactive_flg,'N') = 'N'
and    nvl(jo.inactive_flg,'N') = 'N'
union all
select ap.name "Applet Name"
      ,bc.name "BC Name"
      ,fld.name "BC Field"
      ,fld.required "Required"
      ,fld.calculated "Calculated"
      ,fld.calcval "Calculated Value"
      ,fld.join_name "Join Name"
      ,(case when fld.mvlink_name is null then nvl(nvl(jotab.name, fld.join_name), case when fld.calculated = 'Y' then null else bc.table_name end) else null end) "Table"
      ,fld.col_name "Column"
      ,fld.type "Data Type"
      ,(case when fld.prec_num is null then to_char(fld.textlen)
             else to_char(fld.prec_num) || to_char(case when fld.scale is null or fld.scale = 0 then '' else ',' || fld.scale end)
        end) "Length"
      ,fld.multi_valued "Multi-valued"
      ,fld.mvlink_name "MV Link"
      ,pl.name "Pick List"
      ,pl.type_value "LOV Name"
      ,coi.display_name "Caption"
      ,co.sequence "Display Order"
from   siebel.s_list li
       inner join siebel.s_applet ap on li.applet_id = ap.row_id
       inner join siebel.s_list_column co on co.list_id = li.row_id
       left outer join siebel.s_list_col_intl coi on coi.list_column_id = co.row_id and coi.name = 'ENU-STD'
       inner join siebel.s_buscomp bc on ap.buscomp_name = bc.name
       inner join siebel.s_field fld on fld.name = co.field_name and fld.buscomp_id = bc.row_id
       inner join siebel.s_repository rep on bc.repository_id = rep.row_id
       left outer join siebel.s_join jo on jo.buscomp_id = fld.buscomp_id and fld.join_name = jo.name
       left outer join siebel.s_table jotab on jotab.name = jo.dest_tbl_name and jotab.repository_id = rep.row_id
       left outer join siebel.s_picklist pl on fld.picklist_name = pl.name and pl.repository_id = rep.row_id
where  rep.name = 'Siebel Repository'
and    li.repository_id = rep.row_id
and    ap.repository_id = rep.row_id
and    co.repository_id = rep.row_id
and    bc.repository_id = rep.row_id
and    fld.repository_id = rep.row_id
and    nvl(li.inactive_flg,'N') = 'N'
and    nvl(co.inactive_flg,'N') = 'N'
and    nvl(ap.inactive_flg,'N') = 'N'
and    nvl(bc.inactive_flg,'N') = 'N'
and    nvl(fld.inactive_flg,'N') = 'N'
and    nvl(rep.inactive_flg,'N') = 'N'
and    nvl(jo.inactive_flg,'N') = 'N'
)
group by  "Applet Name"
,"BC Name"
,"BC Field"
,"Required"
,"Calculated"
,"Calculated Value"
,"Join Name"
,"Table"
,"Column"
,"Data Type"
,"Length"
,"Multi-valued"
,"MV Link"
,"Pick List"
,"LOV Name"
,"Display Order"
order by "Applet Name"
        ,"BC Name"
        ,"MV Link" desc
        ,"Table"
  ,"Display Order"

Output looks like -








So there you go...you could later consolidate both to have a full UI to Data level mapping.

Oh! Almost forgot, Your welcome ;)

Cheers!

יום רביעי, 24 באוגוסט 2011

Dynamically Skills Refresh in AM

It is a real divine feeling to watch how Assignment Manager works. One of the joys of AM is system takes care of assigning everything you have created. But as they say, Devi-lies-in-details, issue starts when you dig deep.


Recently we were asked to implement AM for assignment of Service Request only to Logged in Employees. System should not assign SR to any employee which is not available in system.


First look of this problem seems this to be a cake walk. We created Employee availability as skill which was updated every time when he logs in our logs out of the system. But however on actual implementation we realized that skills of employees were not getting refreshed dynamically. It required "Release" button to be pressed every time in order to flush the employee skills and to update rulecache.dat file. Once again Support Web came to rescue and job was saved.


When the employees to assign are not Dynamic Candidates, AM during assignment looks into the cache for the candidate employees instead reading skills directly from the database. However with certain parameters we can achieve dynamic refresh. I will try to club all the possible ways to refresh the skills(One can definitely add more).


There are three possible ways, based on the flavour of Assignment (dynamic, batch , interactive).


1 - 'Refresh People Skills Interval(MaxSkillsAge)' Parameter - The value for this parameter should be greater than 0 seconds. This will refresh skill in specified seconds.


2 - 'Ignore Assignment Rule Code' Parameter - The value for this parameter should be set to TRUE in order to avoid cache.


The above two solutions work fine for Batch Assignment but still for dynamic assignments we were not able to assign service request properly. One reason was dynamic assignment makes use of WorkMon agent and this component doesn't have above parameters.


3 - This approach should be thoroughly tested prior implementation as it can very taxing on your system if you have large number of assignment rules. The idea is to recursively Release the assignment rules using a batch job which runs below business service.


function Service_PreInvokeMethod (MethodName, Inputs, Outputs)
{
var busobj;
var buscomp;
busobj = TheApplication().GetBusObject("Assignment");
buscomp = busobj.GetBusComp("Assignment Group");
buscomp.InvokeMethod("Release");
return (CancelOperation);
}


Disclaimer: If you have a lot of rules and data to load, it will take AsgnSrvr component some time to completely this process, which also means that AsgnSrvr will not be able to accept any incoming assignment requests during this process startup/shutdown and rulecache.dat update until the cache file is completely updated.


With the above three mechanisms one can dynamically refresh the skills or can always bank on Dynamic Candidate mechanism for smooth assignments.


Happy Assignment!!!

יום שישי, 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

יום ראשון, 14 באוגוסט 2011

BIP Reports as Siebel Attachments

Continuing in the vein of BIP Reporting series, lets discuss another reporting requirement.


"Generate the SLA for the Service Request based on the associated Agreement and add the generated SLA as attachment to the Service Request."


The closest solution which i was able to achieve was based on the support web solution "Siebel BI Publisher 8 Reports Business Service [ID 823360.1]". The key idea here is to generate BIP report and associate that report as attachment to the Service Request. Below workflow was created in order to accomplish the desired task.




Lets discuss each step in detail.


1 - Report Output


This subprocess step invokes the "BIP Create Report Output" workflow process. This workflow creates a new record in the "Report Output BC" buscomp to be used in next step.


Input Arguments


SubProcess Input: Report Name
Type: Literal
Value: SR SLA Report


The input is name of BIP Report to be executed.




Output Arguments


PropertyName: ReportId
Type: Output Argument
Subprocess Output: ReportOutputId


2 - Generate Report


This step is the heart of this workflow. "XMLP Driver Service" business service generates the BIP report on the server based on the search specification given in the Bookmark argument using the integration object as mentioned. Generated report is associated with the row id (ReportId) obtained in the earlier step. One can also see generated report in "My BIP Reports view".This step takes following input argument.


Business Service Name:XMLP Driver Service
Business Service Method: GenerateBIPReport


Input Arguments


InputArgument: BIPUserId
Type: Literal
Value: Name of the BIP User Id


InputArgument: BIPPassword
Type: Literal
Value: Pwd of the BIP User Id


InputArgument: LoginId
Type: Expression
Value: LoginId()


InputArgument: MethodName
Type: Literal
Value: GenerateBIPReport


InputArgument: ReportName
Type: Literal
Value: SR SLA Report


InputArgument: ReportOutputId
Type: Process Property
Value: ReportId


InputArgument: ReportOutputType
Type: Literal
Value: PDF


InputArgument: ReportSelected
Type: Literal
Value: SR SLA Report


InputArgument: ViewMode
Type: Literal
Value: All


InputArgument: LanguageCode
Type: Literal
Value: ENU


InputArgument: Bookmark
Type: Expression
Value: "[Id] = '" + [&Object Id] + "'"


InputArgument: IntegrationObject
Type: Literal
Value: BIP SR IO


InputArgument: LDAPEnabled
Type: Literal
Value: True


3 - Get Report Path


Once the report is generted the next step is to get the path of the report file stored in the file system. This could be easily done using "FINS Industry BC Facility Service" business service. The output of this the absolute path name of the report file.


Business Service Name: FINS Industry BC Facility Service
Busienss Service Method: GetFile


Input Arguments


InputArgument: AttachmentId
Type: Process Property
Property Name: ReportId


InputArgument: BusObjName
Type: Literal
Value: Report Administration


InputArgument: FileBusCompName
Type: Literal
Value: Report Output BC


InputArgument: FileNameField
Type: Literal
Value: ReportOutputFileName


InputArgument: RootBusCompName
Type: Literal
Value: Report Output BC


InputArgument: RowId
Type: Process Property
Property Name: ReportId


Output Arguments


Property Name: Sourcepath
Type: Output Argument
Output Argument: Value


4 - Create Attachment


Once we have the absolute path of report in the file system, next step is to associate report as attachment to the service Request buscomp. This is achieved using the same business service used in earlier step but different method.


Business Service Name: FINS Industry BC Facility Service
Busienss Service Method: CreateFile


Input Arguments


InputArgument: BusObjName
Type: Literal
Value: Service Request


InputArgument: FileBusCompName
Type: Literal
Value: Service Request Attachment


InputArgument: FileNameField
Type: Literal
Value: ActivityFileName


InputArgument: RootBusCompName
Type: Literal
Value: Service Request


InputArgument: RowId
Type: Process Property
Property Name: Object Id


InputArgument: SourcePath
Type: Process Property
Property Name: SourcePath


This will create attachment record in the Service Request Attachment buscomp for the specified service Request.


This type of requirement can be frequent across Public Sector or Life Sciences domain and this post might just help in conquering those. During the heist of creating attachment i also found that one can also email the generated BIP report. One can look at Alex post for more details regarding this.


Happy Reporting!!


יום רביעי, 10 באוגוסט 2011

BI Publisher Integration

Welcome to the world of BI Publisher. BIP reports can be soother for those who are bitten by actuate. Architecture wise both works same but the key ease is in the development of report template for BIP. A typical comparison between Actuate and BIP is depicted below.




With Siebel 8.1.x.x release and BIP Enterprise server 10.1.3.4, we have tightly coupled integration with BIP reports just like actuate. However users on earlier versions can still avail benefits of BIP reports. Reports can be written in BI Publisher using web services or SQL to retrieve data from the siebel application. The reports can be executed from siebel application on button click with flexibility of passing parameters at run time.


The attached document from oracle unearth the secrets of executing reports.


Happy Reporting!!


יום חמישי, 4 באוגוסט 2011

Authentication for Siebel Reports

The best part from oracle is they keep coming with patches and tough part is we need to adhere them. In siebel 8.0 we were not having built in integration with BIP reports so one has to resort to either web service call or SQL strategy for executing BIP reports. With advancement of 8.1.x we have tightly coupled integration with BIP reports.
With integration comes authentication. Typically there are several options to choose for configuring security and authentication for Siebel Reports. When using WebServices or SQL based reports generally "Web Single Sign-On Authentication" mechanism is used as it requires Users logging into BI Publisher via its administrative interface.
However this authentication fails when one is using integration based approach which comes with Siebel 8.1. Since the release of Siebel 8.1.1.1 and BI Publisher 10.1.3.4.1 a new security model is introduced in BI Publisher, Siebel Security. When using the Siebel Security model, BI Publisher relies on Siebel for its authentication and authorization. This is primarily used for IO based reports. But now the question arises if we want to run webservice/sql based reports in conjunction with tightly coupled BIP reports which authentication to go for.

The intermediate solution is LDAP authentication which supports both types of reports in conjunction. The key points to implement here are:

1) Users logging into Siebel sould be authenticated via LDAP
2) Any reports requested by Siebel users and executed in BI Publisher should cause BI Publisher to request authentication via Siebel (and hence indirectly via LDAP). This will be for Tightly coupled IO based reports.
3) Users logging into the BI Publisher administrative interface sould be authenticated via BI Publisher’s own LDAP authentication mechanism. This will be for reports based on the WebServices or SQL.

However, The BI Publisher LDAP Security model has one disadvantage, it requires hardcoded LDAP Security Groups like XMLP_DEVELOPER,XMLP_ADMIN. BIP gurus can definitely throw more light on this.

Happy Reporting!!