Friday, August 2, 2013

Two Buttons with same Method Invoked = ShowPopup, displaying different popup applets!!

After reading the title of this post, you might have got some idea what the scenario I am going to talk about today. This is the scenario where I have two buttons exposed on the UI and both having the same Method Invoked = "ShowPopup".

Here below is the snapshot:

1.      Create SR        :           this button is being used for displaying “Create SR Popup Applet”.
2.   Create Order  :           this button is being used for displaying “Create Order Popup Applet”.

For configuring this simple requirement, you can have the following configuration:

“Create SR” Button
“Create Order” Button
Method Invoked = ShowPopup
Control User Properties
o   Popup = Create SR Popup Applet
o   Mode = Edit
Method Invoked = ShowPopup
Control User Properties
o   Popup = Create Order Popup Applet
o   Mode = Edit

No Issue till now. This pretty simple configuration would work fine!

But the problem comes in when there is a need to execute few lines of server script when each button is clicked, something like:
            If “Create SR” button clicked then
                        Set the Profile Attribute “NewEntityCreated” to “Service Request
                        Call the web service “X” to retrieve some values from other system.
                        After that display the popup applet : “Create SR Popup Applet”

            If “Create Order” button clicked then
                        Set the Profile Attribute “NewEntityCreated” to “Order Entry - Orders
                        Call the web service “Y” to retrieve some values from other system.
                        After that display the popup applet : “Create Order Popup Applet”

So, now the problem is, both button clicked will invoke the method “ShowPopup” and there is no way to identify which button is actually clicked.

Solution:
To overcome this, we have to have the different “Method Invoked” on each button.

1.      Instead of using “ShowPopup”, invoke the custom method for each button i.e.
a.      Method Invoke for “Create SR” button would be “CreateSR”.
b.      Method Invoke for “Create Order” button would be “CreateOrder”.

2.       Put the server script in PreInvokeMethod of the applet:
if(MethodName == "CreateSR")
            {
TheApplication().SetProfileAttr(“NewEntityCreated”, “Service Request”);
//         Code for calling the Web Service X
//         ……………………………………………………
//         ……………………………………………………
PopupApplet(“Create SR Popup Applet”);
                        return (CancelOperation);
            }
            if(MethodName == "CreateOrder")
            {

TheApplication().SetProfileAttr(“NewEntityCreated”, “Order Entry - Orders”);
//         Code for calling the Web Service Y
//         ……………………………………………………
//         ……………………………………………………
PopupApplet(“Create Order Popup Applet”);
                        return (CancelOperation);
            }
3.      Create a new Function as per below script:

function PopupApplet(strAppletName)
{
var oBSSLM = TheApplication().GetService("SLM Save List Service");
var psInp = TheApplication().NewPropertySet();
var psOut = TheApplication().NewPropertySet();
psInp.SetProperty("Applet Height", "400");
psInp.SetProperty("Applet Mode", "2");                          
psInp.SetProperty("Applet Name", strAppletName);
psInp.SetProperty("Applet Width", "800");
oBSSLM.InvokeMethod("LoadPopupApplet", psInp , psOut);
            }

Limitation of “SLM Save List Service” business service
If there is a requirement to display another popup applet from a button click on a Popup applet, then this business service doesn’t work and you might see the error:
View: <?> does not contain applet: <?>.(SBL-UIF-00401)

So, in this case the only choice is to either use “ShowPopup” method or if you can’t use it because of the scenario explained above (having two buttons with same Method Invoke i.e. ShowPopup) then other option is to use hijack the custom method invoked and invoke the Browser Script (for displaying popup applet) as explained here in earlier post.


How to display Popup applet in Siebel - Possible ways!!

Siebel provides various different OOB ways to display a Popup applet, no matter if it a list applet or form applet. Here below is the list of all possible ways:

1.     ShowPopup

This is a straight forward OOB way to display a popup applet which is mostly used to display a popup when button is clicked.

a.      Create a button control on the UI with Method Invoked = ShowPopup.
b.      Create following Control User Properties:

Name
Value
Comments
Popup
<Applet Name>
Name of the popup applet
Mode
<Mode>
Base, Edit, Edit List
Popup Dimension
<Height> X <Width>
Eg: 300 X 300

2.     From Server Script using business service : “SLM Save List Service”, Method: LoadPopupApplet

This method can be used as per below example:

var oBSSLM = TheApplication().GetService("SLM Save List Service");
var psInp = TheApplication().NewPropertySet();
var psOut = TheApplication().NewPropertySet();
psInp.SetProperty("Applet Height", "400");
psInp.SetProperty("Applet Mode", "1");                           // 1 - List Applet, 2 - Form Applet
psInp.SetProperty("Applet Name", "<Applet Name>");
psInp.SetProperty("Applet Width", "800");
oBSSLM.InvokeMethod("LoadPopupApplet", psInp , psOut);

3.     From Browser Script

Here below is the sample code to display applet via browser script:

      function Applet_InvokeMethod (name, inputPropSet)
{
if(name == "ButtonClick")
            {
                        inputPropSet.SetProperty("SWEMethod", "ShowPopup");
                        inputPropSet.SetProperty("SWETA", "<Applet Name>");
                        inputPropSet.SetProperty("SWEW", "300");
                        inputPropSet.SetProperty("SWEH", "100");
                        inputPropSet.SetProperty("SWESP", "true");
                        inputPropSet.SetProperty("SWEM", "<Mode>");  // Base, Edit, Edit List
                        this.InvokeMethod("ShowPopup", inputPropSet);
            }
            }

4.     From Command

This can be used if there is a need to display popup applet from toolbar button or some menu item:

Name
<Any name you want to give to Command>
Method
GotoApplet
Method Argument
ShowMode=<Mode>, Applet = <Applet Name>
HTML Popup Dimension
200 X 200                  (Height X Width)
ShowPopup
True
Target
Server


Thursday, August 1, 2013

How to disable Query on an Applet?

This is a very simple requirement that you might come across during your project. And yes, this has got the very simple answer too:

Create two applet user properties as mentioned below:
·         User Prop 1:
Name CanInvokeMethod: NewQuery
Value - False

·         User Prop 2 :
Name - CanInvokeMethod: RefineQuery
Value - False


Friday, July 26, 2013

How to send Email in HTML Format with dynamic data and dynamic attachments?

After reading my earlier post on sending emails in HTML format, two readers Rishikesh and VP asked, if it is possible sending email using dynamic email template and with the attachments. After reading the complete requirement, I thought its worth a separate post. So, here is the solution - 


1. Lets assume we have an email template based on Quote business component as per below screen shot:



2. Create a Quote record as per below details:


3. Attach two files under the Quote in Attachments view:


So, now system is required to send the email in HTML format with dynamic data coming-up from the Quote record and that email should also have the attachments tied with the Quote.

Here below is the script to execute (you can create the workflow also as per your need)
====================================================================
// 1. Retrieve the email body after the substitution

var OCMBS = TheApplication().GetService("Outbound Communications Manager");
var psOCMInp = TheApplication().NewPropertySet();
var psOCMOut = TheApplication().NewPropertySet();
psOCMInp.SetProperty("CommTemplateName", "Template for Quote");   // Email Template Name
psOCMInp.SetProperty("SourceBusObj", "Quote");
psOCMInp.SetProperty("SourceId", "1-ALUGT");                                   // Row Id of the Quote Record
// Undocumented method for retrieving email body after substitution
OCMBS.InvokeMethod("ExpandCommTemplate", psOCMInp, psOCMOut); 
var strEmailBody = psOCMOut.GetProperty("ExpandedText");                // Get the Email Body
var strEmailSubject = psOCMOut.GetProperty("ExpandedSubject");        // Get the Email Subject

// 2. Retrieve the attachments path

var bsFINSService = TheApplication().GetService("FINS Industry BC Facility Service");
var psFINSInp = TheApplication().NewPropertySet();
var psFINSOut = TheApplication().NewPropertySet();
psFINSInp.SetProperty("BusObjName", "Quote");
psFINSInp.SetProperty("RootBusCompName", "Quote");
psFINSInp.SetProperty("FileBusCompName", "Quote Attachment");
psFINSInp.SetProperty("FileNameField", "QuoteFileName");                   
psFINSInp.SetProperty("RowId", "1-ALUGT");                                       // Row Id of the Quote Record

var QuoteBO = TheApplication().GetBusObject("Quote");
var QuoteBC = QuoteBO.GetBusComp("Quote");
var QuoteAttachBC = QuoteBO.GetBusComp("Quote Attachment");
with(QuoteBC)
{
ClearToQuery();
SetViewMode(AllView);
SetSearchSpec("Id", "1-ALUGT");                                               // Row Id of the Quote Record
ExecuteQuery();
with(QuoteAttachBC)
{
var isRecord = FirstRecord();
var strFinalFilePath = "";
while(isRecord)
{
psFINSInp.SetProperty("AttachmentId", GetFieldValue("Id"));
bsFINSService.InvokeMethod("GetFile", psFINSInp, psFINSOut);
strFinalFilePath = strFinalFilePath + "*" + psFINSOut.GetValue();
isRecord = NextRecord();
}
}
}

// 3. Send the email using “SendMessage”

psOCMInp.SetProperty("CommProfile", "SiebelMantra Profile");
psOCMInp.SetProperty("MsgHTMLBody", strEmailBody);
psOCMInp.SetProperty("MsgSubject", strEmailSubject);
psOCMInp.SetProperty("MsgToList", "siebelmantra@gmail.com");
psOCMInp.SetProperty("AttachFileList", strFinalFilePath);
OCMBS.InvokeMethod("SendMessage", psOCMInp, psOCMOut);

 ====================================================================

Finally, here below is the email that I received:


Thursday, July 25, 2013

How to get Carriage Return in Siebel Workflow?

I was working on a requirement where in one of the step in the Workflow using "Outbound Communications Manager" business service for sending an email using method "SendMessage". And depending upon the value of some process property, I need to add some more texts at the end of email body. 

The problem came in when I tried adding extra text using expression, the carriage return was not working like:

[&EmailBody] + "\n" + [&ExtraText]

So, easy way is to get the carriage return in a string process property and use it in the expression. The business service you can use :

Name : SSSE Address Parser (eScript)
Method: GetCRLF 


Wednesday, July 24, 2013

Siebel Runtime Event and Workflow Process

In Siebel world, Runtime Event (RTE) and Workflow Process seems to be very good friends. Both understand each other pretty well. Whenever there is a need to implement any functionality on based of some trigger, these two friends comes hand in hand. I usually make use of both of them most of the time to make a good solution.

Few things to keep in mind when we use them for any requirement:

  1. If a workflow process needs to be invoked synchronously like, via button click on the UI or some action done by user, RTE can be used. The best part is if the Workflow is also based on the active business object, system will automatically set the "Object Id" process property with the Row Id of the primary business component on UI. Moreover, the complete context of the UI handed over to the workflow.

    Note: RTE will not get invoked if the business object, on which workflow is based on, is different from the UI context BO. 

  2. In the scenario where point#1 can't be used due to any reason i.e. workflow is not based on any BO, then the only way to pass the Row Id or any other field values of the current record to the workflow is via setting the profile attributes. In the RTE action set, you can set the profile attibutes as the first step and in the next step call the desired workflow. Then inside the workflow, you can read the profile attribute values.
    .
  3. One of the tracking feature that OOB provides is, if you have "Monitoring Level" set to "4 - Debug" for a workflow process, and if that workflow process being called from RTE then system automatically add a new property named "Triggering Event" with the Row_Id of RTE. So it becomes easy to track the triggering event.

How to expose a hidden field in Siebel list applet?

This is a very simple requirement that I am talking about today, where on a button click you are required to do a GetFieldValue() of a active BC field, which is NOT exposed on the UI and doesn't have the Force Active property checked. If you try to do that, system prompts an error sayng:

A script failed to get the value for field <field name> because the field was not active.(SBL-EXL-00119)

So the basic solution anybody can tell is, "why don't you expose the field on the applet with HTML Type = Hidden?"

Well, this sounds very simple and works fine also, but ONLY in the form applet. So in a form applet, if you expose a field with HTML Type = "Hidden", then it will not be visible to the user and you can easily do GetFieldValue of that field. But the same thing doesn't work if it is a List Applet, even if HTML Type = Hidden, the list column would be visible.

The only workaround I found was, set the HTML Type = Hidden and instead of exposing the field as the list column, expose it as the control i.e. expose at any empty placeholder where you can expose buttons/labels etc. It works fine.

How to migrate Runtime Events (RTE) from one env to another env?

Runtime Events (RTE) and Data Validation Manager (DVM) are the two highly used features whenever there is a requirement for imposing business rules in the process. Every another project has their own business rules to implement and Siebel developers use RTE and DVM as their first choice (mostly). Problem comes in when you are done with the development and now its time to move the RTE and DVM (Rule Sets) to different Env (QA, UAT etc). So if you have plenty of RTE implmented, it would be cumbersome job to create those RTE again in different env at various stages of the project life cycle.

To ease the job, Siebel has provided the way for taking the export it into a XML file and again import it back into another env. Runtime Events -> Menu -> XML Import/XML Export.

But, the irony is, it doesn't work as you expect. The basic assumption would be, you query your RTE, take the XML export and import the XML file into other env. System should get the new RTE created for you. But the reality is, this way you will end up exporting "ALL" RTE from the source env to destination env (which you never wants).

So, how to get the Runtime migrated?

  1. Navigate to ‘Administration Deployment Manager -> Deployment Projects’. Click ‘New’ and create a project for exporting the RTE. Remember to check ‘Export to File’ flag to ‘Y’.
  2. In the below applet create a new record and pick ‘Data Type Name’ as ‘Personalization – Events’. Save the record.
  3. Expand the ‘Data Type Name’ (by clicking on the + icon)      
  4. Drill down on the ‘Personalization – Events’ and you are navigated to ‘Administration Runtime Events -> Events’
  5. Query for the event you want to export and by using "Query Assistant", save this as PDQ.
  6. Again go back to your deployment project at ‘Administration Deployment Manager -> Deployment Projects’ and in the pick applet for the field ‘Deployment Filter’ against ‘Personalization – Events’ select the name of the PDQ you saved in the above step.
  7. Now Drill down on the ‘Personalization – Action’ and you are navigated to ‘Administration Runtime Events -> Action Sets'
  8. Query for the Action Set associated with your event you want to export and by using "Query Assistant", save this as PDQ.
  9. Again go back to your deployment project at ‘Administration Deployment Manager -> Deployment Projects’ and in the pick applet for the field ‘Deployment Filter’ against ‘Personalization – Actions’ select the name of the PDQ you saved in the above step.
  10. Check your configuration by clicking ‘Validate Filter’ button. If everything is fine click the ‘Enable’ button on the top applet. Status of your deployment project changes to ‘Enabled’ from ‘Draft’.
  11. Now go to ‘Administration Deployment Manager -> Deployment Sessions’. Create a new record and select the project you created in step 1.  Save the record
  12. Press the ‘Deploy’ button on the top applet and give the path on the server (if connected to thin client) or local machine (if connected to thick client) where you want the export file to be generated.
  13. Status changes to ‘Export Completed’ and the field ‘Log’ gives you the name of the xml file generated as a result of your export.
  14. Copy the xml files generated to you local machine (if connected to thin client)
  15. Go to the ‘Administration Data Manager -> Deployment Sessions’ on the server where you want to import your RTE. Click ‘Menu’ and select ‘Deploy From Local File’ and give the path where you have saved the xml files created and press ‘Import'.
  16. Your RTE will be created in the target system.

Special thanks to Manuj Garg for sharing this information.