Showing posts with label Script. Show all posts
Showing posts with label Script. Show all posts

June 17, 2016

Scriptless Challenge : How to constrain association list applet dynamically?

Association applet let's you associate records from an existing list of records. Unlike pick applets these association list applets doesn't have any out of the box way of constraining records.

Consider scenario: When opportunity type is internal, system should only show internal marketed products for opportunity in product association list applet and for opportunity type external system should show only external marketed products. Products are marked as internal and external by product type field.

Challenge: According to oracle there is no other way then scripting on web load of association applet to filter the records. Script can look something like following. And it works flawlessly.

Can you suggest any script less alternative?

function WebApplet_Load ()
{
var BO;
var ParentBC;
var BC;
var AccountId;
BO = TheApplication().ActiveBusObject();
ParentBC = BO.GetBusComp("Opportunity");
if(ParentBC.Name = "Opportunity")
{
    AccountId = ParentBC.GetFieldValue ("Account Id");
    BC = this.BusComp();
    with (BC)
    {
        ClearToQuery();
        ActivateField("Account Id");
        SetSearchSpec ("Account Id", AccountId);
        ExecuteQuery();
    }
}
ParentBC = null;
BC = null;
BO = null;
}


March 18, 2015

Siebel Interview Questions : Scripting

See collection of Date functions in Siebel eScript

Siebel Scripting is one the most interesting areas of Siebel, if it is done properly it can do wonders for business, otherwise it can lead to ever increasing technical debt.

Siebel Tools Scripting IDE

Before jumping to questions let us look at some lessor known facts of Siebel Scripting:
  1. Siebel support two scripting languages: eScript and VBScript
  2. Full name of eScript is ECMA script which developed further to become javascript. 
  3. Garbage collection of Siebel scripts in not automatic
  4. Siebel eScript does support prototype overriding and classes
  5. Siebel eScript can pass arguments by value and pass by reference

Question: Which Siebel objects supports scripting?

Answer: Script can be written on following objects in Siebel:
  1. Business Services
  2. Client Side Business Services
  3. Business Components
  4. Applets
  5. Application
  6. Product Configurator Events
  7. Smart Scripts
  8. Workflows (via business services)
  9. Open UI js class files
  10. Browser scripts on Applets, BusComps, Application, Business Services
  11. Siebel Webtemplates SWTs
  12. ?????

Question : How to change primary record of MVG using scripting?

Answer: Primary record of MVG can be changed by setting the SSA Primary Field of the associated record. 

Script could look like:  
        bcOpty.ClearToQuery();
        bcOpty.ExecuteQuery();
        if(bcOpty.FirstRecord())
        {
            var bcMVG = bcOpty.GetMVGBusComp("MVF Name");
           bcMVG.ActivateField("SSA Primary Field");
            bcMVG.ClearToQuery();
            bcMVG.SetViewMode(AllView);
            bcMVG.SetSearchSpec("Id", "1-12345");
            bcMVG.ExecuteQuery();
             if(bcMVG.FirstRecord())
            {
               bcMVG.SetFieldValue("SSA Primary Field", "Y");
               bcOpty.WriteRecord();
            }
        }

Question : How to set pick list field using script?

Answer:  GetPicklistBusComp() Pick() methods are available in eScript by which system can search on pick list buscomp and pick desired record.

Syntax for pick method can look like:
oPickBusComp = buscomp.GetPickListBusComp("FieldName");
oPickBusComp.ClearToQuery();
oPickBusComp.SetSearchSpec("Id","12345");
oPickBusComp.ExecuteQuery();
oPickBusComp.Pick();
buscomp.WriteRecord();

Question : How to show a confirmation(Ok/Cancel) dialogue box in Siebel?

Answer: Confirmation Dialog box should be implemented through browser script using javascript confirm method. This method prompts users with option to proceed or cancel the process.



Click here for example.



Question : How to call batch file through scripting?

Answer: Siebel provides C libraries to access the host of Siebel server.
Clib.system() is one of those functions which allows script to pass some instructions to command processor of server host.
Using this method, a batch file can be invoked from Siebel which can do OS level changes.
Following instruction can execute Siebel.bat file on the server:

Clib.system("C:\\Scripts\\Batch\\Siebel.bat");

Question : How to update read only fields in Siebel?

Answer: Fields in Siebel are configured as read-only using "Field Read Only Field" and "BC Read Only Field" user properties. These user properties does not work on views where admin mode flag is set to Y.

BusComp.InvokeMethod("SetAdminMode", flag)

Question: What is the difference between SetAdminMode and SetViewMode(AllView)?

Answer :
  • SetAdminMode mimics the behaviour of Admin Views, and is used to update read only fields
  • SetViewMode instruction changes the default view mode of the business component, it used to access records which are not visible with default view mode.


Question : Is it possible to invoke workflow through browser script?

Answer: Workflow can be invoked through browser script if "Workflow Process Manager" declared as Client side business service in Application's User Property. 


Question : What type of error handling is available in Siebel eScript?

Answer: try catch finally instructions helps to handle run time errors in e-script.

  • try block marks the code which needs to handled
  • catch block declares commands which should be executed in case of error,
  • finally block is executed after try and catch has completed executing.

try
{
   statement_block
}
catch
{
   exception_handling_block
   [throw exception]
}
finally
{
   statement_block_2
}

Finally block is always executed no matter if there was error encountered or not.

Question: How to get language of Object Manager?

var lang = TheApplication().InvokeMethod("LANGUAGE");

Question :  What is difference between ActiveBusObject() and GetBusObject() methods?

Answer: ActiveBusObject is mostly used in UI based scripting requirements, this method can only return the handle of current BO instance.

For example: In Accounts screen ActiveBusObject will return Account BO and subsequent .GetBusComp().GetFieldValue will return the information from the record selected by user.

Same script in Contact Screen will return the Contact BO.

Important Points about ActiveBusObject: 
- It is not recomended to use ClearToQuery and ExecuteQuery on BC of ActiveBusObject as UI context for user will get lost.
- ActiveBusObject is the only way to get BO in browser script.

GetBusObject method should be used when current BO instance does not have the BC of interest. We can get handle of any BO in application using GetBusObject This is mostly used in background processes and workflows.

 



February 13, 2015

How to get current timestamp in JavaScript?

Following Javascript code returns current date and timestamp of client. This is quite handy for Open UI development, one can call following code from console.log() method to record the invocation sequence which is otherwise very difficult.

function displayTime(str2) {  
    var str = "";
    var currentTime = new Date()
    var hours = currentTime.getHours()
    var minutes = currentTime.getMinutes()
    var seconds = currentTime.getSeconds()
    var milliseconds = currentTime.getMilliseconds()
    if (minutes < 10) {
        minutes = "0" + minutes
    }
    if (seconds < 10) {
        seconds = "0" + seconds
    }
    str += hours + ":" + minutes + ":" + seconds + ":" + milliseconds;
    return str2 + ": " + str;
    }

Siebel Open UI Example:

 console.log("PR Invoked" + displayTime("@"));

Hope it helps. 

February 10, 2015

How to traverse javascript object?

For in loop is one of my favourite commands of JavaScript and it just one step behind the modest alert() ;) 

It is a very powerful command and helps you to loop through any JavaScript object without knowing what object is all about. You don't need to know the types that exists in the object or number of child objects that object has. You just need have the handle of the object and you can loop through all its properties.

It is quite handy if you cant get your head around Siebel Open UI and you want to know what else is available in that object and how the functions are implemented in an object.

Examples:
MyPM.prototype.Setup = function (propSet) {       
    for(var x in propSet){console.log(x + "" + propSet[x]);
    }
        SiebelAppFacade.MyPM.superclass.Setup.call(this, propSet);
}

In this example I am trying to find what else is passed through the property set by Siebel to the Setup function of Presentation Model. and the following I am trying to all the methods that are available by theApplication() object.

for(var x in theApplication()){
console.log(x + " " + theApplication[x]);
}


For those who don't know, For in loop is just plain old JavaScript and is not some thing the jQuery offers.

Happy Hacking :)

February 01, 2014

Siebel - Twitter Integration - Part 1: Authentication

This is post is second in series of Siebel Twitter Integration and will talk about logging in to twitter as an application.

Twitter has support two form of authentication, O-Auth Authentication and Application only authentication. For pulling tweets in Siebel we need Application only authentication, luckily which is technically easier than O-Auth and have more generous rate limits.






Before starting with Siebel configuration follow these steps:
  1. Create account on http://dev.twitter.com by agreeing to terms and conditions.
  2. Request to create your access token, and copy your Consumer Key and Consumer Secret.

Now copy paste following code to your repository, I prefer client side scripting as it easy to change.

StringToBase64 encoder

http://www.siebel-tech.com/2013/07/escript-base64-encoder/
This is piece of code is required for encoding the Client Key and Client Secret to Base64 before sending it to twitter. Developers at siebel-tech.com has done wonderful work in converting String to Base64, which saved me lot of time. Thanks Iain.

function StringToBase64(Inputs, Outputs)
{
  // *************************************************************************
  // Purpose: Encodes to a Base64 string
  // Author: Iain Ollerenshaw
  // Date: 30-Jul-2013
  //
  // Inputs: InString - string to be encoded
  // Outputs: Base64String - string in Base64
  //
  // Modification History
  //
  // Date          By                Details
  // 25-Jul-2013   Iain Ollerenshaw   Created
  // 2-Feb-2014    Jim  Updated
  // **************************************************************************

  try
  {

    // Define the Base64 codex
    var sCodex = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    var sOutput = "";
    var sInput = Inputs.GetProperty("InString");
    var iLen = sInput.length;
    // Parse input string
    var iPos = 0;
    while (iPos < iLen)
    {
      var sChr1 = sInput.charCodeAt(iPos);
      iPos++;
      var sChr2 = sInput.charCodeAt(iPos);
      iPos++;
      var sChr3 = sInput.charCodeAt(iPos);
      // Shift bytes
      var iEnc1 = sChr1 >> 2;
      var iEnc2 = ((sChr1 & 3) << 4) | (sChr2 >> 4);
      var iEnc3 = ((sChr2 & 15) << 2) | (sChr3 >> 6);
      var iEnc4 = sChr3 & 63;
      if (isNaN(sChr2))
      {
        iEnc3 = iEnc4 = 64;
      }
      else if (isNaN(sChr3))
      {
        iEnc4 = 64;
      }
      sOutput +=(sCodex.charAt(iEnc1) + sCodex.charAt(iEnc2)+ sCodex.charAt(iEnc3) + sCodex.charAt(iEnc4));
      iPos++;
    }
    Outputs.SetProperty("Base64String", sOutput);  }
  catch(e)
  {    throw(e);  }
}

Get Description / Set Description

This is a small piece of code which helps to get the description of any LOV value, I have used LOV as scratch pad to store access token in this example, I will explain to store an maintain these in custom Twitter dashboard. I thought of saving them in system preferences first, but it only has 100 char limit thus had to switch over to LOV Description column.

function GetDescription (sType,sName)
{
var boListOfVal = TheApplication().GetBusObject("List Of Values");
var bcListOfVal = boListOfVal.GetBusComp("List Of Values");
bcListOfVal.ClearToQuery();   
bcListOfVal.ActivateField("Description");
bcListOfVal.SetSearchSpec("Name",sName);
bcListOfVal.SetSearchSpec("Type",sType);
bcListOfVal.ExecuteQuery();
if(bcListOfVal.FirstRecord()){
return(bcListOfVal.GetFieldValue("Description"));
}else return("none");
}


function SetDescription (sType,sName,sDesc)
{
var boListOfVal = TheApplication().GetBusObject("List Of Values");
var bcListOfVal = boListOfVal.GetBusComp("List Of Values");
bcListOfVal.ClearToQuery();   
bcListOfVal.ActivateField("Description");
bcListOfVal.SetSearchSpec("Name",sName);
bcListOfVal.SetSearchSpec("Type",sType);
bcListOfVal.ExecuteQuery();
if(bcListOfVal.FirstRecord()){
bcListOfVal.SetFieldValue("Description",sDesc);
bcListOfVal.WriteRecord();
}
}
LOVs look like:

Main code for Twitter login is as follows:


//Get Consumer Key and consumer Secret from LOV Description
var sConsumerKey = GetDescription("TWITTER_TOKEN","ConsumerKey");
var sConsumerSecret = GetDescription("TWITTER_TOKEN","ConsumerSecret");

//Encode Key and Secret into Base64
var inp = TheApplication().NewPropertySet();
var op = TheApplication().NewPropertySet();
inp.SetProperty("InString",sConsumerKey + ":" + sConsumerSecret);
StringToBase64(inp,op);


//Use EAI HTTP Transport to call Twitter API to login.
var httpSvc= TheApplication().GetService("EAI HTTP Transport");
var httpIn = TheApplication().NewPropertySet();
httpIn.SetProperty("HTTPRequestURLTemplate","https://api.twitter.com/oauth2/token?grant_type=client_credentials");
httpIn.SetProperty("HTTPRequestMethod","POST");
httpIn.SetProperty("HTTPIsSecureConn","TRUE");
httpIn.SetProperty("HTTPContentType","application/x-www-form-urlencoded;charset=UTF-8");
httpIn.SetProperty("HDR.Authorization","Basic " + op.GetProperty("Base64String"));
httpIn.SetProperty("HDR.Accept-Encoding","identity");
httpIn.SetProperty("HDR.User-Agent","something");
httpSvc.InvokeMethod("SendReceive", httpIn, Outputs);


//Transcode the JSON response into UTF-8
var oTransService = TheApplication().GetService("Transcode Service");
var oTransOutputs = TheApplication().NewPropertySet();
Outputs.SetProperty("ConversionMode", "EncodingToString");
Outputs.SetProperty("TargetEncoding", "UTF-16");
Outputs.SetProperty("SourceEncoding", "UTF-8");
oTransService.InvokeMethod("Convert", Outputs, oTransOutputs);
var sResponse = oTransOutputs.GetValue();


//Convert the JSON response to property set
var oJSONConverter = TheApplication().GetService("EAI JSON Converter");
oJSONConverter.InvokeMethod("JSONToPropSet",oTransOutputs,Outputs);

//extract access_token and clip
var token = Outputs.GetChild(0).GetProperty("access_token");
token = token.substring(1,token.length-1);


//Save the token for future use
SetDescription("TWITTER_TOKEN","EncodedTokenCredentials",token);


This access token will be used in all the future communications with twitter as authorization code.
Post version: Draft :) keep checking for more updates on explanations over the HTTP transport.

December 28, 2013

Google Analytics with Siebel

I have seen couple of questions regarding use of Google Analytics with Siebel CRM, but no one seems to answer completely. This article is created to answer those questions.

When it comes to web analytics there is no parallel to Google Analytics, I am not selling Google Analytics, but people who have already used GA before can understand the need of powerful web analytics tools and how Google Analytics fills the gap.


This article will give you steps to create Google Analytics account and to embed the tracking code in Siebel.

Google Analytics can be used with Siebel CRM applications for both internal like Siebel Financial Services and external customer facing applications like eService or eSales. Only requirements from Google to use tracking are:
  • User must be able to reach the ga.js/analytics.js JavaScript file at http://www.google-analytics.com/ga.js or https://www.google-analytics.com/ga.js.
  • Intranet Application must be accessible through a fully qualified domain name such as http://intranet.example.com, application need not to be internet hosted application to use google analytics.

If your application can satisfy these requirements then you can create GA code and embed it to the Siebel Application.Once it is setup one can report on user behaviour demographic and many more metrics in GA.

I have used GA's Universal Analytics(newer version of GA) and created custom dimensions to store Active View Name, Application Name and Login User on Google.






Additionally I created events to capture the user interaction application. You can create event to business specific needs like: product configurator or service request creation or tasks.

How to embed Google Analytics tracker in Siebel Open UI?

Add the following code in postload.js file under the public directory, this code will be executed always when ever view is refreshed in Open UI. Code shown in bold is added after creation of dimension shown above.

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  ga('create', 'YOUR_CODE', 'yoursitename');
  ga('send', 'pageview');
ga('set', 'dimension2', theApplication().GetProfileAttr("Login Name"));
ga('set', 'dimension1', theApplication().GetProfileAttr("ActiveViewName"));

ga('set', 'dimension3', theApplication().GetProfileAttr("ApplicationName"));
ga('send', 'event', theApplication().GetProfileAttr("ActiveViewName"), 'click', theApplication().GetProfileAttr("Login Name"));

How to embed Google Analytics with Siebel HI? 

Add following code to the  swecommon.js for high interactive applications, this js is also executed allways after page refresh in HI applications. 

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  ga('create', 'YOURCODE', 'yoursitename');
  ga('send', 'pageview');
ga('set', 'dimension2', theApplication().GetProfileAttr("Login Name"));
ga('set', 'dimension1', theApplication().GetProfileAttr("ActiveViewName"));
ga('set', 'dimension3', theApplication().GetProfileAttr("ApplicationName"));
ga('send', 'event', theApplication().GetProfileAttr("ActiveViewName"), 'click', theApplication().GetProfileAttr("Login Name"));

Caution : Do not track customer information such as user details using custom dimesions and metrics as it is against the google analytics policy and could be against the organisation policy as well.

After all this is done you would be able to see the analytics information in your google account.










Now you can do full fledged analytics on your user interactions. My favorite is real time analytics, which one is your favorite??

Happy Analytics :)

December 14, 2013

EAI JSON Converter


Siebel does not provide any out of the box functionality to convert Siebel data into JSON string or vice versa. Developers end up with string manipulations or giving up on integration. I have created custom EAI JSON Converter business service which uses Java capabilities and Siebel-Java integration EAI Java Business Service to produce fully compliant JSON strings and convert the external JSON into Siebel Property Sets.

The service built on the lines of methods of EAI XML Converter which converts Property set to XML Doc and XML Doc to property set.
Methods available in EAI JSON Converter are:

  1. JSONToPropSet
  2. PropSetToJSON


Input data to this service is sent to EAIJSONConvert java class using Siebel API(Siebel.jar) which converts the data in required format using GSON 2.2.4 Java API . The Gson library was originally developed for internal purposes of Google, and Version 1.0 was later released on May 22, 2008 under the terms of Apache License 2.0. The latest version, 2.2.4, is used for the service.

How to set up:

1. Download and place java files in the CLASSES folder of Siebel Client the binaries 
Files:
EAIJsonConverter.class
gson-2.2.4.jar
Siebel.jar

2. Download the sif file for EAI JSON Converter from github
3. Update the cfg file to include gson-2.2.4.jar file. My cfg file look like:
[JAVA]
DLL = C:\Program Files\java\jre6\bin\client\jvm.dll
CLASSPATH = C:\Siebel\8.1\Tools_1\CLASSES\Siebel.jar;C:\Siebel\8.1\Tools_1\CLASSES\SiebelJI_enu.jar;C:\Siebel\8.1\Tools_1\CLASSES\gson-2.2.4.jar;C:\Siebel\8.1\Tools_1\CLASSES\.
VMOPTIONS = -Xrs -Djava.compiler=NONE -Djms.log=C:\logs\

4. Simulate the service

How to use:

Service can simply be used in place of EAI XML converter to convert the Siebel message into JSON or convert back JSON to property set.




Please feel free to use comments for any questions or to post any difficulty faced in using the service.

Hope it helps.

-Jim

October 19, 2013

How to Pre-populate CC or BCC in Siebel F9 Functionality?

Siebel F9 Email Client no doubt is one of best out of the box functionality of Siebel. It has lot of its logic built into the classes thus presents some limitations. In our previous post we saw how we can bring data from child business component data into email body.

In this posts lets see how we can pre-default CC or BCC recipients using some scripting. Out of the box
when ever Send Email method is invoked from on any Siebel Applet, Send Communication Applet is opened, and "To" email field is populated with the value of the field specified in Recipient Email Address Field  user property on the BC.

However there is no way we can pre-default CC and BCC fields out of the box. With the help of small script on  Send Communication Applet can set the value of To Email, CC, BCC and Email Body as well. This can be useful little customization that can help to pre-populate data which can not be achieved using email templates and recipient groups.

function WebApplet_Load ()
{
    var oBC = this.BusComp();
    oBC.SetFieldValue("Email BCC Line","a@a.com");
    oBC.WriteRecord();
}

Siebel Email Client - Siebel 7.8
Hope it helps

-Jim

October 10, 2013

How to take backup of Siebel Tables?

This article explains how to take backup of Siebel Tables or any other table in Oracle database. It is a good practice to take backup of data before making any changes to schema or before updating bulk records. However Siebel does not provide any archiving or data backup solution out of the box.

There are couple of solutions available if you are using oracle database, some of them are:
1. First option is to copy the table with all the data into a new table in same or any other database.As compared with the any other option turnaround time is very less, as this command executes on the server and there is no payload transferred between client and server.

This can be done with the help of create table command with select statement.

CREATE TABLE new_table  AS (SELECT * FROM old_table);