What is user hooks in oracle apps
In this Post , We will be discuss
about user hooks in oracle apps. User hooks help us to trigger the custom code
inside the standard package which allows use to meet the business requirement. User
Hooks is the most controlled way to customizing process in oracle apps.
User Hooks are a feature that allows
customizing the application in a way that is less invasive and that can be
easily disabled for diagnosing problems with the customization. Hooks
are code that is conditionally executed by some application
packages. The condition is that the hook has to be enabled.
Hook calls are interleaved in some
of ASO APIs, mostly on public APIs.
2 types of Hooks
Pre-processing Hooks:
Are hooks that execute (if enabled) before the
API does any actual processing. These are good for modifying/adding information
so the API can proceed with that change in place. These hooks are of type B
(from Before)
Post-processing Hooks:
Pre hooks that execute (if enabled) after the
API did all processing. Post hooks are usually good for cleanup of a pre-hook
or for further processing after the vanilla API has finished work. These hooks
are of type A (from after).
In an API that support hooks the
following structure is observed:
PROCEDURE
<proc name>
<variables>
BEGIN
...
IF (JTF_USR_HKS.ok_to_execute (G_PKG_NAME, l_api_name, 'B', 'C')) THEN
<CALL TO PRE-HOOK>
<ERROR HANDLING>
END IF;
...
<ACTUAL API PROCESSING CODE>
...
IF (JTF_USR_HKS.ok_to_execute (G_PKG_NAME, l_api_name, 'A', 'C')) THEN
<CALL TO POST-HOOK>
<ERROR HANDLING>
END IF;
...
END;
<variables>
BEGIN
...
IF (JTF_USR_HKS.ok_to_execute (G_PKG_NAME, l_api_name, 'B', 'C')) THEN
<CALL TO PRE-HOOK>
<ERROR HANDLING>
END IF;
...
<ACTUAL API PROCESSING CODE>
...
IF (JTF_USR_HKS.ok_to_execute (G_PKG_NAME, l_api_name, 'A', 'C')) THEN
<CALL TO POST-HOOK>
<ERROR HANDLING>
END IF;
...
END;
II. Vertical and
Custom Hooks
Custom hooks are available for implementation customizations. Vertical hooks are reserved for Oracle Development use.
Vertical hooks are called the same as custom hooks but the last parameter instead of a 'C' is a 'V'. These hooks should not be enabled or disabled by customer and the state must be left unchanged. Also no custom code should be implemented in Vertical hooks.
The actual name of the package. Procedure of a hook is found in the API calling the hook. For example in the procedure ASO_QUOTE_PUB.delete_quote (asopqteb.pls) you can see:
IF (JTF_USR_HKS.ok_to_execute
(G_PKG_NAME, l_api_name, 'B', 'C')) THEN
ASO_QUOTE_CUHK.Delete_quote_PRE(
P_Qte_Header_Id => l_qte_header_id,
X_Return_Status => x_return_status,
X_Msg_Count => x_msg_count ,
X_Msg_Data => x_msg_data
);
ASO_QUOTE_CUHK.Delete_quote_PRE(
P_Qte_Header_Id => l_qte_header_id,
X_Return_Status => x_return_status,
X_Msg_Count => x_msg_count ,
X_Msg_Data => x_msg_data
);
IF
(JTF_USR_HKS.ok_to_execute(G_PKG_NAME, l_api_name, 'A', 'C')) THEN
ASO_QUOTE_CUHK.Delete_quote_POST(
P_Qte_Header_Id => l_qte_header_id,
X_Return_Status => x_return_status,
X_Msg_Count => x_msg_count,
X_Msg_Data => x_msg_data );
ASO_QUOTE_CUHK.Delete_quote_POST(
P_Qte_Header_Id => l_qte_header_id,
X_Return_Status => x_return_status,
X_Msg_Count => x_msg_count,
X_Msg_Data => x_msg_data );
Thus the pre and post “delete_quote” custom hooks are named:
ASO_QUOTE_CUHK.delete_quote_pre (asocqtes.pls)
And
ASO_QUOTE_CUHK.delete_quote_post (asocqtes.pls)
The Quoting User Hooks are automatically populated
in the JTF_USER_HOOKS table according
to Quoting Implementation Guide :
"For user hooks to work properly, the following SQL
scripts must run:
■ asocruhk.sql — The Populate Script populates data into the JTF_USER_HOOKS table. This script is run automatically."
If by any reason the user hooks are not available in the table, please run manually the script above.
■ asocruhk.sql — The Populate Script populates data into the JTF_USER_HOOKS table. This script is run automatically."
If by any reason the user hooks are not available in the table, please run manually the script above.
Only the package specification of custom hooks is seeded in the application. Package body must be created (and corresponding custom code added).
All package specification procedures must at least be implemented as a NULL procedure to avoid package body compilation errors.
Example:
If seeded package spec for a hook is
Create or replace package xyz_hook
as
Procedure action1_pre(<params>);
Procedure action1_post(<params>);
Procedure action2_pre(<params>);
Procedure action2_post(<params>);
End;
Procedure action1_pre(<params>);
Procedure action1_post(<params>);
Procedure action2_pre(<params>);
Procedure action2_post(<params>);
End;
And if customer wants to implement action1_pre, then body must look like
Create or replace package body
xyz_hook as
Procedure action1_pre(<params>) as
<variables>
BEGIN
<Custom Code>
END;
Procedure action1_post(<params>) as
BEGIN
NULL;
END;
Procedure action2_pre(<params>) as
BEGIN
NULL;
END;
Procedure action2_post(<params>) as
BEGIN
NULL;
END;
End;
Procedure action1_pre(<params>) as
<variables>
BEGIN
<Custom Code>
END;
Procedure action1_post(<params>) as
BEGIN
NULL;
END;
Procedure action2_pre(<params>) as
BEGIN
NULL;
END;
Procedure action2_post(<params>) as
BEGIN
NULL;
END;
End;
Although typically the application can manage an exception thrown by a custom hook, it is recommended to return errors posting then on the FND Message Stack and returning an error in the corresponding parameter:
IF <error condition> THEN
FND_MESSAGE.Set_Name('<APPL>', '<MESSAGE NAME>');
FND_MSG_PUB.ADD;
FND_MESSAGE.Set_Name('<APPL>', '<MESSAGE NAME>');
x_msg_data := FND_MESSAGE.get;
x_msg_count := 1;
x_return_status := FND_API.G_RET_STS_ERROR;
END IF;
FND_MESSAGE.Set_Name('<APPL>', '<MESSAGE NAME>');
FND_MSG_PUB.ADD;
FND_MESSAGE.Set_Name('<APPL>', '<MESSAGE NAME>');
x_msg_data := FND_MESSAGE.get;
x_msg_count := 1;
x_return_status := FND_API.G_RET_STS_ERROR;
END IF;
<APPL> and <Message Name> must be defined in the FND message dictionary: Application Developer Application Messages. Here a language independent message name is defined and a language dependent message text is entered. The application will show the error on the language the user has currently selected.
V. Enabling and Disabling Hooks
Once the package body of the hook is implemented and compiled into the database, the hook can be enabled.
There is no user interface for enabling/disabling hooks. The procedure must be done directly in the database with SQL*Plus.
The table JTF_USER_HOOKS holds the hook information. To activate a hook the following statement must be used:
UPDATE JTF_USER_HOOKS
SET EXECUTE_FLAG = 'Y'
WHERE upper(PKG_NAME) = upper('&ENTER_PACKAGE_NAME')
AND upper(API_NAME) = upper('&ENTER_API_NAME')
AND PROCESSING_TYPE = '&ENTER_PROC_TYPE' -- A for POST , B for PRE
AND USER_HOOK_TYPE = 'C';
To disable a hook, simply use the same SQL above but instead of execute_flag = 'Y' use execute_flag = 'N'.
With the same purpose the script $ASO_TOP/patch/115/sql/asoenuhk.sql is provided.
[Top]
- Never change the execution_flag of a HOOK_TYPE 'V'
- Package name is the name of the API package where hook will execute. Eg: ASO_QUOTE_PUB
- Api name is the name of the API where hook will execute. Eg: DELETE_QUOTE
- Processing type is when the hook will execute. Enter B (pre-hook) or A (post-hook).
- According to DEV's recommendation in bug 9434049 , make sure that all the output parameters are populated correctly for implemented user hooks. In case the return status is not populated correctly for an enabled user hook, Quoting Forms will most likely error out or produce incorrect results.
- As of 11.5.10 Quoting does NOT fire Quote Line hooks. Quote Header Hooks need to be used instead, and will get line information for lines in line tables. HTML Quoting still fires Line Hooks independently. Explanation is:
* Forms Quoting calls Aso_quote_pub.update_quote and this does Fire Quote Header Hooks.
* Calls aso_quote_headers_pvt.update_quote, which in turn calls ASO_QUOTE_LINES_PVT.Create_Quote_Lines . ASO_QUOTE_LINES_PVT does NOT fire Quote Line Hooks. Only ASO_QUOTE_PUB fires Line Hooks.
* The solution for scanning line events is as follows.
* Code a hook for UPDATE_QUOTE_PRE (or POST)
* Scan the Line Table for the operation being performed: CREATE, UPDATE or DELETE
* For example, should it be needed to perform code before a line delete
PROCEDURE Update_quote_PRE(...) is
BEGIN
FND_MSG_PUB.initialize;
For i IN 1..P_Qte_Line_Tbl.count LOOP
IF P_Qte_Line_Tbl (i).OPERATION_CODE = 'DELETE' THEN
_____ your code here _______
END IF;
END LOOP;
END;
BEGIN
FND_MSG_PUB.initialize;
For i IN 1..P_Qte_Line_Tbl.count LOOP
IF P_Qte_Line_Tbl (i).OPERATION_CODE = 'DELETE' THEN
_____ your code here _______
END IF;
END LOOP;
END;
- When a user hook is fired at line level ASO code does not fully populate the quote header IN parameter, p_qte_header_rec. Instead only the quote header is populated and the rest of the information can be extracted from aso_quote_headers_all using this ID. If different custom code needs to be executed at quote header and quote line level, a simple check should be implemented to determine whether the user hook was fired at quote header or quote line level :
PROCEDURE Update_quote_PRE(...) is
BEGIN
FND_MSG_PUB.initialize;
IF p_qte_header_rec.quote_number = FND_API.G_MISS_NUM
---- operation done at line level
ELSE
--- operation done at header level
END IF;
END;
BEGIN
FND_MSG_PUB.initialize;
IF p_qte_header_rec.quote_number = FND_API.G_MISS_NUM
---- operation done at line level
ELSE
--- operation done at header level
END IF;
END;
Hooks:-
Order Capture User Hooks
[ID 373923.1]
Hooks are code that is conditionally
executed by some application packages.
Step#1 –
Create the Package Body ASO_QUOTE_CUHK (Package Specification for this Package already exists in System).Make sure all the functions that are available in the specifications got created in the Body
Step#2-
Modify the Package Body
In Procedure Create_quote_PRE(
Add following Code
-----------------
BEGIN
P_hd_Shipment_Rec.FREIGHT_TERMS_CODE := 'Due'; -- IMPORTANT ( Write the code to populate Freight Term from iStore).
x_return_Status:='S';
END;
------------------
PLEASE , please make sure you add "x_return_Status:='S'"
Step#3-
Similarly in Procedure Update_quote_PRE , Add
BEGIN
If P_Hd_Shipment_Tbl.Count>0 Then
P_Hd_Shipment_Tbl(1).Freight_Terms_Code := 'Due'; -- IMPORTANT , we need to populate the Value from iStore
IF aso_debug_pub.g_debug_flag = 'Y' THEN
Aso_Debug_Pub.Add('P_hd_Shipment_tbl(1).FREIGHT_TERMS_CODE: '||P_Hd_Shipment_Tbl(1).Freight_Terms_Code);
End If;
x_return_Status:='S';
end if;
END;
PLEASE , please make sure you add "x_return_Status:='S'"
Step#4- Run
Select * From Jtf_User_Hooks
Where Pkg_Name Like 'ASO_QUOTE_PUB'
And User_Hook_Type = 'C'
and api_name in ('CREATE_QUOTE', 'UPDATE_QUOTE').
1. and verify that we have data for api_name in ('CREATE_QUOTE', 'UPDATE_QUOTE') and User_hook_type =C and Processing type = B and A.
2. If we don't have data for api_name in ('CREATE_QUOTE', 'UPDATE_QUOTE') then we need to run asocruhk.sql.
Step#5-
Execute
Update Jtf_User_Hooks
Set Execute_Flag = 'Y'
Where Upper(Pkg_Name) = 'ASO_QUOTE_PUB'
And UPPER(API_NAME) = 'CREATE_QUOTE'
And User_Hook_Type = 'C'
and processing_type='B'
Update Jtf_User_Hooks
Set Execute_Flag = 'Y'
Where Upper(Pkg_Name) = 'ASO_QUOTE_PUB'
And Upper(Api_Name) = 'UPDATE_QUOTE'
And User_Hook_Type = 'C'
and processing_type='B'
Create the Package Body ASO_QUOTE_CUHK (Package Specification for this Package already exists in System).Make sure all the functions that are available in the specifications got created in the Body
Step#2-
Modify the Package Body
In Procedure Create_quote_PRE(
Add following Code
-----------------
BEGIN
P_hd_Shipment_Rec.FREIGHT_TERMS_CODE := 'Due'; -- IMPORTANT ( Write the code to populate Freight Term from iStore).
x_return_Status:='S';
END;
------------------
PLEASE , please make sure you add "x_return_Status:='S'"
Step#3-
Similarly in Procedure Update_quote_PRE , Add
BEGIN
If P_Hd_Shipment_Tbl.Count>0 Then
P_Hd_Shipment_Tbl(1).Freight_Terms_Code := 'Due'; -- IMPORTANT , we need to populate the Value from iStore
IF aso_debug_pub.g_debug_flag = 'Y' THEN
Aso_Debug_Pub.Add('P_hd_Shipment_tbl(1).FREIGHT_TERMS_CODE: '||P_Hd_Shipment_Tbl(1).Freight_Terms_Code);
End If;
x_return_Status:='S';
end if;
END;
PLEASE , please make sure you add "x_return_Status:='S'"
Step#4- Run
Select * From Jtf_User_Hooks
Where Pkg_Name Like 'ASO_QUOTE_PUB'
And User_Hook_Type = 'C'
and api_name in ('CREATE_QUOTE', 'UPDATE_QUOTE').
1. and verify that we have data for api_name in ('CREATE_QUOTE', 'UPDATE_QUOTE') and User_hook_type =C and Processing type = B and A.
2. If we don't have data for api_name in ('CREATE_QUOTE', 'UPDATE_QUOTE') then we need to run asocruhk.sql.
Step#5-
Execute
Update Jtf_User_Hooks
Set Execute_Flag = 'Y'
Where Upper(Pkg_Name) = 'ASO_QUOTE_PUB'
And UPPER(API_NAME) = 'CREATE_QUOTE'
And User_Hook_Type = 'C'
and processing_type='B'
Update Jtf_User_Hooks
Set Execute_Flag = 'Y'
Where Upper(Pkg_Name) = 'ASO_QUOTE_PUB'
And Upper(Api_Name) = 'UPDATE_QUOTE'
And User_Hook_Type = 'C'
and processing_type='B'
1 comments:
Good Blog, well descrided, Thanks for sharing this information.
Oracle Fusion HCM Training
Post a Comment