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");
SetSearchSpec("Id", "1-ALUGT");                                               // Row Id of the Quote Record
var isRecord = FirstRecord();
var strFinalFilePath = "";
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", "");
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.