Search This Blog

Monday, June 27, 2016

Validation in absence screen to prevent overlap leaves entered both in HR Absence screen and SSHR Absence


 To make Validation in absence screen to prevent overlap leaves entered both in HR Absence screen and SSHR Absence Management screen.

1- Create Define Function
Package source is at the end of document.


2- Create Context usage
Create Parameters


4- Add Condition in BG_ABSENCE_DURATION formula

Default overlap = 0
OVERLAP = CHECK_ABSENCE_OVERLAP(date_start,date_end)

/********************** Over Lap ******************************/

IF OVERLAP > 0
THEN
(
duration = 'FAILED'
invalid_msg = 'There exists an overlapping Leave during these dates'
return duration, invalid_msg
)
/********************************************************************/









BODY OF FUNCTION
FUNCTION CHECK_ABSENCE_OVERLAP (
P_BUSINESS_GROUP_ID in number,
P_ASSIGNMENT_ID in number,
P_Process_Start_Date in date,
P_Process_end_Date in date
)
RETURN NUMBER IS
COUNTER NUMBER:=0;
P_PERSON_ID NUMBER:=0;
BEGIN
-- Fetch Person Id from Assignment ID
Select PERSON_ID into P_PERSON_ID
From PER_ALL_ASSIGNMENTS_F
Where ASSIGNMENT_ID = P_ASSIGNMENT_ID
And P_Process_Start_Date Between effective_start_Date and effective_end_Date ;
BEGIN
SELECT nvl(count(AT.ABSENCE_ATTENDANCE_ID),0)
INTO COUNTER
FROM
Per_Absence_Attendances AT
WHERE
AT.BUSINESS_GROUP_ID = P_BUSINESS_GROUP_ID AND
AT.PERSON_ID = P_PERSON_ID AND
(
(AT.date_start <= P_Process_Start_Date
and AT.date_end between P_Process_Start_Date and P_Process_end_Date)
OR (AT.date_start between P_Process_Start_Date and P_Process_end_Date
and AT.date_end >= P_Process_end_Date)
OR (AT.date_start between P_Process_Start_Date and P_Process_end_Date
and AT.date_end between P_Process_Start_Date and P_Process_end_Date )
OR (AT.date_start <= P_Process_Start_Date and AT.date_end >= P_Process_end_Date)
) ;
EXCEPTION WHEN OTHERS THEN COUNTER:=0;
END;
RETURN(COUNTER);
END CHECK_ABSENCE_OVERLAP;


















Testing:

Sunday, June 26, 2016

Validation on HR Special Info (SIT) in SSHR Pages:

Validation on HR Special Info (SIT) in SSHR Pages:

User hooks doesn’t work on SIT SSHR Pages for validations but works once the final approval is done.
This is known bug.

To overcome above issue we will implement logic in FND_FLEX_PLSQL package.

Requirement : To make validation on SIT SSHR page so the user can update once and submit for approval, once the user update the same record twice which is under approval, then the error message should appear.

new update.........

     0. create one new segment in the structure named 'sequence' not mandatory and hidden.
    valuset10 char, default type sql,
SELECT F_FND_FLEX_S.NEXTVAL FROM DUAL WHERE :$FLEX$.FND_DATE4_REQUIRED2 IS NOT NULL

f_fnd_flex_s is the sequence in the database created custom.
FND_DATE4_REQUIRED2 is the valuset for the resumption_date, once this date changed/updated the sequence will update auto.

as the package FND_FLEX_PLSQL mentioned in the step7 will validate/fires only when there is no code combination exists, so we need to have difference code combinations by generating the sequence to validate everytime.

Oracle reference: How to avoid that FND_FLEX_PLSQL.VALIDATE() is not triggered when the same data is re-entered ? (Doc ID 2023950.1)

  1. SIT Open the record
  1. Updating the record of joining Date (or Resumption)
  1. Click Apply,

  1. Click Next, Submit

  1. Confirmed.

  1. Lets update the same transaction , when its under approval.

When clicked ‘Apply’ button the error appears.


  1. Package Body:

CREATE OR REPLACE PACKAGE BODY APPS.FND_FLEX_PLSQL AS
/* $Header: AFFFPLVB.pls 115.0 99/07/16 23:18:46 porting ship $
Modified by Afzal for SIT Validation on 28-06-2016
*/

 FUNCTION validate(application_id         IN   NUMBER,
           id_flex_code           IN   VARCHAR2,
           id_flex_num            IN   NUMBER,
                   vdate                  IN   DATE,
                   segment_delimiter      IN   VARCHAR2,
                   concatenated_segments  IN   VARCHAR2,
                   numsegs                IN   NUMBER,
                   user_segment1          IN   VARCHAR2,
                   user_segment2          IN   VARCHAR2,
                   user_segment3          IN   VARCHAR2,
                   user_segment4          IN   VARCHAR2,
                   user_segment5          IN   VARCHAR2,
                   user_segment6          IN   VARCHAR2,
                   user_segment7          IN   VARCHAR2,
                   user_segment8          IN   VARCHAR2,
                   user_segment9          IN   VARCHAR2,
                   user_segment10         IN   VARCHAR2,
                   user_segment11         IN   VARCHAR2,
                   user_segment12         IN   VARCHAR2,
                   user_segment13         IN   VARCHAR2,
                   user_segment14         IN   VARCHAR2,
                   user_segment15         IN   VARCHAR2,
                   user_segment16         IN   VARCHAR2,
                   user_segment17         IN   VARCHAR2,
                   user_segment18         IN   VARCHAR2,
                   user_segment19         IN   VARCHAR2,
                   user_segment20         IN   VARCHAR2,
                   user_segment21         IN   VARCHAR2,
                   user_segment22         IN   VARCHAR2,
                   user_segment23         IN   VARCHAR2,
                   user_segment24         IN   VARCHAR2,
                   user_segment25         IN   VARCHAR2,
                   user_segment26         IN   VARCHAR2,
                   user_segment27         IN   VARCHAR2,
                   user_segment28         IN   VARCHAR2,
                   user_segment29         IN   VARCHAR2,
                   user_segment30         IN   VARCHAR2,
                   error_message          OUT  VARCHAR2)
          return BOOLEAN IS
          L_COUNT_LEV_SIT NUMBER;
          lb_return       BOOLEAN ;
          l_join_date_exists varchar2(200);
          L_TRANSACTION_VALUE_ID NUMBER;
          L_DATE_START DATE; L_END_DATE DATE; L_JOIN_DATE DATE; L_LEAVE_NAME NUMBER; L_LATE_REASON VARCHAR2(200);
         

BEGIN
   if id_flex_num= 50318 THEN
                  BEGIN
                  DECLARE
CURSOR C1 IS                 
SELECT * --INTO L_TRANSACTION_VALUE_ID, L_DATE_START, L_END_DATE, L_JOIN_DATE, L_LEAVE_NAME, L_LATE_REASON
FROM(
SELECT TRANSACTION_VALUE_ID,fnd_conc_date.string_to_date(PAC.SEGMENT1) DATE_START,fnd_conc_date.string_to_date(PAC.SEGMENT2) END_DATE,
fnd_conc_date.string_to_date(PAC.SEGMENT3) JOIN_DATE,
(SELECT ABSENCE_ATTENDANCE_TYPE_ID FROM PER_ABS_ATTENDANCE_TYPES_TL
WHERE NAME = PAC.SEGMENT8
AND LANGUAGE = 'AR')LEAVE_NAME,
PAC.SEGMENT11 LATE_REASON
from
hr_api_transaction_values hrtv
,per_person_analyses ppa
,per_analysis_criteria pac
,hr_api_transactions hat
,hr_api_transaction_steps hats
where
NAME = 'P_OLD_ANALYSIS_CRITERIA_ID'
AND NUMBER_VALUE = PPA.ANALYSIS_CRITERIA_ID
AND PPA.PERSON_ID =  hat.SELECTED_PERSON_ID--FND_PROFILE.VALUE('PER_PERSON_ID')
AND PPA.ANALYSIS_CRITERIA_ID = PAC.ANALYSIS_CRITERIA_ID
AND hat.transaction_id = hats.transaction_id
and hats.TRANSACTION_STEP_ID = hrtv.TRANSACTION_STEP_ID
AND hat.SELECTED_PERSON_ID = FND_PROFILE.VALUE('PER_PERSON_ID')
AND hat.status IN ('W', 'S', 'Y', 'YS', 'RI', 'RIS','E')
AND fnd_conc_date.string_to_date(PAC.SEGMENT1) = fnd_conc_date.string_to_date(user_segment2)
AND fnd_conc_date.string_to_date(PAC.SEGMENT2) = fnd_conc_date.string_to_date(user_segment3)
UNION
select TO_NUMBER(''),fnd_conc_date.string_to_date(''),fnd_conc_date.string_to_date(''),
fnd_conc_date.string_to_date(PAC.SEGMENT3),
TO_NUMBER(''),''
from
per_person_analyses ppa
,per_analysis_criteria pac
where
 PPA.PERSON_ID in (select  hat.SELECTED_PERSON_ID from hr_api_transactions hat where selected_person_id =  FND_PROFILE.VALUE('PER_PERSON_ID'))--FND_PROFILE.VALUE('PER_PERSON_ID')
AND PPA.ANALYSIS_CRITERIA_ID = PAC.ANALYSIS_CRITERIA_ID
AND fnd_conc_date.string_to_date(PAC.SEGMENT1) = fnd_conc_date.string_to_date(user_segment2)
AND fnd_conc_date.string_to_date(PAC.SEGMENT2) = fnd_conc_date.string_to_date(user_segment3)
AND fnd_conc_date.string_to_date(PAC.SEGMENT3) IS NOT NULL
);

          BEGIN
FOR I  IN C1 LOOP
IF C1%NOTFOUND THEN
        L_JOIN_DATE := NULL;
        L_TRANSACTION_VALUE_ID := 0;
        --below condition to make if any pending transaction for approval pending, no need function , its just for testing
ELSIF F_GET_FNDFLEX_VALID(FND_PROFILE.VALUE('PER_PERSON_ID'), fnd_conc_date.string_to_date(I.DATE_START), fnd_conc_date.string_to_date(I.END_DATE)) = 'Y' OR--TO_DATE('09-Aug-2015'),TO_DATE('23-Aug-2015') 
 I.JOIN_DATE IS NOT NULL OR  I.TRANSACTION_VALUE_ID IS NOT NULL  THEN
   /*lb_return := FALSE;
   error_message  := 'Under IF FUNCTION F_GET_FNDFLEX_VALID--->2-->'   ||fnd_conc_date.string_to_date(user_segment2)||'--3-->'||fnd_conc_date.string_to_date(user_segment3)
   ||'--4-->'||fnd_conc_date.string_to_date(user_segment4);
   */
                           lb_return := FALSE;
                           error_message := 'under approval-';
                     hr_utility.set_message (800,'FUJ_JOINDATE_PEND_VALID');
                     hr_utility.raise_error;
END IF;
               END LOOP;

        EXCEPTION WHEN OTHERS THEN
        L_JOIN_DATE := NULL;
        L_TRANSACTION_VALUE_ID := 0;
           END;
                END;         
  END IF;
--belo condition, if resmption is more than 1 day , need to make the resume_late_type mandatory
IF
    ( fnd_conc_date.string_to_date(user_segment4) - fnd_conc_date.string_to_date(user_segment3) > 1 AND  user_segment10 IS NULL ) THEN
   /*lb_return := FALSE;
   error_message  := 'Under IF FUNCTION F_GET_FNDFLEX_VALID--->2-->'   ||fnd_conc_date.string_to_date(user_segment2)||'--3-->'||fnd_conc_date.string_to_date(user_segment3)
   ||'--4-->'||fnd_conc_date.string_to_date(user_segment4);
   */
                        lb_return := FALSE;
                     hr_utility.set_message (800,'FUJ_LATE_REASON_MAND');
                     hr_utility.raise_error;
   END IF;
   return lb_return;

 END validate;

END FND_FLEX_PLSQL;
/




Useful Points:
1. The segments of our Structure will not be same segments as user_segment1 or user_segment2. to overcome just pass the parameters in error_message and get the values, if the segments are ok, then use the parameter segments in your logic. As I used the parameters segments in my logic.

Thursday, June 23, 2016

How to Cancel/Delete the Workflow Notification

Navigate to Status Monitor-->Query for the transaction-->Click the Activity History-->Click on cancel workflow.

Run the hr_transaction_api.rollback_transaction( p_transaction_id => sshr_transaction_id ,p_validate

=> false );  to remove the record, so the same is not shown as pending in the notification page.


if above didnt remove then run the concurreng program available in System Administrator or Workflow Administrator

Purge Obsolete Workflow Runtime Data
Parameters: Item Type --> HR
                    item Key --> <pass_item_key>


And the notification will deleted.

SSHR error The changes were not applied because This transaction has failed because the employee's record or eligibility status has changed

Error:
The changes were not applied because This transaction has failed because the employee's record or eligibility status has changed. 
Submit a new transaction.
Another user has updated this person's record. Please reject the transaction 
so the initiator can check whether the change is still valid for the updated record.
 
Reason: The base tables are updated before the Workflow is completed. 
(like object version number is changed)
 
Identify:
SELECT distinct hat.creation_date workflow_start
       , wn.notification_id nid
       , (SELECT MAX(last_update_date) FROM hr.per_all_assignments_f paaf2 WHERE paaf2.person_id = papf3.person_id) last_assig_update
       , wn.begin_date error_date
       , wn.begin_date - (SELECT MAX(last_update_date) FROM hr.per_all_assignments_f paaf2 WHERE paaf2.person_id = papf3.person_id) dd
       , wn.item_key
             , SUBSTR(
                  wn.subject
                , 48
                , INSTR(SUBSTR(wn.subject, 48 + 2), 'performed on ')
               ) transaction_type
   ,CASE
                  WHEN SUBSTR( wn.subject , INSTR(wn.subject, 'performed on ') + 13 , 
LENGTH(wn.subject) - INSTR(wn.subject, 'performed on ') + 13 ) LIKE '%Miss%' 
THEN REPLACE( SUBSTR( wn.subject , INSTR(wn.subject, 'performed on ') + 13 ,
LENGTH(wn.subject) - INSTR(wn.subject, 'performed on ') + 13 ) , ' Miss' , '' )
                  WHEN SUBSTR( wn.subject , INSTR(wn.subject, 'performed on ') + 13 , 
LENGTH(wn.subject) - INSTR(wn.subject, 'performed on ') + 13 ) LIKE '%Mrs%' 
THEN REPLACE( SUBSTR( wn.subject , INSTR(wn.subject, 'performed on ') + 13 , 
LENGTH(wn.subject) - INSTR(wn.subject, 'performed on ') + 13 ) , ' Mrs' , '' )
                  WHEN SUBSTR( wn.subject , INSTR(wn.subject, 'performed on ') + 13 , 
LENGTH(wn.subject) - INSTR(wn.subject, 'performed on ') + 13 ) LIKE '%Ms%' 
THEN REPLACE( SUBSTR( wn.subject , INSTR(wn.subject, 'performed on ') + 13 , 
LENGTH(wn.subject) - INSTR(wn.subject, 'performed on ') + 13 ) , ' Ms' , '' )
                  WHEN SUBSTR( wn.subject , INSTR(wn.subject, 'performed on ') + 13 , 
LENGTH(wn.subject) - INSTR(wn.subject, 'performed on ') + 13 ) LIKE '%Mr%' 
THEN REPLACE( SUBSTR( wn.subject , INSTR(wn.subject, 'performed on ') + 13 , 
LENGTH(wn.subject) - INSTR(wn.subject, 'performed on ') + 13 ) , ' Mr' , '' )
                  ELSE SUBSTR( wn.subject , INSTR(wn.subject, 'performed on ') + 13 , 
LENGTH(wn.subject) - INSTR(wn.subject, 'performed on ') + 13 )
               END performed_on
       , wn.subject
       , papf3.full_name
       , papf3.employee_number empno
       , fu.user_name by_un
       , fu.description by_desc
       , papf.full_name by_name
    FROM applsys.wf_notifications wn
       , applsys.fnd_user fu
       , hr.hr_api_transactions hat
       , hr.per_all_people_f papf
       , hr.per_all_people_f papf3
       , hr.per_all_assignments_f paaf
   WHERE hat.item_key = wn.item_key
     AND hat.created_by = fu.user_id
     AND hat.creator_person_id = papf.person_id
     AND papf.person_id = paaf.person_id
     AND hat.selected_person_id = papf3.person_id
     AND SYSDATE BETWEEN papf.effective_start_date AND papf.effective_end_date
     AND SYSDATE BETWEEN papf3.effective_start_date AND papf3.effective_end_date
     AND SYSDATE BETWEEN paaf.effective_start_date AND paaf.effective_end_date
     --AND subject NOT LIKE '%Phone Numbers%'
    -- AND recipient_role = 'HRMS_DEV_ROLE'
     AND subject LIKE 'Application Error%'
     AND papf.current_employee_flag = 'Y'
     AND papf.employee_number = :P_EMPLOYEE_NUMBER --enter the issued empno 
      AND paaf.assignment_type = 'E'
ORDER BY 1 DESC 
 

User Hooks for SITs

 User Hooks for SITs. The APIs are:

hr_sit_api.create_sit
hr_sit_api.update_sit
hr_sit_api.delete_sit

The API hooks are:

hr_sit_bk1.create_sit_b (Create, Before)
hr_sit_bk1.create_sit_a (Create, After)
hr_sit_bk2.update_sit_b (Update, Before)
hr_sit_bk2.update_sit_a (Update, After)
hr_sit_bk3.delete_sit_b (Delete, Before)
hr_sit_bk3.delete_sit_a (Delete, After)

User hooks doesnt work on SSHR for validations, they work once the final approval is done and inserted/updated the database.

Examples:
1. Once final Approval done
http://mogalafzal.blogspot.ae/2016/03/user-hook-on-special-info-to-attach.html

2. For validations on SIT's before Approval
http://mogalafzal.blogspot.ae/2016/06/validation-on-hr-special-info-sit-in.html

Thursday, June 16, 2016

Working with Oracle HRMS Custom Form and Task Flows

Working with Oracle HRMS Custom Form and Task Flows:

Requirement:  To restrict People screen Form with below features only.
  1. Picture
  2. Address
  3. Assignment
  4. EIT
  5. Documents of Records

Steps:

1. Custom Form
2. Task Flow Nodes
3. Task Flow definition
4. Function
5. Menu
6. Responsibility with Above Menu
7. Add Resp to User
8. Create 2 new Organizations
9. Add above organizations under ur primary org hierarchy
10. Security profile with restricted
11. Profile option HR%Security Profile
12. Profile Option HR%User%Type
13. Run conc program 'Security Maintainance' for above security profile.
14. Hiding Tabs Personalization.


Details :
  1. Custom Form:
HRMS Manager Resp> Security> CustomForm

C:\Users\egov\Desktop\1.1.png


C:\Users\egov\Desktop\1.2.png
Custom Form: FUJ_HOTEL_PERSON

  1. Task Flow Nodes:
C:\Users\egov\Desktop\2.1.png

  1. Task Flow Definition:
C:\Users\egov\Desktop\3.1.png

C:\Users\egov\Desktop\3.2.png

Add + button , by keeping cursor in the Name field of Node, do it for all the functions needed.
Once saved, go to your top node, then you can select the above functions in sequence.
C:\Users\egov\Desktop\3.3.png

C:\Users\egov\Desktop\3.4.png
C:\Users\egov\Desktop\3.5.png

C:\Users\egov\Desktop\4.4.png

We can give max 5 buttons and no other functions.
Or we can give 4 buttons and rest will come in ‘Others’ Button.

If its making difficult do the step 3, then just query the base task flow, click ‘Copy to’ and give ur custom name. Once given it will save automatically. Query your newly created Custom task flow.
Remove the nodes which you don’t want.

4. Function
Application developer> Application> Function>

C:\Users\egov\Desktop\4.1.png


C:\Users\egov\Desktop\4.2.png


C:\Users\egov\Desktop\4.3.png


Be sure of WORKFLOW_NAME Above I created _TF for example only. Make your correct name here.

5. Menu
Application developer> Application>Menu

C:\Users\egov\Desktop\5.1.png


  1. Responsibility with Above Menu:
System Administrator> Security> Responsibility>
C:\Users\egov\Desktop\6.1.png

  1. Add Resp to User:
C:\Users\egov\Desktop\7.1.png

  1. Create 2 new Organizations:
HRMS Manager>  Work Structures > Organization > Description
C:\Users\egov\Desktop\8.1.png
C:\Users\egov\Desktop\8.2.png
  1. Add above organizations under ur primary org hierarchy
HRMS Manager>  Work Structures > Organization >Hierarchy
C:\Users\egov\Desktop\9.1.png

  1. Security profile with restricted:
HRMS Manager>  Security > Profile
C:\Users\egov\Desktop\10.1.png

  1. Profile option HR%Security Profile
System Administrator> Profile> System
C:\Users\egov\Desktop\11.1.png
C:\Users\egov\Desktop\11.2.png

  1.  Profile Option HR%User%Type
System Administrator> Profile> System

C:\Users\egov\Desktop\12.1.png
C:\Users\egov\Desktop\12.2.png

  1. Run conc program 'Security Maintainance' for above security profile.
C:\Users\egov\Desktop\13.1.png




Lets login with user and Resp:
C:\Users\egov\Desktop\FINAL.png


  1. Hiding Tabs Personalization
C:\Users\egov\Desktop\person1.pngC:\Users\egov\Desktop\person2.png

C:\Users\egov\Desktop\person3.png



Further Name Target Object: REGION_LIST.FNM
Office DetailsTarget Object : REGION_LIST.LOC
Alternate NameTarget Object: REGION_LIST.LOC_PAGE1

C:\Users\egov\Desktop\After pers.png




Useful Points:
  1. If you change the Taskflow Nodes:
    1. Clear Cache functional Administrator Resp> Core Services> Caching Framework> global configuration> Clear Cache> Apply
    2. If above point doesn’t work then Logout and Login to see the changes.
  2. If get the error when clicked the Documents of Records’ or ‘Picture’ as Function not available, pls add the functions in ur menu as shown in step 5.
  3. Regarding EIT
  1. DFF
Human Resources>Extra Person Information
Create new Structure and add attributes> Save>Compile.
C:\Users\egov\Desktop\14.1.png

C:\Users\egov\Desktop\14.2.png

2. Run conc Program
Register Extra Information Types (EITs)
Parameters:
Table: PER_PEOPLE_INFO_TYPES
Information Type: FUJ_HOTELS_EIT --once registered will not show in the lov
Multiple Rows: Yes

3. Adding to Responsibilities.
HRMS>Security>Information types
Query your Resp in the Responsibility Name then
Add the EIT code under the Information Types Block. (Down)