Friday, December 30, 2016
Back to Siebel
Thursday, December 1, 2016
TCC: Date Manipulation
cleartext.blogspot.com
<quer:projection id="idEEO2bDisabledPersonAnswerNo" alias="CorrectedStartDate">
<!--quer:customFunction name="TO_CHAR"-->
<quer:query projectedClass="Location" alias="Corr_Start_Dt">
<quer:projections>
<quer:projection>
<quer:add>
<quer:field ownerQuery="MainQuery" path="Applications,Offers,ActualStartDate"/>cleartext.blogspot.com
<quer:divide>
<quer:add>
<quer:field path="NetworkLocation,TimeZone,Offset"/>
<quer:multiply>
<!---->
<quer:add>
<quer:customFunction name="TO_NUMBER">
<quer:customFunction name="SUBSTR">
<quer:customFunction name="TZ_OFFSET">
<quer:customFunction name="TO_CHAR">
<quer:field ownerQuery="MainQuery" path="Applications,Offers,ActualStartDate"/>
<quer:string>TZR</quer:string>
</quer:customFunction>
</quer:customFunction>
<quer:integer>1</quer:integer>
<quer:integer>3</quer:integer>
</quer:customFunction>
</quer:customFunction>
<quer:divide>
<quer:customFunction name="TO_NUMBER">cleartext.blogspot.com
<quer:customFunction name="SUBSTR">
<quer:customFunction name="TZ_OFFSET">
<quer:customFunction name="TO_CHAR">
<quer:field ownerQuery="MainQuery" path="Applications,Offers,ActualStartDate"/>
<quer:string>TZR</quer:string>
</quer:customFunction>
</quer:customFunction>
<quer:integer>5</quer:integer>
<quer:integer>2</quer:integer>
</quer:customFunction>
</quer:customFunction>
<quer:integer>60</quer:integer>cleartext.blogspot.com
</quer:divide>
</quer:add>
<quer:integer>-1</quer:integer>
<!---->
</quer:multiply>
</quer:add>
<quer:integer>24</quer:integer>
</quer:divide>
</quer:add>
</quer:projection>
</quer:projections>
<quer:filterings>
<quer:filtering>
<quer:equal>
<quer:field path="Code"/>cleartext.blogspot.com
<quer:field ownerQuery="MainQuery" path="Applications,Requisition,JobInformation,PrimaryLocation,Location.Code"/>
</quer:equal>
</quer:filtering>
</quer:filterings>
</quer:query>
<!--quer:string>yyyy-MM-dd hh:mm:ss</quer:string></quer:customFunction-->
</quer:projection>
cleartext.blogspot.com
Monday, September 19, 2016
Too Much Javascript
I can't understand this trend. After years of focus and interest in compiled languages and binary executables, now everyone is focussed on what can be done in the humble browser. And its programming language, Javascript. And that's where the action is. Everyday I hear about new javascript based libraries and frameworks. And the language syntax is getting worse. With new conventions of invoking script and processing data, its almost as if they are re-inventing multiple wheels again. There are new graphing and charting libraries, and it is now possible to build entire standalone desktop applications running on javascript. It seems to be everyone's favourite, enjoying a position once occupied by Java. I can straightly see the advantages of moving your UI code to Javascript.
- It is truly portable. Runs in all modern browsers, even on smartphones and tablets.
- Flash and Java, the previous leaders in browser programming, are no longer supported by newer browsers. Maybe due to security vulnerabitlies in them.
- None of that bytecode compilation you see in Java class files.
- The source stays with you, so it is still modifyable.
- It is free. Truly free. It is open source.
But I can't help noticing that it greatly increases the amount of data being downloaded into the final browser. And takes up a lot of bandwidth. Sure, many of those applications use require.js and files are loaded only conditionally. But still, they need to be downloaded. And the humongous task of executing the program is now transferred from the server to the end-user's browser. Which is definitely good for the server, lesser load balancing to take care of. But on many sites, I can actually feel the browser slowing down due to the additional processing power it needs.
I like browsing light weight. I sometimes turn off javascript completely on some news sites, I feel it gives a much faster rendering of the site, as none of those additional garbage is loaded and run. The URL links still work, because those are in the HTML.
But the bigger problem is see is un-regulated development. Everyone is writing their own libraries and packages. First it was just google and facebook. Now even new players like oracle has entered the race and are giving out their own libraries. And the tutorials of all their libraries does the same thing: render graphs and charts in the browser.
Too many tools. Too much configuration. That is the problem. Javascript experts have written better about these problems, so I will leave that there.
The bigger problem I see lines of code. After programming for more than 20 years now, I have learned to understand is that the real challenge (and fun) in programming is to achieve maximum tasks writing as little code as possible. You don't have to be Phd to understand that it is easier to debug and test a 10 line program than a 100 line program. Every extra line added to the codebase increases the difficulty in debugging it at a later stage. Not to mention the huge effort of merging code written by large teams during checkin. But all these javascript based boilerplates, linters and generators don't solve this problem, they just make it worse.
A library should be simple enough to add it into ones current code base, and the developer should not have to know how it is implemented to use it. All the real work must be transferred into the library being invoked, leaving the base code base minimal. Minimal. That should be the keyword.
Or there should be a way for RAD tools. A system of abstractions which will hide the complexity beneath and generate highly efficient code.
When I started work in Siebel, I used to hate the idea of Enterprise Application development. But I absolutely admired the way Siebel had built a layer of abstraction and user properties, and through them, indirectly invoked C++ code to achieve its functionality. Sure there is one extra layer in this packaged application method, but the final code which the consultant/developer writes is very minimal. I have seen entire projects implemented with a total of less than 1000 lines of escript code in it.
I was looking into the new Oracle JET library for javascript application development which was created by Oracle and it is completely bonkers. All they have done is to re-implement a couple of already perfecte ideas and re-do it in their own way. A lot of the final code looks exactly the same as from Angular or React. I have no idea why any enterprise customer would decided to writes thousands of lines of javascript code just to get charts rendered in the browser, when other Oracle delivered packaged and cloud applications can do the same without ANY lines of code.
Hope somebody sits up and takes notice.
Friday, August 26, 2016
Linux is 25 today !
25 years ago , Linus Torvalds let the world know of his pet project for a new operating system. And started the revolution.
Wednesday, August 24, 2016
Oracle JET
Oracle has released the training videos of their new Java Toolkit, Oracle JET. They are calling it a MOOC, or Massive Open Online Course.
Tuesday, August 23, 2016
Tuesday, August 16, 2016
Importing WSDLs with cyclic references into Siebel
In this example schema, element "LineItemARBOType" has a child of type "LineItemARBOType" again.
Following are warnings generated in the process:
Service 'xx' can not be imported, because none of its ports could be imported.(SBL-EAI-04333)
Port 'xx' can not be imported. PortType 'xx' can not be imported. The http://schemas.xmlsoap.org/wsdl/:operation 'xx' was ignored. Error importing XML schema via method 'xx' for 'element' 'xx' in 'xx'(SBL-EAI-08009)
Cycle detected in the 'xx' schema: xx 'xx' has a cycle (SBL-EAI-09008).
(SBL-EAI-04331).
Tuesday, August 2, 2016
Wednesday, July 27, 2016
BIP: Report Usernames
There was a simple requirement to print the login name of the user running a BIPublisher report on that report itself. This got me hunting. There are tonnes of ways to get the login name from an oracle database, but because of the way BIP uses the DB and runs the SQL, not all of those ways would give the right answers. cleartext.blogspot.com
Simplest way, use the <?$XDO_USER_NAME?> parameter n your template.
But my requirement was to enforce data security on the report, to ensure the logged in user sees only the records he should see. This meant fetching the username at the SQL itself.
One sure shot way to do this is to use :XDO_USER_NAME in the SQL. This will fetch the userid of the logged in user. cleartext.blogspot.com
And there is one more way.
Use the sys_context ('userenv','CLIENT_IDENTIFIER') CLIENT_IDENTIFIER function in the SQL. cleartext.blogspot.com
To get all the sys_context parameters, this SQL can be used. cleartext.blogspot.com
select
sys_context ('userenv','ACTION') ACTION,
sys_context ('userenv','AUDITED_CURSORID') AUDITED_CURSORID,
sys_context ('userenv','AUTHENTICATED_IDENTITY') AUTHENTICATED_IDENTITY,
sys_context ('userenv','AUTHENTICATION_DATA') AUTHENTICATION_DATA,
sys_context ('userenv','AUTHENTICATION_METHOD') AUTHENTICATION_METHOD,
sys_context ('userenv','BG_JOB_ID') BG_JOB_ID,
sys_context ('userenv','CLIENT_IDENTIFIER') CLIENT_IDENTIFIER,
sys_context ('userenv','CLIENT_INFO') CLIENT_INFO,
sys_context ('userenv','CURRENT_BIND') CURRENT_BIND,
sys_context ('userenv','CURRENT_EDITION_ID') CURRENT_EDITION_ID,
sys_context ('userenv','CURRENT_EDITION_NAME') CURRENT_EDITION_NAME,
sys_context ('userenv','CURRENT_SCHEMA') CURRENT_SCHEMA,
sys_context ('userenv','CURRENT_SCHEMAID') CURRENT_SCHEMAID,
sys_context ('userenv','CURRENT_SQL') CURRENT_SQL,
sys_context ('userenv','CURRENT_SQLn') CURRENT_SQLn,
sys_context ('userenv','CURRENT_SQL_LENGTH') CURRENT_SQL_LENGTH,
sys_context ('userenv','CURRENT_USER') CURRENT_USER,
sys_context ('userenv','CURRENT_USERID') CURRENT_USERID,
sys_context ('userenv','DATABASE_ROLE') DATABASE_ROLE,
sys_context ('userenv','DB_DOMAIN') DB_DOMAIN,
sys_context ('userenv','DB_NAME') DB_NAME,
sys_context ('userenv','DB_UNIQUE_NAME') DB_UNIQUE_NAME,
sys_context ('userenv','DBLINK_INFO') DBLINK_INFO,
sys_context ('userenv','ENTRYID') ENTRYID,
sys_context ('userenv','ENTERPRISE_IDENTITY') ENTERPRISE_IDENTITY,
sys_context ('userenv','FG_JOB_ID') FG_JOB_ID,
sys_context ('userenv','GLOBAL_CONTEXT_MEMORY') GLOBAL_CONTEXT_MEMORY,
sys_context ('userenv','GLOBAL_UID') GLOBAL_UID,
sys_context ('userenv','HOST') HOST,
sys_context ('userenv','IDENTIFICATION_TYPE') IDENTIFICATION_TYPE,
sys_context ('userenv','INSTANCE') INSTANCE,
sys_context ('userenv','INSTANCE_NAME') INSTANCE_NAME, cleartext.blogspot.com
sys_context ('userenv','IP_ADDRESS') IP_ADDRESS,
sys_context ('userenv','ISDBA') ISDBA,
sys_context ('userenv','LANG') LANG,
sys_context ('userenv','LANGUAGE') LANGUAGE,
sys_context ('userenv','MODULE') MODULE,
sys_context ('userenv','NETWORK_PROTOCOL') NETWORK_PROTOCOL,
sys_context ('userenv','NLS_CALENDAR') NLS_CALENDAR,
sys_context ('userenv','NLS_CURRENCY') NLS_CURRENCY,
sys_context ('userenv','NLS_DATE_FORMAT') NLS_DATE_FORMAT,
sys_context ('userenv','NLS_DATE_LANGUAGE') NLS_DATE_LANGUAGE,
sys_context ('userenv','NLS_SORT') NLS_SORT,
sys_context ('userenv','NLS_TERRITORY') NLS_TERRITORY,
sys_context ('userenv','OS_USER') OS_USER,
sys_context ('userenv','POLICY_INVOKER') POLICY_INVOKER,
sys_context ('userenv','PROXY_ENTERPRISE_IDENTITY') PROXY_ENTERPRISE_IDENTITY,
sys_context ('userenv','PROXY_USER') PROXY_USER,
sys_context ('userenv','PROXY_USERID') PROXY_USERID,
sys_context ('userenv','SERVER_HOST') SERVER_HOST,
sys_context ('userenv','SERVICE_NAME') SERVICE_NAME,
sys_context ('userenv','SESSION_EDITION_ID') SESSION_EDITION_ID,
sys_context ('userenv','SESSION_EDITION_NAME') SESSION_EDITION_NAME,
sys_context ('userenv','SESSION_USER') SESSION_USER,
sys_context ('userenv','SESSION_USERID') SESSION_USERID,
sys_context ('userenv','SESSIONID') SESSIONID,
sys_context ('userenv','SID') SID,
sys_context ('userenv','STATEMENTID') STATEMENTID, cleartext.blogspot.com
sys_context ('userenv','TERMINAL') TERMINAL
from dual
Try running this on Oracle Live SQL
Monday, July 11, 2016
SQLFiddle (for Oracle) is broken. Try Oracle Live SQL
BI Publisher reporting work involves a lot of SQL. And often (in the Oracle world) one needs a quick way to try an Oracle function in a quick sandbox like system. For long time, I have been using SQLFiddle, which provides a simple browser UI to create schema and run SQLs on them. But for many months now, the Oracle support on SQLFiddle has been broken. And I was looking for alternatives.
Turns out, Oracle themselves provides an excellent replacement tool to create schemas and run SQLs. Free for anyone who has an oracle.com login. That includes all customers and vendors working on their products. cleartext.blogspot.com
Go to Oracle Live SQL. The SQL worksheet page there can be used to run any SQLs, and its on a 12c DB server. cleartext.blogspot.com
There is a simple schema designer to create schema. Or you can also use standard DDL functions. Turns out , this is actually a simple Apex application. cleartext.blogspot.com
cleartext.blogspot.com
Tuesday, June 14, 2016
BIP: Distinct
cleartext.blogspot.com
BIP has a distinct function
xdoxslt:distinct_values
If you use it on a node of elements, it returns a space separated sequence of its distinct elements.
Eg: for this xml:
cleartext.blogspot.com
<ROWSET>
<ROW>
<CwaProductCode>001</CwaProductCode>
</ROW>
<ROW>
<CwaProductCode>002</CwaProductCode>
</ROW>
<ROW>
<CwaProductCode>001</CwaProductCode>
</ROW>
<ROW>
<CwaProductCode>003</CwaProductCode>
</ROW>
</ROWSET>
cleartext.blogspot.com
Using <?xdoxslt:distinct_values(CwaProductCode)?> gives:
001 002 003
Using <?count(xdoxslt:distinct_values(CwaProductCode))?> gives:
3
But what if one needs to group by the distinct values, and then count the number of elements under it ? Then distinct can’t help.
cleartext.blogspot.com
<?for-each-group:ROW;./CwaProductCode?>
<?CwaProductCode?><?'-'?><?count(current-group()/.)?>
<?end for-each-group?>
Gives the answer:
001-2
002-1
003-1
cleartext.blogspot.com
cleartext.blogspot.com
Wednesday, June 1, 2016
What caused the NA14 outage ?
There is a very nice indept article here explaining what happened during the SFDC outage on May 9th, 2016, when server NA14 went down. It also discusses the aftermath and lessons learnt from the outage.
Friday, May 20, 2016
HCM: Printing Hours and Rates on Checkwriter
Fusion HCM Cloud uses BIP templates as part of it payroll process, its also used for printing checks. One of the most common requirements I have received is to print the employees hours and rates on the checkprinter output.
Here is what the vanilla template looks like, its called USCheckWriterReport.rtf.
cleartext.blogspot.com
It can be seen that the earnings section in the bottom prints only current and YTD amounts. The hours and rates are not printed by default.
The hours and rates are in a different node in the Payslip xml
cleartext.blogspot.com
This is the node for earnings:
And this is the one for Hours and Rates
So what we need to do is the use the REPORTING_NAME as a foreign key, and lookup the correct HOURS_X_RATE record, and then print it in the earnings table.
cleartext.blogspot.com
This is the code to use:
<?$ava_earnings/GLB_PAY_ARCH_PR_HOURS_X_RATE[REPORTING_NAME=current()/REPORTING_NAME]/EARNINGS_HOURS?>
PS: I am just putting this up for my own reference, and for anyone out there stuck like me.
cleartext.blogspot.com
Wednesday, May 11, 2016
Major SFDC Outage
Today there is a hackernews thread describing a major SFDC Outage.
This is the side effect of the cloud computing. An outage affects multiple businesses.
Friday, April 15, 2016
Fusion HCM: Testing Payroll templates
Oracle’s Fusion HCM cloud service uses BIP templates as part of its pay processing. When the Payoll processes are submitted, HCM does a lot of things, it generates the Pay data, and populates tables. But the final step of this process is to generate the actual payslip , and for this it invokes a BIP report. © 2016 cleartext.blogspot.com
As report designer, I often get requests to modify these reports. But to test the reports, one need not run the entire payroll process again. Simply re-running the report with the modified template will suffice. © 2016 cleartext.blogspot.com
The BIP template to modify for US is the USOnlinePayslip.
To see when it was last run, simply check the history of this report, under More-> History. Reset the query and run search.
Pick up any of the last records, and drilldown on it. Now copy the Payroll Action Identifier from this page © 2016 cleartext.blogspot.com
Now you can go back and re-run this report with this parameter, and can see the changes of your template instantly ! Ta-da ! © 2016 cleartext.blogspot.com
Friday, April 8, 2016
Oracle Sales Cloud: Getting around OSC’s WSDL parsing , Siebel UCM
Recently working on getting Oracle Sales Cloud integrated to Siebel UCM for Accounts. Oracle Sales Cloud can read a WSDL specification from a URL, but you still have to build the request message using Groovy script (would be nice to shoot whoever designed this). So you have to use Groovy script and write a global function to build up the message. Turns out, you can only add elements and attributes to the message which is already in the parsed WSDL. Nothing new can be added. © 2016 cleartext.blogspot.com
The problem here is that for integrations to Siebel UCM, a hidden attribute named ExternalSystemId has to be populated in the incoming message. This attribute is not in the WSDL when it gets generated from Siebel UCM. But it has to be sent in the SOAP request (would also be nice to shoot whoever designed this). © 2016 cleartext.blogspot.com
Error invoking service 'UCM Transaction Manager', method 'SOAPExecute' at step 'Transaction Manager'.(SBL-BPR-00162)
--
<?> Failed to find ExternalSystemId in input message(SBL-IAI-00436)
This is what you get when you consume the UCM WSDL in SOAP UI.
The actual message has to be (see highlighted changes) © 2016 cleartext.blogspot.com
If you add the groovy script to add this attribute, OSC will simply ignore it, and the attribute is not send to UCM. The only viable workaround is to Edit the WSDL AFTER it is generated, but BEFORE it is given to Sales Cloud ! © 2016 cleartext.blogspot.com
1: Generate the WSDL from UCM.
2: Open it in an XML editor , use XMLSPY if you have it. © 2016 cleartext.blogspot.com
3: Find the definition of the top container element int the WSDL: © 2016 cleartext.blogspot.com
4: Add this text (highlighted) : © 2016 cleartext.blogspot.com
<xsd:attribute name="ExternalSystemId" type="xsd:string"/>
5: Now validate, save and upload this WSDL to your public folder from where OSC can read it. OSC does not consume WSDLs, but reads the definition on the fly. © 2016 cleartext.blogspot.com
6: Now add the groovy script to populate this new attribute with the registered SystemId Name.
Phew !!
© 2016 cleartext.blogspot.com© 2016 cleartext.blogspot.com
Thursday, March 31, 2016
TCC: Handling Encoding
Aahh…multilingual. That word increases the complexity of any project intantly. When your enterprise application is multilingual, it means users will be able to add and edit data in different languages, and that the data can no longer be stored in ASII/ANSI format. East Asian, and Middle Eastern and some European languages require more than one byte for a single charachter, so it has to be stored in Unicode format. While working on Taleo’s TCC scripts, I recently hit a roadblock with multilingual data, but the fantastic folks at Taleo had already solved the problem. © cleartext.blogspot.com 2016
TCC’s pipelines handle data in UTF-8 format, but many enterprise systems will produce output in UTF-16. So which one is better ? There is a common misconception that UTF-8 can not store all language charachters, and that UTF-16 is required. That’s not true. UTF-8 has an amazing awesome format, and it can depict every Unicode charachter, same as UTF-16. Here is a spectucular explanation of this miracle.
So if you get data in UTF-16 (or any of the other formats), how do you load them via TCC ? In the configuration file, TCC provides an option to set the encoding of the source file. © cleartext.blogspot.com 2016
If you know the encoding of the source, you enter it here. This will work for standard Import files. There is also an option to set the response encoding.
But some complicated TCC configurations, like NetChange, require the pipeline data to be in UTF-8. So how do you get around that ?
The encoding can be changed in the configuration file. Go to Pre-Processing tab, and add a new step.
There is an option to add an ‘Convert Encoding’ step. © cleartext.blogspot.com 2016
Choose the source encoding, and set the target as UTF-8. This step has to be the first step in your NetChange configuration file.
Thats it ! cleartext.blogspot.com
Tuesday, March 29, 2016
Monday, March 21, 2016
Date calculations in eText templates
Aahh, eText. That most hated or Oracle templates. One area where this template really falls is in the area of date calculation, or date manipulations. Example a standard requirement is to calculate an end date, or proposed/expected end date for some transaction. Check is valid for only ..30 days from date of issue. cleartext.blogspot.com
The official documentation does no mention any way to x number of days to dates. But if you search on supportweb, you will come across the INCREASE_DATE function.
To add 30 days to today’s date, use INCREASE_DATE(SYSDATE(),30). To substract days, use a negative number for the offset. cleartext.blogspot.com
But that’s it, eText does not provide a way to get the month, year, or day from a date. So those will have to be calculated in whatever onpremise/cloud system is being used and the value must be present in the xml. eText also does not provide a way to add extra functions or XSLT functions in the templates, like in BIP RTF templates. cleartext.blogspot.com
Originally published on cleartext.blogspot.com
Thursday, March 10, 2016
Sequence Numbers in eText templates
As I said earlier, Oracle’s eText template is really painful to work with. Its does not have support variables or arrays, so when the need arises to have something temporarily stored somewhere, you are lost. The one thing eText does have, is a method to generate sequence numbers. Basically you use the DEFINE_SEQUENCE command.
The define sequence command has four subcommands: reset at level, increment basis, start at, and maximum. The increment basis subcommand specifies if the sequence should be incremented based on record or extract instances. The allowed parameters for this subcommand are RECORD and LEVEL. Enter RECORD to increment the sequence for every record. Enter LEVEL to increment the sequence for every new instance of a level. cleartext.blogspot.com
To generate the sequnce numbers, use the SEQUENCE_NUMBER function in the template.
But what if you just want to keep count of something, and not count levels or records in the data ? Just leave out the INCREMENT_BASIS completely. cleartext.blogspot.com
So now, whenever SEQUENCE_NUMBER function is called, the current value will be printed, and the counter will be increased by 1. This happens everytime the function is invoked.
There are some payment interfaces where the number has to be incremented in steps of 5 or 10. For example, one of the ADP checkprinter format template requires a counter to start at 30, and be incremented in steps of 5. So its 30, 35, 40, 45…
To do that the SEQUENCE_NUMBER function should be used with some mathematics.
Originally published on cleartext.blogspot.com