How to make an invisible Screen

Requirement

Restrict users from navigating and browsing through Client information, this information could be classified and access is provided on a need to know basis. The only way Client information can be accessed is through a drilldown from another part of the application.

Problem

Siebel does not provide any obvious mechanism to hide a Screen completely from the Application. When adding Views to Screens, we are given two options

1. Display in Page
2. Display in Sitemap

The first option, determines wether a view should be displayed when navigating to a Screen, while the later determines wether this view will be show under the Screen link under SiteMap.

But there is no similiar options for a Screen, the best you can do is make the Screen hidden from the page tabs, but this will still show up in the SiteMap.

Solution

Under Application/Screen Menu Item, just blank out the screen name text for the Screen you want to hide. Siebel has some internal logic to prevent screens with empty names to be displayed in SiteMap. Obscure? Absolutely!

An interview with the creator of the ABS Framework



I've recently had the pleasure and good fortune, of meeting the creator of the Siebel ABS eScript Framework and what follows will be an interesting journey.

This is a continuation of my first article on the implementation of an eScript Framework.

If you dont know what the ABS Framework is then, this article wont mean much, but for those are keanly following this topic, it will make us re-think the way we develop Siebel and also open a lot of doors that we didnt know existed.

In my first article, i discussed an implementation of a Siebel framework, that solves Mike M. Lin's dilenma of creating a custom Siebel class with proper method chaining.

In the closing of the first article, i hinted on another implementation of the framework, which avoids the horrible problem of attaching methods to the Object constructor.

But my opportunistic meeting with the creator of the ABS Framework (who wishes to remain anonymous), has confirmed this theory, that attaching custom methods to the Object constructor is not the way to go.

I've also discovered, that while our implementation mechanism of the eScript class method chaining is different, our ideas for laying the foundations for a framework and the results are the same.

Our initial conversation covered the architectural design of a framework and the different implementation methods, scripting standards, and the absolute need for such a framework.

We are currently evaluating this framework, and also looking at some potential changes for Siebel 8, but thats as far as we got.

The first and only place, that we've heard about this framework is from the Siebel Unleashed forum, and there is little if any knowledge of this framework, by Oracle or any other independant source, but in conclusion to this article, i can definitely confirm that the ABS Framework exists.

In the next article, i will provide some more information on our eScript framework, so stay tuned...


Impossible Solutions Poll



I've started a new poll on the website, to see which topics readers had the most interests in.

The 4 options are

  1. Create a VBC without scripting
    This is unusual and widely unknown, but it is not impossible.

    Most people would like to reduce scripting in their lives, and VBCs were traditionally a declarative free zone. It was like Siebel developed it only for the geeks, but i think its time the non geeks got in on the fun as well.

  2. Create a MVG on a VBC
    In bookshelf, it states "VBCs cannot contain a multi-value group (MVG)". This does seem impossible... but not for the creative developer.

    Although, most developers wont touch VBCs in their lives, but for those who do, its unimaginable that Siebel didnt provide a vanilla way of doing this.

  3. Selectively Enable/Disable multiple ShowPopup buttons
    On an applet you have two buttons, one pops up an organizations list, and the other a contacts list.

    Siebel PreCanInvoke is used to Enable/Disable buttons based on their methods, but when you have multiple buttons based on the same method, it is not possible to selectively enable/disable it...

    or is it...?

  4. Show a tooltip on a button MouseOver
    This is one of the worse usability problems of Siebel. It is frustrating when you see an applet and have no idea why a button is disabled.

    Wouldn't it be nice to display a nice message to the user when the user hovers over the button? But according to the documentation, MouseOver is not supported in HI.

    Use the documentation as a guide, because there are various solutions to this problem.

Maybe the above 4 solutions dont interest you, the comments are open for you to request solutions to your own impossible problems, or are you waiting on the conclusion to an article, put in your requests for these as well, so i know where to concentrate my efforts.

Format DTYPE_PHONE EAI phone challenge - Part 2




This will be the conclusion to our series on the DTYPE_PHONE phone challenge.

This solution will pick up where the last article left of from and I am assuming that you already have a WF and have queried your IO to get your message.

For added fun, this is our new beefed up XML message.

<phone>
<home>+610296480999
(00) 0000 0000</home>
<work>+610296480888
(00) 0000 0000</work>
<mobile>+610401123456
0000 000 000</mobile>
<voip>+610296480222
00 0000 0000</voip>
<mum>+610296480111
(00) 00 00 00 00</mum>
<dad>+610296480333
0000 0000</dad>
<brother>+610296480444
00 0000 0000</brother>
<sister>+610296480555
000000000</sister>
</phone>

We will use the technique in the first article to split the phone and pattern using XSLT, and also apply the phone formatting in the same transaction!

Heres the new XSLT that will do the magic for us.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:variable name="CRLF"><xsl:text>&#10;</xsl:text></xsl:variable>
<xsl:template match="/">
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/home"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/work"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/mobile"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/voip"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/mum"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/dad"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/brother"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/sister"/></xsl:call-template>
</xsl:template>
<xsl:template name="applyPhoneFormat">
<xsl:param name="dtypephone"/>
<xsl:param name="output"/>
<xsl:param name="num" select="substring-before($dtypephone, $CRLF)" />
<xsl:param name="pattern" select="substring-after($dtypephone, $CRLF)" />
<xsl:param name="ploop" select="string-length($pattern)" />
<xsl:param name="nloop" select="string-length($num)" />
<xsl:variable name="patterncursor" select="substring($pattern, $ploop , 1 )" />
<xsl:variable name="numbercursor" select="substring($num, $nloop , 1 )" />
<xsl:choose>
<xsl:when test="$ploop > 0">
<xsl:choose>
<xsl:when test="$patterncursor = 0">
<xsl:call-template name="applyPhoneFormat">
<xsl:with-param name="dtypephone" select="$dtypephone"/>
<xsl:with-param name="ploop" select="$ploop - 1"/>
<xsl:with-param name="nloop" select="$nloop - 1"/>
<xsl:with-param name="output" select="concat($numbercursor,$output)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="applyPhoneFormat">
<xsl:with-param name="dtypephone" select="$dtypephone"/>
<xsl:with-param name="ploop" select="$ploop - 1"/>
<xsl:with-param name="nloop" select="$nloop"/>
<xsl:with-param name="output" select="concat($patterncursor,$output)" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($output,$CRLF)" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

To make this solution work, we needed to have cursors that loops through the phone pattern and build the phone string, but since there is no concept of looping in XSLT (we have the for-each, but that just iterates over the XML nodes, it dosnt do a custom for loop for us), i have used the next best thing, which is build a recursive template to give us the same effect.

I originally designed this solution 3 years ago, but sadly never kept a copy of it when i moved on. So the XSLT you see here is a re-write of the original.

Whenever we use a new technology in our environment, and especially when it uses loops, its prudent to do performance testing to ensure it runs as expected. When i did my testing on the original XSLT against the Xalan (Siebel's XSLT translator which uses the Xerces 1.1 parser) engine in version 7.5, i used a dummy XML with 100 phone numbers, and each phone number had between 8-10 characters for the phone number. When i analysed the logs, the transaction completed within a split millisecond.

This is only a proof of concept, and dosnt handle cases where the user enters the correct phone format, and the system needs to lookup the correct number format, and in the above solution i've chopped of the country code.

The XSLT above hasnt been performance tested, so before you use it in your environment take sometime to analyse the XSLT logic to ensure it meets your needs, and test its performance in your environment, you should be quite surprised by the Xalan engines efficiency.

In the example above, i've included the special formatting characters, but Alex from Siebel Essentials has requested that i show how to send only the numeric phone number.

This was achieved in the first article in the series, by using XSLT to split the phone and pattern portions.

To apply the correct format with spacing, but not non numeric characters such as (,),/,- etc. In other words, we are stripping off all the special characters and just applying the correct spacing.

To do this we just need to modify our XSLT a little.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:variable name="CRLF"><xsl:text>&#10;</xsl:text></xsl:variable>
<xsl:variable name="SP"><xsl:text>&#32;</xsl:text></xsl:variable>
<xsl:template match="/">
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/home"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/work"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/mobile"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/voip"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/mum"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/dad"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/brother"/></xsl:call-template>
<xsl:call-template name="applyPhoneFormat"><xsl:with-param name="dtypephone" select="phone/sister"/></xsl:call-template>
</xsl:template>

<xsl:template name="applyPhoneFormat">
<xsl:param name="dtypephone"/>
<xsl:param name="output"/>
<xsl:param name="num" select="substring-before($dtypephone, $CRLF)" />
<xsl:param name="pattern" select="substring-after($dtypephone, $CRLF)" />
<xsl:param name="ploop" select="string-length($pattern)" />
<xsl:param name="nloop" select="string-length($num)" />

<xsl:variable name="patterncursor" select="substring($pattern, $ploop , 1 )" />
<xsl:variable name="numbercursor" select="substring($num, $nloop , 1 )" />

<xsl:choose>
<xsl:when test="$ploop > 0">
<xsl:choose>
<xsl:when test="$patterncursor = 0">
<xsl:call-template name="applyPhoneFormat">
<xsl:with-param name="dtypephone" select="$dtypephone"/>
<xsl:with-param name="ploop" select="$ploop - 1"/>
<xsl:with-param name="nloop" select="$nloop - 1"/>
<xsl:with-param name="output" select="concat($numbercursor,$output)" />
</xsl:call-template>
</xsl:when>
<xsl:when test="$patterncursor = $SP">
<xsl:call-template name="applyPhoneFormat">
<xsl:with-param name="dtypephone" select="$dtypephone"/>
<xsl:with-param name="ploop" select="$ploop - 1"/>
<xsl:with-param name="nloop" select="$nloop"/>
<xsl:with-param name="output" select="concat($patterncursor,$output)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="applyPhoneFormat">
<xsl:with-param name="dtypephone" select="$dtypephone"/>
<xsl:with-param name="ploop" select="$ploop - 1"/>
<xsl:with-param name="nloop" select="$nloop"/>
<xsl:with-param name="output" select="$output" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($output,$CRLF)" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

Before we leave this topic, i want to touch on the original challenge, which was to retrieve the phone number portion from the DTYPE_PHONE field without using any scripting, and although we've achieved that, plus a whole lot more. Some could argue that the XSLT solution is a form of scripting, but without all the negative associations.

Its not quite black or white, so i'll leave that for you to think about.

Stay tuned for more Impossible solutions!


Auto login into iSQL

Sometimes its the little things that make a big difference in life, i see a lot of people tediously entering all the connection details each time they want to log into their local database.

The following shortcut will allow you to log into the local database automatically.

C:\<Siebel directory>\Tools\BIN\dbisqlc.exe -c
"uid=SIEBEL;dbf=C:\<Siebel directory>\Tools\LOCAL\sse_data.dbf;pwd=<your password>"

In some projects, system policy forces us to change our server passwords every 45 days, even for development environments, which means our passwords will be out of sync with the local database.

This causes all sorts of issues, the most annoying is being locked out of the database. When the local database tries to connect with the old password, this is the counted as the first failed attempt, if you enter in an incorrect password, this is the second attempt, and when you try to connect again, the local still uses the incorrect password, causing you to fail authentication 3 times, when you only had 1 try.

To change the local database password, issue the following commands.

--Change password
grant connect to <USERNAME> identified by <PASSWORD>;
grant connect to SIEBEL identified by <PASSWORD>;

commit;

Remember to also change your auto login script, you can get around this task by using the DBA login, but then you have to prefix all your table references with SIEBEL when typing your statements, its a compromise either way.

Format DTYPE_PHONE EAI phone challenge - Part 1




This is the followup article to Strip off Number format in DTYPE_PHONE field (No Script) and also Scriptless Siebel Challenge: Phone Numbers in EAI from Siebel Essentials.

I first came across this problem 3 years ago in a production environment. There was a complaint, that the phone numbers that we were sending across to the external system had inconsistent number formatting.

In Siebel, the phone formatting is controlled by the PHONE_FORMAT LOV. If the user enters in the correct number format, the system will store the number in a compressed format, and use the PHONE_FORMAT lookup to apply to the UI.

However if the user enters in a phone number different to the LOV, the system stores the phone number + the new format string.

The root cause of our problem 3 years ago, was that we had an EIM process that created new and updated existing records. Any phone numbers that were updated by EIM, took the literal value, and not the compressed value that the UI stored.

Example
02 1234 4567 // value from EIM
+611234567 // value from UI using default LOV format
+61021234567|(00) 0000 0000 //value with custom format

All these values could exist simultaneously in the same database column, because the physical type is a varchar(40).

We raised the problem with our TAM, and were told that no declarative means exists and needed to use a custom business service.

The solution that i'm about to share, involves no scripting, and can be applied to all sorts of string challenges.

It nicely meets all of Alex's pre-requisites for a non-scripting solution, ie. It dosnt introduce any custom code to the Applets, Application, BCs, BSs or even use obscure user properties.

Here's my thoughts on this challenge

The DTYPE_PHONE field is a proprietry Siebel format, so there are no standard string functions that will single handedly apply the formatting, there are no documented Siebel user properties that will apply the formatting for us, and to add more complexity the challenge, the user may not want the country codes to be sent across.

Heres how we solve it
Conceptully we need to implement a custom string function that does the following

  1. Split the TYPE_PHONE into a number and a pattern string
  2. Have a cursor that iterates through the pattern string

    • If character = 0 then and place the corresponding position on the number string into an Output property
    • Otherwise place the non numeric character from the pattern string into an Output property

  3. Loop through pattern string and concatenate the Output string until it has finished

I've highlighted key design concepts to solve this problem, now since we cannot use any scripting, the above concept seems impossible, but thats what we are all about.

In the next post i will provide the actual technical solution.


Run eScript dynamically on the fly without compiling < 8.0

In our lives as developers, we face daily situtaions where we have to meet business process automation challenges.

In the Siebel essentials course, we are trained into the Siebel mantra of exhausting all declarative alternatives before resorting to using script.

But to be a successful Siebel consultant, we have to be adept in more than just one discipline.

We cannot sell ourselves as declarative config specialists.

We can dream up solutions of using fancy calculated fields (within calculated fields) and funky links based on twisted joins, that rely on sort orders to work, but this tends to be less maintainable then writing nicely encapsulated code, that can be reused.

Writing eScript is a neccessary part of life, but the process is quite cumbersome. You have to write the code, wait for it to compile, and then wait for the client to launch and test it.

As any curious developer would do, I thought there must be a better way, there should be a way to access Siebels eScript engine externally.

The breakthrough came from T.Mueller, a colleague who had the idea to build his own eScript engine.

At first, this sounds really hardcore, what kind of geek is willing to re-implement the eScript engine which has been around since the 90s?, but anyone with a strong background in ECMA/Javascript can achieve this, (a little Java background would defintely come in handy, but not neccessary).

This guide is aimed at the advanced developer, so I will outline the main concepts of this implementation.

Here is the solution overview.

  1. Install Java Developemnt Kit/Java IDE
  2. Import ECMA scripting engine
  3. Use Java Databean to connect to Siebel
  4. Pass Siebel Java application object into ECMA engine
  5. Create a class abstraction layer to translate Java methods into eScript language

You might be wondering, wether it is worth your while to build this tool, since in Siebel 8 we have Fix and Go for the ST engine. The answer depends on how close you are to using version 8.

For those who cant see 8 on the horizon, or are geeky enough to try this, then you will be priviledged to have a new Scripting tool in your arsenal.

Also remember, that even if you are using 8 now, the next project you end up on might be pre 8 =). I know of a couple of places still using 6, but hopefully none of us end up there.

Here are the advantages of this tool:

  1. Run eScript dynamically on the server without compile
  2. Quickly prototype solutions
  3. Rapid debugging and testing of scripts
  4. Highlight script and syntax problems before they are checked-in

In the next article in the series, I will show you how to build this tool, so stay tuned.

Strip off Number format in DTYPE_PHONE field (No Script)




There is an interesting post Scriptless Siebel - A Challenge over at Alex's Siebel Essentials blog.

One of his readers posts this challenge.

  • Scenario
    "We were sending a Contact Record to external system via HTTP.That contact Record had a field called Work Phone of Dtype_Phone.I guess you might be aware that Dtype_Phones are stored along with Format string which consists of zeroes, if user enterd some space in Phone number like - If User Enters +44123 456 789 then it will be stored in database as -
    +44123456789CRLF000 000 000.

    Now I was using a WF which use EAI Siebel adapter to get Siebel Message. Then I would convert that into xml and send to external system.External system said to remove those zeroes and send.Though there is a delimitter in form of new line between zeroes and actual number, I was unable to do this task in config."
If i am understanding the requirement correctly, it should be quite simple to transform the message in WF, before sending it to the external system.

Assuming our XML looks like this.

<phone>+44123456789
000 000 000</phone>
//Note: there this a real CRLF character between the phone and the phone format

We can use the following XSLT to split the field to return us just the phone number without the format.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:variable name="CRLF">&#10;
<xsl:variable name="num" select="substring-before(phone, $CRLF)" />
<xsl:variable name="pattern" select="substring-after(phone, $CRLF)" />
phone: <xsl:value-of select="$num" /> <xsl:value-of select="$CRLF"/>
pattern: <xsl:value-of select="$pattern" /> <xsl:value-of select="$CRLF"/>
</xsl:template>
</xsl:stylesheet>


However, i think we can make it better, so i would like to propose a new challenge.

Following the above scenario, get the DTYPE_PHONE value, extrapolate the pattern and apply it to the phone number on the fly before sending out to the external system (this of course must be done without any sort of custom script).

eg. The system must take this format "000 000 000" and apply it to "+44123456789" to output "+44 123 456 789"

Stay tuned to see the solution to the problem.