Monday, March 17, 2008

BI Publisher: BIP in the OA Framework part I



Have you ever wondered how the PO report pops up without a submitting a concurrent request? Pretty sweet huh! Well your going to know how do it after you reading this blog.

When this type of functionality came out in 11.5.10 myself and others wondered how is this possible, how can you generate a document and display it in "real-time." After digging into in 2005, I figured out that it was using the OA Framework. The problem for me at the time though was that I didn't have a clue about the OA Framework. I was literally baffeled and frustrated (see screaming baby above). I kept searching for the poViewDocumentPG and for the life of me I couldn't freakin' find it.

Well it's a two years later and I finally spent some time into figuring it out. A couple of key factors was reading the documentation, plus, I've started doing some OA Framework development. When we look at bare-bones how a pdf can be displayed on a screen in using the OA Framework it's really straightforward. Throughout this document I'm going to refer to this type of development as the "Real-Time" model.

How the Oracle PO Works

Step 1. find the form function PO_VIEW_DOCUMENT,

HTML CALL: OA.jsp?page=/oracle/apps/po/communicate/webui/poViewDocumentPG

Step 2. Create an OA framework page, very simple. This is ridicuosly easily. You need to have a controller and application module. Note, the application module doesn't have to have anything it but it must exist.

FYI: For our example, the PO_VIEW_DOCUMENT function has a page called poViewDocumentPG, however when we go out to the code tree (/oracle/apps/po/communicate/webui/) it doesn't exist. This because the xml files are loaded in the database. We can use this utility to download it:

begin

JDR_UTILS.printDocument('/oracle/apps/po/communicate/webui/poViewDocumentPG');

end;

We can see it's a bare bones page with one region and zero fields.

Step 3: write the logic in the controller class to get the document and return it. Note: this is a weird way to create an OAF page, usually you call the Application Module to generate the data and set the where clauses for the view objects in the AM, which bind to the OAF page. However the controller in this example generates the data/document and use HttpServletResponse to create the page, the application module doesn't really do anything. The application module could if you wanted it to, the blanket sales agreement is an example where the AM generates the xml.

sample code snippet:

public class poViewDocumentCO extends oracle.apps.fnd.framework.webui.OAControllerImpl
{
public void processRequest(oracle.apps.fnd.framework.webui.OAPageContext oapagecontext, oracle.apps.fnd.framework.webui.beans.OAWebBean oawebbean)

int j = java.lang.Integer.parseInt(oapagecontext.getParameter("DocumentId"));
....
....
....
....
httpservletresponse.setContentType("application/pdf");
httpservletresponse.setContentLength(abyte0.length);
httpservletresponse.setHeader("Content-Disposition", "attachment;Filename = " + pogeneratedocument.getfileName());
httpservletresponse.getOutputStream().write(abyte0, 0, abyte0.length);
httpservletresponse.getOutputStream().flush();
httpservletresponse.getOutputStream().close();
return;

Step 4: Call the function from your form to create basically a pop up and generate the document. Exluded in step 3's code above is the snippet to grab all the parameters that are appended together below from the function call in the form. I left just one so you would get the point.

fnd_function.execute( function_name => 'PO_VIEW_DOCUMENT',
other_params=>'DocumentId='l_document_id'
&RevisionNum=':HEADERS_FOLDER.REVISION_NUM'
&LanguageCode='userenv('LANG''
&DocumentType='l_document_type'
&DocumentSubtype='l_document_subtype'
&OrgId=' :po_startup_values.org_id'
&AuthorizationStatus=':headers_folder.authorization_status'
&UserSecurity='userSecurity '
&StoreFlag=N'
&ViewOrCommunicate=View');

DONE DEAL

Yes that's it, there really is no OA Framework code to write for the application module or controller. Note, as a best practice if you decide to do this development, your controller class should call another class to generate the final output, the purpose of the controller in this case is purely to push the document upto the browser. This is a better practice because it allows the developer to create new and additional constructors for one class that generates the document, versus copying and pasting the logic in each implementation (OAF, JavaConcurrentProgram, etc).

Things to Keep in Mind

If your still doing report development using reports6i you really need to stop that. While reports6i is a great tool, it has one big downside (besides being dated and replaced with BIP) and that is in-order to generate xml file, you have to submit a concurrent request (there are workarounds for this, none that are pleasant). This doesn't work in the "real-time" model.

In the above example the PO will actually generate the xml using pl/sql package. While this was acceptable in the past, you really shouldn't be doing this either.

Data templates should be used for generating the xml. Besides ease of use and it being less intense than using pure pl/sql, in this model it works because it can be run in "real-time."

There are a lot of possibilities with form personalization's to plug reports in line with standard oracle forms. Simply create a menu and call a built-in function which submits a function call to the OA Framework page. This allows the developer to have even more flexibility in customizing the application and reporting, while saving users time for keying and submitting concurrent requests.

A caveat here is don't do the real-time model with slow reports. Slow reports should be concurrent requests so they can be managed and maintained more effectively. From a high-level it doesn't make any sense at all to have a slow running report in real-time, it's a distraction for end-users and it may make it harder for them to manage there report(s), hence concurrent manager.

Part II: The next article will have a zip of an OA Framework project that will push a pdf up on the screen. Booyah!

Part III: Understand BIP Integration points

Wednesday, March 12, 2008

BI Publisher: BIPublisherIDE

BI Publisher Integrated Development Environment

If you ever wondered how the BI Publisher API's worked then look no further. This is the ultimate blog on how the API's and there is a free working code base you can download and use for development.

There are four caveats:

1. This code is free but cannot be copyrighted, unless your oracle (but you need to discuss terms first with me)

2. I don't think I can distribute xdocore.jar file, you will need to download either in the latest patchset (ebs) or standalone version.

For 11i environment, I would suggest downloading patch: 5472959. If you put the j5472959_xdo.zip file in c:\JDeveloper\jdev\mywork\BIPublisherIDE\BIPublisherIDE\lib
the project should work.

3. If you improve the project you should share the information here in this blogpost.

4. If you download the project please post a "positive comment." Kidding...but it would nice!

History

Long ago, I was doing a tremedous amount of BI Publisher development inside the EBS and Oracle Portal. One of the problems I was having is that BI Publisher development can be time consuming when you continually have to reload your format template, data template into the database and re-iteratively submit concurrent requests.

I was also faced with other issues as well, what if I wanted to test eText and Bursting locally? There was no option to do this any product. The only way to test eText is start->programs- your bip installation-> run template viewer


How It Works: Architecture


The BIPublisherIDE is setup for a developer by a developer (it's just like the hair club for men, "I'm not only a member but I'm also a client.")

There is a config class, api class and utility class.

config->api->utility

1. The config class contains methods and creates connections to databases.

2. The api's class extends the config class and inherits the methods and has the ability to override the methods. This class contains all of the bi publisher core api's.

3. The utility class extends the api class, put simply the utility class is a wrapper. It sets the foundation for which api's to call based on what is set in the config file (xml).

The design is intentional and sets a precedence for doing report development. As developers we iteratively run unit tests till we receive the desired result. One of the most cumbersome problems we face is that there is a lot of "non-value" added steps in report development process. This is why report development to a certain degree needs to be configurable and run locally.

Other benefits of the design is that fact that it's not only a development tool, it can be deployed in other environments. For instance you can deploy the BIPublisherIDE jar file in a concurrent program or other web based environment like portal, websphere, etc (this might be helpful for apex too).

How to run the IDE (BIPublisherIDE.pdf)

Download the IDE (BIPublisherIDE.zip)

Next Article to Come: How to display a BIP Report using the OA Framework (i.e: like the PO)