Pages

Monday, June 5, 2017

Creating a sequence of activities

Customer requirement:

There are some approval activities in opportunity as Gate 0 Approval, Gate 1 Approval, Gate 2 Approval, Gate 3 Approval, Users will be allowed to create each approval only after the previous approval activity status is "Approved" except Gate 0 Approval.

Solution:

This I have achieved basically through scripting. First we have to create four different activity types for the above requirement. I have created below four activity types under Administration- Data -- List of Values (Lov Type - TODO_TYPE)
  1. ESGB Gate 0
  2. ESGB Gate 1
  3. ESGB Gate 2
  4. ESGB Gate 3
Then we can write validation under BusComp_PreSetFieldValue of 'Action' BC to validate the previous activity status, when the user select the activity type. 
Here as we have to validate three activities, I have written a general function and then associated the function at BusComp_PreSetFieldValue .
Please be reminded that, the Action BC should be a child of Opportunity BC while we do this validation.

Function ESGBApprovalSeq(fVal)
{
var optyId ="";
//Verify whether the Parent is Opportunity
if (this.ParentBusComp() != null)
{
if (this.ParentBusComp().Name() == "Opportunity")
{
//Get the Opportunity ID related to the activity.
var Optybc = this.ParentBusComp();
optyId = Optybc.GetFieldValue("Id");
}
}
//Search in Action BC for activities which is having the opportunity ID, 
//Activity type defined by function variable and activity status as approved

var boBusObj = TheApplication().GetBusObject("Opportunity");
var bcAct = boBusObj.GetBusComp("Action");
with (bcAct)
{
ClearToQuery();
SetViewMode(AllView);  
ActivateField("Status");
SetSearchSpec("Opportunity Id", optyId);
SetSearchSpec("Type", fVal);
SetSearchSpec("Status", "Approved");
ExecuteQuery(ForwardOnly)
//If No such record throw error;
if(FirstRecord()== false)
{
this.UndoRecord()
TheApplication().RaiseErrorText("Previous Gate Approval not yet completed!");
}
}
}


In BusComp_PreSetFieldValue , write below;

function BusComp_PreSetFieldValue (FieldName, FieldValue)
{

if(FieldName == "Type")
{
if (FieldValue == "ESGB Gate 1")
ESGBApprovalSeq("ESGB Gate 0")
else if (FieldValue == "ESGB Gate 2")
ESGBApprovalSeq("ESGB Gate 1")
else if (FieldValue == "ESGB Gate 3")
ESGBApprovalSeq("ESGB Gate 2")
}


}

This will validate whether the defined activity status is "Approved"

Hope this helps...

Sequence Number Field in parent BC

Customer requirement as below;

On updating sales stage of Opportunity to a particular stage (Eg: “Governance Approval”), There will be a custom field as ESGB reference number, which will be generated sequentially in a defined format (Eg: ESGB000300001)


Solution:

I have used the vanilla BC sequence generation to accomplish the requirement together with some scripting to generate the format

It is also possible to create a DB sequence and associate the sequence to the field.(Which is not discussed here)

So in our way, first we create the sequence field as below;

  • Add a Field in the Opportunity BC
    • Name: esgb_seq
    • Type : DTYPE_NUMBER
    • Column : X_ESGB_SEQ (Pls add a new column or associate existing column which is not used)
  • Add a Business Component User property to Opportunity  BC
    • Name: Sequence Field
    • Value : esgb_seq
  • Create a new Business Component
    • Name: Opportunity.esgb_seq (Sequence)
    • Class : CSSSequence
    • Sort Spec: Sequence (DESCENDING)
    • Table: S_OPTY
  • Add a field in BC created above step
    • Name : Sequence
    • Column : X_ESGB_SEQ
  • Add the Business Object Component under Business Object Opportunity
    • Bus Comp : Opportunity.esgb_seq (Sequence)
Now a sequence number should be generated starting from 1 for each new opportunity created.
You can expose the esgb_seq field in UI for verification. But later you should remove it from UI

Then define a method to populate this sequence(Formatted according to requirement) to a different field when a button is clicked.


function BusComp_PreInvokeMethod (MethodName)
{
if (MethodName=="ESGBRef")
{
var rowSeq=this.GetFieldValue("esgb_seq");
var strEsgbSeq="" ;
var strLength = 9 - rowSeq.length;
if (strLength == 1)
strEsgbSeq = "ESGB" +  "0" + rowSeq;
else if (strLength == 2)
strEsgbSeq = "ESGB" +  "00" + rowSeq;
else if (strLength == 3)
strEsgbSeq = "ESGB" +  "000" + rowSeq;
else
strEsgbSeq = "ESGB" + rowSeq;
this.SetFieldValue("ESGB_Number", strEsgbSeq);
this.WriteRecord();
}
}

Here I have used the starting value of the sequence as 300001 to fulfill the formatting

Hope this helps...

Sunday, May 7, 2017

Adding/Copying Accounts Team to Opportunity Sales team

I have used eScript for this function. There can be several other methods like dynamic candidate assignment to achieve the same functionality. But here I'm giving an  example code for copying the positions of Accounts Team of an Account to the Sales Team of an Opportunity, while associating the account to an Opportunity.

This is written under BusComp server scripts in Opportunity BusComp.

Below is the code and comments will explain the functionality within the script.


function BusComp_SetFieldValue (FieldName)
{
//Added to copy Accounts team to Opportunity Sales Team while associating an account to opportunity

if (FieldName == "Account")
{
var OptyAccountId = GetFieldValue("Account Id");

//First check whether the Account is input, otherwise
//Prevent code execution while removing the account from the opportunity
if (OptyAccountId)
{
var boBusObj = TheApplication().GetBusObject("Account");
var bcAcct = boBusObj.GetBusComp("Account");
var sSalesTeam ='';

with(bcAcct)
{
ClearToQuery();
SetViewMode(AllView);
ActivateField("Sales Rep");
SetSearchSpec("Id", OptyAccountId);
ExecuteQuery(ForwardOnly)
if(FirstRecord())
{
//the account was found. Now cycle through the positions

var bcMVG = bcAcct.GetMVGBusComp("Sales Rep");
bcMVG.ActivateField ("Position Id");
var isRec = bcMVG.FirstRecord();

while(isRec)
{

var PosId = bcMVG.GetFieldValue("Position Id");

var optyMVG = this.GetMVGBusComp("Sales Rep");

//search in optyMVG whether the position which is there in account already exist in oppotunity.

optyMVG.ClearToQuery();
optyMVG.SetViewMode(AllView);
optyMVG.ActivateField("Position Id");
optyMVG.SetSearchSpec("Position Id",PosId);
optyMVG.ExecuteQuery(ForwardOnly)
var isRecopty = optyMVG.FirstRecord();
//If the position record is not there in oppotunity;
if (isRecopty == false)
{
//Add position to oppotunity
var bcAssoc = optyMVG.GetAssocBusComp();
bcAssoc.ClearToQuery();
bcAssoc.SetViewMode(AllView);
bcAssoc.ActivateField("Position Id");
bcAssoc.SetSearchSpec("Position Id",PosId);
bcAssoc.ExecuteQuery(ForwardOnly)
var isRecpos = bcAssoc.FirstRecord();
if (isRecpos)
{
bcAssoc.Associate(NewAfter);
}
}
isRec = bcMVG.NextRecord();
}
}
}
}
}
}

Hope this helps...
When write a new script and save, Siebel tools get stuck

Hi all,

This issue came for me while I was writing a Buscomp Script and due to some issue in the script, Siebel Tools got stuck. I tried to close and reopen Tools, but when ever I go to Edit Server Script of that particular BusComp, again tools get stuck.

So the Solution, which I found is this;

We will take an example of 'Opportunity' Business Component. If we write some bogus script on BusComp_SetFieldValue method, then here is the steps you can resolve the issue.

1. Once tools get stuck, reopen Siebel tools
2. Search for Business Component 'Opportunity'
3. Go to 'BusComp Server Script' (By default this will not appear in object explorer. You will have to enable it from View --> Options --> Object Explorer)
4. Select the particular record for 'BusComp_SetFieldValue'
5. Click on the 'Script' field and edit the script to remove the issue or totally delete the script from there and save record

Issue should be resolved... ⏩

Wednesday, March 22, 2017

Script Not compiling when the object is compiled

This is a very basic functionality. But some one can spend hours searching in the web for a solution. 

The issue here is when we add/edit a server script and we compile the object, (Applet/Business Component etc.) the server script won't get compiled. Also when we try to exit Siebel Tools, we get a warning similar to below;

The following scripts have been saved but not compiled into the SRF. Press "OK" to exit. Press "CANCEL" to stop exiting Siebel Tools


This can happen specially in Opportunity Business component, BusComp_PreSetFieldValue method, as there is a vanilla script added and when we try to modify code.

The cause of the issue is that, the inactive flag is on for this script.

To fix the issue, You have to go to Business Component --> Select the required business component ('Opprtunity' in above case). Then go to BusComp Server Script (You have to make this visible from View --> Options --> Object Explorer) and remove the inactive flag

Compile the object and it will work.

Tuesday, January 24, 2017

Enable/Disable Export menu item conditionally in list applets

Enabling or disabling a button conditionally is pretty common requirement in Siebel. There are many ways to do so, you can choose any of these based upon your requirement but as you know, it is always advisable to get rid of scripting as much as possible. Here I will only describe about one method which is easy and script less.

We use applet user properties for this configuration.

Method of configuration

By default "Export" is enabled in list applet menu. So we will create a responsibility, for which we will disable the menu item "Export". Who ever the users assigned with this responsibility will see "Export" as disabled in the list applet. 

Step 1.
Create a responsibility and assign a test user. (Eg. We create "No Export" responsibility). No need to associate any views.
For more information in creating a responsibility, refer below link
https://docs.oracle.com/cd/E14004_01/books/DevDep/CompanyStructure6.html

Step 2.
Find the applet you want to restrict the "Export" (Eg. We'll select "SIS Account List Applet" for this)

Step 3.
Go to Siebel Tools and query the applet 'SIS Account List Applet' and go to Applet User Properties.

Step 4.
Create new record where Name= 'CanInvokeMethod: ExportQuery' and Value = GetProfileAttrAsList("User Responsibilities") NOT LIKE "*No Export*"

Step 5.
Compile the object changes to srf and check with the user user login assigned with above responsibility.

Explanation;
 1. CanInvokeMethod : is used to define whether the button or other user property should   be enabled or disabled.
          Syntax : Name = CanInvokeMethod: MethodName
                        Value = TRUE/FALSE

 2. GetProfileAttrAsList(“User Responsibilities”) : is used to get the responsibilities assigned for the current logged in user. This will be retrieved as a comma separated list

 3. InList : Will determine whether the given string in the first argument is in the second  comma seperated list"



Avoid scripting in ‘PreCanInvoke’ event as much as possible and use ‘CanInvokeMethod’ user property as an alternative

Feel free to comment here..