11i Oracle Apps Technical Manual
11i Oracle Apps Technical Manual
11i Oracle Apps Technical Manual
This blog is an effort to help you become a technical Oracle Apps consultant. In this blog,
I will publish articles on Oracle Applications training right from the very basics.
In my case, 10 years ago, I first took training in some programming languages like C, C+
+, VB, & of course Oracle. The good thing that came out was that I realised all
programming languages have a commonality, i.e logic. But logic I was the thing I feared
the most, I never knew I could do it. At university, I had always bunked my Fortran and
Unix lessons simply because of the logic phobia I had in my mind. Anyway, eventually I
learnt Oracle SQL-PL/SQL, Forms and Reports. The bottom line is, keep your fears aside
and take the dive and get started with the learning path.
Please note the pre-requisites. Kindly note that you can't jump onto becoming an Oracle
Apps Technical Career path without having learnt the prerequisites that will form the base
of Oracle Apps Development work.
Pre-requisites
------------------
1. Learn SQL and PL/SQL.
Firstly learn SQL. I think this link for w3schools will get you started from the very basics.
You may also install Oracle Lite from technet and practice some SQL. Just the basic SQL
with couple of joins and couple of where clauses are good enough to get started. When
learning SQL, try to imagine/visualize the scanning and filtering of records that Oracle
will be performing behind the scenes.
2. Learn D2k. More importantly Oracle Forms 6i and Reports 6i. All you need to learn are
the fundamentals at this stage. You should be able to create a Master Detail block based
form that calls from PL/SQL and one pll. For Oracle Reports, you must try to develop a
report from scratch that has at least two queries with one link joining the two. You should
also know things like formula column, b4 report & after param triggers.
3. It is good to know some Java Programming; however, knowledge of java has not yet
become mandatory for Oracle Apps Technical Consultants. Ditto for XML and HTML. If
you are a beginner, then dont bother to learn Java right now. Java can be learnt in parallel
while you work on Oracle Applications.
Once having learnt the above tools, you will then be ready to begin Oracle Apps
Technical Training from scratch.
Basics Of Oracle Apps Training Material (Step by Step
Learning of Oracle Apps)
What happens when you login to Oracle Apps
Why is it called apps
What is a profile option?
What is org_id. Why is it important.
Relationship between Applications and Modules
Where to find/deploy the code (Forms tier/Middle tier or DB Tier)
The testing cycle in Oracle Apps
Difference between forms and form functions and menu
What is a Concurrent Program
What is Concurrent Manager
What is a Value set
What is a lookup in oracle apps
How does lookup differ from Value Sets
Descriptive Flexfield Basics in Oracle Apps
How to make context sensitive descriptive flexfields ( step by step)
Key Flexfields Basics
Setting up your PC for development environment
Your first custom form from scratch
Your first pl/sql concurrent program from scratch
Oracle FNDLOAD Script Examples
Restart or Bounce Apache in Oracle Apps 11i
Playing with CUSTOM.pll
Read Only Schema in Oracle APPS 11i
Create Oracle FND_USER with System Administrator ( Using Script )
A New Custom Form in Oracle Apps
Forms Customization Steps in Oracle Applications
Reports Customization Steps in Oracle Applications
Your first Migration program in Apps. Migrate Customers
FNDLOAD for Oracle Web ADI
API to Update FND_USER and Add Responsibility
Forms Personalization Example 1
Various Examples of Forms Personalizations [ Everything that you wanted to know about
FP ]
Oracle Fusion Development Tools
Debugging In Oracle Applications
XML Publisher Concurrent Program Report
Audit Trail in Oracle Apps
Hierarchy Profile Options in Oracle Apps
Design and Development of Open Interfaces in Oracle Apps
Customization of Reports in Oracle Apps , How to find the Request Group for
Concurrent program , Smart Descriptive Flexfields
Using XML Publisher with Pre-Printed Stationary
Firstly and surely there is a URL for Oracle Applications that is structured possibly in
below format, although it can vary from version of apps.
http://machinename:portnumber/OA_HTML/US/ICXINDEX.htm
Eg: http://linuxerp.com:8000/OA_HTML/US/ICXINDEX.htm
http://machinename:portnumber /oa_servlets/AppsLogin
When you join an Oracle Apps development team for an employer, you will first be given
URL of the development environment.
In any Oracle Apps implementation project (assuming it has gone live), there are
minimum of three Environments, each with different URL's and different Database
Instances.
These are:-
---------------
Development environment
Testing environment
Production environment
NOTE:-You will most probably, as a Techie, be given URL, User name and Password of
the Development environment.
B. As you can see below, this User name xxpassi is attached to two responsibilities (this
will be discussed in details in latter training lesson). It is this assignment to the
responsibility that controls what a logged in person can do and can't do. In laymans
words, A Responsibility is a group of Menus.
User Definition screen
This screen below will prompt you to change your password, to a value different than that
assigned by System Administrator.
Click on either of the above Responsibility Names, will initiate Oracle Apps( Note: You
might be prompted to install jinitiator..just keep clicking OKOK for all Jinitiator
messages). Effectively, what I mean to say is that you do not need to download jInitiator
from anywhere; Oracle will do this automatically (provided your DBAs got this
cofiged) for you during your first logon attempt from the PC. Once your jInitiator gets
installed
Is it just the short name of Oracle Applications? Possibly yes, however this question is an
excuse for me to explain to you the evolution of APPS schema.
I started working in Oracle Financials 9 years ago. Those days each module had its own
Database Schema (which we still have). However, a purchasing user (until version 10.6)
used to connect to PO schema (by the virtue of the screen being a PO screen).
However, now we have several database schemas(in most cases one schema per module).
The tables are still owned by their respective schema, but now we have a Central
Schema named APPS.
Oracle ERP simply connects to APPS database schema for all its operations (with a
couple of exceptions that are best ignored for now).
Hence, if Oracle wants to create a new table named PO_HEADERS_ALL, they will do
the following
By following the above steps, as you can see, APPS schema is able to access
PO_HEADERS_ALL without the notation PO.PO_HEADERS_ALL
In Oracle ERP, now we have 100s of schemas, example PO, AR, AP, GL etc.
But the screens, reports, workflows etc in Oracle Applications connect to APPS schema
only. Just like saying, ALL ROADS LEAD TO ROME. Here, All schemas lead to APPS.
Hence if you have a Pseudo report that joins AP_INVOICES_ALL table( in AP schema)
to PO_HEADERS_ALL table( in AP schema), you will simply need to do the below
once connected to APPS.
SELECT *
FROM po_headers_all p, ap_invoices_all a
WHERE a.po_Id = p.po_Id;
Note thata prior to version 10.6(of Oracle ERP not database version), one had to do
SELECT *
FROM PO.po_headers_all p, AP.ap_invoices_all a
WHERE a.po_Id = p.po_Id;
Some notes:-
Custom tables are generally required in Oracle ERP because:-
1. You wish to create a Custom screen (your own screen to capture some info) for a
functionality that is not delivered by Oracle.
2. Pre-Interface tables (Interface will certainly be discussed in one of the latter chapters)
3. Temp processing
4. Staging of data for third party Extract Interfaces.and much more
What are Profile Options in Oracle Apps?
Profile Options provide flexibility to Oracle Apps. They are a key component of Oracle
Applications, hence these much be understood properly. I will be taking multiple
examples here to explain what profile options mean. I will also try to explain by stepping
into Oracle shoes "How will you design a program that is flexible", by using Profile
Options.For the learners of Oracle Apps, understanding profile options is mandatory.
Enough definitions, give me some scenarios where profile options are used by
Oracle....
1. There are profile options which can turn the debugging on, to generate debug messages.
Say one of 1000 users reports a problem, and hence you wish to enable debugging against
just that specific user. In this case you can Turn On the debugging profile option "again
that specific user".
2. There are profile options that control which user can give discount to their customers at
the time of data entry. You can set profile option "Discount Allowed" to a value of either
Yes or No against each Order Entry user.
3. Lets assume an Organization has departments D1 and D2. Managers of both the
Departments have "HRMS Employee View" responsibility. But you do not want
Manager of D2 to be able to see the list of Employees in Organization D1. Hence you can
set a profile option against the username of each of these users. The value assigned to
such profile option will be "Name of the Organization" for which they can see the
employees. Of course, the SQL in screen that displays list of employees will filter off the
data based on logged in users profile option value.
1. Screen should be flexible to ensure that different users of the screen can give different
levels of discounts. For example, in Order Entry screen a Clerk can not enter an Order
with more than 5% discount. But Sales Manager can enter an Order with 15% discount.
2. There should not be any hard-coding regarding the maximum permissible discount.
3. In the screen there will be a discount field.
4. When the discount value is entered in discount field, an error will be raised if user
violates the maximum permissible discount.
IF
:OE_LINE_BLOCK.DISCOUNT_VALUE >
FND_PROFILE.VALUE('OEPASSI_MAX_DISCOUNT')
THEN
MESSAGE(
'You cant give discount more than '
|| FND_PROFILE.VALUE('OEPASSI_MAX_DISCOUNT') || '%'
);
RAISE FORM_TRIGGER_FAILURE; -- Raise error after showing message
END IF;
Here is how, the client implementing Oracle Order Entry will configure
their system:
1. Navigate to System Administrator and click on System->Profile menu.
2. For Clerk user(JOHN), set value of profile "OEPASSI Maximum Discount Allowed" to
5 For Sales Manager user(SMITH), set value of profile "OEPASSI Maximum Discount
Allowed" to 15
Question: This sounds good, but what if you have 500 Order Entry Clerks and 100
Order Entry Sales Managers? Do we have to assign profile option values to each 600
users?
Answer : Well, in this case, each Clerk will be assigned Responsibility named say XX
Order Entry Clerk Responsibility
Each Sales Manager will be assigned Responsibility named say XX Order Entry Sales
Manager Responsibility
In this case, you can assign a profile option value to both these responsibilities.
XX Order Entry Clerk Responsibility will have a value 5% assigned against it.
However, XX Order Entry Sales Manager Responsibility will have a profile option
value of 15% assigned.
In the WHEN-VALIDATE-ITEM trigger of the discount field, following code will then
be written
IF
:OE_LINE_BLOCK.DISCOUNT_VALUE >
FND_PROFILE.VALUE('OEPASSI_MAX_DISCOUNT')
THEN
MESSAGE(
'You cant give discount more than '
|| FND_PROFILE.VALUE('OEPASSI_MAX_DISCOUNT') || '%'
);
RAISE FORM_TRIGGER_FAILURE; -- Raise error after showing message
END IF ;
Please note that our coding style does not change even though the profile option is now
being assigned against responsibility. The reason is that API (Application Program
Interface) FND_PROFILE.VALUE will follow logic similar to below.
1. Firstly, lets define the responsibility for Clerk and save the responsibility, as we
discussed in the above article.
2. Next, lets define the Sales Manager responsibility and save the responsibility, as we
discussed in Article.
3. Lets define user JOHN, that is Clerk
6. When you click on menu "Profile" above, you will then see below screen for defining
Profile Option. Please note that the "Name" field is the short name of profile option, and
it is this name used in API call to FND_PROFILE.value
7. Now, after having defined a profile option, its time to assign these to JOHN & SMITH.
Hence go to responsibility "System Administrator"
12. And this time we will assign value of 15 against user SMITH.
OK, what if we have too many Clerks, we can also simply assign profile value to
Responsibility of Clerk. Doing so, all the users that use this responsibility, will inherit
profile option value against Responsibility.
Before I tell you what is org_id, lets do some questions & answers:-
How can all this be achieved, without any hard coding in the screen.
Well....the answer is org_id
Qns: How will you establish a relation between UK responsibility and UK organization
Ans: By setting profile option MO: Operating unit to a value of UK Org, against UK
order entry responsibility
Qns: How will the system know that UK VAT belongs to UK org?
Ans: In VAT code entry screen (where Tax Codes will be entered), following insert will
be done
INSERT INTO ap_vat_codes_all
VALUES(:ScreenBlock.vatfield, Fnd_Profile.Value('org_id'));
3. In the Lov,
SELECT * FROM ap_vat_codes;
2. Vendor Sites/Locations are partitined too, because UK will place its orders from
dell.co.uk whereas France will raise orders from dell.co.fr. These are called Vendor Sites
in Oracle Terminology.
3. Any table that is Mutli-Org (has column named Org_Id), then such table name will
end with _ALL
4. For each _ALL table, Oracle provides a correspondong View without _ALL. For
example,
CREATE OR REPLACE VIEW xx_invoices
AS
SELECT * FROM xx_invoices_all
WHERE org_id=Fnd _Profile.Value('org_id');
5. At the time of inserting records in such table, Org_Id column will always be populated.
6. If you ever wish to report across all operating units, then select from _ALL table.
7. _ALL object in APPS schema will be a Synonym to the corresponding _ALL table in
actual schema. For example po_headers_all in APPS schema is a Synonym for
po_headers_all table in PO schema.
In this training chapter I will explain what Application means, in Oracles context.
Untill 8 years ago, it was mandatory for each table to be registered against an Application
in Oracle Financials; but now such a relation no longer exists.
Oracle is a mixture of various applications like Payables, General Ledger, Payroll, Human
Resources, and Manufacturing. You can call these Modules, but officially these are
called Applications. Hence the name Oracle Applications (i think)
Qns: For an Oracle Apps developer, what else must be the consideration with
respect to Application.
Ans: I will jump the training ship to explain this. In case you do not understand, then wait
for the training lesson on Concurrent programs.
1. Each program has an Executable. For example Reports have .rdf, Sql*plus has
.sql file, Forms has .fmx, Unix Shell Script has .prog (in apps) & D2K libraries
have .plx
2. When you register an Executable with Oracle Apps, you must then register this against
an Application.
3. Each application is mapped to a specific path, say to a directory in Unix box. For
example, Applicaton XXPO (that holds PO Customizations) may Map
to /home/oracle/apps/appl/po
4. Say you have developed/customized a report for PO Module. Assume your report
Executable name is XXPOPRINT.rdf . If you register this Executable with XXPO
applicaton, then this .rdf must be copied/ftp'ed to /home/oracle/apps/appl/po
5. When running this report in Oracle Apps, oracle will ask below series of questions to
itself
I see that user is running XXPOPRINT.rdf, which applicaton is this report registered
against? Oh well, it is XXPO application, then where is the directory location where I can
expect to find this file? Oh ok, application definition of XXPO is mapped
to /home/oracle/apps/appl/po (as per application definition), hence lets pick the rdf
from /home/oracle/apps/appl/po/reports/US
Here lies the significance of applicaton in oracle apps.
The below image can be clicked to see how applications are defined in Oracle Apps. One
needs to navigate to System Administrator responsibility and select
Menu /Application/Register.
When you are a fresh new Oracle Apps developer, your fundamental question is...where
to find the piece of code that you are being asked to customize?
Before I begin to explain you this, first some fundamentals.
1. You will most likely find that any implementation of oracle apps will involve at least
two machines, i.e. Database tier and then at least one Web/Forms tier (also known as
Middle-tier).
2. Oracle thought very logically to decide which Executable runs on Database tier and
which on Web/Forms tier (also known as Mid-tier).Any Executable that has intense
Database operations is deployed /stored at Database tier. To give you some examples....
.sql files, Oracle report Java concurrent programs, Sql*loader are all deployed in
Database tier of Oracle Applications.
3. Any Executable that has intense UI operations is deployed at Forms tier. Examples
are Oracle Forms .fmx files, .jsp files, .pll/.plx etc.
Qns: The above sounds good in most cases, but what if you have to build a Form that
has intense database processing.
Ans: Well the Form will still be deployed in the Mid-tier, otherwise your Form will never
be run. However, for such Forms, you must handle most of the database processing within
PL/SQL Packages. The APIs that you build in PL/SQL must have well defined
Parameters.
I am saddened to see that some apps programmers write tons of sql code/DMLs inside the
Oracle forms Triggers. In this era of high speed networks, such aproach may be justified
to an extent, but what if some other developer desires to use validations developed for
your Form in other areas of APPS? Hence building Pl/Sql API's is the preferred approach.
Qns: That's fine for the theory, but how do multiple Mid-tiers impact my forms
deployment?
Ans: You will need to deploy your Forms file to each Middle tier machine (unless Shared
APPL_TOP) has been implemented.
Qns: How do I generate .fmx, should this be done on PC or on the Mid tier?
Ans: This must always be done on the Mid tier i.e., Oracle Applications Server.
For example use below steps
Step 1
FORMS60_PATH=$FORMS60_PATH:$AU_TOP/forms/US
Step 2
export FORMS60_PATH
Step 3
cd $XXPO_TOP/forms/US
Qns: I have deployed the form at $XXPO_TOP but I can't run it, I get message Can
not find Form
Ans: Firstly find out the Application to which this Form is registered against. In reality
the Forms are attached to Form Functions and it is the Form Function that is attached to
an Application
Qns: How can I generate the CUSTOM.plx or any other Forms Library?
Ans:
----Below statements in one single line
cd $AU_TOP/resource
echo $FND_TOP
If the above returns blank, then it means you need to contact your DBAs to find out why
Environment variables are not being populated on your sign-on to Unix
...Ditto for DB Tier
Oracle Apps Training Testing Environments
In every implementation, there is always more than one environment in Oracle Apps.
2. Testing environment:
Developers usually do not and must not have apps password to this
environment. This is where users Sign-off customizations or even setup changes.
3. Production environment:
This is where the business runs
Optional environments:-
2. Patching environment:
This is where all new Oracle Patches are Sanity tested.
3. Support environment:
This environment is exclusive to support staff. This environment is usually the
most frequently cloned environment in Oracle Apps site that has gone live. Frequent
cloning helps the Oracle Applications support staff to reproduce production issues
4. Migration Environment:
This is where repeated data migration can take place before migration code gets
frozen and ready for UAT.
You as a developer do not need to worry about these environments, as your focus
will be on Development Environment only.
5.
2. The Development to Production Cycle is.... Developer does Development & Unit
Testing on Development environment, and their code gets promoted to User Testing
environment. Following this, the changes get applied to Production environment.
3. The changes done to "Development environment" must be Scripted in all cases where
possible. As a thumb rule, everything except for Functional Configuration can be scripted.
Oracle FNDLOAD Script Examples
In this article I wish to give real working examples of Oracle's FNDLOAD utility.
Besides that, I have included some useful notes on FNDLOAD utility
I have used FNDLOAD successfully in past for several different entities/data types within
Oracle 11i for almost all my previous clients, ever since this utility became available.
Some of the examples in this FNDLOAD article include:-
FNDLOAD to transfer Request Groups
FNDLOAD for moving Concurrent Programs
FNDLOAD to download and upload Forms Personalizations ( or Personalisations
depending on where you are located )
Please note that the text written down here could get wrapped in the browser.
Hence you may have to use \ to continue the single line command on Unix, in case you
find the lines wrapping
In my case I am ensuring that $CLIENT_APPS_PWD has the apps password before
running the scripts
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
## Now it's the turn of Lookup values. Again, its not a rocket science
FNDLOAD apps/$CLIENT_APPS_PWD 0 Y DOWNLOAD aflvmlu.lct
XX_TRX_BATCH_STATUS.ldt FND_LOOKUP_TYPE
APPLICATION_SHORT_NAME ='XXGMS'
LOOKUP_TYPE="XX_TRX_BATCH_STATUS"
## Note that
## XX_TRX_BATCH_STATUS is the name of FND Lookup Type in this example
## This will download all the lookup codes within the defined lookup
## To upload
FNDLOAD apps/$CLIENT_APPS_PWD 0 Y UPLOAD aflvmlu.lct
XX_TRX_BATCH_STATUS.ldt
------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
----------------
## Now lets have a look at the profile option using oracle's FNDLOAD
FNDLOAD apps/$CLIENT_APPS_PWD O Y DOWNLOAD
$FND_TOP/patch/115/import/afscprof.lct POR_ENABLE_REQ_HEADER_CUST.ldt
PROFILE PROFILE_NAME="POR_ENABLE_REQ_HEADER_CUST"
APPLICATION_SHORT_NAME="ICX"
## Note that
## POR_ENABLE_REQ_HEADER_CUST is the short name of profile option
## We aren't passing the user profile option name in this case. Validate using ...
########----->select application_id, PROFILE_OPTION_NAME || '==>' ||
profile_option_id || '==>' ||
########----->USER_PROFILE_OPTION_NAME
########----->from FND_PROFILE_OPTIONS_VL
########----->where PROFILE_OPTION_NAME like '%' ||
upper('&profile_option_name') || '%'
########----->order by PROFILE_OPTION_NAME
########----->/
## Now to upload
FNDLOAD apps/$CLIENT_APPS_PWD O Y UPLOAD
$FND_TOP/patch/115/import/afscprof.lct POR_ENABLE_REQ_HEADER_CUST.ldt
------------------------------------------------------------------------------------------------------------
----------------
## Now for the request sets that contain the stages and links for underlying
concurrent programs
## For this you will be firstly required to download the request set definition.
## Next you will be required to download the Sets Linkage definition
## Well, lets be clear here, the above sequence is more important while uploading
FNDLOAD apps/$CLIENT_APPS_PWD 0 Y DOWNLOAD
$FND_TOP/patch/115/import/afcprset.lct XX_GL_MY_INTERFACE_SET.ldt
REQ_SET REQUEST_SET_NAME="FNDRSSUB4610101_Will_look_like_this"
FNDLOAD apps/$CLIENT_APPS_PWD 0 Y DOWNLOAD
$FND_TOP/patch/115/import/afcprset.lct XX_GL_MY_INTERFACE_SET_LINK.ldt
REQ_SET_LINKS
REQUEST_SET_NAME="FNDRSSUB4610101_Will_look_like_this"
## Note that FNDRSSUB4610101 can be found by doing an examine on the
########----->select request_set_name from fnd_request_sets_vl
########----->where user_request_set_name = 'User visible name for the request set
here'
## Now for uploading the request set, execute the below commands
FNDLOAD apps/$CLIENT_APPS_PWD 0 Y UPLOAD
$FND_TOP/patch/115/import/afcprset.lct XX_GL_MY_INTERFACE_SET.ldt
FNDLOAD apps/$CLIENT_APPS_PWD 0 Y UPLOAD
$FND_TOP/patch/115/import/afcprset.lct XX_GL_MY_INTERFACE_SET_LINK.ldt
------------------------------------------------------------------------------------------------------------
----------------
------------------------------------------------------------------------------------------------------------
Notes :
1. Give special attention when downloading Menus or Responsibilities.
In case your client has several developers modifying Responsibilities and Menus, then be
ultra carefull. Not being carefull will mean that untested Forms and Functions will
become available in your clients Production environment besides your tested forms,
functions and menus.
2. Be very careful when downloading flexfields that reference value sets with independent
values for GL Segment Codes.
By doing so, you will download and extract all the test data in GL Codes that might not be
applicable for production.
3. There are several variations possible for FNDLOAD, for example you can restrict the
download and uploads to specific segments within Descriptive Flex Fields. Please amend
the above examples as desired for applying appropriate filterations.
5. FNDLOAD is very reliable and stable, if used properly. This happens to by one of my
favourite Oracle utilities.
6. Last but not the least, please test your FNDLOAD properly, so as to ensure that you do
not get any unexpected data. In past I have noticed undesired results when the Lookup
gets modified manually directly on production, and then the FNDLOAD is run for similar
changes. If possible, try to follow a good practice of modifying FNDLOADable data only
by FNDLOAD on production environment.
7. As the name suggests, FNDLOAD is useful for FND Related objects. However in any
implementation, you will be required to migrate the Setups in Financials and Oracle
HRMS from one environment to another. For this you can use iSetup. "Oracle iSetup".
Some of the things that can be migrated using Oracle iSetup are
GL Set of Books, HR Organization Structures, HRMS Employees, Profile Options Setup,
Suppliers, Customers, Tax Codes & Tax Rates, Financials Setup, Accounting Calendars,
Chart of Accounts, GL Currencies.
Oracle Form Functions, Menus and their relationship
Every screen we develop delivers a business functionality of sorts. Notice the word
functionality.
Hence the word Function or call it "Form Function" is related to Oracle Forms.
You all know that a Form is nothing but a screen from where users can enter or retrieve
(query) existing data.
Qns: In Oracle why do we have a Form and then also a Form Function? Isn't just
having a Screen/Form just well enough?
Ans: What if, for the same Form, you wish to provide slightly different functionalities
depending upon which Menu is clicked to invoke that Form??
Our requirement
-------------------------------
If the Invoice screen is invoked from Payables Manager Responsibility, then at startup
of the screen we want to provide a "Search Window", so that manager can search for the
invoices to review
If the Invoice screen is invoked from "Payables Clerk Responsibility, then at startup of
the screen we want to provide "Invoice Data Entry window", so that clerk can begin
entering the invoices.
Question: From above example it appears that Form Function will be passing
Parameter named Invoice_Mode to the form?
Answer. Correct in this case.
So that we understand how things hang together.
Invoice form is attached to a Form Function, when defining the Form Function we pass
Parameters to it. Then this Form Function is attached to the Menu, and it is the Menu that
gets attached to responsibility.
Question: Did you wonder how Oracle will know to look for a Payables Form
executable in AP_TOP and not in PO_TOP?
Answer:Oracle will think like this...hmm user clicked on a Menu, what is the Form
Function for this Menu...hmm it is Invoice Review....ok...what is the Application
assigned to the Form Function...oh...its AP(Account Payables) application...right....what is
the Base path for this Application...right..it is AP_TOP...lets then run the .fmx file from
ap_top/forms/us
2.Define your Form...remember, oracle will expect an executable of .fmx for this name
4. Define your two Functions Invoice Review, Invoice Entry and pass the Parameter
Invoice Mode and set the values as CLERK, MANAGER
Being a developer, you have just developed a SQL Script or a PL/SQL Package
procedure. The end user wants to be able to run this Script ad-hoc or they wish to
schedule this to run every night.
Question: How can an end-user be given the control to run a Script developed by a
developer, given that an end user will never have access to apps password (and
rightly so)?
Answer: This Script can be attached to a Concurrent Program via a Concurrent Program
Executable. The user will then be given access to this Concurrent Program.
Question: But how will the end user or Oracle Apps make this script run every
10hours daily?
Answer: A Concurrent Program can be Scheduled to run at desired intervals. The
schedule is defined at the time of submission.
Question: What are the different types of Scripts/Programs that can be attached to
Concurrent Programs?
Answer:
1.Sql script
2.Sql*Loader program
3.Java program
4.Oracle report
5.PL/SQL program (or call it a Stored procedure/Package procedure)
6.Host script, like a Unix Shell script
7.Pro*C/Spawned
8.Perl
Question: What are the basic steps when defining a Concurrent Program?
Answer: Broadly speaking there are three steps when developing a Concurrent Program
in Oracle Apps
Step 1. Make Oracle Apps identify the Executable
Step 2. Provide a handle to the Executable by means of defining a Concurrent Program
Step 3. Make this Concurrent Program accesible to selected users via their Responsibility.
Step 3. Make this Concurrent Program accesible to selected users via their Responsibility.
We do this by adding the Concurrent Program to something called as Request Group. The
Request Group is either associated with a Responsibility or is passed in as a Parameter to
the function request Form Function
Question: Please explain the steps for defining a PL/SQL Concurrent Program, with
screenshots and with almost real life example?
Answer:
1. Create a Table and a Stored procedure in pl/sql
CREATE TABLE xx_hello_world_tab
(
message_text VARCHAR2(100) ,
creation_date DATE
);
CREATE OR REPLACE PROCEDURE
xx_register_user_prc(errbuf OUT VARCHAR2,retcode OUT VARCHAR2) IS
BEGIN
INSERT INTO xx_hello_world_tab VALUES ('Hello World' ,SYSDATE);
END xx_register_user_prc;
Question: Why does the Concurrent Manager put a Concurrent Program into a
Queue? Why doesn't the Manager simply let the Program run?
Answer: Because at any given point in time a Concurrent Manager can run no more than
say 10 programs concurrently. This figure of 10 is Configurable of course. First the
manager puts a submitted Program into a Queue, next the manager checks if there is a Slot
available (i.e. Less than 10 programs are currently running). If a Slot is found available,
theCconcurrent Manager then runs the Program, or else it keeps the Concurrent Program
in a Queue with status Pending.
Question: If we have two Concurrent Programs that must never run in Parallel
(oops I mean Concurrently)....can Concurrent Manager manage such Scenarios?
Answer: Of course it can. When you define a Concurrent Program, you can specify if
there are any Incompatible Programs. If Incompatible Concurrent Programs exist, then
Concurrent Manager will wait for the Incompatible Program to complete.
Optimization options:-
The Concurrent Program definition provides an option to specify Optimization Mode, like
choose, first rows, all rows, rule based etc. The Concurrent Manager will alter the
optimization mode of the session before the submission of the Program. Obviously this
option has no relevance to Host type Concurrent Program.
Value Set basics in Oracle Apps
Question: Is Value Set attached to all the fields that require validations?
Answer: A big NO
At the time of submission of the Concurrent Program the user should be able to pick a
Cost Centre from a list. This is where Value Set gets used.
Step 4:- Here we add the values for IT, HR, SEC to this independent Value Set.
Step 5:- Now let us go back to Concurrent Program that we created in earlier training
lesson and Click on Parameters
Step 6:- Now lets create a Parameter, and attach the Value Set that we created to this
Parameter.
Step 7:-
Now to test this, lets go to Receivables Manager responsibility and click on Requests.
Step 8:-
Click on Submit New Request, and then click on OK.
Step 9:-
Now, we can see the values defined in the value set here.
Lookup Types and Lookup Codes in Oracle Apps
Question: Will the Gender column in above Table hold the value of M or F or U?
Answer: Correct, and the screen that displays people details will in reality display the
meaning of those respective codes (i.e. Male, Female, Unknown etc) instead of displaying
the code of M or F or U
Question: hmmm...so are Lookups used to save the Bytes space on database
machine?
Answer: Noooo. Imagine a situation as below
a. There are 30,000 records in people table of which 2000 records have gender value = U.
In the screen, their Gender is being displayed as "Unknown". Now lets say you want this
to be changed to "Undisclosed". To implement this change, all you have to do is to change
the meaning of the Lookup codes for Lookup type GENDER. Hence it will look like
Code Meaning
------ -------------
M Male
F Female
U Undisclosed
Here lies the beauty of lookups, you do not need to modify 2000 odd records in this case.
Question: Any other usage of lookups?
Answer: Sure, lets take another example. In HRMS, there is a field named Ethnicity.
By default Oracle ERO delivers the below values
Lookup code Lookup meaning
---------------- ---------------------
AS Asian
EU European
Now, if your client wants to track Ethnicity at a granular level, they can amend the
Oracle delivered Lookup definition as below
Hence these values will then be available in the list of values for Ethnicity field.
Question: Are we saying that all the Lookups delivered by Oracle can be Modified?
Answer: It Depends. If oracle has a Lookup called Termination Status, and if based on
the Termination Status Code Oracle has some rules defined within Payroll Engine....!!
Surely Oracle Payroll Engine will not like it if you end date an existing status code or add
a new status code to termination. For this very reason, Oracle flags some Lookups as
System Lookups, and the Lookup Entry screen will not let you modify those Lookup
Codes.
Question: OK, what if I do not wish to modify existing Lookup codes, but only wish
to Add new Lookup codes to an existing Oracle delivered Lookup Type?
Answer: Yes You can do so, provided the Oracle delivered Lookup Type is flagged as
Extensible. Please see the screenshot
Once in the screen, you can define your Lookup Type and Lookup Codes as below.
Difference between Lookups and Value Sets
Difference 1
Value Sets can be attached to Parameters of a Concurrent Program, whereas Lookups
can't.
Difference 2
Certain types of Lookups are maintainable by the Users too, for example HR Users will
maintain "Ethnic Minority" lookups. Value Sets are almost never maintained by End
users, with the exception of GL Flexfield codes. Value Sets are usually maintained by
System Administrators.
Difference 3
Value Sets can contain values that are a result of an SQL Statement.Hence it is possible to
make Value Set list of values Dynamic.On the contrary, Lookup Codes are Static list of
values.
First some basic Question and answers, and then we will do screenshots detailing how
flexfields are configured.
Question: Oh good, but can these new fields be added without modifying/
customization of the screen?
Answer: Yes, certainly. Only some Setup is needed, but no Programmatic change is
needed to setup DFF.
Question: So we can create New fields in Existing screen, but why the need of doing
so?
Answer: Oracle delivers a standard set of fields for each screen, but different customers
have different needs, hence Oracle lets us create new fields to the screen.
Question: Are these new fields that get created as a result of DFF free text?
I mean, can end user enter any junk into the new fields that are added via DFF?
Answer: If you attach a Value Set to the field (at the time of Setup of DFF), then field
will no longer be free text. The entered value in the field will be validated, also a list of
valid values will be provided in LOV.
Question: Will the values that get entered by the user in DFF fields be updated to
database?
Answer: Indeed, this happens because for each field that you create using DFF will be
mapped to a column in Oracle Applications.
Question: Hmmm, I can see that DFFs are related to table and columns...
Answer: Yes correct. Each DFF is mapped to one table. And also each Segment (or call it
Field) is mapped to one of the attribute columns in that table.
Question: I want these fields to appear in screen only when certain conditions are
met. Is it possible?
Answer: Yes, we have something known as Context Sensitive Descriptive Flexfields.
In Order to do this, we will follow the below steps (screenshots will follow):-
1. Navigate to the DFF Registration screen in Oracle Apps and query on Table
AP_BANK_BRANCES. Now click on Reference Field
2. Navigate to DFF Segments screen and query on the Title of the Bank Branch and
Unfreeze the Flexfield and add segments as to Section "GLOBAL Data Elements" as
shown in screenshots.
Here are the screenshots......The descriptions are embedded within the screenshots.
Once having noted down the table, we try to find the Title of the DFF for that Table. We
go to Flexfield/Register
Here we pick the Title of the respective DFF
The options for making mandatory or enabling validations for the new field.
Once you finalize the changes, you will be prompted to Freeze the DFF definition. Click
on OK
First some basic Question and answers, and then we will do screenshots detailing how
flexfields are configured.
Question: I want these Flex fields to appear in screen only when certain conditions are
met. Is it possible?
Answer: Yes, you can. Lets take an Example. You have a "Bank Branch" screen where
you enter the Bank names and their branches . There is a field named Branch Type in that
screen. You wish to show & capture following new fields:-
a. Banks Country of Origin Field ( regardless of bank branch type, we must show this
new field). As we configured in earlier training chapter.
b. If user entered a value of SWIFT in Branch type, then display a new DFF segment
"SWIFT Partner field".
c. If Branch type CHIPS is selected by the user, then display a DFF segment "Chip ID"
field.
Hmmmm not clear yet, see the the screenshots and you will surely understand......
Find out the table name for Bank Branch screen, this will enable us to find the DFF that is
available for Bank Branch
Now we need to define the new fields(segments). This screen is accessed via
menu /Descriptive/Segments . In this screen, lets make BANK_BRANCH_TYPE as the
context/reference. This means that DFF will become sensitive to values in Branch Type
field
IMPORTANT: If your requirement is not to have any conditiional logic, then no need for
all the "Reference Field" blaaa. All you need to do is to add your segment to Global Data
Elements
When the user selects Type=SWIFT, we see the relevant SWIFT field appear in Flexfield
window
When user selects Type=CHIPS, we see CHIP Id field appearing in Flexfield window.
Here we now see that value entered in DFF field gets stored in the database column,
Key Flexfields Basics
Question: Key Flexfields help us capture additional fields, and so does descriptive
flexfield too? What is the deal here?
Answer: Ok, lets assume for a minute that there is no such thing as a key flexfield. All
we have is a descriptive flex (lets assume).
Requirement is this:-
Your client wants to capture values in following additional fields for a purchase order
transaction and invoices...
Company name: GM
Cost Centre: IT
Project: OFP --means Oracle Fusion Project
Expense Type: OCC -- Oracle Consultant Cost
In a DFF ONLY WORLD, when your client raises Purchase Order to IT Consulting
Company, in PO_DISTRIBUTIONS_ALL table record you will store
ATTRIBUTE1 :- GM
ATTRIBUTE2 :- IT
ATTRIBUTE3 :- OFP
ATTRIBUTE4 :- OCC
When an invoice is received from consulting company, the Payables clerk will capture the
Invoice Line accounting as below in AP_INVOICE_DISTRIBUTIONS_ALL
ATTRIBUTE1 :- GM
ATTRIBUTE2 :- IT
ATTRIBUTE3 :- OFP
ATTRIBUTE4 :- OCC
These 4 text values for fields(above) are physically being duplicated in each module, for
the related/unrelated transactions.
Imagine further when this transaction flows to Oracle General Ledger, would you again
expect oracle to physically store the 4 columns into table GL_JE_LINES? If so your table
GL_JE_LINES will have following values in its DFF (Descriptive Flex) columns....
ATTRIBUTE1 :- GM
ATTRIBUTE2 :- IT
ATTRIBUTE3 :- OFP
ATTRIBUTE4 :- OCC
Surely, such design using a descriptive flexfield will be flawed, as it causes duplication of
data at various places.
Now that you understand why Descriptive flexfield does not fit into this design, lets
consider a new scenario.
Again, in Account Payables, even though the clerk will enter in screen values for four
columns (four each segment), the database will only store value 10902 in column
CODE_COMBINATION_ID of payables distributions table.
Ditto for the entry in GL_JE_LINES table in oracle general ledger, only the ID that
references those 4 columns will be stored.
Hence all the tables(PO Dist, AP Dist, GL JE Lines) will reference just the
CODE_COMBINATION_ID.
Question: Does this mean, for each key flexfield, there will be a dedicated table? And
such table will hold the unique combination of field values that can be reused?
Answer: correct. For gl accounting key flexfield, there is a table named
gl_code_combinations. Other examples are grades in oracle human resources. A grade can
be defined as a combination of say Clerk + Senior or Clerk + Junior. These combinations
will be stored in per_grades table.
Question: do all the tables which are used for storing key Flexfields have columns named
segment1,segment2...segmentx?
Answer : Correct, it is a standard practice used by oracle. Thee segments columns are
generic columns so that each client can call them by whatever name as they desire.
Question: Does Oracle deliver Key-Flexfields out of the box, which will pop-up a
window with relevant fields, as configured during setup.
Answer : Yes, and if value sets are attached, the fields can be validated too.
In this article, I will explain in steps:- How to create special information types in Oracle
HRMS.
Once you have learnt the fundamentals of SIT, you can then also reference the article on
migrating special information types into Oracle.
Before we dive into the special information type creation example, lets first do some
questions and answers.
Question : Why use an SIT when we can enable descriptive flexfields against the person
record.
Answer : Various reasons, as listed below:-
A. Data in Descriptive Flexfield against an employee record will be visible to all the users
that have access to the Employee creation/query screen.
On the contrary, using HR Workflow security, we can make SIT to become visible for the
responsibility that we desire.
B. There is limited number of descriptive flex field columns available.
C. SIT let you logically group similar information together. For example, you may wish to
capture "Medical illness history/details" and also Citizenship/Country Residency History"
of your employees. In this case, you will create two different SIT.
Question : Give me the example of the SIT, to which we will migrate values.
Answer : For this training exercise, we will assume following SIT exists in Oracle Apps.
Sit name : "XX Medical History Of Person"
Sit Fields:
Medical Condition
Year of illness
Cured Flag (Yes/No)
First, go to Key Flexfield register screen and query to find the title of KFF. No changes
are done in this screen,
Now go to person record, by finding for the person that we migrated in earlier article .
This article is for setting up the PC for Oracle Apps development, for the readers of
http://getappstraining.blogspot.com
Once installed, ensure that you can connect to apps schema from Oracle Forms and Oracle
Reports.
A Unix client
---------------------------
A unix shell program like ssh or putty or any others, that
a. Lets you do ftp or sftp with your servers
b. Lets you logon to your middle tier or the database tier to Unix Prompt
Note: I am assuming a Unix install for Oracle Applications.
Oracle jDeveloper for OAF ( Optional:- Only needed if developing extensions to
OAF).
Download patch 4045639 from Metalink. Please note that this patch comes bundled with
jDeveloper and all the Apps related libraries.
Oracle IDE
---------------------------
A rapid pl/sql development tool like TOAD or PL/SQL developer or Golden or
SQL*navigator. Note this is optional, but I suggest you get used to one of these. My
personal favorite is Pl/SQL developer from
http://www.allroundautomations.com/plsqldev.html
Workflows
--------------
I suggest you create a directory similar to c:\oracle\wf
Next you need to ensure that you are able to connect to apps schema from the workflow
builder. Once connected, open workflow named Standard, and save this as WFSTD.wft.
You are now ready to roll with your Oracle Apps development tasks..
Steps for your first PL/SQL Concurrent Program in Oracle Apps
I think this topic is already covered partially in one of the previous training lesson[ for concurrent
programs], but I would like to touch base on this again.
Question: Does this stored procedure need to have some specific parameters, in order to
become an executable of a concurrent program?
Answer: Yes, such procedure must have at least two parameters
( errbuff out VARCHAR2, retcode out NUMBER)
Question: Can we add additional parameters to such pl/sql procedures that happen to be
Conc Prog Executables?
Answer: Sure you can, but those parameters must be defined after the first two
parameters. Effectively I mean first two parameters must always be errbuff and retcode.
The sequence of the remaining parameters must match with the sequence in which
parameters are registered in define concurrent program-parameters window.
Question: Can those parameters be validated or will these parameters be free text?
Answer: These parameters can be attached to a value set, hence this will avoid users
passing free text values.
Question: What are the possible things that a concurrent pl/sql program can do?
Answer: Firstly your stored procedure would have been created in apps. This concurrent
program will connect to "apps schema" from where access to all the tabes across every
module will be available.
You can do the following:-
1. Insert records in tables(usually interface or temp tables)
2. Update and delete records
3. Initiate workflows
4. Display messages in the output file or the log file of the concurrent program.
5. Make this concurrent program complete with status Error or Warning or Normal.
I find this script very handy for bouncing the Apache, specially when
working on Self Service Applications.
Please find the two commands that I use for bouncing the Apache
$COMMON_TOP/admin/scripts/$TWO_TASK*/adapcctl.sh stop
$COMMON_TOP/admin/scripts/$TWO_TASK*/adapcctl.sh start
In case you have modified any java or class file in OAF ( Oracle Applications
Framework ), then Apache bounce becomes mandatory for those changes to take effect.
In case you modify and load the XML Document in Oracle Framework, then
it is noticed, for those XML changes to take effect, complete bounce of Middle
Tier is required in Oracle Apps.
If your client is still stuck with AK Developer, then Apache bounce will be required
after akload has been executed.
To convert back from CUSTOM.pld to CUSTOM.pll ( after having edited the text
pld file )
f60gen module_type=LIBRARY module=CUSTOM parse=YES userid=apps/apps
In this article I have discussed how to create and maintain a read only schema for APPS in
Oracle eBusiness Suite.
Whilst in the past I have known clients to implement this using synonyms. However the
approach discussed below is designed without the need of having to create a single
synonym in APPS_QUERYschema.
Step 1
Create the read-only schema, in this case lets call it APPS_QUERY.
Step 2.
Surely, the schema created in above Step 1 will be given read only grants to objects in
apps. There will be cases where the grant command might fail. To monitor such failures
create a table as below
conn xx_g4g/&2 ;
--For APPS_QUERY. This table will capture the exceptions during Grants
PROMPT create table XX_GRANTS_FAIL_APPS_QUERY
create table XX_GRANTS_FAIL_APPS_QUERY (
object_name VARCHAR2(100)
,sqlerrm varchar2(2000)
,creation_date DATE
);
Step 3
In this step we grant select on all the existing views and synonyms in apps schema to
apps_query.
conn apps/&1 ;
Step 4
Write a after logon trigger on apps_query schema. The main purpose of this trigger is to
alter the session to apps schema, such that the CurrentSchema will be set to apps for the
session(whilst retaining apps_query restrictions).In doing so your logon will retain the
permissions of apps_query schema(read_only). Howerver it will be able to reference the
apps objects with exactly the same name as does a direct connection to apps schema.
conn apps/&1 ;
PROMPT CREATE OR REPLACE TRIGGER xx_apps_query_logon_trg
CREATE OR REPLACE TRIGGER xx_apps_query_logon_trg
--16Jun2006 By Anil Passi
--Trigger to toggle schema to apps, but yet retaining apps_query resitrictions
--Also sets the org_id
AFTER logon ON apps_query.SCHEMA
DECLARE
BEGIN
EXECUTE IMMEDIATE
'declare begin ' ||
'dbms_application_info.set_client_info ( 101 ); end;';
EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA =APPS';
END;
/
Step 5
Create a Trigger on the apps schema to issue select only grants for all new views and
synonyms. Please note that I am excluding grants for sequences. SELECT grants for
views and synonyms will be provided to apps_query as and when such objects are created
in APPS. Please note that, all the APPS objects (views and synonyms) that existed in
APPS schema prior to the implementation of this design, would have been granted read-
only access to apps_query in Step 2.
conn apps/&1 ;
PROMPT CREATE OR REPLACE TRIGGER xx_grant_apps_query
CREATE OR REPLACE TRIGGER xx_grant_apps_query
--16Jun2006 By Anil Passi
--
AFTER CREATE ON APPS.SCHEMA
DECLARE
l_str VARCHAR2(255);
l_job NUMBER;
BEGIN
IF (ora_dict_obj_type IN ('SYNONYM', 'VIEW'))
AND (ora_dict_obj_name NOT LIKE '%_S')
THEN
l_str := 'execute immediate "grant select on ' || ora_dict_obj_name ||
' to apps_query";';
dbms_job.submit(l_job, REPLACE(l_str, '"', ''''));
END IF;
END;
/
Note1
You need to ensure that the schema created in Step 1 has very limited permissions. Most
importantly it must not be given grant for EXECUTE/CREATE ANY PROCEDURE.
You will need to agree with your DBAs upfront for the permissions,
Note 2
Only views and synonyms will be granted access. Objects in your xx_g4g(bespoke)
schema should have their synonyms in apps already in place.
Note 3
If your site has multi org enabled, you will then have to set the org I'd after loggiong on to
apps query schema. In case you have only one single ORG_ID, then would have been set
as in Step 4 above.
Note 4
ALTER SESSION SET CURRENT_SCHEMA =APPS
This facilitates users to run their queries as if they were connected to apps schema.
However, their previliges will be restricted to those of apps_query
Note 5
It is assumed that ALTER SESSION privilege will exist for APPS_QUERY schema.
Create Oracle FND_USER with System Administrator
If you have the Apps Password, its quite easy to create a FND_USER for yourself by
using the API.
I find this script very useful when development environment gets cloned from Production
(that is when i do not have FND_USER in Production.
--------Beging of script--------------
DECLARE
--By: Anil Passi
--When Jun-2001
v_session_id INTEGER := userenv('sessionid');
v_user_name VARCHAR2(30) := upper('&Enter_User_Name');
BEGIN
--Note, can be executed only when you have apps password.
-- Call the procedure to Creaet FND User
fnd_user_pkg.createuser(x_user_name => v_user_name
,x_owner => ''
,x_unencrypted_password => 'oracle'
,x_session_number => v_session_id
,x_start_date => SYSDATE - 10
,x_end_date => SYSDATE + 100
,x_last_logon_date => SYSDATE - 10
,x_description => 'appstechnical.blogspot.com'
,x_password_date => SYSDATE - 10
,x_password_accesses_left => 10000
,x_password_lifespan_accesses => 10000
,x_password_lifespan_days => 10000
,x_employee_id => 30 /*Change this id by running below SQL*/
/*
SELECT person_id
,full_name
FROM per_all_people_f
WHERE upper(full_name) LIKE '%' || upper('<ampersand>full_name') || '%'
GROUP BY person_id
,full_name
*/
,x_email_address => 'appstechnical.blogspot@gmail.com'
,x_fax => ''
,x_customer_id => ''
,x_supplier_id => '');
fnd_user_pkg.addresp(username => v_user_name
,resp_app => 'SYSADMIN'
,resp_key => 'SYSTEM_ADMINISTRATOR'
,security_group => 'STANDARD'
,description => 'Auto Assignment'
,start_date => SYSDATE - 10
,end_date => SYSDATE + 1000);
END;
/
A New Custom Form in
Oracle Apps
In the previous chapter we learnt "how to customize an existing oracle delivered form"
Question: Why bother teaching this when Oracle fusion is destined to replace oracle
forms by OA Framework?
Answer: Well firstly I am yet to hear an official word from Oracle in this regard, but I
agree it is highly likely that fusion will se demise of Oracle Forms. However more
importantly Oracle will support current tech stack indefinitely, I.e Release 12 will be
supported for foreseen time as per Apps Unlimited statement. Hence, many of the clients
will keep using this technology for decades. Yes, I won't bother my kid learning Oracle
form though.
Question : Ok, what are the steps for building a screen from scratch?
Answer: Below steps in brief
A) Open up TEMPLATE.fmb, and save this as XXHELLOAPPS.fmb
B) Create a new window, by right clicking on Window/new
Name this window as XXHELLOAPPS,and assign it SubClass Type WINDOW from
picklist.
C) Create a new canvas and name it XXHELLOAPPS , ensuring its Sublcass Type is
Content
D) Make the windows property reference canvas XXHELLOAPPS and vice versa make
the canvas reference windows XXHELLOAPPS.
E) Now create a block named XXHELLOAPPS . Lets keep this a control block for
simplicity.
F) go to form level property, and set first navigation block to XXHELLOAPPS.
G) Add a label and a field named Hello_World to this block.
H) Generate the form on PC using Control-T keystrokes. This will ensure that nothing
critical has been missed out.
I) FTP the form file to $XXPO_TOP/forms/US
Surely, this XX will be replaced by the naming convention at your client/company.
J) cd to $XXPO_TOP/forms/US
And f60gen on XXHELLOAPPS.fmb
This will create a file executable as XXHELLOAPPS.fmx
K) Go to Application Developer responsibility
Menu /applicaton/form
Register the form
L) Register the Forms Function
Have you read he article form
functions[http://getappstraining.blogspot.com/2006/10/oracle-forms-functions-menus-
and-their.html] yet?
This forms function must be registered against application "XX Purchasing".
M) Now add a menu item so that this forms function becomes available to specific
responsibility.
Thats it, you will be able to open up this form from the responsibility.
Please let me know if anything is unclear. Feel free to ask your questions.
Forms Customization Steps in Oracle Applications
Question: How can I modify screen without modifying the underlying executable ?
Answer: There are two ways, listed in the order of preferences:-
1. Forms Personalizations
2. CUSTOM.pll
Question: Fine then, but why is CUSTOM.pLL needed when we already have forms
personalization?
Answer: Well just like any technology, forms personalization has its limitations.
Question: What about CUSTOM.pll, what can't be done via custom.pll ?? Hence calling
for forms customization.
Answer: For example, you need to add a complete new section to the screen at a very
specific location, this must be done via forms customization.
Question: Ok, what are the steps for customization of such screen?
Answer: Below steps in brief
A) Identify the form in Oracle Apps that needs to be customized.
B) Go to the specific directory on one of the mid-tiers to get that forms executable. Say
from $AU_TOP/forms/US/POENTRY.fmb.
C) FTP that form and all its dependable form objects & pll files to your PC.
D) Open the form, ensuring that you do not receive any errors pertaining to missing
library or missing form object.
E) Perform a save-as to rename this form on your pc, using your company's naming
conventions.
G) Generate the form on PC using Control-T keystrokes. This will ensure that nothing
critical has been missed out. Surely you will need to connect to apps schema before
generating the form.
I) cd to $XXPO_TOP/forms/US
And f60gen on XXPOENTRY.fmb
This will create a file executable as XXPOENTRY.fmx
Question: Well, a question about (A), how to identify the form executable?
Answer: There are two ways.
Method1
Open the form to be customized in Oracle Apps from respective Responsibility/Menu
Next select menu /Help/About Oracle Application.
Here, scroll down within the subwindow and search for fmx. This is the executable that
oracle application runs when specific form is invoked.
Method2
Query the responsibility definition which has the form attached to this. Note down the
Menu which is attached to Responsibility. Go to the menu definition screen and find the
form function attached to this menu. From this form function find the form attached to
this function.
Oracle Reports will become a thing of past in Fusion, however it will still demand
resources for the next 5yrs or so.
Important note: Just like Oracle Forms, there is no place for D2K Reports in Fusion.
This will be replaced by XML publisher. I will explain that transition in a latter article
very soon.
Question: I have been asked to customize Invoice Print program which happens to be an
Oracle Report. What will be the steps, that I must follow.
Answer : Follow the steps below.
1. You will be told the name of the existing report that must be customized. Note down
the exact name and query that name in Concurrent Program screen. Click on Copy
Program button selecting checkbox option Copy Parameters. This will help you copy
the current program definition to custom version of the program.
Also note down the name of the executable as it appears in concurrent program definition
screen.
3. Copy that file to your custom AR Top directory. Basically that is the directory where
custom reports for AR will be deployed..
cd $XXAR_TOP/reports/us
cp $AR_TOP/reports/us/RAXINV.rdf $XXAR_TOP/reports/us
Note: We havent made any changes as yet. Also, you need to include the new concurrent
program name in the relevant request group.
Now you can ftp that report to your pc, make modifications for necessary customizations,
and then ftp that piece of rdf back to the server. Run it again, to see it working.
This article explains the steps to write programs for data migration in Oracle Apps.
Question : What is involved in the preparation stage of data migration in oracle apps?
Answer: For the Preparation stage, following must be done.
1. Understand the structure of the data being imported and also its business purpose.
2. Fully understand where the data will end up residing into Oracle Apps.
3 Find out if open interfaces or APIs exist in Oracle Apps to facilitate loading the required
data.
4. Ensure that lookup codes or setup in Oracle apps support the values that are coming
from source system.
5. Think about how the errors will be reported and managed.
6. Also think about how the transactions that fail migration will be re-tried. You may
decide to knock of a simple screen if high volume of transactions needs user intervention
for cleansing.
Question : If I get a comma delimited file, how will I load that into tables?
Answer : You can use a Sql*Loader, or a java program with a csv parser or a file based
table approach.
Question : In oracle apps during migration, do we usually receive xml data file?
Answer : Keep in mind that you usually migrate data from mainframe or standalone
systems which now stand outdated.
Such systems usually produce comma delimited or tab delimited file.
Question : Ok, once the data from source system has been loaded using sql*loader, what
next?
Answer: The data model of the source data may or may not comply with the data model
in oracle apps. Hence you need a transformation step in most cases. This is explained
below with an example of TCA API to migrate customers/parties.
Question : Should I not ask the legacy system people to transform data as per our
requirements?
Answer : No, don't bother doing so, for below reasons :-
A. Techies of legacy system will not be happy that their system is now being made
redundant. Hence don't expect much value addition from them.
B. There is a possibility that in an attempt to transform data to Oracle's data structure, they
might induce faults/bugs.
If the transformation bugs are encountered at your end in apps, you can fix them yourself.
However if legacy team does transformation for you, then you become dependent on
them for bug fixes. Eventually tired of waiting on them, you might end up doing
transformation yourself anyway.
C. If your design for transformation changes, you should not be dependent upon the
legacy system...just fix it yourself at your own end in apps.
Question : If we end up using interface api's in apps for data migration, then where lies
the difference between migration and interfaces?
Answer : Migration is a one-off activity, even though it uses the same sets of tables/API's
as interfaces do.
Question : Enough explanation, now give me an example.
Answer : Lets assume you get a task to migrate customers from legacy system into TCA
(or call it AR - Receivables for simplicity).
Your file from source is:-
lcust.dat
1000,GE, GE Capital,1000-1
1001,Cisco,Cisco Routers,1001-1
1002,Barclays,Barclays Investments,1001-1
1003,Barclays,Barclays Mortgages,1001-2
Step 1. FTP this file to your database server and run sql*loader to load the file into a table
named xx_legacy_cust, this table will have four columns, one column for each file in
source.
Step 2. Transform this data...
For this we create two tables...
XX_TRNSFRM_PARTY
--parent_cust_Id
--parent_cust_name
XX_TRNSFRM _CUST_ACCOUNT
--parent_cust_Id
--operating_cust_Id
--operating_cust_name
Now, you can write a pl/sql program to split data from table xx_legacy_cust into the two
tables listed above.
Step 3. Now write the pl/sql program to migrate this data into Oracle.
Create or replace procedure xx_migrate_parties(errbuff out varchar2,retcode out varchar2)
is
Begin
FOR p_party_rec in (select * from XX_TRNSFRM_PARTY )
LOOP
--call api to create party
Hz_Party_Site_V2pub.create_party();
END LOOP ;
END LOOP ;
END ;
Question: Why does one need to use FNDLOAD FOR WEB ADI?
Answer : In any implementation that uses Web ADI, the setup for formatting letters and
docments can be overwhelming. More importantly, once configured on a development
environment you would not like to repeat the tedious setup on test, crp or other
environment. Using FNDLOAD you can migrate 99% of your setup.
Question : What are the man steps when using FNDLOAD for Web ADI?
Answer :
First step
Identify the pieces that must be moved across using fndload. These can be:-
Integrators
Layouts
Mappings
Contents
This article covers the above listed components one by one.
Second step
Download the above web adi attributes into various ldt files. Basically we will create one
ldt file for each of the above four web adi entities.
Third step
Upload those ldt files into the new environment. For this we will run the fndload in upload
mode.
Question: How do I execute Step 1, given that FNDLOAD requires the internal names of
these entities, these internal names are not visible from the Web ADI screens?
Answer: In this example,I will demonstrate using scripts how to recognize the web adi
components Names for fndload. SQL will be provided to identify the internal names.
This will return two internal codes, both in application PER (Application ID 800). Lets
say the two internal codes are HR_101_INTG & HR_41_INTG.
Now in order to upload these into new environment, use below commands
FNDLOAD apps/$APPS_PASSWORD 0 Y UPLOAD
$BNE_TOP/admin/import/bnelay.lct XX_C_O_F_T.ldt
To upload these files into a new environment, ftp the ldt files and run below commands on
the new environment
For each content code returned by SQL above, we will now do FNDLOAD as below
This article explains how you can reset the passwords and add responsibilities in APPS
using scripts. This was tried and tested on 11.5.10 environment.
That's the end of our talk. Now let me give you some background.
Self Service HRMS kicks off a workflow each time a user logs onto system to either view
or update their personal information.
The reason for this approach is that SSHR uses workflow to manage the state of its
transaction.
Question: Why does Oracle Self Service HR use workflow to manage its state?
Answer: Because SSHR was developed before OAF was invented by Oracle. Using OA
Framework, it is possible to manage the state of a web based applications via something
known as AM(Application Module).
Question : Are you saying that Self Service HR in Oracle does not use OA Framework
Answer: Not saying that. In fact Oracle has re-written most of its SSHR to use the OAF,
but for some reasons(which I believe are legacy), the underlying workflow has been
retained. I am not saying that this is bad design, but yet this begs to be load tested before
goLive.
Question: Why is my client so concerned about load testing self service HR?
Answer: Workflows have their overheads, but beyond that SSHR uses some staging
tables to capture before and after state of the personal information, while the user is
updating the same. This alongwith workflow overhead may hit the system hard, hence the
need for load test.
After the script has completed, you can spool the data from temp table ....
NOTE: DO NOT RUN THIS ON PRODUCTION
DECLARE
duplicate_responsibility EXCEPTION;
PRAGMA EXCEPTION_INIT(duplicate_responsibility
,-20001);
i INTEGER := 0;
no_action_required EXCEPTION;
CURSOR c_get IS
SELECT *
FROM fnd_responsibility_vl
WHERE responsibility_name = 'XX HR Employee Self Service';
p_get c_get%ROWTYPE;
BEGIN
OPEN c_get;
FETCH c_get
INTO p_get;
CLOSE c_get;
DELETE xxschema.fu_4_which_pwd_reset;
FOR p_rec IN (SELECT user_name, user_id
FROM fnd_user
WHERE user_name NOT IN (SELECT fu.user_name
FROM fnd_user fu, fnd_logins fl
WHERE fl.start_time > SYSDATE - 40
AND fu.user_id = fl.user_id
GROUP BY fu.user_name, fu.user_id
)
AND user_name NOT LIKE '00%'
AND end_date IS NULL
AND employee_id > 0
ORDER BY user_id DESC)
LOOP
i := i + 1;
--First 1000 users only
IF i = 1001
THEN
RAISE no_action_required;
END IF;
fnd_user_pkg.updateuser(x_user_name => p_rec.user_name
,x_owner => 'SEED'
,x_unencrypted_password => 'abcd0123'
,x_password_date => SYSDATE + 500);
BEGIN
fnd_user_resp_groups_api.insert_assignment(user_id => p_rec.user_id
,responsibility_id => p_get.responsibility_id
,responsibility_application_id => p_get.application_id
,security_group_id => 0
,start_date => SYSDATE - 1
,end_date => NULL
,description => 'Load testing SSHR on Test
environment');
EXCEPTION
WHEN duplicate_responsibility THEN
fnd_user_resp_groups_api.update_assignment(user_id =>
p_rec.user_id
,responsibility_id => p_get.responsibility_id
,responsibility_application_id => p_get.application_id
,security_group_id => 0
,start_date => SYSDATE - 1
,end_date => NULL
,description => 'Access Reinstated via Load
testing SSHR on Test environment');
END;
INSERT INTO xxschema.fu_4_which_pwd_reset
(user_id
,user_name)
VALUES
(p_rec.user_id
,p_rec.user_name);
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
COMMIT;
END;
Forms Personalization in Oracle HRMS
For quite some time I was thinking about publishing an article about forms
personalization in Oracle HRMS.
The Metalink note on Forms Personalization is helpful, but what it lacks is a pictorial
approach to implementing
Forms Personalizations. I am a visual animal, so I like to explain in that manner too.
Please note that when Person type Employee is selected, value in field
PERSON.D_PTU_USER_PERSON_TYPE is assigned a value of Employee
Now the requirement is that for Employee field PERSON.D_TITLE must be made
mandatory.
There are two possible ways the Person Type can change.
Either by picking a dropdown list of Action (e.g. Create Employee) or by directly picking
up a value from LOV on field Person Type for Action. Whenever the person type
changes, WHEN-NEW-ITEM-INSTANCE is fired for one for the below fields(depending
upon how its changed). Hence forms personalization must check conditions for below
three fields
PERWSHRG.PERSON.PTU_ACTION_TYPE
PERWSHRG.PERSON.D_PTU_USER_PERSON_TYPE
PERWSHRG.PERSON.SHOW_NUMBER
When implementing this, you will have to replicate the steps in the demo for WNII on
both PERWSHRG.PERSON.D_PTU_USER_PERSON_TYPE &
PERWSHRG.PERSON.SHOW_NUMBER
I have tested the steps below myself, and they appear to work.
STEP 1
Create Personalization as below( to make Title field mandatory)
Sequence: 50
Description: Make Person Title Mandatory when Person Type is Employee.
Trigger Event: WHEN-NEW-ITEM-INSTANCE
Trigger Object: PERSON.PTU_ACTION_TYPE
Condition: ${item.person.d_ptu_user_person_type.value} = 'Employee
Action Sequence: 10
Action Type: Property
Action Object Type: Item
Action Target Object: PERSON.D_TITLE
Action Property Name: REQUIRED
Action Value: TRUE
Check if Person Type is anything other than Employee in When New Item Instance
Action Sequence: 10
Action Type: Property
Action Object Type: Item
Action Target Object: PERSON.D_TITLE
Action Property Name: REQUIRED
Action Value: FALSE
Forms Personalizations
In this article, I would like to explain different possibilities of Forms Personalizations.
Surely before explaining what can be done, first we will touch base upon what exactly it
is.
For displaying messages, you can either enter a plain text, or your message can be
displayed from the result of a SQL Statement.
Local variables can be defined and they will be active for throughout the session of the
current form.
Use global variables if you wish to share the variable between multiple forms.
Below, just for demo, I am setting the local variable to 0.
As seen below, the above two setups have instantiated the new Menu Items
You can capture the click on those newly created menu items by trapping event MENU1
or SPECIAL1 [or whatever you defined]
Oracle Fusion Development Tools
The roadmap for Oracle Fusion strategy is becoming clearer, thanks to most recent article
by Steven Chan.
So the question is, what will be the development skills required by Oracle Fusion
Developer?
In order to answer this, lets have a look at current skillsets required for Oracle Apps, and
then map those to Oracle Fusion.
There was a time when every individual Oracle Applications module used its own
debugging technique.
But this is changing now, thanks to FND Logging. I have been using FND Logging for
over one year now, ever since 11.5.10 was released, hence I would like to share
knowledge on this topic.
Where is the debug message stored, once the logging is turned on?
Debug messages are stored in a table called FND_LOG_MESSAGES
A program written in any technology, either form, or report, or pl/sql or java concurrent
program or OAFall their debug messages will be stored in fnd_log_messages.
Step 2
Login to the application and reproduce the problem.
Step 3
SELECT *
FROM fnd_log_messages
WHERE user_id = 209122 /*your FND_USER user_id here*/
AND TIMESTAMP > SYSDATE - .3
ORDER BY log_sequence DESC /*note the order by clause here*/
The result of this select statement will provide the list of all the debug messages, on top
will appear the most recent debug messages..
Why must I bother debugging Oracle's Standard code when I can quickly raise a
tar.
If the issue is with Standard Oracle Code, first thing you must do is to search into
Metalink. However having the debug information on error helps your searching ability
further. Uploading the debug messages upfront during Tar creation will also help Oracle
speedily understand and fix your issues.
I like setting this to "Statement" level as it extracts debug messages at all levels, in one
glance. You can latter filter those debug messages by using below SQL for example
select * from fnd_log_messages where user_id = 111 and LOG_LEVEL =5
What if the piece of code causing the error is not appearing in fnd_log_messages?
This is very much possible. The fnd_log_messages might have helped you get close to the
culprit piece of code , but may not be able to pinpoint the error as there may not be
enough debug messages implanted by Oracle.
I have written a pl/sql concurrent process to interface Purchase Orders from 3rd
Party System. How will add debug messages?
fnd_log.STRING(log_level => fnd_log.level_statement
,module => 'xxpo.packagename.procedurename'
,message => 'debug message here');
What if a rollback occurs due to unhandled exception. Will the inserts done to
fnd_log_messages be lost?
fnd_log.string eventually calls procedure
FND_LOG.STRING_UNCHECKED_INTERNAL2. This procedure uses pragma
AUTONOMOUS_TRANSACTION with a commit.
Hence your debug messages will not be lost despite a rollback in parent session.
begin
/* Short circuit if logging not turned on at this level */
if (LOG_LEVEL < G_CURRENT_RUNTIME_LEVEL) then
return;
end if;
if FND_LOG_REPOSITORY.CHECK_ACCESS_INTERNAL (MODULE,
LOG_LEVEL) then
FND_LOG_REPOSITORY.STR_UNCHKED_INT_WITH_CONTEXT(
LOG_LEVEL => LOG_LEVEL,
MODULE => MODULE,
MESSAGE_TEXT => MESSAGE);
end if;
exception
when others then
NULL; /* supress the exception */
end;
XML Publisher Concurrent Program - XMLP
In this article I have listed a step by step demo of XML Publisher as a Concurrent
Program in Oracle Apps.
I think it is very important that you get a feel of XML Publisher, as this will become the
reporting tool in Fusion [assuming XMLP can become as powerful as Oracle Report in
the given time].
Before I explain the steps in details with screenshots, let me brief them:-
a. Create a report and register it as Concurrent Program of type XML
b. Build a Data Definition & XML Template using XML Publisher.
c. Create a relation between XML Template & Concurrent Program.
Sounds simple, it is indeed, but devil lies in detail. Hence read the below carefully.
I have provided the source code with installation instructions for you to try this. Please
note to try this you need 11.5.10 environment.
2. Next you need a concurrent program that spit out an XML file to the output of the
concurrent program. Such concurrent program can be of type SQL or PL/SQL or Oracle
Report or any other supportable type, provided it can produce a XML output.
Hence in this case, we will develop a Report that has all the columns from table
xx_managers
Create a plain default Oracle Report using wizard in Oracle Reports 6i.
This can be done using wizard with SQL select * from xx_managers
Above picture shows the report output in Reports 6i preview
8. Run the report and you will see an xml output appearing. Save the output as
XX_MANAGERS_241106.xml on your computer. You will need to use
menu /Tool/Copy to open this XML output in browser, and then save it as
XX_MANAGERS_241106.xml on your PC.
9. Install this XML Publisher Desktop software on your pc, ensuring that you have MS-
Word installed(for this demo)
The XML Builder Desktop Patch for Word is Patch Number: 4561835
This software can be downloaded from
http://updates.oracle.com/download/4561835.html
This is a tool given by Oracle[Desktop XML Publisher] that will read any XML file, will
create the fields automatically.
10. Open MS Word after installing as per step 9, and you will now see something similar
to below in Microsoft Word
Now in MS Word, click on Load XML Data and select file
XX_MANAGERS_241106.xml that was created in Step 8.
Effectively by doing these steps, you have just created a Layout for the report in XML
Publisher. The layout will look like this [as below].
12. Now, lets do the real bit in attaching the Concurrent Program definition to XML
Publisher. Logon to responsibility XML Publisher Administrator.
Click on Data Definition menu as aboveso that we can create the XMLs source data
Definition. Effectively we are saying that output of the Concurrent program becomes the
data definition for XMLP.
For doing so, click on Templates Tab. We need to create a Template for the data-
definition of previous step.
Oracle Apps provides an Out of the Box Audit Trail Functionality that works like a
charm.
I never had thought about writing an Article on Audit Trail feature, until Kartikey pinged
me to write an article on this subject. You can achieve Auditing[as explained in Step by
Step example below] without writing a single piece of Code in Oracle Apps. It can be
argued that CDC [change data capture] might be used, but I think the design of CDC is
more friendly for Warehousing purposes, rather than Audit Reporting.
Lets say that we wish to create a audit trail on a table named FND_LOOKUP_VALUES.
Now, add audit tables to this group[you can add as many tables]
User Table Name: FND_LOOKUP_VALUES
OBJECT_NAME OBJECT_TYPE
-------------------------- --------------------------
FND_LOOKUP_VALUES_A TABLE
FND_LOOKUP_VALUES_A SYNONYM
FND_LOOKUP_VALUES_AC TRIGGER
FND_LOOKUP_VALUES_AC1 VIEW
FND_LOOKUP_VALUES_AD TRIGGER
FND_LOOKUP_VALUES_ADP PROCEDURE
FND_LOOKUP_VALUES_AH TRIGGER
FND_LOOKUP_VALUES_AI TRIGGER
FND_LOOKUP_VALUES_AIP PROCEDURE
FND_LOOKUP_VALUES_AT TRIGGER
FND_LOOKUP_VALUES_AU TRIGGER
FND_LOOKUP_VALUES_AUP PROCEDURE
FND_LOOKUP_VALUES_AV1 VIEW
Fine, this proves that the concurrent program in Step 4 did its job.
Optionally, you may run concurrent process AuditTrail Report for Audit Group
Validation to validate the success of Audit Table/Trigger creation.
You can add additional columns to audit trail and re-execute Step 4.
Please note that adding columns for Audit could have been done immediately after Step 3.
This explains how you can Audit trail changes to Data in Oracle Applications, without
writing a single line of code
Hierarchy Profile Options
This article is an attempt to explain the Hierarchy Profile Options with examples.
Can all the profile options be set at Organization Level and Server level?
You need to set Hierarchy Type field in Profile Option definition to enable that profile
to be eligible for Hierarchy Level. This functionality was introduced in 11.5.9
In this article, I would like to give you a quick trick to find "which request group should the concurrent
program be added to"? Many a times, we create a new concurrent program following which we try to
make that program available from a specific Menu under a specific responsibility.
I have created a concurrent program, and I now wish to know which request group must this program be
added to?
Step 1. Ensure that profile option "Utilities:Diagnostics" is set to Yes at your user level.
Note:- This step can be skipped in case you have the apps password.
Step 2. Navigate to the responsibility from where you will submit the concurrent program.
Step 3. Navigate to the "Submit New Request" screen, where you will enter the name of the concurrent program to
run.
Step 4. Now you must do examine using the help menu as shown below.
Step 5. In the block field, enter PARAMETER, and in the field name enter REQUEST_GROUP_CODE
Note down this value
Step 6. Now in the value field enter REQUEST_GROUP_APPL_SHORT_NAME
Note down the two values from Step 5 and Step 6.
These will indicate the request group to which you must add your concurrent program.
In this case use the Request group specified in "Define Responsibility Screen"
The rule is :-
If request group code is being passed in as parameter to Submit Request form function, then use that request
group. Or else use the request group at responsibility level.
NOTES:-
Why do I need both the request group code and the request group application?
Request group name and its application is a composite primary key, hence you need the application name. For
example "All Reports" request group can be found under every possible application.
This request group name and application are defined as parameters to the form functions.
Correct
If at the time of defining form function, we do not pass request group parameter, then request group from
responsibility is used?
Correct, because request group specified against responsibility is the default request group.
Smart Descriptive Flexfields
In this article, I would like to explain some tricks with context sensitive Descriptive
Flexfields. To begin with lets consider some scenarios as below.
Scenario 1. Depending upon the responsibility user has logged into, you wish to either
show two flexfield segemts or three segments. This is a fairly common requirement.
Scenario 2. There are two different oracle screens, both based on same table but different
functionality. Hence the share the same descriptiveflexfields. You wish to use
notation :block.fieldname in the value set. But this will work in one screen and error in
another.
What are the options at hand for solutions to Scenatio 1 and Scenario 2?
Option 1. Use profile option as the context
Option 2. Use a system global variable as the context.
Ah, what if same user in a single responsibility has access to different screens that
share same DFF?
In this scenario, you can design your descriptive flexfield on a System variable context.
Hence your context will be :SYSTEM.CURRENT_FORM. Depending upon which form
the user has navigated to, they will see different segments.
Note: Use Examine utility to find out the Current Form Name
In this article, he will explain the steps to implement XML Publisher reports for Pre-
Printed Stationary in Oracle eBusiness Suite.
Many thanks to Darshan for sharing this knowledge.
This article from Darshan will help a lot of technical consultants in implementing similar
solutions for their respective clients.
The Sample Template and Data file can be downloaded from the end of this article.
Abstract
I was inspired to come up with this because I feel that lots of people want this solution
and they are struggling to implement this.
In this whitepaper, I am going to explain the approach which I used for developing pre-
printed stationary reports by XML publishers RTF method. This approach I used for 2
customers and it works absolutely fine. They are very happy. Example Pre-Printed
stationary reports which I worked on are following AP Check Printing(Bank) ,AR invoice
Printing,PO purchase Order Printing . etc.
Background
I have a customer who wants to convert their 40+ Oracle Apps reports to XML publisher
Reports. These reports are fall in categories of AR invoice report, check printing report
and PO print report which they are printing on pre-printed (pre-defined) stationary.
Just a little background of pre-printed stationary reports layout where there is a fix
Header section and fix Detail Section Table. Detail section table should always have fix
table height, in the sense it should always have fix number of rows in the table no matter
how many rows returned by actual report run. For example Invoice stationary has fix 30
rows in line detail table, and Actual report run is returning only 5 rows then rest 25 blank
rows should be generatedprogrammatically.
So far there are solutions available which are talking about fixing table height for
the 1st pages onwards not for the first page itself, i.e. where actual report run is
returning lines which are less than lines_fixed_per_page. For example Invoice run
is returning only 5 rows where as pre-printed stationary has fixed 30 lines per
page.I struggled a lot to get this solution and now I got this and sharing it in this
whitepaper.
So far it has not been discovered because of the limitation of for-loop in XSL-FO (XML
Technology).Limitation I mean is ,we can not write loop like for (i=10;i<15;i++) in XML.
In XML for loop will always iterate till it gets data, if we want to go beyond that then we
can not go. I mean we can write for loop based on data value.
Detail Solution
I am giving this solution for Standard Check Printing Report. Tree structure of data
(Sample XML data is as follow).
<LIST_G_CHECKS>
<C_CHECK_NUMBER>21897</C_CHECK_NUMBER>
<C_VENDOR_NUMBER>2205</C_VENDOR_NUMBER>
<LIST_G_INVOICES>
<C_PAYMENT_NUMBER>1</C_PAYMENT_NUMBER>
<C_INVOICE_NUMBER>ERS-20-SEP-06-243</C_INVOICE_NUMBER>
</G_INVOICES>
<C_PAYMENT_NUMBER>2</C_PAYMENT_NUMBER>
<C_INVOICE_NUMBER>ERS-20-SEP-06-244</C_INVOICE_NUMBER>
</G_INVOICES>
</LIST_G_INVOICES>
</G_CHECKS>
</LIST_G_CHECKS>
Below is the step-step guide which I follow.
<?for-each@section:G_CHECKS?>
<?for-each:$inner_group?>
5) Before putting any elements with the help of current record pointer 'position(), I am
checking if the current position is modulizing with the no_of_lines_per_page equals zero
or not. If it reaches the first record after modulizing then I will create local variable
'first_rec' and initialize it with '0'.
<?for-each:$inner_group?>
7) I will check with the help of current record pointer 'position()' that the current record
position is either greater than 'first_rec' i.e. the first record or less the
'no_of_lines_per_page' value set up earlier. If it is then show the record otherwise not
otherwise it will not go in loop.
10) Now I am calling sub-template recursively for filling the blank rows. While
calling this template I am passing one parameter which is having value of
no_of_rows to fill. Sub-template will have just one row table.
<xsl:template name="countdown">
<xsl:param name="countdown"/><xsl:if test="$countdown"><xsl:call-template
</xsl:call-template></xsl:if>
</xsl:template>
12) I have created page break after the fixed number of rows have been displayed.
<xsl:attribute name="break-before">page</xsl:attribute>
</xsl:if>
13) Finally closing outer if and inner for loop and outer for loop.
A. Business Case
1) Creation of Items
3) Define Customer
6) Define Resources
7) Define Departments
19) Create, Release, Complete, Close Discrete Job for CPU Subassembly
20) Create, Release, Complete, Close Discrete Job for Dell Computer
21) Sales Order Booking, Releasing, Ship Confirm the Finished Goods
23) View Sales Invoice, Create Receipt, Remittance and view Account Balances
This Document has been broken to three parts owing to the size of the document is very
huge. Hence readers are requested to read the Document Links in the following Sequence
to understand the complete flow of Transactions
This is a quick note to share a SQL that will tell you the FND_USER.USER_NAME of
the person that has locked a given table in Oracle APPS.
The column named "module" will tell you the name of the Form Function or the
Concurrent Program Short name which has aquired a lock onto that table.
SELECT c.owner
,c.object_name
,c.object_type
,fu.user_name locking_fnd_user_name
,fl.start_time locking_fnd_user_login_time
,vs.module
,vs.machine
,vs.osuser
,vlocked.oracle_username
,vs.sid
,vp.pid
,vp.spid AS os_process
,vs.serial#
,vs.status
,vs.saddr
,vs.audsid
,vs.process
FROM fnd_logins fl
,fnd_user fu
,v$locked_object vlocked
,v$process vp
,v$session vs
,dba_objects c
WHERE vs.sid = vlocked.session_id
AND vlocked.object_id = c.object_id
AND vs.paddr = vp.addr
AND vp.spid = fl.process_spid(+)
AND vp.pid = fl.pid(+)
AND fl.user_id = fu.user_id(+)
AND c.object_name LIKE '%' || upper('&tab_name_leaveblank4all') || '%'
AND nvl(vs.status
,'XX') != 'KILLED';
Another usage of Java Concurrent Programs
Did we connect to all those 400 bank accounts using Java Concurrent Program?
Not really. We used a third party named Biveroni[link]. Biveroni used to collect SWIFT
messages for all our 400+ bank accounts. SWIFT message, if nothing but an
message/instruction in specific format, that tells how much moneyhas been transacted on
a given bank account number.
So Biveroni received all the SWIFT messages, and java concurrent program was
used to get those messages from Biveroni?
Correct.
For the complete java technical design, please click on the link Java Bank Poller- Using
Java Concurrent Program.
I primarily used JDeveloper 9.0.2 for this development then, although Eclipse was
partially used as well for its code generation features.
Switch off CUSTOM.pll programatically
Yesterday someone asked me a very interesting question. The question was, how to turn
off CUSTOM.pll programatically based on some condition. The idea behind this article is
not only to provide solution to this question, but also to discuss another major limitation
of forms personalization.
Turn custom code off using help menu, and then you will notice the value of global
variable changing.
What are the two options to disable CUSTOM.pll programatically?
Option 1:- Use Forms Personalization
Note: The limitation of Forms personalization, is that you will need to implement this
change for each and every FORM/Function separately
This limitation does not exist in CUSTOM.pll as we will see below.
Option 2:- Use CUSTOM.pll [yes CUSTOM.pll to turn off CUSTOM.pll conditionally]
IF event_name = 'WHEN-NEW-FORM-INSTANCE' THEN
IF fnd_profile.value( 'GL_SET_OF_BKS_ID' ) = 999 THEN
copy ( 'OFF' , 'GLOBAL.APP_CUSTOM_MODE' ) ;
ELSE
copy ( 'NORMAL' , 'GLOBAL.APP_CUSTOM_MODE' ) ;
END IF ;
END IF ;
So, CUSTOM.pll still rules in certain cases, as in this case whereby you wish to implement a logic spanning
multiple forms with few lines of code.
Some Scripts commonly used in Oracle E-Business Suite
Written by Ahmad
Sunday, 03 June 2007
Ahmad Bilal has thankfully decided to share some of the commonly used scripts that he
uses.
Please find these scripts below.
Note: - all queries are executed on RDBMS: 9.2.0.6.0 Oracle Applications: 11.5.10.2 by using
Toad for Oracle version 8.5.0.50
1. Responsibilities Listing
Description Query useful when user wants to get application wise responsibility list
Parameters None
Query
FROM fnd_application fa
frt.responsibility_id, frt.responsibility_name
Query
FROM apps.fnd_responsibility_tl a,
apps.fnd_responsibility b,
apps.fnd_menus_tl c,
apps.fnd_menus d,
apps.fnd_application_tl e,
apps.fnd_application f
Description By using this query user can check function and submenus attached to that
specific menu
Parameters User_menu_name Which user can get from query of section Menu
Listing
Query
Parameters None
Query
FROM fnd_user u,
fnd_user_resp_groups g,
fnd_application_tl a,
fnd_responsibility_tl r
Parameters None
Query
ORDER BY responsibility_name
1. Profile Option With Modification Date and User
Purpose To get modified profile options.
Description Query used for audit point of view i.e. when a profile is changed and by whom
user
Parameters None
v.last_update_date,
FROM fnd_user
(SELECT user_name
FROM fnd_user
FROM fnd_profile_options o,
fnd_profile_option_values v,
fnd_profile_options_tl t
FROM fnd_languages
GL Interface API to Import Journals
Please find below an API for creating Journals in Oracle General Ledger ( GL ) . I had
developed this API in year 2002, and I have used this for three of my clients.
The idea behind this API is that you do not need to program for:-
1. Inserts to GL Interface ( GL_INTERFACE )
2. The validations required for Oracle GL Import
3. Submission of GL Import
For the source code for these API's click on the links below:-
GL Import API Package Header
GL Import API Package Body
END xx_import_xfer_gl_iface_api;
Oracle API for GL Interface Package Body:
g_gl_batch_prefix VARCHAR2(30) :=
nvl(fnd_profile.VALUE('XX_OVERRIDE_GL_BATCH_PREFIX')
,'XX_GL_FEED_NAME:');
g_debug_procedure_context VARCHAR2(30);
g_debug_header_context CONSTANT VARCHAR2(80) :=
'xx_gl_feed.plsql.xx_import_xfer_gl_iface_api.';
--Programming variables
--g_group_id and g_interface_run_id will be set each time separately for a batch
g_group_id NUMBER;
g_interface_run_id NUMBER;
PROCEDURE new_gl_interface_batch IS
BEGIN
g_group_id := NULL;
g_interface_run_id := NULL;
END new_gl_interface_batch;
END debug_stmt;
PROCEDURE debug_begin_procedure IS
BEGIN
fnd_log.STRING(log_level => fnd_log.level_statement
,module => g_debug_header_context ||
g_debug_procedure_context
,message => 'Begin ' || g_debug_procedure_context);
END debug_begin_procedure;
PROCEDURE debug_end_procedure IS
BEGIN
fnd_log.STRING(log_level => fnd_log.level_statement
,module => g_debug_header_context ||
g_debug_procedure_context
,message => 'End ' || g_debug_procedure_context);
END debug_end_procedure;
g_sob_id := p_sob_id;
debug_stmt('set_sob_id() Setting g_sob_id=>' || g_sob_id);
debug_end_procedure;
END set_sob_id;
g_source_name := p_source_name;
debug_stmt('set_source_name() Setting g_source_name=>' ||
g_source_name);
debug_end_procedure;
END set_source_name;
g_group_id := p_group_id;
g_interface_run_id := p_interface_run_id;
debug_end_procedure;
EXCEPTION
WHEN re_use_gl_interface_control THEN
debug_stmt('Returning Global Group g_group_id=>' || g_group_id ||
' g_interface_run_id=>' || g_interface_run_id);
debug_end_procedure;
END populate_interface_control;
PROCEDURE interface_record IS
n_group_id INTEGER;
n_sob_id INTEGER;
n_interface_run_id INTEGER;
BEGIN
set_debug_context('interface_record');
n_sob_id := get_sob_id;
populate_interface_control(p_user_je_source_name => g_source_name
,p_group_id => n_group_id
,p_set_of_books_id => n_sob_id
,p_interface_run_id => n_interface_run_id);
debug_end_procedure;
END interface_record;
p_check c_check%ROWTYPE;
BEGIN
set_debug_context('check_ccid');
debug_stmt('p_sob_id=>' || p_sob_id || ' p_ccid=>' || p_ccid);
OPEN c_check;
FETCH c_check
INTO p_check;
IF c_check%NOTFOUND
THEN
CLOSE c_check;
debug_stmt('check_ccid() RETURNED FALSE;');
RETURN FALSE;
END IF;
CLOSE c_check;
debug_stmt('check_ccid() RETURNED TRUE;');
RETURN TRUE;
debug_end_procedure;
END check_ccid;
p_check c_check%ROWTYPE;
BEGIN
set_debug_context('check_conversion_type');
debug_stmt('g_conversion_type=>' || g_conversion_type);
OPEN c_check;
FETCH c_check
INTO p_check;
IF c_check%NOTFOUND
THEN
CLOSE c_check;
debug_stmt('check_conversion_type() RETURNED FALSE;');
RETURN FALSE;
END IF;
CLOSE c_check;
debug_stmt('check_conversion_type() RETURNED TRUE;');
RETURN TRUE;
END check_conversion_type;
IF c_check%NOTFOUND
THEN
CLOSE c_check;
debug_stmt('check_gl_source() RETURNED FALSE;');
RETURN FALSE;
END IF;
CLOSE c_check;
debug_stmt('check_gl_source() RETURNED TRUE;');
RETURN TRUE;
END check_gl_source;
IF v_count > 0
THEN
debug_stmt('validate_accounting_date() RETURNED TRUE');
RETURN TRUE;
ELSE
debug_stmt('validate_accounting_date() Cant find open Period for ' ||
p_accounting_date);
--try to find next available date now
p_accounting_date := get_next_available_open_date(p_accounting_date =>
v_accounting_date
,p_gl_appl_id => p_gl_appl_id
,p_sob_id => p_sob_id);
IF p_accounting_date IS NULL
THEN
log_error(p_batch_header_id => p_batch_header_id
,p_trx_header_id => p_trx_header_id
,p_error_message => 'Accounting Date ' ||
to_char(v_accounting_date
,'DD-MON-YYYY') ||
' does not belong to a Open Period');
END validate_accounting_date;
IF v_count > 0
THEN
debug_stmt('validate_currency() RETURNED TRUE');
RETURN TRUE;
ELSE
debug_stmt('validate_currency() RETURNED FLASE');
RETURN FALSE;
END IF;
END validate_currency;
PROCEDURE set_conversion_type_code IS
CURSOR c_get IS
SELECT conversion_type
FROM gl_daily_conversion_types
WHERE user_conversion_type = g_conversion_type;
BEGIN
set_debug_context('set_conversion_type_code');
debug_stmt('g_conversion_type=>' || g_conversion_type);
OPEN c_get;
FETCH c_get
INTO g_conversion_type_code;
CLOSE c_get;
debug_stmt('g_conversion_type_code=>' || g_conversion_type_code);
debug_end_procedure;
END set_conversion_type_code;
/**************************************************
Main code for gms_cost_xfer GL Interface begins here
**************************************************/
PROCEDURE transfer_to_gl(p_sob_id IN INTEGER
,p_batch_header_id IN INTEGER
,p_trx_header_id IN INTEGER
,p_trx_line_id IN INTEGER
,p_date IN OUT DATE
,p_currency_code IN VARCHAR2
,p_amount IN NUMBER
,p_dr_account IN INTEGER
,p_cr_account IN INTEGER
,p_journal_name IN VARCHAR2
,p_header_description IN VARCHAR2
,p_line_description IN VARCHAR2
,p_success_flag OUT BOOLEAN
,p_first_record_in_batch IN VARCHAR2
,p_submit_gl_interface IN VARCHAR2
,p_gl_user_je_source_name IN VARCHAR2
,p_gl_user_je_category_name IN VARCHAR2
,p_trx_number IN VARCHAR2) IS
v_gl_appl_id NUMBER;
l_gl_int_type_rec g_gl_int_type_rec;
v_conc_id INTEGER;
conversion_rate_does_not_exist EXCEPTION;
invalid_conversion_type EXCEPTION;
invalid_dr_ccid EXCEPTION;
invalid_cr_ccid EXCEPTION;
invalid_currency_code EXCEPTION;
not_in_open_period EXCEPTION;
invalid_gl_source EXCEPTION;
v_func_curr VARCHAR2(30);
v_group_id NUMBER;
v_interface_run_id NUMBER;
v_ret_val BOOLEAN;
v_request_id INTEGER;
phase VARCHAR2(100);
status VARCHAR2(100);
dev_phase VARCHAR2(100);
dev_status VARCHAR2(100);
v_message VARCHAR2(100);
v_bool BOOLEAN;
v_old_status VARCHAR2(30);
BEGIN
set_debug_context('transfer_to_gl');
SAVEPOINT gms_cost_xfer_gl_int;
set_conversion_type_code;
IF p_first_record_in_batch = 'Y'
THEN
debug_stmt('p_first_record_in_batch is Y. Hence will reset global variables to initiate
new batch');
new_gl_interface_batch;
ELSE
debug_stmt('Not being the first record, accumulating this line to existing batch.');
END IF;
/* May be GL team forgets to create source for gms_cost_xfer, lets see...*/
IF NOT check_gl_source(p_gl_user_je_source_name)
THEN
RAISE invalid_gl_source;
END IF;
/* During the design phase in Swiss Re the conversion type has already been changed
once
Lets not take any chances and check is this is a valid conversion type */
IF NOT check_conversion_type
THEN
RAISE invalid_conversion_type;
END IF;
v_func_curr := get_sob_currency(p_sob_id);
IF nvl(v_func_curr
,'XX') != nvl(p_currency_code
,'XX')
THEN
IF 'N' =
gl_currency_api.rate_exists(x_from_currency => p_currency_code
,x_to_currency => v_func_curr
,x_conversion_date => p_date
,x_conversion_type => g_conversion_type_code)
THEN
RAISE conversion_rate_does_not_exist;
ELSE
l_gl_int_type_rec.user_currency_conversion_type := g_conversion_type;
l_gl_int_type_rec.currency_conversion_date := p_date;
END IF;
END IF;
l_gl_int_type_rec.reference_date := p_date;
l_gl_int_type_rec.reference21 := p_header_description;
l_gl_int_type_rec.group_id := v_group_id;
l_gl_int_type_rec.set_of_books_id := p_sob_id;
l_gl_int_type_rec.user_je_source_name := nvl(p_gl_user_je_source_name
,g_gl_user_je_source_name);
l_gl_int_type_rec.user_je_category_name := nvl(p_gl_user_je_category_name
,g_gl_user_je_category_name);
l_gl_int_type_rec.accounting_date := p_date;
l_gl_int_type_rec.transaction_date := p_date;
l_gl_int_type_rec.currency_code := p_currency_code;
l_gl_int_type_rec.date_created := p_date;
l_gl_int_type_rec.created_by := fnd_global.user_id;
l_gl_int_type_rec.actual_flag := 'A';
l_gl_int_type_rec.status := 'S';
l_gl_int_type_rec.attribute1 := p_trx_header_id;
l_gl_int_type_rec.attribute2 := p_trx_line_id;
l_gl_int_type_rec.attribute3 := p_trx_number;
l_gl_int_type_rec.attribute4 := get_xx_transaction_source;
l_gl_int_type_rec.attribute5 := p_batch_header_id;
IF p_dr_account IS NOT NULL AND
(NOT check_ccid(p_sob_id => p_sob_id
,p_ccid => p_dr_account))
THEN
RAISE invalid_dr_ccid;
END IF;
IF p_cr_account IS NOT NULL AND
(NOT check_ccid(p_sob_id => p_sob_id
,p_ccid => p_cr_account))
THEN
RAISE invalid_cr_ccid;
END IF;
IF p_submit_gl_interface = 'Y'
THEN
debug_stmt('p_submit_gl_interface=>' || p_submit_gl_interface);
/* After inset, submit the request*/
COMMIT;
v_conc_id := fnd_request.submit_request(application => 'SQLGL'
,program => 'GLLEZL'
,description => NULL
,start_time => SYSDATE
,sub_request => FALSE
,argument1 => v_interface_run_id
,argument2 => p_sob_id
,argument3 => 'N'
,argument4 => NULL
,argument5 => NULL
,argument6 => 'N'
,argument7 => 'W');
SELECT status_code
INTO v_old_status
FROM fnd_concurrent_requests
WHERE request_id = fnd_global.conc_request_id;
UPDATE fnd_concurrent_requests
SET status_code = 'W'
WHERE request_id = fnd_global.conc_request_id;
COMMIT;
v_bool := fnd_concurrent.wait_for_request(v_conc_id
,5
,1000
,phase
,status
,dev_phase
,dev_status
,v_message);
UPDATE fnd_concurrent_requests
SET status_code = v_old_status
WHERE request_id = fnd_global.conc_request_id;
COMMIT;
IF (v_conc_id = 0)
THEN
/* If request not submitted, return false */
ROLLBACK TO gms_cost_xfer_gl_int;
p_success_flag := FALSE;
debug_stmt(' Returning false as request could not be submitted');
RETURN;
END IF;
END IF;
p_success_flag := TRUE;
EXCEPTION
WHEN conversion_rate_does_not_exist THEN
ROLLBACK TO gms_cost_xfer_gl_int;
p_success_flag := FALSE;
fnd_message.set_name('XTR'
,'XTR_2207');
fnd_message.set_token('CURR1'
,v_func_curr);
fnd_message.set_token('CURR2'
,p_currency_code);
fnd_message.set_token('XCHG_DATE'
,to_char(p_date));
fnd_message.set_token('C_TYPE'
,g_conversion_type);
WHEN invalid_currency_code THEN
ROLLBACK TO gms_cost_xfer_gl_int;
p_success_flag := FALSE;
fnd_message.set_name('SQLGL'
,'R_PPOS0026');
WHEN invalid_gl_source THEN
ROLLBACK TO gms_cost_xfer_gl_int;
p_success_flag := FALSE;
fnd_message.set_name('SQLGL'
,'SHRD0152');
WHEN invalid_conversion_type THEN
ROLLBACK TO gms_cost_xfer_gl_int;
p_success_flag := FALSE;
fnd_message.set_name('SQLGL'
,'GL_JE_INVALID_CONVERSION_TYPE');
WHEN not_in_open_period THEN
ROLLBACK TO gms_cost_xfer_gl_int;
p_success_flag := FALSE;
fnd_message.set_name('SQLGL'
,'GL_JE_NOT_OPEN_OR_FUTURE_ENT');
WHEN invalid_cr_ccid THEN
ROLLBACK TO gms_cost_xfer_gl_int;
p_success_flag := FALSE;
fnd_message.set_name('AR'
,'AR_AAPI_INVALID_CCID');
fnd_message.set_token('CCID'
,p_cr_account);
WHEN invalid_dr_ccid THEN
ROLLBACK TO gms_cost_xfer_gl_int;
p_success_flag := FALSE;
fnd_message.set_name('AR'
,'AR_AAPI_INVALID_CCID');
fnd_message.set_token('CCID'
,p_dr_account);
WHEN OTHERS THEN
ROLLBACK TO gms_cost_xfer_gl_int;
p_success_flag := FALSE;
fnd_message.set_name('FND'
,'FS-UNKNOWN');
fnd_message.set_token('ERROR'
,SQLERRM);
END transfer_to_gl;
END xx_import_xfer_gl_iface_api;
Splitting the instance into different Set Of Books
His question:-
Well, we are working on 11.5.4 with Oracle Financials.
My question is...
We have two companies with two SEPERATE set of books in our setup.
Now we want to seperate both the companies on two seperate Setups (Apps + DB) ....
A very interesting question this is, but the solution is unbelievably simple....
They wish to split their ERP install base into two different independent instances of
database.
In instance A, you will close all periods for SOB 2. And disable all the responsibilities
that have their profile options pointing to SOB2.
In instance B, do vice versa, i.e. close all periods for SOB 1. And disable all the
responsibilities that have their profile options pointing to SOB1.
By doing the above, Instance A will be used for SOB 1, whereas Instance B will be used
for SOB 2.
Calling a PL/SQL Concurrent Program in Real-Time
Your requirement is such that you wish to call that PL/SQL Executable [attached to
concurrent program] directly from some other process, in real-time mode, in the same
session as that of the parent Oracle session[forms or report or some other plsql ]. In order
to call that pl/sql program within the same session, your challenge may be that the
concurrent program could be writing into log/output file using fnd_file API which you
want to display to the user somehow.
To get a handle to the log/output of the API [which is executable of Conc Program], we
need to do the following:-
1. Call fnd_global.initialize ensuring you pass it two parameters in bold below
declare
...your variables here
v_session_id INTEGER := userenv('sessionid');
v_trace VARCHAR2(2000) := fnd_trace.get_trace_filename;
n_conc_request_id INTEGER ;
begin
//optionally trace the API Call with bind variable values
execute immediate 'alter session set events=''10046 trace name context forever, level
12''' ;
//the trace file details will be in variable v_trace
//Now call fnd_global.initialize ensuring you pass it two parameters in bold below
fnd_global.initialize
(
session_id => v_session_id
,user_id => 18594 //or pass the current
fnd_global.user_id itself
,resp_id => 4650126 //or pass the current
fnd_global.resp_id itself
,resp_appl_id => 8405 //or pass the current
fnd_global.resp_appl_id itself
,security_group_id => 0
,site_id => NULL
,login_id => 3115003
,conc_login_id => NULL
,prog_appl_id => NULL
,conc_program_id => 229233 //The program id of concurrent
request
,conc_request_id => n_conc_request_id //From
fnd_concurrent_requests_s.nextval
,conc_priority_request => NULL
);
//Lets assume the nextval from sequence is 14633154
//now call the API, i have arbitrarily typed in just any API
ar_process_trx.place_hold( v_errbuf, v_retcode, v_trx_id ) ;
end ;
2. Run the SQL on fnd_temp_files, as below, using the fictional request_id generated
from sequence [ in variable n_conc_request_id ]
3. In order to read those files, ensure that the directory [/usr/tmp in this case] is listed in v
$parameter utl_file_dir
In this approach, no change is made to the Original concurrent program. Hence, if need
be, users can continue to run the concurrent process as usual from SRS.
This article discusses the best practices & strategies for developing Interface Programs in
Oracle Financials / APPS/ EBS.
This article assumes that you have already read the article on data migration, if not the
click here.
XML Gateway
If you want an Oracle delivered tool to implement interfaces using messaging, you can
use XML Gateway with Message Maps. But investment in this tool may be lost when you
move to BPEL based architecture.
Web Services
Wait for Fusion that integrates BPEL, unless you wish to manage Web Services in a
standalone manner.
Migration program in Apps. Migrate Customers
This article explains the steps to write programs for data migration in Oracle Apps.
Question : What is involved in the preparation stage of data migration in oracle apps?
Answer: For the Preparation stage, following must be done.
1. Understand the structure of the data being imported and also its business purpose.
2. Fully understand where the data will end up residing into Oracle Apps.
3 Find out if open interfaces or APIs exist in Oracle Apps to facilitate loading the required
data.
4. Ensure that lookup codes or setup in Oracle apps support the values that are coming
from source system.
5. Think about how the errors will be reported and managed.
6. Also think about how the transactions that fail migration will be re-tried. You may
decide to knock of a simple screen if high volume of transactions needs user intervention
for cleansing.
Question : If I get a comma delimited file, how will I load that into tables?
Answer : You can use a Sql*Loader, or a java program with a csv parser or a file based
table approach.
Question : In oracle apps during migration, do we usually receive xml data file?
Answer : Keep in mind that you usually migrate data from mainframe or standalone
systems which now stand outdated.
Such systems usually produce comma delimited or tab delimited file.
Question : Ok, once the data from source system has been loaded using sql*loader, what
next?
Answer: The data model of the source data may or may not comply with the data model
in oracle apps. Hence you need a transformation step in most cases. This is explained
below with an example of TCA API to migrate customers/parties.
Question : Should I not ask the legacy system people to transform data as per our
requirements?
Answer : No, don't bother doing so, for below reasons :-
A. Techies of legacy system will not be happy that their system is now being made
redundant. Hence don't expect much value addition from them.
B. There is a possibility that in an attempt to transform data to Oracle's data structure, they
might induce faults/bugs.
If the transformation bugs are encountered at your end in apps, you can fix them yourself.
However if legacy team does transformation for you, then you become dependent on
them for bug fixes. Eventually tired of waiting on them, you might end up doing
transformation yourself anyway.
C. If your design for transformation changes, you should not be dependent upon the
legacy system...just fix it yourself at your own end in apps.
Question : If we end up using interface api's in apps for data migration, then where lies
the difference between migration and interfaces?
Answer : Migration is a one-off activity, even though it uses the same sets of tables/API's
as interfaces do.
Question : Enough explanation, now give me an example.
Answer : Lets assume you get a task to migrate customers from legacy system into TCA
(or call it AR - Receivables for simplicity).
Your file from source is:-
lcust.dat
1000,GE, GE Capital,1000-1
1001,Cisco,Cisco Routers,1001-1
1002,Barclays,Barclays Investments,1001-1
1003,Barclays,Barclays Mortgages,1001-2
Step 1. FTP this file to your database server and run sql*loader to load the file into a table
named xx_legacy_cust, this table will have four columns, one column for each file in
source.
Step 2. Transform this data...
For this we create two tables...
XX_TRNSFRM_PARTY
--parent_cust_Id
--parent_cust_name
XX_TRNSFRM _CUST_ACCOUNT
--parent_cust_Id
--operating_cust_Id
--operating_cust_name
Now, you can write a pl/sql program to split data from table xx_legacy_cust into the two
tables listed above.
Step 3. Now write the pl/sql program to migrate this data into Oracle.
Create or replace procedure xx_migrate_parties(errbuff out varchar2,retcode out varchar2)
is
Begin
FOR p_party_rec in (select * from XX_TRNSFRM_PARTY )
LOOP
--call api to create party
Hz_Party_Site_V2pub.create_party();
END LOOP ;
END LOOP ;
END ;