Friday 30 May 2014

Set application message and token and retrieve it / Oracle application messages / FND Messages



Create a new application message as shown below.





You can set the message ,it's tokens, retrieve the value and then you can use it user hooks,form personalizations and other scripts.


DECLARE

   lv_msgdata   VARCHAR2 (32000);

BEGIN

   apps.fnd_message.set_name ('PER', 'XX_MSG_1');
   apps.fnd_message.set_token ('MSG_NAME', 'XXXX', TRANSLATE => TRUE);
   apps.fnd_message.set_token ('MSG_START_DATE',
                               '01-Jan-2014',
                               TRANSLATE      => TRUE
                              );
   lv_msgdata := apps.fnd_message.get ();

END;



Wednesday 28 May 2014

How to Hide Reassign and Request for information button in workflow notification in oracle apps



HIDE REASSIGN BUTTON

Create an attribute with below details and drag and drop under the message for which you want to hide reassign button.




HIDE REQUEST FOR INFORMATION BUTTON

Create an attribute with below details and drag and drop under the message for which you want to hide reassign button.



Sunday 25 May 2014

Running the pre-processor after registering user-hook in oracle apps / Alternative of pre-processor


To run the pre-processor run one of the following commands:

cd $PER_TOP/admin/sql
Log into SQLPLUS as the APPS user
SQL> @hrahkall.sql

or

SQL> @hrahkone.sql


The first script will create all hook package bodies, whilst the second will
create hook package bodies for one API module only, and prompt for that
api_module_id.

==========================================================

Sometimes if you don't have server credentials then you can use below alternative to run the pre-processor through sqlplus

Log in to database through apps

SQL> @hrahkall.sql

instead of running above script you can execute below statement

exec hr_api_user_hooks_utility.create_hooks_all_modules;

SQL> @hrahkone.sql

instead of running above script you can execute below statement

exec hr_api_user_hooks_utility.create_hooks_one_module(p_module_id);


Saturday 24 May 2014

How to send attachment in oracle workflow notification / blob documents as attachment in oracle workflow notification



Create normal workflow process with simple notification as below.





Create a new document type attribute with below details.





drag and drop this attribute under "Attachment_notification"(notification message). Set the Attributes property as shown below.





Your workflow is complete. Now write the following PL/SQL code and run the workflow to get the notification. 


Sequence for item key :::

create sequence xx_example_s
start with 1
increment by 1;




CREATE OR REPLACE PACKAGE xx_example
IS
   PROCEDURE xx_training_wf;

   PROCEDURE xx_attach_p (
      document_id     IN       VARCHAR2,
      display_type    IN       VARCHAR2,
      document        IN OUT   BLOB,
      document_type   IN OUT   VARCHAR2
   );
END;

CREATE OR REPLACE PACKAGE BODY xx_example
IS
   gv_document_id   VARCHAR2 (100) := '2955797';

   PROCEDURE xx_training_wf
   IS
      l_itemtype   VARCHAR2 (30)  := 'XXTEST';
      l_itemkey    VARCHAR2 (300);
   ---l_file_name   VARCHAR2 (100) := 'holidaylist.xls';
   --l_unique_id   VARCHAR2 (50)  := unique_id;
   BEGIN
      SELECT TO_CHAR (xx_example_s.NEXTVAL)
        INTO l_itemkey
        FROM DUAL;

      wf_engine.createprocess (l_itemtype, l_itemkey, 'XX_TEST_ATTACHMENT');
      wf_engine.setitemattrdocument
                         (itemtype        => l_itemtype,
                          itemkey         => l_itemkey,
                          aname           => 'XX_ATT1',
                          documentid      =>    'PLSQLBLOB:XX_EXAMPLE.XX_ATTACH_P/'
                                             || gv_document_id
                         );
      wf_engine.setitemattrtext (itemtype      => l_itemtype,
                                 itemkey       => l_itemkey,
                                 aname         => '#FROM_ROLE',
                                 avalue        => 'WF_EMP1'
                                );
      wf_engine.setitemattrtext (itemtype      => l_itemtype,
                                 itemkey       => l_itemkey,
                                 aname         => 'XXTIMEOUT',
                                 avalue        => 2880
                                );
      wf_engine.startprocess (l_itemtype, l_itemkey);
      COMMIT;
   END xx_training_wf;

   PROCEDURE xx_attach_p (
      document_id     IN       VARCHAR2,
      display_type    IN       VARCHAR2,
      document        IN OUT   BLOB,
      document_type   IN OUT   VARCHAR2
   )
   IS
      lv_file_name           VARCHAR2 (100) := NULL;
      lv_file_content_type   VARCHAR2 (100) := NULL;
      ld_document            BLOB;
   BEGIN
      SELECT file_name, file_content_type, file_data
        INTO lv_file_name, lv_file_content_type, ld_document
        FROM fnd_lobs
       WHERE file_id = 2955797;

      document_type := lv_file_content_type || ';name=' || lv_file_name;
      DBMS_LOB.COPY (document, ld_document, DBMS_LOB.getlength (ld_document));
      COMMIT;
   EXCEPTION
      WHEN OTHERS
      THEN
         wf_core.CONTEXT ('xx_example',
                          'xx_attach_p',
                          'document_id',
                          'display_type'
                         );
         RAISE;
   END xx_attach_p;
END xx_example;



====================================================

Now execute procedure  to initiate the workflow.

execute xx_example.xx_training_wf ;

====================================================

Attachment will look like this










TImeout functionality in workflow notification / Due date of notification in workflow



- Log in to workflow builder , open the workflow process





select the notification , right click and select properties then click on node tab.

it will be as below.





In the timeout section you can select timeout properties.

There are 3 options.


1- No timeout : It means no due date of the notification.


2 -  Relative Time : It is nothing but the constant time details .
you can set the value in days, hours and minutes combination.






3 - Item Attribute : You can create number type attribute and assign it here.





you can set the attribute value as below.


wf_engine.setitemattrtext (itemtype      => l_itemtype,
                                 itemkey       => l_itemkey,
                                 aname         => 'XXTIMEOUT',
                                 avalue        => 2880
                                );

2880 - it is  minutes.

if you want to set due date to 3 days then value should be =(24*60*3)= 4320.











Friday 23 May 2014

How to send notification through pl/sql without creating a new workflow


You can use any existing workflow and send notification by using wf_notification.send

Just you need to set the attributes of workflow message that you want to send.


Below is the example:


Here we will use seeded CS_MSGS (Service Messages)  item type nothing but the message type.

You can any of the predefined seeded item type or any custom workflow item type.

you just need the internal name of item type that you can get as shown below.

log in to workflow builder , load the item type , right click on item type and get the internal name.









or you can use the below query to get item type and it's internal name.


select * from WF_ITEM_TYPES_vl
where name ='CS_MSGS';

Now there are 4 messages in this item type and you want to use Expanded FYI Message

right click and select properties to get internal name. EXPANDED_FYI_MSG.






Now you just need to set the attributes of the message.
But you don't know the message attributes, so right click on message and select body tab.





Now you have everything so it's time to write the code .




DECLARE

   v_notification_id        NUMBER                 := NULL;
   v_from_user_name    VARCHAR2 (500)    := 'XX_FROM_USER';
   l_to_user_name         VARCHAR2 (500)    := 'XX_TO_USER';
   v_subject_line           VARCHAR2 (500)    := 'Subject Line';
   v_message_line         VARCHAR2 (500)    := 'Message Line';

BEGIN

   v_notification_id :=
      wf_notification.send (UPPER (l_to_user_name),
                            'CS_MSGS',
                            'EXPANDED_FYI_MSG'
                           );

   wf_notification.setattrtext (v_notification_id,
                                '#FROM_ROLE',
                                v_from_user_name
                               );

   wf_notification.setattrtext (v_notification_id,
                                'OBJECT_TYPE',
                                v_subject_line
                               );

   wf_notification.setattrtext (v_notification_id, 'SENDER', v_from_user_name);

   wf_notification.setattrtext (v_notification_id,
                                'MESSAGE_TEXT',
                                v_message_line
                               );

   wf_notification.denormalize_notification (v_notification_id);

   COMMIT;

END;

===================================================================

wf_notification.denormalize_notification and COMMIT is mandatory at last.


==================================================================

This way you can send normal text as well as HTML notifications.

Just you need to identify proper item type and message name.


Friday 16 May 2014

How to Purge old completed workflows

How to Purge old completed workflows 


After years few years of go-live ,

workflow transaction tables will become heavy and will lot of data.
It may cause performance issue for new workflow transactions.
So you can purge the old existing workflow transaction through below procedure.

You can loop through below procedure for all old workflow transactions.

Just you need to pass the item type and item key as parameters.


execute wf_purge.Total(itemtype =>'Test',itemkey => 23);


How to approve/reject or respond a notification through script


How to approve/reject or respond a notification through script


BEGIN
   wf_notification.setattrtext (nid         => '4754620',
                                aname       => 'RESULT',
                                avalue      => 'REJECTED'
                               );
   wf_notification.respond (nid         => '4754620',
                                     respond_comment =>  'Reject From backend',
                                     responder =>  'XXTEST');
   COMMIT;
END;


nid =  will be notification id

There are multiple ways to get notification id

-  Open the notification in the application through SYSADMIN or any other user
    in the notification below sent and to date, you can see the ID

or

-   you can search the notification in wf_notification table

aname = will be always RESULT

avalue = will be APPROVE,REJECTED or any other action .

Generally for avalue , perform the appropriate action on the notification through front end
and see the value of RESULT attribute in wf_notification_attributes table.

responder coment = any comment

responder => will be recipient role/user name


Wednesday 14 May 2014

Batch Balance Adjustment

Batch Balance Adjustment


If your responsibility is not having ‘Batch Balance Adjustment’ function then add the 3 functions to your menu as shown below.

Functions Name:
-          Batch Balance Adjustment Spreadsheet Interface
-          Create or Update Batch Balance Adjustment Lines
-          Desktop Integration - Create Document




      Double click on ‘BBA Spreadsheet Interface’






k      Click on the ‘Create Batch’ button




       
It will create WEB ADI document, enter the details as below and then upload the document.





The Batch will be created.
Search the batch as shown below.




Select the batch, select create lines in the drop down and click on process button.





Select the element that you want to use for balance adjustment.
Then click on go button.




It will create a new WEB ADI document; enter the details shown as below and upload the document.





Then validate and transfer the batch.




Monday 12 May 2014

Important Tables in HRMS

Important Tables in HRMS

person details
  • per_all_people_f
Assignment details
  • per_all_assignments_f
person type details 
  • per_person_types
  • per_person_type_usages_f
Termination details
  • per_periods_of_service
Person SIT
  • per_person_analyses
  • per_analysis_criteria
Person EIT
  • per_people_extra_info
HR Locations
  • hr_locations_all
HR Organizations
  • hr_all_organization_units
HR Jobs
  • per_jobs
  • per_job_definitions
HR Grades

  • per_grades
  • per_grade_definitions
HR Positions

  • hr_all_positions_f
  • per_position_definitions
People Group

  • pay_people_groups
Employee address
  • per_addresses
Employee Phones

  • per_phones
Employee Qualifications
  • per_qualifications
Employee Contracts
  • per_contracts_f
Organization additional information / organization classification/ organization eit details
  • hr_organization_information
All self service transaction details are stored in the below tables.

For all hr transactions

- hr_api_transactions
- hr_api_transaction_steps
- hr_api_transaction_values

for payroll related transactions, e.g. salary change

- per_pay_transactions

=====================================================

History tables for SSHR transactions

PQH_SS_TRANSACTION_HISTORY
PQH_SS_STEP_HISTORY
PQH_SS_VALUE_HISTORY
PQH_SS_APPROVAL_HISTORY        

======================================================


You can use above all tables in AME for tracking the self service transactions.

you can use transaction_id of hr_api_transactions and per_pay_transactions in  AME test workbench to see the attributes values, approvals , rules.

Join these tables with wf_notifications to identify status of the transaction.


How to Add custom organization classification and add custom organization EIT



How to Add  custom organization classification and add custom organization EIT

Add a new value to ‘ORG_CLASS’ lookup.





Search any organization, now you can see new custom classification in classification LOV and you can attach the new classification to any new organization.






Now create an organization EIT.
Go to Application developer è flex field è Descriptive è Segments 




Add a new structure to ‘Org Developer DF’





Add few segments to the structure.




Freeze and compile the new structure and DFF.
Then run Register Extra information types program with parameters as shown below.









Search any organization, go to classification and click on others button, you can see the newly structure








Sunday 11 May 2014

AUTONOMOUS Debug procedure -- IMP for debugging purpose in Oracle apps




- Create table XX_DEBUG_T

CREATE TABLE XX_DEBUG_T
(
  SEQ        NUMBER,
  DATA_TEXT  VARCHAR2(4000 BYTE)
);

- Create sequence XX_DEBUG_S

CREATE SEQUENCE APPS.XX_DEBUG_S
  START WITH 1
  INCREMENT BY 1
  MAXVALUE 999999999999999999999999999
  MINVALUE 1
  NOCYCLE
  NOCACHE
  NOORDER;


- Create debug procedure as pragma procedure

CREATE OR REPLACE PROCEDURE APPS.xx_debug_p (p_data VARCHAR2)
AS
   PRAGMA AUTONOMOUS_TRANSACTION;
   a   NUMBER;
BEGIN
   a := xx_debug_s.NEXTVAL;

   INSERT INTO xx_debug_t
               (seq, data_text
               )
        VALUES (a, p_data
               );

   COMMIT;
END xx_debug_p;
/

You can call the above debug procedure in any other procedure,function, fast formulas, packages for debugging purpose.

You can see the latest messages in the log table .

select * from xx_debug_t
order by seq desc;


How to get apps password and application user password in R12/11i - With Clear fundas



Step -1 

Create get_pwd package specification as below.

CREATE OR REPLACE PACKAGE get_pwd
AS
   FUNCTION decrypt (KEY IN VARCHAR2, VALUE IN VARCHAR2)
      RETURN VARCHAR2;
END get_pwd;


Step -2 

Create get_pwd package body as below.

CREATE OR REPLACE PACKAGE BODY get_pwd
AS
   FUNCTION decrypt (KEY IN VARCHAR2, VALUE IN VARCHAR2)
      RETURN VARCHAR2
   AS
      LANGUAGE JAVA
      NAME 'oracle.apps.fnd.security.WebSessionManagerProc.decrypt(java.lang.String,java.lang.String) return java.lang.String';
END get_pwd;


Step-1 and step-2 are common in both R12 and 11i
For executing get_pwd package u need access on

'oracle.apps.fnd.security.WebSessionManagerProc.decrypt(java.lang.String,java.lang.String) return java.lang.String';

class file.Generally apps user will have this access , so you need to create the above package in APPS package.

Now For 11i

In 11i oracle has defined one seeded profile option GUEST_USER_PWD (Guest User Password)
This profile option holds the value 'GUEST/ORACLE' in almost all the 11i instances.

===========================================

ALTER SESSION SET current_schema = apps;

===========================================

For both step-3 and step-4 execute the above or log in as apps 

Step-3 

Query to get apps password

SELECT (SELECT get_pwd.decrypt
                  (UPPER ((SELECT UPPER (fnd_profile.VALUE ('GUEST_USER_PWD'))
                             FROM DUAL)
                         ),
                   usertable.encrypted_foundation_password
                  )
          FROM DUAL) AS apps_password
  FROM fnd_user usertable
 WHERE usertable.user_name LIKE
          UPPER ((SELECT SUBSTR (fnd_profile.VALUE ('GUEST_USER_PWD'),
                                 1,
                                   INSTR (fnd_profile.VALUE ('GUEST_USER_PWD'),
                                          '/'
                                         )
                                 - 1
                                )
                    FROM DUAL)
                );


Step-4 

Query to get application user password


SELECT usertable.user_name,
       (SELECT get_pwd.decrypt
                  (UPPER
                      ((SELECT (SELECT get_pwd.decrypt
                                          (UPPER
                                              ((SELECT UPPER
                                                          (fnd_profile.VALUE
                                                              ('GUEST_USER_PWD'
                                                              )
                                                          )
                                                  FROM DUAL)
                                              ),
                                           usertable.encrypted_foundation_password
                                          )
                                  FROM DUAL) AS apps_password
                          FROM fnd_user usertable
                         WHERE usertable.user_name LIKE
                                  UPPER
                                     ((SELECT SUBSTR
                                                 (fnd_profile.VALUE
                                                             ('GUEST_USER_PWD'),
                                                  1,
                                                    INSTR
                                                       (fnd_profile.VALUE
                                                             ('GUEST_USER_PWD'),
                                                        '/'
                                                       )
                                                  - 1
                                                 )
                                         FROM DUAL)
                                     ))
                      ),
                   usertable.encrypted_user_password
                  )
          FROM DUAL) AS encrypted_user_password
  FROM fnd_user usertable

 WHERE usertable.user_name LIKE 'SYSADMIN';


Now in R12

In R12 oracle has removed GUEST_USER_PWD (Guest User Password) Profile option.

So the above queries will not work.

oracle has provided new seeded Procedure fnd_web_sec.get_guest_username_pwd which will help us to find out user password.

===========================================

ALTER SESSION SET current_schema = apps;

===========================================

For both step-3 and step-4 execute the above or log in as apps 

Step-3 

Query to get apps password in R12.

SELECT (SELECT get_pwd.decrypt
                    (fnd_web_sec.get_guest_username_pwd,
                     usertable.encrypted_foundation_password
                    )
          FROM DUAL) AS apps_password
  FROM fnd_user usertable
 WHERE usertable.user_name LIKE
          (SELECT SUBSTR (fnd_web_sec.get_guest_username_pwd,
                          1,
                          INSTR (fnd_web_sec.get_guest_username_pwd, '/') - 1
                         )
             FROM DUAL);


Step-4 

Query to get application user password in R12.


SELECT usr.user_name,
       get_pwd.decrypt
          ((SELECT (SELECT get_pwd.decrypt
                              (fnd_web_sec.get_guest_username_pwd,
                               usertable.encrypted_foundation_password
                              )
                      FROM DUAL) AS apps_password
              FROM fnd_user usertable
             WHERE usertable.user_name =
                      (SELECT SUBSTR
                                  (fnd_web_sec.get_guest_username_pwd,
                                   1,
                                     INSTR
                                          (fnd_web_sec.get_guest_username_pwd,
                                           '/'
                                          )
                                   - 1
                                  )
                         FROM DUAL)),
           usr.encrypted_user_password
          ) PASSWORD
  FROM fnd_user usr
 WHERE usr.user_name LIKE 'SYSADMIN';

==============================================================

Now if you have gone through the step-3 and step-4 queries for both 11i and R12.
we can simplified the queries as below :)
The below will work in both 11i and R12.

Step-3 

Query to get apps password

In the below query you can replace 'GUEST/ORACLE' with any application username and password.

Let say in the below example :

- user name : GUEST
- password   : ORACLE

SELECT (SELECT get_pwd.decrypt
                           ('GUEST/ORACLE',
                            fu.encrypted_foundation_password
                           )
          FROM DUAL) AS apps_password
  FROM fnd_user fu
 WHERE fu.user_name LIKE 'GUEST';

Let say in the below example :

- user name : TEST_USER_NAME
- password   : TEST_USER_pwd

Note : note that password should be case sensitive. 


SELECT (SELECT get_pwd.decrypt
                           ('TEST_USER_NAME/TEST_USER_pwd',
                            fu.encrypted_foundation_password
                           )
          FROM DUAL) AS apps_password
 FROM fnd_user fu

WHERE fu.user_name LIKE 'TEST_USER_NAME';


Step -4

Query to get application password.

TEST_APPS_PWD - is the apps password

TEST_USER_NAME  - is the application user for whom you want to know the password.


SELECT fu.user_name,
       (SELECT get_pwd.decrypt
                       ('TEST_APPS_PWD',
                        fu.encrypted_user_password
                       )
          FROM DUAL) AS encrypted_user_password
  FROM fnd_user fu

 WHERE fu.user_name LIKE 'TEST_USER_NAME';


Saturday 10 May 2014

Create table type LOV in WEB ADI through API

Create table type LOV in WEB ADI through API.


BEGIN
BNE_INTEGRATOR_UTILS.CREATE_TABLE_LOV
                  (p_application_id       => 20106,
                   p_interface_code       => 'GENERAL_122_INTF',
                   P_INTERFACE_COL_NAME   => 'P_BUSINESS_GROUP_ID',
                   P_ID_COL               => 'BUSINESS_GROUP_ID',
                   P_MEAN_COL             => 'NAME',
                   P_DESC_COL             => 'NAME',
                   P_TABLE                => 'PER_BUSINESS_GROUPS',
                   P_ADDL_W_C             => null,
                   P_WINDOW_CAPTION       => null,
                   P_WINDOW_WIDTH         => NULL,
                   P_WINDOW_HEIGHT        => NULL,
                   P_TABLE_BLOCK_SIZE     => NULL,
                   P_TABLE_SORT_ORDER     => 'ascending',
                   P_USER_ID              => 0,
                   P_TABLE_COLUMNS        => 'BUSINESS_GROUP_ID,NAME',
                   P_TABLE_SELECT_COLUMNS => 'BUSINESS_GROUP_ID',
                   P_TABLE_COLUMN_ALIAS   => 'BUSINESS_GROUP_ID',
                   P_TABLE_HEADERS        => 'BUSINESS_GROUP_ID,NAME',
                   P_POPLIST_FLAG         =>'N'
);
EXCEPTION
when NO_DATA_FOUND then
dbms_output.put_line('error no data ' ||sqlerrm);
when others then
dbms_output.put_line('error ' ||sqlerrm);
end;