How to get Employee Absence in a period in Oracle HRMS Payroll
Please find the PL-SQL Function to get the employee absence in a given period. Function also calculates the absence days even if the absence are split on pay_proc_start_date or pay_proc_end_date.
Here is the code!!
    
        
        
If something you could not understand, ask your query in the comment.
Feedback is much appreciated.
Here is the code!!
CREATE OR REPLACE FUNCTION CUST_GET_ABSENCE_DAYS (
  
P_ASG_ID         IN   NUMBER,
  
PAY_START_DATE   IN   DATE,
  
PAY_END_DATE     IN   DATE,
  
P_ABSENCE_TYPE   IN   CHAR
)
   RETURN NUMBER
IS
  
ABS_DAYS_PERIOD              NUMBER (15);
  
ABS_START_DATE              
PER_ABSENCE_ATTENDANCES.DATE_START%TYPE;         --DATE;
  
ABS_END_DATE                
PER_ABSENCE_ATTENDANCES.DATE_END%TYPE;           --DATE;
  
MISSING_DAYS                 NUMBER (15,1);
  
SUB_TOTAL                    NUMBER (15,1);
  
ACTUAL_DAYS                  NUMBER (15,1);
  
MISSING_DAYS_1               NUMBER (15,1);
  
SUB_TOTAL_1                  NUMBER (15,1);
  
ACTUAL_DAYS_1                NUMBER (15,1);
  
CONDITION_1                  NUMBER (15,1);
  
CONDITION_2                  NUMBER (15,1);
  
TOTAL_ABS_DAYS               NUMBER (15,1);
  
ABSENCE_ATTENDANCE_ID        VARCHAR2(200);
  
P_ABSENCE_ATTENDANCE_ID      VARCHAR2(200);
   CURSOR ABS_DATES
   IS
      SELECT PABA.DATE_START, PABA.DATE_END
        --INTO ABS_START_DATE
,ABS_END_DATE
      FROM   PER_ABSENCE_ATTENDANCES PABA, PER_ABSENCE_ATTENDANCE_TYPES
PAAT
       WHERE PABA.ABSENCE_ATTENDANCE_TYPE_ID = PAAT.ABSENCE_ATTENDANCE_TYPE_ID
       AND UPPER(PAAT.NAME) = UPPER(P_ABSENCE_TYPE)
       AND PABA.PERSON_ID =
               
(SELECT DISTINCT PPF.PERSON_ID
                  
FROM PER_PEOPLE_F PPF, PER_ASSIGNMENTS_F PAF
                 
WHERE PPF.PERSON_ID = PAF.PERSON_ID
                   
AND PAF.ASSIGNMENT_ID = P_ASG_ID);
BEGIN
  
TOTAL_ABS_DAYS := 0;
   --P_ABSENCE_ATTENDANCE_ID
:=0;
   --ABSENCE_ATTENDANCE_ID := 0;
--   SELECT PAAT.ABSENCE_ATTENDANCE_TYPE_ID
--        INTO P_ABSENCE_ATTENDANCE_ID
--      FROM  
PER_ABSENCE_ATTENDANCE_TYPES PAAT
--       WHERE UPPER(PAAT.NAME) =
UPPER(P_ABSENCE_TYPE);
--    
--   ABSENCE_ATTENDANCE_ID :=
P_ABSENCE_ATTENDANCE_ID;
   SELECT TO_NUMBER (SUM (ABSENCE_DAYS))
     INTO ABS_DAYS_PERIOD
     FROM PER_ABSENCE_ATTENDANCES PABA
    WHERE PABA.PERSON_ID =
             (SELECT DISTINCT PPF.PERSON_ID
               
FROM PER_PEOPLE_F PPF, PER_ASSIGNMENTS_F PAF
              
WHERE PPF.PERSON_ID = PAF.PERSON_ID
                
AND PAF.ASSIGNMENT_ID = P_ASG_ID
                
/*AND SYSDATE BETWEEN
PPF.EFFECTIVE_START_DATE
                                 AND
PPF.EFFECTIVE_END_DATE
                 AND SYSDATE BETWEEN
PAF.EFFECTIVE_START_DATE
                                 AND
PAF.EFFECTIVE_END_DATE*/)
      AND PABA.ABSENCE_ATTENDANCE_TYPE_ID = (SELECT PAAT.ABSENCE_ATTENDANCE_TYPE_ID      
      FROM   PER_ABSENCE_ATTENDANCE_TYPES PAAT
       WHERE UPPER(PAAT.NAME) = UPPER(P_ABSENCE_TYPE))
      AND PABA.DATE_START BETWEEN PAY_START_DATE AND PAY_END_DATE
      AND PABA.DATE_END BETWEEN PAY_START_DATE AND PAY_END_DATE;
   OPEN ABS_DATES;
   LOOP
      FETCH ABS_DATES
       INTO ABS_START_DATE, ABS_END_DATE;
      EXIT WHEN ABS_DATES%NOTFOUND;
      IF (ABS_START_DATE > PAY_START_DATE AND ABS_END_DATE > PAY_END_DATE)
      THEN
         SELECT TO_NUMBER (DATE_END - DATE_START) + 1
           INTO SUB_TOTAL
           FROM PER_ABSENCE_ATTENDANCES PABA
          WHERE PERSON_ID =
                  
(SELECT DISTINCT PPF.PERSON_ID
                     
FROM PER_PEOPLE_F PPF, PER_ASSIGNMENTS_F PAF
                    
WHERE PPF.PERSON_ID = PAF.PERSON_ID
                       AND PAF.ASSIGNMENT_ID = P_ASG_ID)                    
            AND PABA.ABSENCE_ATTENDANCE_TYPE_ID = (SELECT PAAT.ABSENCE_ATTENDANCE_TYPE_ID      
      FROM   PER_ABSENCE_ATTENDANCE_TYPES PAAT
       WHERE UPPER(PAAT.NAME) = UPPER(P_ABSENCE_TYPE))
            AND
PABA.DATE_START > PAY_START_DATE
            AND PABA.DATE_END > PAY_END_DATE;
         SELECT TO_NUMBER (TO_DATE(PAY_END_DATE) - DATE_START) + 1
           INTO MISSING_DAYS
           FROM PER_ABSENCE_ATTENDANCES PABA
          WHERE PERSON_ID =
                  
(SELECT DISTINCT PPF.PERSON_ID
                     
FROM PER_PEOPLE_F PPF, PER_ASSIGNMENTS_F PAF
                    
WHERE PPF.PERSON_ID = PAF.PERSON_ID
                       AND PAF.ASSIGNMENT_ID = P_ASG_ID)                    
            AND PABA.ABSENCE_ATTENDANCE_TYPE_ID = (SELECT PAAT.ABSENCE_ATTENDANCE_TYPE_ID      
      FROM   PER_ABSENCE_ATTENDANCE_TYPES PAAT
       WHERE UPPER(PAAT.NAME) = UPPER(P_ABSENCE_TYPE))
            AND PABA.DATE_START > PAY_START_DATE
            AND
PABA.DATE_END > PAY_END_DATE;
         SELECT TO_NUMBER (SUM (ABSENCE_DAYS))
           INTO ACTUAL_DAYS
           FROM PER_ABSENCE_ATTENDANCES PABA
          WHERE PERSON_ID =
                  
(SELECT DISTINCT PPF.PERSON_ID
                   
  FROM PER_PEOPLE_F PPF, PER_ASSIGNMENTS_F PAF
                    
WHERE PPF.PERSON_ID = PAF.PERSON_ID
                       AND PAF.ASSIGNMENT_ID = P_ASG_ID)                  
            AND PABA.ABSENCE_ATTENDANCE_TYPE_ID = (SELECT PAAT.ABSENCE_ATTENDANCE_TYPE_ID      
      FROM   PER_ABSENCE_ATTENDANCE_TYPES PAAT
       WHERE UPPER(PAAT.NAME) = UPPER(P_ABSENCE_TYPE))
            AND PABA.DATE_START > PAY_START_DATE
            AND PABA.DATE_END > PAY_END_DATE;
        
CONDITION_1 := ROUND((NVL (MISSING_DAYS, 0) / NVL (SUB_TOTAL, 0)) * NVL (ACTUAL_DAYS, 0),1);
      ELSIF (ABS_START_DATE < PAY_START_DATE AND ABS_END_DATE < PAY_END_DATE)
      THEN
         SELECT TO_NUMBER (DATE_END - DATE_START) + 1
           INTO SUB_TOTAL_1
           FROM PER_ABSENCE_ATTENDANCES PABA
          WHERE PERSON_ID =
                  
(SELECT DISTINCT PPF.PERSON_ID
                     
FROM PER_PEOPLE_F PPF, PER_ASSIGNMENTS_F PAF
                    
WHERE PPF.PERSON_ID = PAF.PERSON_ID
                       AND PAF.ASSIGNMENT_ID = P_ASG_ID)
           AND PABA.ABSENCE_ATTENDANCE_TYPE_ID =  (SELECT PAAT.ABSENCE_ATTENDANCE_TYPE_ID      
      FROM   PER_ABSENCE_ATTENDANCE_TYPES PAAT
       WHERE UPPER(PAAT.NAME) = UPPER(P_ABSENCE_TYPE))
            AND
PABA.DATE_START < PAY_START_DATE
            AND PABA.DATE_END < PAY_END_DATE
            AND PABA.DATE_END > PAY_START_DATE;
         SELECT TO_NUMBER (DATE_END - TO_DATE(PAY_START_DATE)) + 1
           INTO MISSING_DAYS_1
           FROM PER_ABSENCE_ATTENDANCES PABA
          WHERE PERSON_ID =
                  
(SELECT DISTINCT PPF.PERSON_ID
                     
FROM PER_PEOPLE_F PPF, PER_ASSIGNMENTS_F PAF
                    
WHERE PPF.PERSON_ID = PAF.PERSON_ID
                     
AND PAF.ASSIGNMENT_ID = P_ASG_ID)
             AND PABA.ABSENCE_ATTENDANCE_TYPE_ID =  (SELECT PAAT.ABSENCE_ATTENDANCE_TYPE_ID      
      FROM   PER_ABSENCE_ATTENDANCE_TYPES PAAT
       WHERE UPPER(PAAT.NAME) = UPPER(P_ABSENCE_TYPE))
            AND PABA.DATE_START < PAY_START_DATE
            AND PABA.DATE_END < PAY_END_DATE
            AND PABA.DATE_END > PAY_START_DATE;
         SELECT TO_NUMBER (SUM (ABSENCE_DAYS))
           INTO ACTUAL_DAYS_1
           FROM PER_ABSENCE_ATTENDANCES PABA
          WHERE PERSON_ID =
                  
(SELECT DISTINCT PPF.PERSON_ID
                     
FROM PER_PEOPLE_F PPF, PER_ASSIGNMENTS_F PAF
                    
WHERE PPF.PERSON_ID = PAF.PERSON_ID
                       AND PAF.ASSIGNMENT_ID = P_ASG_ID)
           AND
PABA.ABSENCE_ATTENDANCE_TYPE_ID =  (SELECT PAAT.ABSENCE_ATTENDANCE_TYPE_ID      
      FROM   PER_ABSENCE_ATTENDANCE_TYPES PAAT
       WHERE UPPER(PAAT.NAME) = UPPER(P_ABSENCE_TYPE))
            AND PABA.DATE_START < PAY_START_DATE
            AND PABA.DATE_END < PAY_END_DATE
            AND PABA.DATE_END > PAY_START_DATE;
        
CONDITION_2 := ROUND((NVL (MISSING_DAYS_1, 0) / NVL (SUB_TOTAL_1, 0)) * NVL (ACTUAL_DAYS_1, 0),1);
      END IF;
   END LOOP;
   CLOSE ABS_DATES;
  
TOTAL_ABS_DAYS :=
          NVL (ABS_DAYS_PERIOD, 0) + NVL (CONDITION_1, 0) + NVL (CONDITION_2, 0);
   RETURN TOTAL_ABS_DAYS;
          -- ABS_DAYS_PERIOD;
           --ABSENCE_ATTENDANCE_ID;
          --CONDITION_1;
          --CONDITION_2;
          --SUB_TOTAL_1;
          --MISSING_DAYS_1;
          --ACTUAL_DAYS_1;
EXCEPTION
   WHEN OTHERS
   THEN
      RETURN 0;
END;
If something you could not understand, ask your query in the comment.
Feedback is much appreciated.
0 comments: