DBA Data[Home] [Help]

PACKAGE BODY: APPS.PQH_SS_WORKFLOW

Source


1 Package body pqh_ss_workflow as
2 /* $Header: pqwftswi.pkb 120.27.12020000.4 2013/01/22 15:24:42 ckondapi ship $*/
3 
4 
5 --
6 -- To modify this template, edit file PKGBODY.TXT in TEMPLATE
7 -- directory of SQL Navigator
8 --
9 -- Purpose: Briefly explain the functionality of the package body
10 --
11 -- MODIFICATION HISTORY
12 -- Person      Date    Comments
13 -- ---------   ------  ------------------------------------------
14    -- Enter procedure, function bodies as shown below
15 /*
16 PRF_DT_RULE_FUTUR_CHANGE_FOUND VARCHAR2(30) := 'PQH_DT_RULE_FUTUR_CHANGE_FOUND';
17 PRF_ALLOW_TRANSACTION_REFRESH  VARCHAR2(30) := 'PQH_ALLOW_TRANSACTION_REFRESH';
18 PRF_ALLOW_CONCURRENT_TXN       VARCHAR2(30) := 'PQH_ALLOW_CONCURRENT_TXN';
19 PRF_ALLOW_INELIGIBLE_ACTIONS   VARCHAR2(30) := 'PQH_ENABLE_INELIGIBLE_ACTIONS';
20 */
21 
22 -- Global variables
23 g_date_format  constant varchar2(12)  DEFAULT 'RRRR-MM-DD';
24 g_package      constant varchar2(100) DEFAULT 'pqh_ss_workflow';
25 g_OA_HTML      constant varchar2(100) DEFAULT fnd_web_config.jsp_agent;
26 g_OA_MEDIA     constant varchar2(100) DEFAULT fnd_web_config.web_server||'OA_MEDIA/';
27 --
28 --
29 /* **************************************************************
30     UPDATE_TXN_CURRENT_VALUES
31     Private procedure to update current values to previous values in
32     hr_api_transaction_values table
33   *************************************************************** */
34   PROCEDURE update_txn_current_values ( p_transactionId NUMBER) IS
35   BEGIN
36         IF ( p_transactionId IS NULL ) THEN
37              RETURN;
38         END IF;
39         --
40         UPDATE  hr_api_transaction_values
41         SET     varchar2_value    = previous_varchar2_value,
42                 number_value      = previous_number_value,
43                 date_value        = previous_date_value
44         WHERE   transaction_step_id    IN    (
45                 SELECT  transaction_step_id
46                 FROM    hr_api_transaction_steps
47                 WHERE   transaction_id    =  p_transactionId
48                 --AND     api_name         <> 'HR_SUPERVISOR_SS.PROCESS_API');
49                 AND    api_name  NOT in ('HR_SUPERVISOR_SS.PROCESS_API'
50                                         ,'HR_PROCESS_SIT_SS.PROCESS_API'
51                                         ,'HR_QUA_AWARDS_UTIL_SS.PROCESS_API'
52                                         ,'HR_PROCESS_PHONE_NUMBERS_SS.PROCESS_API'
53                                         ,'HR_PROCESS_ADDRESS_SS.PROCESS_API'
54                                         ,'HR_PROCESS_CONTACT_SS.PROCESS_API'
55                                         ,'HR_PROCESS_PERSON_SS.PROCESS_API'
56                                         ,'HR_COMP_PROFILE_SS.PROCESS_API')
57                 );
58 
59 
60 -- ns 08-May-2003: Bug 2927679: On Cancel the changes and the review activity ids were mismatching
61 -- causing the issue
62 --        AND     name NOT IN ('P_REVIEW_PROC_CALL','P_REVIEW_ACTID');
63 -- end 08-May-2003
64 
65         -- For supervisor step only:
66         -- Copy the previously saved values from history to
67         -- the current transaction
68         PQH_SS_HISTORY.copy_value_from_history(p_transactionId);
69   --
70   EXCEPTION
71       WHEN OTHERS THEN
72            -- raise it so that calling procedure can track it
73            raise;
74   --
75   END;
76 /* **************************************************************
77     UPDATE_TXN_PREVIOUS_VALUES
78     Private procedure to update previous values to current values in
79     hr_api_transaction_values table
80   *************************************************************** */
81    --
82   PROCEDURE update_txn_previous_values ( p_transactionId NUMBER) IS
83   --
84   BEGIN
85       --
86       IF ( p_transactionId IS NULL ) THEN
87             RETURN;
88       END IF;
89       --
90       UPDATE  hr_api_transaction_values
91       SET     previous_varchar2_value   = varchar2_value,
92               previous_date_value       = date_value,
93               previous_number_value     = number_value
94       WHERE   transaction_step_id IN (
95               SELECT transaction_step_id
96               FROM   hr_api_transaction_steps
97               WHERE  transaction_id     = p_transactionId
98               --AND     api_name         <> 'HR_SUPERVISOR_SS.PROCESS_API');
99               AND    api_name  NOT in ('HR_SUPERVISOR_SS.PROCESS_API'
100                                         ,'HR_PROCESS_SIT_SS.PROCESS_API'
101                                         ,'HR_QUA_AWARDS_UTIL_SS.PROCESS_API'
102                                         ,'HR_PROCESS_PHONE_NUMBERS_SS.PROCESS_API'
103                                         ,'HR_PROCESS_ADDRESS_SS.PROCESS_API'
104                                         ,'HR_PROCESS_CONTACT_SS.PROCESS_API'
105                                         ,'HR_PROCESS_PERSON_SS.PROCESS_API'
106                                         ,'HR_COMP_PROFILE_SS.PROCESS_API')
107              );
108 
109 
110         -- For supervisor step only:
111         -- Store the saved/submitted values to history tables
112       PQH_SS_HISTORY.copy_value_to_history ( p_transactionId);
113   --
114   EXCEPTION
115       WHEN OTHERS THEN
116            -- raise it so that calling procedure can track it
117            raise;
118   --
119   END;
120 
121 /*  *****************************************
122 --  Private Procedure to
123 --  Update the transaction with original values from history
124 --  pick the 0th record and below from approval history
125 --  which maintains the original values that was saved (SFL) or submitted (APPROVE_EDIT & SUBMIT)
126 --  ******************************************/
127 PROCEDURE reset_original_values (
128     p_itemType IN VARCHAR2
129    ,p_itemKey  IN VARCHAR2
130    ,p_txnId    IN NUMBER ) IS
131 --
132       CURSOR cur_orig IS
133       SELECT step_history_id, datatype, name, value
134       FROM   pqh_ss_value_history
135       WHERE (step_history_id,approval_history_id) IN (
136              SELECT sh.step_history_id, ah.approval_history_id
137              FROM   pqh_ss_step_history sh,
138                     pqh_ss_approval_history ah
139              WHERE  ah.transaction_history_id = sh.transaction_history_id
140              AND    sh.api_name               = 'HR_PROCESS_ASSIGNMENT_SS.PROCESS_API'
141              AND    ah.transaction_history_id = p_txnId
142              AND    ah.approval_history_id    = 0);
143 --
144 --
145       l_step_history_id NUMBER(15);
146       l_datatype        VARCHAR(20);
147       l_name            VARCHAR(35);
148       l_originalValue   VARCHAR2(2000);
149       l_dateOption      VARCHAR2(10);
150       l_effectiveDate   DATE;
151       l_dt_update_mode  VARCHAR2(50);
152 --
153 BEGIN
154 --
155         IF ( cur_orig%ISOPEN ) THEN
156              CLOSE cur_orig;
157         END IF;
158         --
159         OPEN  cur_orig;
160         LOOP
161 
162            FETCH cur_orig INTO l_step_history_id, l_datatype, l_name, l_originalValue;
163            EXIT  WHEN cur_orig%NOTFOUND;
164            --
165            IF ( l_datatype = 'NUMBER') THEN
166              HR_TRANSACTION_API.set_number_value (
167                 p_transaction_step_id => l_step_history_id
168                ,p_person_id           => null
169                ,p_name                => l_name
170                ,p_value               => hr_api.g_number
171                ,p_original_value      => l_originalValue
172                 );
173            ELSIF ( l_datatype = 'DATE') THEN
174              HR_TRANSACTION_API.set_date_value (
175                 p_transaction_step_id => l_step_history_id
176                ,p_person_id           => null
177                ,p_name                => l_name
178                ,p_value               => hr_api.g_date
179                ,p_original_value      => fnd_date.canonical_to_date(l_originalValue)
180                 );
181            ELSE
182              HR_TRANSACTION_API.set_varchar2_value (
183                 p_transaction_step_id => l_step_history_id
184                ,p_person_id           => null
185                ,p_name                => l_name
186                ,p_value               => hr_api.g_varchar2
187                ,p_original_value      => l_originalValue
188                 );
189            END IF;
190         END LOOP;
191         CLOSE cur_orig;
192 
193         IF ( l_step_history_id IS NOT NULL) THEN
194            -- Fetch the effective date and date option from transaction Values
195            -- table and set it to the appropriate columns in transaction (header) table
196            l_dateOption  := HR_TRANSACTION_API.get_varchar2_value (
197                                p_transaction_step_id => l_step_history_id
198                               ,p_name                => 'P_EFFECTIVE_DATE_OPTION' );
199            --
200            IF (NVL(l_dateOption,'X') = 'E') THEN
201                 l_effectiveDate  := HR_TRANSACTION_API.get_date_value (
202                                    p_transaction_step_id => l_step_history_id
203                                   ,p_name                => 'P_EFFECTIVE_DATE' );
204            --
205            ELSE
206                 l_effectiveDate := sysdate;
207            END IF;
208            --
209            HR_TRANSACTION_API.update_transaction (
210                 p_transaction_id               => p_txnId
211                ,p_transaction_effective_date   => l_effectiveDate
212                ,p_effective_date_option        => NVL(l_dateOption,'E')  );
213            --
214            wf_engine.setItemAttrText (
215                 itemtype => p_itemType
216                ,itemkey  => p_itemKey
217                ,aname    => 'P_EFFECTIVE_DATE'
218                ,avalue   => TO_CHAR(l_effectiveDate,g_date_format) );
219            --
220            --
221       END IF;
222       --
223 --COMMIT;
224 --
225   --
226   EXCEPTION
227       WHEN OTHERS THEN
228            raise;
229   --
230 END reset_original_values;
231 
232   PROCEDURE get_item_type_and_key (
233               p_ntfId       IN NUMBER
234              ,p_itemType   OUT NOCOPY VARCHAR2
235              ,p_itemKey    OUT NOCOPY VARCHAR2 ) IS
236 
237   CURSOR cur_ias IS
238     SELECT item_type, item_key
239     FROM   wf_item_activity_statuses
240     WHERE  notification_id   = p_ntfId;
241 
242   CURSOR cur_not IS
243     SELECT SUBSTR(context,1,INSTR(context,':',1)-1)
244           ,SUBSTR(context,INSTR(context,':')+1, ( INSTR(context,':',INSTR(context,':')+1 ) - INSTR(context,':')-1) )
245     FROM   wf_notifications
246     WHERE  notification_id   = p_ntfId;
247   BEGIN
248         IF ( cur_ias%ISOPEN ) THEN
249              CLOSE cur_ias;
250         END IF;
251         --
252 
253         OPEN cur_ias;
254         FETCH cur_ias  INTO p_itemType, p_itemKey;
255 
256         IF ( cur_ias%NOTFOUND ) THEN
257              IF ( cur_not%ISOPEN ) THEN
258                   CLOSE cur_not;
259              END IF;
260              --
261              OPEN cur_not;
262              FETCH cur_not INTO p_itemType, p_itemKey;
263              CLOSE cur_not;
264         END IF;
265 
266         CLOSE cur_ias;
267   --
268   EXCEPTION
269       WHEN OTHERS THEN
270            raise;
271   --
272   END;
273 /* **************************************************************
274   -- Public function to Get Transaction Id from transaction table
275   -- using Item Type and Item Key info
276   --
277   *************************************************************** */
278   FUNCTION get_transaction_id (
279         p_itemType      IN VARCHAR2
280        ,p_itemKey       IN VARCHAR2 ) RETURN NUMBER IS
281     CURSOR cur_txn IS
282     SELECT  transaction_id
283     FROM    hr_api_transactions
284     WHERE   item_type     = p_itemType
285     AND     item_key      = p_itemKey;
286     l_transactionId  NUMBER;
287   BEGIN
288     IF ( cur_txn%ISOPEN ) THEN
289          CLOSE cur_txn;
290     END IF;
291     --
292     OPEN  cur_txn;
293     FETCH cur_txn INTO l_transactionId;
294     CLOSE cur_txn;
295     RETURN  l_transactionId;
296   --
297   EXCEPTION
298       WHEN OTHERS THEN
299            raise;
300   --
301   END get_transaction_id;
302 --
303 FUNCTION get_notification_id (
304         p_itemType      IN VARCHAR2
305        ,p_itemKey       IN VARCHAR2
306        ) RETURN NUMBER IS
307 --
308 l_ntfId     NUMBER;
309 --
310   CURSOR cur_ntf IS
311     SELECT ias.notification_id
312     FROM   WF_ITEM_ACTIVITY_STATUSES IAS
313     WHERE ias.item_type        = p_itemType
314     and   ias.item_key         = p_itemKey
315     and   IAS.ACTIVITY_STATUS  = 'NOTIFIED'
316     and   notification_id is not null
317     and   rownum < 2;
318 --
319 BEGIN
320 --
321     IF ( cur_ntf%ISOPEN ) THEN
322          CLOSE cur_ntf;
323     END IF;
324     --
325     OPEN cur_ntf;
326     FETCH cur_ntf INTO l_ntfId;
327     CLOSE cur_ntf;
328     RETURN l_ntfId;
329   --
330   EXCEPTION
331       WHEN OTHERS THEN
332            raise;
333   --
334 END;
335 --
336 
337 FUNCTION isHrRepNtf(
338     p_itemType IN VARCHAR2,
339     p_itemKey  IN VARCHAR2) RETURN Boolean IS
340 
341 l_ntf_name VARCHAR2(100);
342 l_ntfId    NUMBER;
343 
344 BEGIN
345    l_ntfId    := get_notification_id(p_itemType,p_itemKey);
346    l_ntf_name := WF_NOTIFICATION.getattrtext(l_ntfId,'HR_NTF_IDENTIFIER');
347 
348    IF (l_ntf_name = 'HR_EMBED_ON_APPR_NTFY_HR_REP') THEN
349     RETURN true;
350    END IF;
351 
352    RETURN false;
353 
354    EXCEPTION WHEN OTHERS THEN
355       RETURN false;
356 END isHrRepNtf;
357 
358 --
359 FUNCTION get_notified_activity (
360         p_itemType      IN VARCHAR2
361        ,p_itemKey       IN VARCHAR2
362        ,p_ntfId         IN VARCHAR2
363        ) RETURN NUMBER IS
364 --
365 l_activityId   NUMBER;
366 --
367   CURSOR cur_wf IS
368     SELECT process_activity
369     FROM   WF_ITEM_ACTIVITY_STATUSES IAS
370     WHERE ias.item_type        = p_itemType
371     and   ias.item_key         = p_itemKey
372     AND   ias.notification_id IS NULL
373     and   IAS.ACTIVITY_STATUS  = 'NOTIFIED'
374     and rownum < 2;
375   --
376   CURSOR cur_wf_ntfId(p_ntfId VARCHAR2) IS
377     SELECT process_activity
378     FROM   WF_ITEM_ACTIVITY_STATUSES IAS
379     WHERE ias.item_type        = p_itemType
380     and   ias.item_key         = p_itemKey
381     and   ias.notification_id  = p_ntfId
382     and   IAS.ACTIVITY_STATUS  = 'NOTIFIED'
383     and   rownum < 2;
384 --
385   BEGIN
386     IF (p_ntfId is null) THEN
387        IF ( cur_wf%ISOPEN ) THEN
388          CLOSE cur_wf;
389        END IF;
390        --
391        OPEN  cur_wf;
392        FETCH cur_wf  INTO l_activityId;
393        CLOSE cur_wf;
394        --
395     ELSE
396        IF ( cur_wf_ntfId%ISOPEN ) THEN
397          CLOSE cur_wf_ntfId;
398        END IF;
399        --
400        OPEN  cur_wf_ntfId(p_ntfId);
401        FETCH cur_wf_ntfId  INTO l_activityId;
402        CLOSE cur_wf_ntfId;
403        --
404     END IF;
405     --
406     return l_activityId;
407     --
408   --
409   EXCEPTION
410       WHEN OTHERS THEN
411            raise;
412   --
413   END get_notified_activity;
414 --
415 --
416 FUNCTION get_notified_activity (
417         p_itemType      IN VARCHAR2
418        ,p_itemKey       IN VARCHAR2
419        ) RETURN NUMBER IS
420 --
421 l_activityId   NUMBER;
422 --
423   CURSOR cur_wf IS
424     -- Fix for bug 3719338
425     /*SELECT ias.process_activity
426     FROM   wf_item_activity_statuses ias
427     WHERE  ias.item_type          = p_itemType
428     and    ias.item_key           = p_itemKey
429     and    ias.activity_status    = 'NOTIFIED'
430     and    ias.process_activity   in (
431            select  pa.instance_id
432            FROM    wf_process_activities     PA,
433                    wf_activity_attributes    AA,
434                    wf_activities             WA,
435                    wf_items                  WI
436            WHERE   pa.process_item_type   = ias.item_type
437            and     wa.item_type           = pa.process_item_type
438            and     wa.name                = pa.activity_name
439            and     wi.item_type           = ias.item_type
440            and     wi.item_key            = ias.item_key
441            and     wi.begin_date         >= wa.begin_date
442            and     wi.begin_date         <  nvl(wa.end_date,wi.begin_date+1)
443            and     aa.activity_item_type  = wa.item_type
444            and     aa.activity_name       = wa.name
445            and     aa.activity_version    = wa.version
446            and     aa.type                = 'FORM'
447            )
448    order by Decode(ias.activity_result_code,'#NULL',1,2);
449   */
450     SELECT process_activity
451        from
452            (select process_activity
453             FROM   WF_ITEM_ACTIVITY_STATUSES IAS
454              WHERE  ias.item_type          = p_itemType
455                and    ias.item_key           = p_itemKey
456                and    ias.activity_status    = 'NOTIFIED'
457                and    ias.process_activity   in (
458                                                  select  wpa.instance_id
459                                                  FROM    WF_PROCESS_ACTIVITIES     WPA,
460                                                          WF_ACTIVITY_ATTRIBUTES    WAA,
461                                                          WF_ACTIVITIES             WA,
462                                                          WF_ITEMS                  WI
463                                                  WHERE   wpa.process_item_type   = ias.item_type
464                                                  and     wa.item_type           = wpa.process_item_type
465                                                  and     wa.name                = wpa.activity_name
466                                                  and     wi.item_type           = ias.item_type
467                                                  and     wi.item_key            = ias.item_key
468                                                  and     wi.begin_date         >= wa.begin_date
469                                                  and     wi.begin_date         <  nvl(wa.end_date,wi.begin_date+1)
470                                                  and     waa.activity_item_type  = wa.item_type
471                                                  and     waa.activity_name       = wa.name
472                                                  and     waa.activity_version    = wa.version
473                                                  and     waa.type                = 'FORM'
474                                                )
475             order by begin_date desc)
476       where rownum<=1;
477 
478 --
479   BEGIN
480        IF ( cur_wf%ISOPEN ) THEN
481          CLOSE cur_wf;
482        END IF;
483        --
484        OPEN  cur_wf;
485        FETCH cur_wf  INTO l_activityId;
486        CLOSE cur_wf;
487        return l_activityId;
488   --
489   EXCEPTION
490       WHEN OTHERS THEN
491            raise;
492   --
493   END get_notified_activity;
494 
495 /* ******************************************************
496   -- Complete Workflow Activity
497   --
498   ******************************************************* */
499   PROCEDURE complete_wf_activity (
500 	p_itemType    IN VARCHAR2,
501 	p_itemKey     IN VARCHAR2,
502         p_activity    IN NUMBER,
503         p_otherAct    IN VARCHAR2,
504 	p_resultCode  IN VARCHAR2,
505         p_commitFlag  IN VARCHAR2  DEFAULT 'N' ) IS
506 --
507 -- PRAGMA AUTONOMOUS_TRANSACTION;
508 l_activity  Number;
509 
510 actdate date;               -- Active date
511 acttype varchar2(8);        -- Activity type
512 notid pls_integer;       -- Notification group id
513 user varchar2(320);      -- Notification assigned user
514 
515 
516   CURSOR c_wf IS
517     SELECT instance_label,ias.process_activity actvityId, ias.notification_id ntfId
518     FROM  WF_ITEM_ACTIVITY_STATUSES IAS,
519           WF_PROCESS_ACTIVITIES PA
520     WHERE IAS.PROCESS_ACTIVITY = PA.INSTANCE_ID
521     AND ias.item_type = pa.process_item_type
522     and ias.item_type = p_itemType
523     and ias.item_key = p_itemKey
524     and ias.activity_status = 'NOTIFIED'
525     and ias.process_activity <> p_activity
526     and not exists (select 'e'
527                     from WF_ACTIVITIES wa, WF_ACTIVITY_ATTRIBUTES waa, WF_ITEMS wi
528                     where wa.item_type = pa.process_item_type
529                     and wa.name = pa.activity_name
530                     and wi.item_type = ias.item_type
531                     and wi.item_key = ias.item_key
532                     and wi.begin_date between wa.begin_date and nvl(wa.end_date,wi.begin_date)
533                     and waa.activity_item_type  = wa.item_type
534                     and waa.activity_name = wa.name
535                     and waa.activity_version = wa.version
536                     and waa.type = 'FORM');
537 
538 /*
539     and   ( (p_otherAct = 'OTHER' AND ias.process_activity <> p_activity) OR  -- Activity other than the passed one
540             (p_otherAct = 'CURR'  AND ias.process_activity = l_activity ) OR  -- Fetch current first and complete that
541             (p_otherAct = 'THIS'  AND ias.process_activity = p_activity ) ) ; -- Notification to be completed.
542 --
543 p_OtherAct  = yes'OTHER'   - Complete the activity other than the passed one
544 p_OtherAct  = no 'CURR'    - Activity not available, fetch current activity firs
545 t, and then complete that.
546 p_OtherAct  = NTF 'THIS'    - Complete the passed activity
547 */
548   l_activity_name	  VARCHAR2(100);
549 --
550 --
551   BEGIN
552 --
553     IF ( p_otherAct IN ('CURR','THIS'))  THEN
554       IF ( p_otherAct = 'CURR') THEN
555           l_activity   := get_notified_activity(p_itemType,p_itemKey);
556            if(l_activity is null ) then
557            return;
558            end if;
559       ELSIF ( p_otherAct = 'THIS') THEN
560           l_activity   := p_activity;
561       END IF;
562       --
563       l_activity_name  := wf_engine.getActivityLabel(l_activity);
564 
565        begin
566 	 actdate := Wf_Item.Active_Date(p_itemType, p_itemKey);
567          acttype := Wf_Activity.Instance_Type(l_activity, actdate);
568 
569          if (acttype = wf_engine.eng_notification) then
570              -- Get notification id
571           Wf_Item_Activity_Status.Notification_Status(p_itemType, p_itemKey, l_activity,
572                                                       notid, user);
573         end if;
574       exception
575       when others then
576         null;
577       end;
578       --
579     ELSIF ( p_otherAct = 'OTHER') THEN
580       --
581        IF ( c_wf%ISOPEN ) THEN
582          CLOSE c_wf;
583        END IF;
584        --
585       OPEN c_wf;
586       FETCH c_wf into l_activity_name,l_activity,notid;
587       CLOSE c_wf;
588     END IF;
589 --
590 --
591      if l_activity_name is not null then
592  	if (notid is not null) then
593 	        wf_notification.setattrtext(
594        			notid
595        		       ,'RESULT'
596        		       ,p_resultCode);
597         wf_notification.respond(
598         			notid
599       		       ,null
600       		       ,fnd_global.user_name
601       		       ,null);
602       else
603      	wf_engine.CompleteActivity(
604                    p_itemType
605                  , p_itemKey
606                  , l_activity_name
607                  , p_resultCode)  ;
608       end if;
609     end if;
610 -- Removing commit as Pragma Autonomous_Transaction is added;
611 --   if ( p_commitFlag = 'Y' ) then
612        commit;
613 --   end if;
614 --
615 --
616   --
617   EXCEPTION
618       WHEN OTHERS THEN
619            hr_utility.trace(' exception in  '||g_package||'.complete_wf_activity : ' || sqlerrm);
620            Wf_Core.Context(g_package, 'complete_wf_activity', p_itemType, p_itemKey);
621            raise;
622   --
623   END complete_wf_activity;
624 --
625 PROCEDURE start_approval_wf (
626       itemtype        IN     VARCHAR2,
627       itemkey         IN     VARCHAR2,
628       actid           IN     NUMBER,
629       funcmode        IN     VARCHAR2,
630       result          OUT NOCOPY    VARCHAR2 ) IS
631 --
632 l_initialSFL VARCHAR2(30);
633 l_NtfId     NUMBER;
634 l_result    VARCHAR2(30) := 'RESUBMIT'; -- Default result
635 
636 CURSOR cur_sfl IS
637 SELECT nvl(decode(wav.text_value, null, hat.status,
638             decode(hat.status,'S','SUBMIT',hat.status)),'N')
639 FROM   hr_api_transactions       hat,
640         wf_item_attribute_values wav
641 WHERE  hat.item_type  = wav.item_Type
642 AND    hat.item_key   = wav.item_Key
643 AND    wav.item_type  = itemType
644 AND    wav.item_key   = itemKey
645 AND    wav.name       = 'SAVED_ACTIVITY_ID';
646 
647 
648 BEGIN
649 --
650   IF (funcmode = wf_engine.eng_run) THEN
651 
652     -- fix for bug 4454439
653     begin
654       -- re-intialize the performer roles
655       hr_approval_ss.reinitperformerroles(p_notification_id=>null
656                                           ,p_transaction_id=>null
657                                           ,p_item_type=>itemtype
658                                           ,p_item_key=>itemKey);
659     exception
660     when others then
661       null;
662     end;
663 
664 
665        IF ( cur_sfl%ISOPEN ) THEN
666          CLOSE cur_sfl;
667        END IF;
668        --
669       OPEN  cur_sfl;
670       FETCH cur_sfl into l_initialSFL;
671       CLOSE cur_sfl;
672 
673    --If initial save for later then result is APPROVED, else it is RESUBMIT
674    --This is used to ignore two history records for initial SFL & Submit
675    IF  ( l_initialSFL =  'SUBMIT') THEN
676       l_result := 'APPROVED';
677    ELSIF (l_initialSFL = 'Y') THEN
678 
679          l_NtfId := get_notification_id(itemtype, itemKey);
680 
681          wf_notification.setattrtext(
682                            l_NtfId
683                           ,'WF_NOTE'
684                           ,wf_engine.GetItemAttrText(
685                                    itemtype
686                                   ,itemkey
687                                   ,'APPROVAL_COMMENT_COPY'));
688          wf_engine.setitemattrtext(
689                         itemtype
690                        ,itemkey
691                        ,'APPROVAL_COMMENT_COPY'
692                        ,null);
693    ELSE
694          wf_notification.propagatehistory(
695                                itemtype
696                               ,itemkey
697                               ,'APPROVAL_NOTIFICATION'
698                               ,fnd_global.user_name
699                               ,'WF_SYSTEM'
700                               --,hr_workflow_ss.getNextApproverForHist(itemtype, itemkey)
701                               ,'RESUBMIT'
702                               ,null
703                               ,wf_engine.GetItemAttrText(
704                                	        itemtype
705                                	       ,itemkey
706                                        ,'APPROVAL_COMMENT_COPY'));
707    END IF;
708 
709    --Set transaction status to pending
710    --Bug 3018784: This call is moved from set_txn_submit_status
711    set_transaction_status (
712         p_itemType  => itemType
713        ,p_itemKey   => itemKey
714        ,p_action    => 'SUBMIT'
715        ,p_result    => result );
716 
717    --Complete the Activity in approval flow with Approved (if new or SFL txn)
718    --Or Resubmit if pending or RFC transactions.
719    complete_wf_activity (
720             p_itemType    => itemtype,
721             p_itemKey     => itemkey,
722             p_activity    => actid,
723             p_otherAct    => 'OTHER',
724             p_commitFlag  => 'Y',
725             p_resultCode  => l_result ) ;
726   END IF;
727 --
728   result := 'COMPLETE:NEXT';
729 --
730   --
731   EXCEPTION
732       WHEN OTHERS THEN
733            hr_utility.trace(' exception in  '||g_package||'.start_approval_wf : ' || sqlerrm);
734            Wf_Core.Context(g_package, 'start_approval_wf', itemType, itemKey);
735            raise;
736   --
737 END start_approval_wf;
738 --
739 --
740 PROCEDURE get_transaction_info (
741     p_itemType       IN VARCHAR2
742    ,p_itemKey        IN VARCHAR2
743    ,p_loginPerson    IN VARCHAR2
744    ,p_whatchecks     IN VARCHAR2 DEFAULT 'EPIG'
745    ,p_calledFrom     IN VARCHAR2 DEFAULT 'REQUEST'
746    ,p_personId      OUT NOCOPY VARCHAR2
747    ,p_assignmentId  OUT NOCOPY VARCHAR2
748    ,p_state         OUT NOCOPY VARCHAR2
749    ,p_status        OUT NOCOPY VARCHAR2
750    ,p_txnId         OUT NOCOPY VARCHAR2
751    ,p_businessGrpId OUT NOCOPY VARCHAR2
752    ,p_editAllowed   OUT NOCOPY VARCHAR2
753    ,p_futureChange  OUT NOCOPY VARCHAR2
754    ,p_pendingTxn    OUT NOCOPY VARCHAR2
755    ,p_interAction   OUT NOCOPY VARCHAR2
756    ,p_effDateOption IN OUT NOCOPY VARCHAR2
757    ,p_effectiveDate IN OUT NOCOPY VARCHAR2
758    ,p_isPersonElig  OUT NOCOPY VARCHAR2
759    ,p_rptgGrpId     OUT NOCOPY VARCHAR2
760    ,p_planId        OUT NOCOPY VARCHAR2
761    ,p_processName   OUT NOCOPY VARCHAR2
762    ,p_dateParmExist OUT NOCOPY VARCHAR2
763    ,p_rateParmExist OUT NOCOPY VARCHAR2
764    ,p_slryParmExist OUT NOCOPY VARCHAR2
765    ,p_rateMessage   OUT NOCOPY VARCHAR2
766    ,p_terminateFlag OUT NOCOPY VARCHAR2 ) IS
767 --
768 l_effDate          DATE;
769 l_changeDate       DATE;
770 l_terminationDate  VARCHAR2(30);
771 l_effDateOption    VARCHAR2(10);
772 l_functionId       NUMBER(15);
773 l_parameter        fnd_form_functions.parameters%TYPE;
774 dummy              VARCHAR2(10);
775 l_flowName         VARCHAR2(100);
776 l_version          VARCHAR2(10);
777 l_asg_tx          VARCHAR2(1) := 'N';
778 
779 -- Fetch transaction information
780 CURSOR cur_txn IS
781    SELECT   transaction_id, status, transaction_state, NVL(transaction_effective_date,sysdate),
782             assignment_id, effective_date_option, plan_id, rptg_grp_id,
783             NVL(selected_person_id,-1), process_name,function_id
784    FROM     hr_api_transactions
785    WHERE    item_type   = p_itemType
786    AND      item_key    = p_itemKey;
787 --
788 -- Bug 2969312: 21-May-2003: ns
789 -- check to see if assignment is terminated
790 -- if so flag is set
791 -- Check if the transaction is on an assignment
792 CURSOR cur_chk_asg (c_txnId NUMBER) IS
793 SELECT 'X'
794 FROM   hr_api_transaction_steps
795 WHERE  transaction_id  = c_txnId
796 AND    api_name  IN (
797        'HR_PROCESS_ASSIGNMENT_SS.PROCESS_API',
798        'HR_SUPERVISOR_SS.PROCESS_API',
799        'HR_TERMINATION_SS.PROCESS_API',
800        'HR_PAY_RATE_SS.PROCESS_API',
801        'PER_SSHR_CHANGE_PAY.PROCESS_API' );
802 --
803 -- Check if the assignment is terminated
804 CURSOR cur_term_asg (c_asgnId NUMBER, c_effective_date DATE) IS
805 SELECT 'X'
806 FROM   per_all_assignments_f
807 WHERE  assignment_id       = c_asgnId
808 AND    effective_end_date <= trunc(c_effective_date)
809 AND    assignment_status_type_id in (
810        SELECT assignment_status_type_id
811        FROM   per_assignment_status_types
812        WHERE  per_system_status in ('TERM_ASSIGN', 'END'));
813 --
814 -- Check if assignment is terminated in future
815 CURSOR cur_fut_term_asg (c_asgnId NUMBER, c_effective_date DATE) IS
816 SELECT to_char(ser.actual_termination_date,g_date_format)
817 FROM   per_periods_of_service ser,
818        per_all_assignments_f ass
819 where  ass.period_of_service_id = ser.period_of_service_id
820 AND    ass.assignment_id        = c_asgnId
821 AND    TRUNC(c_effective_date) between ass.effective_start_date AND ass.effective_end_date ;
822 
823 -- For Employee transactions check if the person is terminated
824 CURSOR cur_term_emp (c_personId NUMBER, c_effective_date DATE) IS
825 SELECT 'X'
826 FROM   per_all_people_f
827 WHERE  nvl(current_employee_flag,'N') <> 'Y'
828 AND  nvl(current_applicant_flag,'N') <> 'Y'
829 AND    nvl(current_npw_flag,'N') <> 'Y'
830 AND    TRUNC(c_effective_date) BETWEEN effective_start_date AND effective_end_date
831 AND    person_id = c_personId;
832 --
833 CURSOR  cur_fn (c_functionId NUMBER) IS
834 SELECT  parameters
835 FROM    fnd_form_functions
836 WHERE   function_id         = c_functionId;
837 --
838 -- Bug 3003754: check to see if pay rate changes exist on the same date as the transaction effective date
839 CURSOR cur_pay ( c_assignmentId NUMBER, c_bgId NUMBER) IS
840 SELECT change_date
841 FROM   per_pay_proposals
842 WHERE  assignment_id     = c_assignmentId
843 AND    business_group_id = c_bgId
844 ORDER  BY change_date desc ;
845 
846 l_rehire_flow varchar2(25) default null;
847 
848 BEGIN
849 --
850 /*  p_WhatChecks can be
851      E- Edit privilege
852      F- Future dated check alone
853      P- Pending Transaction Check
854      I- Intervening Action and future dated checks
855      G- Eligibility
856 */
857     IF ( p_whatChecks IS NULL ) THEN RETURN; END IF;
858     IF ( cur_txn%ISOPEN ) THEN
859        CLOSE cur_txn;
860     END IF;
861     --
862     OPEN  cur_txn ;
863     FETCH cur_txn INTO p_txnId, p_status, p_state, l_effDate , p_assignmentId, l_effDateOption,
864 	               p_planId, p_rptgGrpId, p_personId, p_processName, l_functionId;
865     CLOSE cur_txn;
866 
867     -- If effective date is passed, validate information as of the
868     -- passed effective date
869     -- else validate against the transaction effective date.
870     IF ( p_effectiveDate IS NOT NULL ) THEN
871         l_effDate := TO_DATE(p_effectiveDate, g_date_format );
872     ELSE
873         p_effectiveDate := TO_CHAR(l_effDate, g_date_format);
874     END IF;
875     --
876     IF (p_effDateOption IS NOT NULL ) THEN
877         l_effDateOption := p_effDateOption;
878     ELSE
879         p_effDateOption := l_effDateOption;
880     END IF;
881     --
882     --
883     -- Bug 2969312: 21-May-2003: ns
884     -- Check if the transaction is assignment related
885     -- if so, check if assignment is terminated, else
886     -- check if person is terminated.
887     -- if either is terminated, set appropriate flag
888     p_terminateFlag := 'NO'; -- reset flag before use.
889 
890     IF ( cur_fut_term_asg%ISOPEN ) THEN
891        CLOSE cur_fut_term_asg;
892     END IF;
893     --
894     OPEN  cur_chk_asg(p_txnId );
895     FETCH cur_chk_asg INTO dummy;
896 
897     IF cur_chk_asg%FOUND THEN -- Assignment related transaction
898         l_asg_tx := 'Y';
899     END IF;
900     CLOSE cur_chk_asg;
901 
902  -- do not perform termination check for non assignment
903  -- related transaction.
904  IF l_asg_tx = 'Y' THEN
905 
906     --
907     OPEN  cur_fut_term_asg(p_assignmentId, TO_DATE(p_effectiveDate, g_date_format ));
908     FETCH cur_fut_term_asg INTO l_terminationDate;
909     CLOSE cur_fut_term_asg;
910 
911     IF ( l_terminationDate IS NOT NULL ) THEN
912 
913     if p_itemType is not null and p_itemKey is not null then
914     		l_rehire_flow := wf_engine.GetItemAttrText(p_itemType,p_itemKey,'HR_FLOW_IDENTIFIER',true);
915 
916          end if;
917 
918          --
919        IF nvl(l_rehire_flow,'N') <> 'EX_EMP'  AND nvl(l_rehire_flow,'N') <> 'REVERSE_TERMINATION' then
920          IF ( to_date(l_terminationDate,g_date_format) <= trunc(sysdate)) THEN
921               p_terminateFlag := 'ASGN'; -- set flag
922          ELSE
923               p_terminateFlag := l_terminationDate;
924          END IF;
925        END IF;
926 
927          --
928     ELSE
929          --
930          IF ( cur_term_emp%ISOPEN ) THEN
931             CLOSE cur_term_emp;
932          END IF;
933          --
934          OPEN  cur_term_emp(p_personId, TO_DATE(p_effectiveDate, g_date_format ));
935          FETCH cur_term_emp INTO dummy;
936          --
937          if p_itemType is not null and p_itemKey is not null then
938     		l_rehire_flow := wf_engine.GetItemAttrText(p_itemType,p_itemKey,'HR_FLOW_IDENTIFIER',true);
939          end if;
940      If nvl(l_rehire_flow,'N') <> 'EX_EMP'  AND nvl(l_rehire_flow,'N') <> 'REVERSE_TERMINATION' then
941         IF cur_term_emp%FOUND THEN -- Person is found to be terminated
942             --
943             p_terminateFlag := 'PRSN'; -- set flag for person termination
944             --
945          ELSE
946             --
947              IF ( cur_term_asg%ISOPEN ) THEN
948                 CLOSE cur_term_asg;
949              END IF;
950              --
951             OPEN  cur_term_asg (p_assignmentId, TO_DATE(p_effectiveDate, g_date_format ));
952             FETCH cur_term_asg INTO dummy;
953             --
954             IF cur_term_asg%FOUND THEN -- Assignment is found to be terminated
955                p_terminateFlag := 'ASGN'; -- set flag
956             END IF;
957             --
958             CLOSE cur_term_asg;
959             --
960          END IF;
961       End if;
962          --
963          CLOSE cur_term_emp;
964          --
965     END IF;
966  END IF;
967     --
968     --
969     -- Check if effective Date parameter exist for the function
970     IF ( cur_fn%ISOPEN ) THEN
971          CLOSE cur_fn;
972     END IF;
973     --
974     OPEN  cur_fn (l_functionId);
975     FETCH cur_fn INTO l_parameter;
976     CLOSE cur_fn;
977 
978     IF ( INSTR(l_parameter,'pEffectiveDate') > 0 ) THEN
979         p_dateParmExist := 'Y';
980     END IF;
981 
982     IF ( INSTR(l_parameter,'pPayRate') > 0 ) THEN
983         p_rateParmExist := 'Y';
984     END IF;
985 
986     IF ( INSTR(l_parameter,'pSalChange') > 0 ) THEN
987         p_slryParmExist := 'Y';
988     END IF;
989 
990     -- if date option is as of approval, take current date for processing.
991     IF (l_effDateOption = 'A' OR p_dateParmExist = 'N') THEN
992        l_effDate := TRUNC( Sysdate);
993     END IF;
994 
995     -- ========================================
996     -- if termination flag is set, then return
997     -- without any further checks.
998     IF ( NVL(p_terminateFlag,'NO') <> 'NO') THEN
999          return;
1000     END IF;
1001     -- ========================================
1002 
1003     p_businessGrpId := PQH_SS_UTILITY.get_business_group_id (
1004                             p_personId      => p_personId
1005                            ,p_effectiveDate => l_effDate );
1006     --
1007     -- check salary changes
1008     IF ( p_assignmentId IS NOT NULL AND p_businessGrpId IS NOT NULL
1009          AND p_rateParmExist = 'Y') THEN
1010        IF ( cur_pay%ISOPEN ) THEN
1011          CLOSE cur_pay;
1012        END IF;
1013        --
1014        OPEN  cur_pay (p_assignmentId, p_businessGrpId);
1015        FETCH cur_pay INTO l_changeDate;
1016        --
1017        IF  cur_pay%FOUND THEN
1018            IF l_changeDate   = l_effDate THEN
1019               p_rateMessage := 'PQH_SS_PAYRATE_SAMEDAY_ERR';
1020            ELSIF l_changeDate > l_effDate THEN
1021               p_rateMessage := 'PQH_SS_PAYRATE_FUTURE_ERR';
1022            END IF;
1023        END IF;
1024        --
1025        CLOSE cur_pay;
1026     END IF;
1027 
1028     IF ( p_processName IS NULL ) THEN
1029         p_processName   :=  wf_engine.GetItemAttrText(
1030                             itemtype    => p_itemType
1031                            ,itemkey     => p_itemKey
1032                            ,aname       => 'PROCESS_NAME');
1033     END IF;
1034     --
1035     BEGIN
1036        l_flowName := wf_engine.GetItemAttrText(
1037                                  itemtype => p_itemType,
1038                                  itemkey  => p_itemKey,
1039 				 aname    => 'HR_FLOW_NAME_ATTR');
1040     EXCEPTION
1041        WHEN OTHERS THEN
1042             NULL; -- if attribute not found then continue w/out error
1043     END;
1044 
1045     p_editAllowed   := 'N';
1046 
1047     -- Bug 3025523: Check access to selected employee's record via secured view
1048     -- Secure access is not checked in case of New Hire as there
1049     -- will be no record in hr tables.
1050     -- added (NVL(p_calledFrom,'X') = 'FINAL_VALIDATION') for bug 13416339
1051     IF ( NVL(l_flowName,'x') <> 'HrCommonInsertOab' AND
1052          NVL(l_flowName, 'x') <> 'CWKPlacement'  AND
1053          p_personid <> -1 AND
1054          NVL(p_calledFrom,'X') <> 'FINAL_VALIDATION') THEN
1055     BEGIN
1056         select 'x'
1057         into   dummy
1058         from   per_people_f
1059         where  person_id  = p_personId
1060         and    l_effDate between effective_start_date and effective_end_date;
1061         --
1062         dummy := null;
1063         --
1064     EXCEPTION
1065         WHEN NO_DATA_FOUND THEN
1066            p_editAllowed := 'NS'; --No access to emp record
1067            -- ========================================================
1068            -- No need to perform all the validations, if manager does not have
1069            -- secure access to the selected person's record.
1070            -- ========================================================
1071            Return;
1072     END;
1073     END IF;
1074 
1075     IF ( INSTR(p_whatChecks,'E') > 0) THEN
1076       --
1077       IF ( INSTR(p_status,'S') >0 OR p_status = 'RI' ) THEN
1078            p_editAllowed := 'Y';
1079       ELSE
1080       --
1081         PQH_SS_UTILITY.check_edit_privilege (
1082           p_personId        => p_loginPerson
1083          ,p_businessGroupId => p_businessGrpId
1084          ,p_editAllowed     => p_editAllowed );
1085       --
1086      END IF;
1087    END IF;
1088 
1089    -- ========================================================
1090    -- After evaluating the edit privilege, there is no need
1091    -- to perform all the validations, if in new hire flow
1092    -- ========================================================
1093    IF ( NVL(l_flowName,'x') = 'HrCommonInsertOab' OR
1094         NVL(l_flowName, 'x') = 'CWKPlacement' ) THEN
1095       if p_effDateOption IS NULL then
1096          p_effDateOption := 'E';
1097       end if;
1098 
1099       RETURN;
1100    END IF;
1101 
1102    -- ========================================================
1103    -- Perform other validations only if the user has Edit privilege
1104    -- these checks are irrelevant if user cannot edit.
1105    -- Either Edit priv was not checked or checked and found eligible
1106    -- ========================================================
1107    IF ( INSTR(p_whatChecks,'E')=0 OR p_editAllowed = 'Y' ) THEN
1108 
1109     IF ( INSTR(p_whatChecks,'P') > 0)  THEN
1110      p_pendingTxn := PQH_SS_UTILITY.check_pending_Transaction (
1111                       p_txnId       => p_txnId
1112                      ,p_itemType    => p_itemType
1113                      ,p_personId    => p_personId
1114   		     ,p_assignId    => p_assignmentId   ) ;
1115     END IF;
1116      --
1117      p_futureChange := 'N';
1118      p_interAction  := 'N';
1119      --Perform date track validations only if the transaction has
1120      --date associated with it.
1121      IF ( p_dateParmExist <> 'N') THEN
1122        --
1123        l_version :=  PQH_SS_UTILITY.get_approval_process_version(
1124                        p_itemType => p_itemType,
1125                        p_itemKey  => p_itemKey );
1126        --
1127        -- ========================================================
1128        -- For V4 approval process, compare the OVN of assignment and the transaction
1129        -- If they do not match return appropriate flag
1130        -- ========================================================
1131        IF ( l_version IS NULL OR l_version <> 'V5') THEN
1132           Declare
1133            --
1134            CURSOR cur_asg_step IS
1135            SELECT transaction_step_id
1136            FROM   hr_api_transaction_steps
1137            WHERE  transaction_id          = p_txnId
1138            AND    api_name                = 'HR_PROCESS_ASSIGNMENT_SS.PROCESS_API';
1139            --
1140            --
1141            CURSOR cur_match_ovn (c_txn_step_id NUMBER, c_effDate DATE) IS
1142            SELECT 'X'
1143            FROM   hr_api_transaction_values  tv,
1144                   per_assignments_f          af
1145            WHERE  af.assignment_id        = p_assignmentId
1146            AND    tv.transaction_step_id  = c_txn_step_id
1147            AND    tv.name                 = 'P_OBJECT_VERSION_NUMBER'
1148            AND    c_effDate BETWEEN af.effective_start_date AND af.effective_end_date
1149            AND    NVL(original_number_value,number_value) = af.object_version_number;
1150            --
1151            l_txn_step_id   NUMBER;
1152            --
1153          Begin
1154            --
1155            Open  cur_asg_step;
1156            Fetch cur_asg_step INTO l_txn_step_id;
1157 
1158            -- ==================================================
1159            -- Assignment step exists, check if the ovns match
1160            -- If assginment step does not exist then do nothing
1161            -- ==================================================
1162            IF cur_asg_step%FOUND THEN
1163               --
1164               Open  cur_match_ovn (l_txn_step_id, l_effDate);
1165               Fetch cur_match_ovn INTO Dummy;
1166               -- If matching ovns are not found -Intervening action -Set flag to throw error
1167               IF cur_match_ovn%NOTFOUND  THEN
1168                  p_interAction := 'YV4';
1169               END IF;
1170               Close cur_match_ovn;
1171               --
1172            END IF;
1173            --
1174            Close cur_asg_step;
1175            --
1176          End;
1177          --
1178        ELSE
1179          --
1180          IF ( INSTR(p_whatChecks,'I') > 0 OR  INSTR(p_whatChecks,'F') > 0)  THEN
1181            --
1182            p_futureChange := PQH_SS_UTILITY.check_future_Change (
1183                           p_txnId           => p_txnId
1184                          ,p_assignmentId    => p_assignmentId
1185                          ,p_effectiveDate   => l_effDate
1186                          ,p_calledFrom      => p_calledFrom );
1187            --
1188          END IF;  -- future/intervening
1189 
1190          IF ( INSTR(p_whatChecks,'I') > 0)  THEN
1191            --
1192            p_interAction := PQH_SS_UTILITY.check_intervening_Action (
1193                              p_txnId             => p_txnId
1194                             ,p_assignmentId      => p_assignmentId
1195                             ,p_effectiveDate     => l_effDate
1196                             ,p_futureChange      => p_futureChange ) ;
1197            --
1198          END IF;  -- intervening
1199          --
1200        END IF; -- End if Approval version
1201        --
1202      END IF; --dateParamExist
1203      --
1204      IF ( INSTR(p_whatChecks,'G') > 0 ) THEN
1205      --
1206       p_isPersonElig :=  PQH_SS_UTILITY.check_eligibility (
1207                        p_planId    => p_planId
1208                       ,p_personId  => p_personId
1209                       ,p_effectiveDate  => l_effDate ) ;
1210     --
1211     END IF;
1212    END IF;
1213   --
1214   EXCEPTION
1215       WHEN OTHERS THEN
1216            hr_utility.trace(' exception in  '||g_package||'.get_transaction_info : ' || sqlerrm);
1217            raise;
1218   --
1219 END get_transaction_info;
1220 --
1221 
1222 
1223 PROCEDURE revert_to_last_save (
1224     p_txnId         IN NUMBER
1225    ,p_itemType      IN VARCHAR2
1226    ,p_itemKey       IN VARCHAR2
1227    ,p_status        IN VARCHAR2
1228    ,p_state         IN VARCHAR2
1229    ,p_revertFlag    IN VARCHAR2      ) IS
1230 --
1231 l_applicationId NUMBER(15);
1232 l_regionCode    VARCHAR2(30);
1233 l_newState      VARCHAR2(5);
1234 l_activityLabel VARCHAR2(240);
1235 l_savedStatus   BOOLEAN   := INSTR(p_status,'S') > 0;
1236 l_activityId    NUMBER(15);
1237 l_currentActivityId    NUMBER(15);
1238 l_savedActivityId    NUMBER(15);
1239 --
1240 BEGIN
1241 
1242 
1243 --  Handle WF Transitions
1244 --  if the txn is in sfl status AND if either unsaved changes found that user wanted to revert or  txn is in transient state
1245 --  transition back to saved activity
1246     IF ( l_savedStatus AND ( (p_state='T') OR (p_state = 'W' AND p_revertFlag = 'Y') ) )THEN
1247                 --
1248                 l_savedActivityId  :=    wf_engine.GetItemAttrText(
1249                                           itemtype => p_itemType,
1250                                           itemkey  => p_itemKey,
1251                                           aname    => 'SAVED_ACTIVITY_ID');
1252                 --
1253                 --
1254                 l_currentActivityId := get_notified_activity(
1255                                             p_itemType  => p_itemType
1256                                            ,p_itemKey   => p_itemKey);
1257 
1258                 IF (l_savedActivityId <> l_currentActivityId ) THEN
1259 
1260                 -- handle error to go back to the saved activity
1261                     l_activityLabel  :=  WF_ENGINE.GetActivityLabel(l_savedActivityId);
1262                     --
1263                     --possibility of the method closing the notification
1264                     -- instead of the form activity.
1265                     if(l_activityLabel is not null) then
1266                     WF_ENGINE.handleError(
1267                         itemType => p_itemType
1268                        ,itemKey  => p_itemKey
1269                        ,activity => l_activityLabel
1270                        ,command  => 'RETRY' ) ;
1271                     end if;
1272 
1273                 -- Bug 2962973:ns complete the current activity
1274                 -- so that only SFL activity is left notified
1275                    -- NO DML Operations directly on FND schema.
1276                    -- Fix for bug#3578646
1277                    /*
1278                     UPDATE wf_item_activity_statuses
1279                      SET   activity_status  = 'COMPLETE',
1280                            activity_result_code ='#NULL'
1281                      WHERE item_type        = p_itemType
1282                      AND   item_key         = p_itemKey
1283                      AND   process_activity = l_currentActivityId;
1284                    */
1285 
1286                 END IF;
1287         -- if  unsave changes found and user does not want to revert
1288         -- if (savedStatus and (p_state IS NULL OR p_state='W' and revert=N)) OR
1289         --    ( otherThanSavedStatus AND p_state='W' and revert=N) ) THEN do nothing
1290    ELSIF ( l_savedStatus OR (p_state ='W' and p_revertFlag='N') or (p_status = 'W' and (p_state is null or p_state = 'T' or p_state = 'W')) ) THEN
1291         NULL;
1292    -- if txn not in sfl status OR if state is null
1293    ELSE --i.e  IF p_state is NULL (redo needed in this cause coz it could be the blocked activity)
1294         -- if  (p_state = 'W' AND p_revertFlag='Y' and status = NOT SAVED)
1295         -- Find the current activity
1296         -- if p_state is not null, Complete WF with RESULT=REDO to go to the first page of the transaction,
1297         -- Since this method is called when Edit is clicked from a notification,
1298         -- Notification is always one of the notified activity,
1299         -- Fetching activity other than that of Ntf will give the notified activity of the txn thread.
1300            l_activityId    := get_notified_activity(
1301                             p_itemType  => p_itemType
1302                            ,p_itemKey   => p_itemKey);
1303         --
1304 
1305            -- In case of a txn send to approval and try to update we get null from
1306            -- get_notified_activity(p_itemType,p_itemKey), as it is a HR Block Activity
1307            -- and we r searching for Page Activities with FORM as value.
1308            -- We are calling overloaded call to get the blocked activity.
1309            if(l_activityId is null ) then
1310 		l_activityId := get_notified_activity(
1311                                         p_itemType => p_itemType,
1312                                         p_itemKey  => p_itemKey,
1313                                         p_ntfId => null);
1314            end if;
1315 
1316 
1317         -- Notified activity which must be completed to
1318         -- go the first page of the transaction and fetch it's activity id.
1319            if(l_activityId is not null) then
1320             complete_wf_activity (
1321                     p_itemType      => p_itemType,
1322                     p_itemKey       => p_itemKey,
1323                     p_activity      => l_activityId,
1324                     p_otherAct      => 'THIS',
1325                     p_resultCode    => 'REDO' );
1326            end if;
1327         --
1328         -- END IF;
1329   --
1330   END IF;
1331 
1332     -- **********************************************
1333     -- Update transaction state : START
1334     IF (p_state = 'W' ) THEN
1335        if (p_revertFlag = 'Y' ) then
1336             l_newState := 'T' ;  -- not null because on edit state is transient.
1337        else
1338             l_newState := p_state;
1339        end if;
1340     ELSE -- (if p_state is null or p_state = 'T')
1341       l_newState := 'T';
1342     END IF;
1343     --
1344     IF (p_state = 'W' AND p_revertFlag = 'Y' ) THEN
1345         --
1346        -- update_txn_current_values(p_txnId );
1347        -- cancel the user previous action and revert the data to
1348        -- previous good state
1349        hr_trans_history_api.cancel_action(p_txnId);
1350         --
1351     elsIF ( l_newState <> NVL(p_state,'**') ) THEN
1352       --
1353       -- update only if no revert is made
1354       hr_transaction_api.update_transaction(
1355                p_transaction_id    => p_txnId,
1356                p_status            => p_status,
1357                p_transaction_state => l_newState );
1358     END IF;
1359 
1360 
1361     -- Update transaction status : END
1362     -- **********************************************
1363 --
1364 --COMMIT;
1365 
1366   --
1367   EXCEPTION
1368       WHEN OTHERS THEN
1369            hr_utility.trace(' exception in  '||g_package||'.revert_to_last_save : ' || sqlerrm);
1370            raise;
1371   --
1372   END revert_to_last_save;
1373 
1374 
1375 /* ******************************************************
1376   -- Get Transaction Information
1377   -- This procedure is called from CompleteWorkflowCO, called when Edit
1378   -- link/button is pressed on the notification
1379   -- It should set appropriate Transient transaction status.
1380   ******************************************************* */
1381 PROCEDURE get_url_for_edit (
1382     p_itemType      IN VARCHAR2
1383    ,p_itemKey       IN VARCHAR2
1384    ,p_activityId   OUT NOCOPY VARCHAR2
1385    ,p_functionName OUT NOCOPY VARCHAR2
1386    ,p_url          OUT NOCOPY VARCHAR2 ) IS
1387 --
1388 l_applicationId NUMBER;
1389 l_regionCode    VARCHAR2(30);
1390 l_newState      VARCHAR2(5);
1391 l_activityLabel VARCHAR2(240);
1392 --l_savedStatus   BOOLEAN   := INSTR(p_status,'S') > 0;
1393 --
1394 BEGIN
1395   --
1396     -- fetch the current activity, from which the url will be built.
1397 /*
1398     p_activityId    := get_notified_activity(
1399                         p_itemType  => p_itemType
1400                        ,p_itemKey   => p_itemKey
1401                        ,p_ntfId     => null);
1402 */
1403     p_activityId    := get_notified_activity(
1404                         p_itemType  => p_itemType
1405                        ,p_itemKey   => p_itemKey);
1406     -- If attribute is not found, means the transaction was submitted and thus current activity is BLOCK
1407     -- Complete this activity with RESULT=REDO and fetch the attribute value from the current activity.
1408     l_regionCode    :=  wf_engine.GetActivityAttrText(
1409                             itemtype    => p_itemType
1410                            ,itemkey     => p_itemKey
1411                            ,actid       => p_activityId
1412                            ,aname       => 'HR_ACTIVITY_TYPE_VALUE' );
1413           --
1414     DECLARE
1415          activity_attr_doesnot_exist exception;
1416          pragma exception_init(activity_attr_doesnot_exist, -20002);
1417     BEGIN
1418        l_applicationId :=  wf_engine.GetActivityAttrText(
1419                             itemtype    => p_itemType
1420                            ,itemkey     => p_itemKey
1421                            ,actid       => p_activityId
1422                            ,aname       => 'APPLICATION_ID' );
1423        IF l_applicationId IS NULL THEN
1424             l_applicationId := '800';
1425        END IF;
1426     EXCEPTION
1427        WHEN activity_attr_doesnot_exist THEN  -- if APPLICATION_ID is not defined for the jsp page, set it to 800 by default
1428              l_applicationId := '800';
1429          WHEN OTHERS THEN
1430              raise;
1431     END;
1432 --
1433     p_functionName   :=  wf_engine.GetItemAttrText(
1434                             itemtype    => p_itemType
1435                            ,itemkey     => p_itemKey
1436                            ,aname       => 'P_CALLED_FROM');
1437 --
1438     p_url  := 'OA.jsp?akRegionApplicationId='||l_applicationId||'&akRegionCode='||l_regionCode||'&retainAM=Y&OAFunc='||p_functionName;
1439 --
1440   --
1441   EXCEPTION
1442       WHEN OTHERS THEN
1443           hr_utility.trace(' exception in  '||g_package||'.get_url_for_edit : ' || sqlerrm);
1444           raise;
1445   --
1446 END get_url_for_edit;
1447 --
1448 --
1449 /* **************************************************************
1450   -- Set transaction Status
1451   --
1452   *************************************************************** */
1453 
1454 PROCEDURE set_transaction_status (
1455       p_itemtype         IN     VARCHAR2,
1456       p_itemkey          IN     VARCHAR2,
1457       p_activityId       IN     VARCHAR2 DEFAULT NULL,
1458       p_action           IN     VARCHAR2,
1459       p_result           OUT NOCOPY    VARCHAR2 )  IS
1460 --
1461 --Pragma Autonomous_Transaction;
1462 
1463 l_ReturnToUser  VARCHAR2(340);
1464 l_CreatorUser   VARCHAR2(340);
1465 l_transactionId NUMBER;
1466 l_status        VARCHAR2(10);
1467 l_state         VARCHAR2(5);
1468 l_newState      VARCHAR2(5);
1469 l_newStatus      VARCHAR2(10);
1470 --
1471 l_activity_id   NUMBER; -- -- added for bug 12561019
1472    CURSOR cur_txn_status IS
1473    SELECT   transaction_id, status, transaction_state
1474    FROM     hr_api_transactions
1475    WHERE    item_type   = p_itemType
1476    AND      item_key    = p_itemKey;
1477    --
1478 BEGIN
1479 --
1480  l_activity_id := to_number(p_activityId); -- added for bug 12561019
1481    IF ( cur_txn_status%ISOPEN ) THEN
1482       CLOSE cur_txn_status;
1483    END IF;
1484        --
1485    OPEN  cur_txn_status;
1486    FETCH cur_txn_status INTO l_transactionId, l_status, l_state;
1487    CLOSE cur_txn_status;
1488    --
1489    -- fix for bug 4886788
1490    -- need to close sfl ntf with new SFL model by default.
1491     IF l_transactionId is not null THEN
1492       hr_sflutil_ss.closeopensflnotification(l_transactionId);
1493    END IF;
1494 
1495    IF (p_action = 'SFL') THEN
1496       -- If saving Supervisor page, then put add value history with step_id =0, no approval_history record
1497 
1498       IF l_transactionId is null THEN
1499  	p_result := 'COMPLETE:SUCCESS';
1500         RETURN;
1501       END IF;
1502 
1503       -- Copy current values to previous values so they can be used to revert later (if needed)
1504       /* update_txn_previous_values (l_transactionId); */ -- ##history
1505       --
1506       -- Update original value in history table (LATEST_ORIGINAL_VALUE) -- ##history
1507       /* PQH_SS_HISTORY.track_original_value
1508         ( p_ItemType        => p_itemType
1509         , p_itemKey         => p_itemKey
1510         , p_action          => 'SFL'
1511         , p_username        => null
1512         , p_transactionId   => l_transactionId); */
1513       --
1514       l_newState   := null; -- New state will be null.
1515       IF ( l_status IN ('W','C','N','S')) THEN
1516            l_newStatus := 'S';
1517       ELSIF ( INSTR(l_status,'S') > 0 ) THEN -- If already saved txn then no change in status
1518            l_newStatus := l_status;
1519       ELSE
1520            l_newStatus := l_status||'S';
1521       END IF;
1522 
1523 
1524 
1525      hr_transaction_api.update_transaction(
1526                p_transaction_id    => l_transactionId,
1527                p_status            => l_newStatus,
1528                p_transaction_state => l_newState );
1529 
1530       hr_trans_history_api.archive_sfl(l_transactionId
1531                                        ,null
1532                                        ,FND_GLOBAL.user_name);
1533 
1534 
1535       --
1536       IF (l_status in ('Y','RI','RO')) THEN
1537          l_newStatus := wf_engine.eng_null;
1538       ELSE
1539          l_newStatus := 'SFL';
1540       END IF;
1541       complete_wf_activity (
1542                	p_itemType    => p_itemType
1543                ,p_itemKey     => p_itemKey
1544                ,p_activity    => l_activity_id -- added for bug 12561019
1545                ,p_otherAct    => 'OTHER'
1546                ,p_resultCode  => l_newStatus);
1547       --
1548    ELSE
1549    -- Get new Transaction Status
1550    IF (p_action  = 'SUBMIT' ) THEN
1551       -- Copy current values to previous values so they can be used to revert later (if needed)
1552    --   update_txn_previous_values (l_transactionId); -- ##history
1553 
1554 
1555 
1556       --
1557       l_newState   := null; -- New state will be null.
1558       -- If transaction submitted or Edited and Submitted then set to Y
1559       l_newStatus := 'Y';
1560        hr_transaction_api.update_transaction(
1561                p_transaction_id    => l_transactionId,
1562                p_status            => l_newStatus,
1563                p_transaction_state => l_newState );
1564 
1565        -- Note:- Initial submit archive is handled in the flow
1566        -- need to handle archive of resubmit
1567        if(l_status not in ('W','S')) then
1568           -- approver edit or rfc edit submit case
1569         hr_trans_history_api.archive_resubmit(l_transactionId,
1570                                                  null,
1571                                                  fnd_global.user_name,
1572                                                  wf_engine.getitemattrtext(p_itemType,
1573                                                                       p_itemKey,
1574                                                                       'APPROVAL_COMMENT_COPY')
1575                                                 );
1576 
1577          end if;
1578 
1579    ELSIF (p_action = 'APPROVE') THEN
1580        l_newStatus  := 'Y';
1581        l_newState   := null;
1582 
1583               hr_transaction_api.update_transaction(
1584                p_transaction_id    => l_transactionId,
1585                p_status            => l_newStatus,
1586                p_transaction_state => l_newState );
1587 
1588        --
1589        --
1590        hr_trans_history_api.archive_approve(l_transactionId,
1591                                             null,
1592                                             fnd_global.user_name,
1593                                             null); -- comments ??
1594 
1595 
1596        IF ( l_state IN ('T','W') ) THEN -- REDO only if transient or WIP
1597           IF (l_state = 'W') THEN
1598           -- ##history
1599             /*update_txn_current_values( l_transactionId );
1600             --
1601             reset_original_values (
1602                p_itemType  => p_itemType
1603               ,p_itemKey   => p_itemKey
1604               ,p_txnId     => l_transactionId);*/
1605               null;
1606             --
1607           END IF;
1608           complete_wf_activity (
1609             p_itemType    => p_itemType
1610            ,p_itemKey     => p_itemKey
1611            ,p_activity    => l_activity_id -- added for bug 12561019  -- not used because current act is fetched
1612            ,p_otherAct    => 'CURR'
1613            ,p_commitFlag  => 'Y'
1614            ,p_resultCode  => 'REDO' );
1615         --
1616        END IF;
1617        --
1618    ELSIF (p_action = 'RFC' ) THEN
1619        -- Fetch the Return to Username and Creator User Name from WF
1620        BEGIN
1621        l_ReturnToUser   :=
1622               wf_engine.GetItemAttrText(
1623                   itemtype => p_itemType,
1624                   itemkey  => p_itemKey,
1625                   aname    => 'RETURN_TO_USERNAME');
1626        EXCEPTION
1627          WHEN OTHERS THEN -- if attributes are not found then don't do anything
1628              null;
1629        END;
1630 
1631        IF (l_ReturnToUSer IS NULL ) THEN
1632             --For customized processes still using the old approval process
1633             --the status is set to C, so that they are listed in
1634             --in pending actions table.
1635             l_newStatus := 'C';
1636             -- Bug 3031918: TRAN_SUBMIT need to be set to C for v4 processes
1637             -- on Return for Correction
1638             wf_engine.SetItemAttrText(
1639                     itemtype    => p_itemType,
1640                     itemkey     => p_itemKey,
1641                     aname       => 'TRAN_SUBMIT',
1642                     avalue      => l_newStatus );
1643 
1644        ELSE
1645            l_CreatorUser    :=
1646                wf_engine.GetItemAttrText(
1647                   itemtype => p_itemType,
1648                   itemkey  => p_itemKey,
1649                   aname    => 'CREATOR_PERSON_USERNAME');
1650        --
1651            IF (l_ReturnToUSer = l_CreatorUser ) THEN -- Return for correction to initiator
1652             l_newStatus := 'RI';
1653            ELSE -- Returned for Correction to other manager
1654             l_newStatus := 'RO';
1655            END IF;
1656        END IF;
1657            l_newState  := null; -- no change to state.
1658             hr_transaction_api.update_transaction(
1659                p_transaction_id    => l_transactionId,
1660                p_status            => l_newStatus,
1661                p_transaction_state => l_newState );
1662           -- update the transaction state table too
1663          pqh_tsh_upd.upd(p_transaction_history_id=>l_transactionId,
1664                          p_approval_history_id=>hr_trans_history_api.gettransstatesequence(l_transactionId),
1665                          p_status=>l_newStatus,
1666                          p_transaction_state=>l_newState);
1667 
1668    END IF;
1669    --
1670     /*hr_transaction_api.update_transaction(
1671                p_transaction_id    => l_transactionId,
1672                p_status            => l_newStatus,
1673                p_transaction_state => l_newState );*/
1674    wf_engine.SetItemAttrText(
1675                     itemtype    => p_itemType,
1676                     itemkey     => p_itemKey,
1677                     aname       => 'TRAN_SUBMIT',
1678                     avalue      => l_newStatus );
1679    --
1680    END IF;
1681    p_result := 'COMPLETE:SUCCESS';
1682 --
1683   --
1684   EXCEPTION
1685       WHEN OTHERS THEN
1686           hr_utility.trace(' exception in  '||g_package||'.set_transaction_status : ' || sqlerrm);
1687           raise;
1688   --
1689 END set_transaction_status;
1690 
1691 --
1692 --
1693 -- Bug 3018784: This procedure is nullified in ver115.34 (hrssa.wft must be 115.196 and above)
1694 -- as it is no longer called from the workflow process.
1695 PROCEDURE set_txn_submit_status (
1696       itemtype        IN     VARCHAR2,
1697       itemkey         IN     VARCHAR2,
1698       actid           IN     NUMBER,
1699       funcmode        IN     VARCHAR2,
1700       result          OUT NOCOPY    VARCHAR2 ) IS
1701 --
1702 BEGIN
1703 --
1704    result := 'COMPLETE:SUCCESS';
1705 --
1706 END set_txn_submit_status;
1707 --
1708 --
1709 PROCEDURE set_txn_approve_status (
1710       itemtype        IN     VARCHAR2,
1711       itemkey         IN     VARCHAR2,
1712       actid           IN     NUMBER,
1713       funcmode        IN     VARCHAR2,
1714       result          OUT NOCOPY    VARCHAR2 ) IS
1715 --
1716 BEGIN
1717 --
1718   IF (funcmode = wf_engine.eng_run) THEN
1719   --
1720      set_transaction_status (
1721         p_itemType  => itemType
1722        ,p_itemKey   => itemKey
1723        ,p_action    => 'APPROVE'
1724        ,p_result    => result );
1725   --
1726   END IF;
1727 --
1728   --
1729   EXCEPTION
1730       WHEN OTHERS THEN
1731           hr_utility.trace(' exception in  '||g_package||'.set_txn_approve_status : ' || sqlerrm);
1732           Wf_Core.Context(g_package, 'set_txn_approve_status', itemType, itemKey);
1733           raise;
1734   --
1735 END set_txn_approve_status;
1736 --
1737 --
1738 PROCEDURE set_txn_rfc_status (
1739       itemtype        IN     VARCHAR2,
1740       itemkey         IN     VARCHAR2,
1741       actid           IN     NUMBER,
1742       funcmode        IN     VARCHAR2,
1743       result          OUT NOCOPY    VARCHAR2 ) IS
1744 --
1745 BEGIN
1746 --
1747   IF (funcmode = wf_engine.eng_run) THEN
1748   --
1749      set_transaction_status (
1750         p_itemType  => itemType
1751        ,p_itemKey   => itemKey
1752        ,p_action    => 'RFC'
1753        ,p_result    => result );
1754   --
1755   END IF;
1756 
1757 EXCEPTION
1758    WHEN OTHERS THEN
1759           hr_utility.trace(' exception in  '||g_package||'.set_txn_rfc_status : ' || sqlerrm);
1760           Wf_Core.Context(g_package, 'set_txn_rfc_status', itemType, itemKey);
1761           raise;
1762 --
1763 END set_txn_rfc_status;
1764 --
1765 PROCEDURE set_txn_sfl_status (
1766       itemtype        IN     VARCHAR2,
1767       itemkey         IN     VARCHAR2,
1768       actid           IN     NUMBER,
1769       funcmode        IN     VARCHAR2,
1770       result          OUT NOCOPY    VARCHAR2 ) IS
1771 --
1772 BEGIN
1773 --
1774   IF (funcmode = wf_engine.eng_run) THEN
1775   --
1776   /* Fix for bug# 3389563
1777      The calls will be part of Java calls.
1778      This procedure should not be invoked from with in any Workflow process.
1779      set_transaction_status (
1780         p_itemType  => itemType
1781        ,p_itemKey   => itemKey
1782        ,p_activityId=> actId
1783        ,p_action    => 'SFL'
1784        ,p_result    => result );
1785   */
1786    result:= wf_engine.eng_trans_default;
1787   --
1788   END IF;
1789 
1790 EXCEPTION
1791    WHEN OTHERS THEN
1792           hr_utility.trace(' exception in  '||g_package||'.set_txn_sfl_status : ' || sqlerrm);
1793           Wf_Core.Context(g_package, 'set_txn_sfl_status', itemType, itemKey);
1794           raise;
1795 END set_txn_sfl_status;
1796 --
1797 
1798 --
1799 -- This procedure sets the effective date and date option in transaction table
1800 -- as well as the transaction_values table.
1801 PROCEDURE  set_effective_date_and_option (
1802            p_txnId               IN VARCHAR2
1803           ,p_effectiveDate       IN DATE
1804           ,p_effectiveDateOption IN VARCHAR2 ) IS
1805 --
1806   CURSOR cur_asgn IS
1807   SELECT api_name,transaction_step_id
1808   FROM   hr_api_transaction_steps
1809   WHERE  transaction_id       = p_txnId;
1810 --
1811 --  AND    api_name             = 'HR_PROCESS_ASSIGNMENT_SS.PROCESS_API';
1812   --
1813   l_txnStepId      NUMBER(15);
1814   l_apiName        VARCHAR2(300);
1815   l_effectiveDate  DATE   := p_effectiveDate;
1816 BEGIN
1817 --
1818     IF ( NVL(p_effectiveDateOption,'E') = 'A') THEN
1819          l_effectiveDate  := sysdate;
1820     END IF;
1821 
1822     HR_TRANSACTION_API.update_transaction (
1823          p_transaction_id               => p_txnId
1824         ,p_transaction_effective_date   => l_effectiveDate
1825         ,p_effective_date_option        => NVL(p_effectiveDateOption,'E')  );
1826 --
1827 
1828     FOR  I IN cur_asgn
1829     LOOP
1830        IF (I.api_name = 'HR_SUPERVISOR_SS.PROCESS_API' ) THEN
1831          HR_TRANSACTION_API.set_date_value (
1832             p_transaction_step_id => I.transaction_step_id
1833            ,p_person_id           => null
1834            ,p_name                => 'P_PASSED_EFFECTIVE_DATE'
1835            ,p_value               => l_effectiveDate );
1836 
1837 /*
1838          -- ====================================================================
1839          -- Also set the effective dates to system date if date option is
1840          -- as of approval for following attributes
1841          -- P_PASSED_EFFECTIVE_DATE : for selected person's reassign date
1842          -- P_EFFECTIVE_DATE_<n>    : for reassigned employees (n is 1,2,3..)
1843          -- P_EMP_DATE_<n>          : for newly assigned employees(n is 1,2,3..)
1844          -- P_SINGLE_EFFECTIVE_DATE : ????
1845          -- Note: Termination step may also have to be added in case the
1846          -- Notification date is to be set to as of approval date
1847          -- ====================================================================
1848          IF ( NVL(p_effectiveDateOption,'E') = 'A' ) THEN
1849            UPDATE  hr_api_transaction_values
1850            SET     date_value          = l_effectiveDate
1851            WHERE   transaction_step_id = I.transaction_step_id
1852            AND     name             like 'P%DATE%';
1853          END IF;
1854          --
1855 */
1856        ELSE
1857     --
1858     --
1859       HR_TRANSACTION_API.set_date_value (
1860          p_transaction_step_id => I.transaction_step_id
1861         ,p_person_id           => null -- used to validate, no other usage
1862         ,p_name                => 'P_EFFECTIVE_DATE'
1863         ,p_value               => p_effectiveDate );
1864    --
1865       HR_TRANSACTION_API.set_varchar2_value (
1866          p_transaction_step_id => I.transaction_step_id
1867         ,p_person_id           => null -- used to validate, no other usage
1868         ,p_name                => 'P_EFFECTIVE_DATE_OPTION'
1869         ,p_value               => NVL(p_effectiveDateOption,'E') );
1870 
1871       END IF;
1872     END LOOP;
1873    --
1874    --
1875   EXCEPTION
1876       WHEN OTHERS THEN
1877           hr_utility.trace(' exception in  '||g_package||'.set_effective_date_and_option : ' || sqlerrm);
1878           raise;
1879   --
1880 END set_effective_date_and_option;
1881 --
1882 --
1883 -- Called from Workflow Cancel Activity
1884 PROCEDURE reset_txn_current_values (
1885       itemtype        IN     VARCHAR2,
1886       itemkey         IN     VARCHAR2,
1887       actid           IN     NUMBER,
1888       funcmode        IN     VARCHAR2,
1889       result          OUT NOCOPY    VARCHAR2 )  IS
1890 --
1891       l_transactionId   NUMBER(15);
1892       l_ntfId           NUMBER(15);
1893       l_activityLabel   VARCHAR2(240);
1894       l_status          VARCHAR2(10);
1895       l_step_id         NUMBER(15);
1896 --
1897 --      CURSOR cur_status IS
1898 --      SELECT  status
1899 --      FROM    hr_api_transactions
1900 --      WHERE   transaction_id  = l_transactionId;
1901 BEGIN
1902   IF (funcmode <> wf_engine.eng_run) THEN
1903     result := wf_engine.eng_null;
1904     RETURN;
1905   END IF;
1906 
1907   l_transactionId  :=  get_transaction_id (
1908                    p_itemType   => itemType
1909                   ,p_itemKey    => itemKey );
1910 
1911 --   if transactionid is null, nothing is saved yet
1912 --   no action needed, just complete the current workflow activity.
1913   IF (l_transactionId IS NOT null ) THEN
1914      l_ntfId    := get_notification_id(
1915                         p_itemType  => itemType
1916                        ,p_itemKey   => itemKey);
1917 
1918 
1919    -- need to check status too
1920     begin
1921        select status into l_status
1922        from hr_api_transactions
1923        where transaction_id=l_transactionId;
1924     exception
1925      when others then
1926       null;
1927     end;
1928    --
1929 
1930  --  Remove transaction if it's a new one, else revert back to previous values
1931      IF ( l_ntfId IS NULL and l_status='W' ) THEN
1932         hr_transaction_api.rollback_transaction
1933                  (p_transaction_id => l_transactionId  );
1934 
1935 	--3099089 change starts
1936         --need to remove transaction_id from wf_item_attribute_values also
1937         wf_engine.setitemattrnumber
1938         (itemtype => itemtype
1939         ,itemkey  => itemkey
1940         ,aname    => 'TRANSACTION_ID'
1941         ,avalue   => null);
1942 	--3099089 change ends
1943 
1944         result := 'COMPLETE:CANCELLED';
1945         RETURN;
1946      ELSE
1947 --        IF ( cur_status%ISOPEN ) THEN
1948 --           CLOSE cur_status;
1949 --        END IF;
1950        --
1951 --        OPEN  cur_status;
1952 --        FETCH cur_status INTO l_status;
1953 --        CLOSE cur_status;
1954 
1955 
1956         -- add new call to archive api to revert to last save
1957         hr_trans_history_api.cancel_action(l_transactionId);
1958         --
1959         --
1960         --vegopala fix for bug 5436747.Commenting as it is not
1961         -- reqd to set to T.
1962         -- Set the state to T once the activities are completed.
1963         --
1964        /*  hr_transaction_api.update_transaction (
1965                p_transaction_id     => l_transactionId
1966               ,p_transaction_state  => 'T' );
1967         */
1968         --
1969         result := 'COMPLETE:ACCEPTED';
1970         RETURN;
1971       END IF; -- notification not null
1972    END IF;      -- txn not null
1973    -- default result
1974    result := 'COMPLETE:CANCELLED';
1975    --
1976    --
1977   --
1978   EXCEPTION
1979       WHEN OTHERS THEN
1980           hr_utility.trace(' exception in  '||g_package||'.reset_txn_current_values : ' || sqlerrm);
1981           Wf_Core.Context(g_package, 'reset_txn_current_values', itemType, itemKey);
1982           raise;
1983   --
1984 END reset_txn_current_values;
1985 
1986 
1987 --
1988 --
1989 PROCEDURE check_initial_save_for_later (
1990       itemtype        IN     VARCHAR2,
1991       itemkey         IN     VARCHAR2,
1992       actid           IN     NUMBER,
1993       funcmode        IN     VARCHAR2,
1994       result          OUT NOCOPY    VARCHAR2 ) IS
1995    --
1996    -- ItemType aNd ItemKey are for the approval wf process
1997     CURSOR cur_txn IS
1998     SELECT NVL(status,'N')
1999     FROM   hr_api_transactions
2000     WHERE  item_type  = itemType
2001     AND    item_key   = itemKey;
2002     l_status   VARCHAR2(10);
2003 --
2004     BEGIN
2005 --
2006        IF (funcmode = wf_engine.eng_run ) THEN
2007 
2008 /*
2009 07-May-2003 ns moved to approval_block
2010           -- Set the Approval process version to distinguish it
2011           -- it from old approval process.
2012 	     wf_engine.SetItemAttrText(
2013 		 itemtype => itemType
2014 	       , itemkey  => itemKey
2015 	       , aname    => 'HR_APPROVAL_PRC_VERSION'
2016 	       , avalue   => 'V5' );
2017 	       --
2018 */
2019            IF ( cur_txn%ISOPEN ) THEN
2020               CLOSE cur_txn;
2021            END IF;
2022            --
2023            OPEN  cur_txn;
2024            FETCH cur_txn INTO l_status;
2025            CLOSE cur_txn;
2026 --
2027            IF l_status in ('S') THEN -- Saved for Later (not yet Submitted)
2028             result := 'COMPLETE:T';
2029            ELSE
2030             result := 'COMPLETE:F';
2031            END IF;
2032 --
2033        END IF;
2034 --
2035   --
2036   EXCEPTION
2037       WHEN OTHERS THEN
2038           hr_utility.trace(' exception in  '||g_package||'.check_initial_save_for_later : ' || sqlerrm);
2039           Wf_Core.Context(g_package, 'check_initial_save_for_later', itemType, itemKey);
2040           raise;
2041   --
2042     END check_initial_save_for_later;
2043 --
2044 --
2045 /* Return_For_Correction to the user passed by the calling method returnForCorrection
2046  * in ReturnForCorrectionAMImpl
2047  * Parameters:
2048  * p_userName - Used to set FROM_ROLE attribute of the notification
2049  * p_userDisplayName - Used in FYI notification send to initiator when RFC to
2050  *                     other than Initiator
2051  * p_approverIndex - Selected users index in the approval chain, to set wf attribute
2052  * p_txnId - To fetch last default approver before the approver who is performing RFC
2053  */
2054   PROCEDURE return_for_correction (
2055        p_itemType        IN VARCHAR2
2056      , p_itemKey         IN VARCHAR2
2057      , p_userId          IN VARCHAR2  -- NOTE: not really userid, it is the personId
2058      , p_userName        IN VARCHAR2
2059      , p_userDisplayName IN VARCHAR2
2060      , p_ntfId           IN VARCHAR2
2061      , p_note            IN VARCHAR2
2062      , p_approverIndex   IN NUMBER
2063      , p_txnId           IN VARCHAR2) IS
2064 --
2065   l_activity    NUMBER;
2066   l_itemType    VARCHAR2(30);
2067   l_itemKey     VARCHAR2(30);
2068   l_userName    FND_USER.user_name%Type;
2069   l_ntfId       NUMBER;
2070   l_lastDefaultApprover NUMBER;
2071   dummy  varchar2(10);
2072 
2073 -- Cursor to find if the person (selected for RFC) is an additional approver
2074    CURSOR cur_add_appr IS
2075    SELECT 'X'
2076      FROM wf_item_attribute_values
2077     WHERE item_type = p_itemType
2078       AND item_key  = p_itemKey
2079       AND name      like 'ADDITIONAL_APPROVER_%'
2080       AND number_value = p_userId;
2081 --
2082 -- Cursor to fetch the last default approver below the person performing
2083 -- RFC. It is used only in case of NON-AME approvals.
2084 --
2085   CURSOR  cur_appr  IS
2086   SELECT pth.employee_id
2087     FROM pqh_ss_approval_history pah,
2088          fnd_user pth
2089    WHERE pah.user_name = pth.user_name
2090      AND pah.transaction_history_id = p_txnId
2091      AND approval_history_id = (
2092       SELECT MAX(approval_history_id)
2093         FROM pqh_ss_approval_history  pah1,
2094              fnd_user pth1
2095        WHERE pah1.user_name = pth1.user_name
2096          AND pah1.transaction_history_id = pah.transaction_history_id
2097          AND pth1.employee_id IN (
2098            SELECT pth2.employee_id --, pth2.user_name, approval_history_id
2099              FROM pqh_ss_approval_history pah2,
2100                   fnd_user                pth2
2101             WHERE pah2.user_name = pth2.user_name
2102               AND pah2.transaction_history_id = pah.transaction_history_id
2103               AND approval_history_id < (
2104                SELECT MIN(approval_history_id)
2105                  FROM pqh_ss_approval_history
2106                 WHERE transaction_history_id = pah.transaction_history_id
2107                   AND user_name = p_userName
2108                   AND approval_history_id > 0
2109                )
2110            and approval_history_id > 0
2111            MINUS
2112            SELECT number_value
2113              FROM wf_item_attribute_values
2114             WHERE item_type = p_itemType
2115               AND item_key  = p_itemKey
2116               AND name      like 'ADDITIONAL_APPROVER_%'
2117       )
2118     );
2119 --
2120   BEGIN
2121 --
2122      Rollback; -- Needed in case of New Hire and CWK to that the changes are not committed.
2123 
2124    -- fix for bug 4454439
2125     begin
2126       -- re-intialize the performer roles
2127       hr_approval_ss.reinitperformerroles(p_notification_id=>null
2128                                           ,p_transaction_id=>null
2129                                           ,p_item_type=>p_itemType
2130                                           ,p_item_key=>p_itemKey);
2131     exception
2132     when others then
2133       null;
2134     end;
2135 
2136      IF ( p_itemType IS NULL OR p_itemKey IS NULL OR p_userName IS NULL ) THEN
2137           get_item_type_and_key (
2138                 p_ntfId    => p_ntfId
2139                ,p_itemType => l_itemType
2140                ,p_itemKey  => l_itemKey );
2141 
2142 	  -- fix for bug 4454439
2143     begin
2144       -- re-intialize the performer roles
2145       hr_approval_ss.reinitperformerroles(p_notification_id=>null
2146                                           ,p_transaction_id=>null
2147                                           ,p_item_type=>l_itemType
2148                                           ,p_item_key=>l_itemKey);
2149     exception
2150     when others then
2151       null;
2152     end;
2153 
2154 
2155           l_userName  :=  wf_engine.GetItemAttrText(
2156                              itemtype => l_itemType
2157                            , itemkey  => l_itemKey
2158                            , aname    => 'CREATOR_PERSON_USERNAME');
2159      ELSE
2160            l_itemType   := p_itemType;
2161            l_itemKey    := p_itemKey;
2162            --l_userName   := p_userName; -- fix for bug 4481775
2163            if(p_userId is not null) then
2164              select user_name
2165              into l_userName
2166              from  fnd_user
2167              where employee_id=p_userId;
2168             end if;
2169 
2170      END IF;
2171 
2172      -- Set the item attribute for the return to user name.
2173      wf_engine.SetItemAttrText(
2174          itemtype => l_itemType
2175        , itemkey  => l_itemKey
2176        , aname    => 'RETURN_TO_USERNAME'
2177        , avalue   => l_userName );
2178      --
2179      hr_approval_wf.create_item_attrib_if_notexist(
2180          p_item_type  => l_itemtype
2181         ,p_item_key   => l_itemkey
2182         ,p_name       => 'RETURN_TO_PERSON_DISPLAY_NAME');
2183 
2184      wf_engine.SetItemAttrText(
2185          itemtype => l_itemType
2186        , itemkey  => l_itemKey
2187        , aname    => 'RETURN_TO_PERSON_DISPLAY_NAME'
2188        , avalue   => p_userDisplayName );
2189      --
2190      -- Fetch the activity id of notification to be completed
2191      l_activity   := get_notified_activity(
2192                         p_itemType      => l_itemType
2193                        ,p_itemKey       => l_itemKey
2194                        ,p_ntfId         => p_ntfId );
2195      --
2196      -- Set the notes for RFC notification.
2197        wf_engine.setItemAttrText (
2198             itemtype => l_itemType
2199            ,itemkey  => l_itemKey
2200            ,aname    => 'NOTE_FROM_APPR'
2201            ,avalue   => p_note );
2202 
2203        wf_engine.setItemAttrText (
2204             itemtype => l_itemType
2205            ,itemkey  => l_itemKey
2206            ,aname    => 'WF_NOTE'
2207            ,avalue   => NULL );
2208 
2209 
2210        wf_notification.setattrtext(
2211        			p_ntfId
2212        		       ,'RESULT'
2213        		       ,'RETURNEDFORCORRECTION');
2214        BEGIN
2215            wf_notification.setattrtext(
2216        			p_ntfId
2217        		       ,'WF_NOTE'
2218        		       ,p_note);
2219         EXCEPTION WHEN OTHERS THEN
2220            -- RFC from SFL Other
2221            wf_notification.propagatehistory(
2222                                l_itemType
2223                               ,l_itemKey
2224                               ,'APPROVAL_NOTIFICATION'
2225                               ,fnd_global.user_name
2226                               ,l_userName
2227                               ,'RETURNEDFORCORRECTION'
2228                               ,null
2229                               ,p_note);
2230        END;
2231 
2232      -- Send Notification
2233 
2234       wf_notification.respond(
2235       			p_ntfId
2236       		       ,null
2237       		       ,fnd_global.user_name
2238       		       ,null);
2239 
2240      -- Fetch the id for RFC notification.
2241      l_ntfId    := get_notification_id(
2242                         p_itemType  => l_itemType
2243                        ,p_itemKey   => l_itemKey);
2244 
2245 
2246      -- Set the from attribute for RFC notification.
2247      wf_notification.setAttrText(
2248            nid           => l_ntfId
2249           ,aname         => '#FROM_ROLE'
2250           ,avalue        => fnd_global.user_name );
2251 
2252      -- Set the two workflow attributes for Non-AME approval process
2253      IF (wf_engine.GetItemAttrText(itemtype => l_itemType ,
2254                                    itemkey  => l_itemKey,
2255                                    aname    => 'HR_AME_TRAN_TYPE_ATTR') IS NULL) THEN
2256        -- CURRENT_APPROVER_INDEX
2257        begin
2258        -- set the attribute value to null
2259         wf_engine.SetItemAttrNumber(
2260                  itemtype => l_itemType ,
2261                  itemkey  => l_itemKey,
2262                  aname    => 'CURRENT_APPROVER_INDEX',
2263                  avalue   => p_approverIndex);
2264        exception
2265         when others then null;
2266        end;
2267 
2268        -- Set LAST_DEFAULT_APPROVER
2269        begin
2270 
2271         --
2272         -- If the selected person (for RFC) is additional approver
2273         -- then fetch the last default approver from history
2274         -- else selected person is the last default approver
2275         IF ( cur_add_appr%ISOPEN ) THEN
2276               CLOSE cur_add_appr;
2277         END IF;
2278          --
2279         OPEN  cur_add_appr;
2280         FETCH cur_add_appr INTO dummy;
2281           if cur_add_appr%found then
2282              --
2283              IF ( cur_appr%ISOPEN ) THEN
2284               CLOSE cur_appr;
2285              END IF;
2286              --
2287              OPEN  cur_appr;
2288              FETCH cur_appr INTO l_lastDefaultApprover;
2289              CLOSE cur_appr;
2290              --
2291           else
2292               l_lastDefaultApprover := p_userId;
2293           end if;
2294 
2295         CLOSE cur_add_appr;
2296 
2297         IF ( l_lastDefaultApprover IS NOT NULL ) THEN
2298            wf_engine.SetItemAttrNumber(
2299                  itemtype => l_itemType ,
2300                  itemkey  => l_itemKey,
2301                  aname    => 'LAST_DEFAULT_APPROVER',
2302                  avalue   => l_lastDefaultApprover);
2303         END IF;
2304        exception
2305         when others then null;
2306        end;
2307      END IF; -- Non-AME approval
2308 
2309    --Commit is needed otherwise from role and notes will not appear for the notification.
2310    COMMIT;
2311   --
2312   EXCEPTION
2313       WHEN OTHERS THEN
2314           hr_utility.trace(' exception in  '||g_package||'.return_for_correction : ' || sqlerrm);
2315           raise;
2316   --
2317    END return_for_correction;
2318 --
2319 -- Local function to return the message_name for the notification
2320 FUNCTION get_message_attr_name(
2321       p_ntfId    in number
2322      ,p_itemType in varchar2) return varchar2 IS
2323   --
2324   CURSOR cur_ntf IS
2325   SELECT wma.display_name
2326   FROM   wf_notifications  wn, wf_message_attributes_vl  wma
2327   WHERE  wn.notification_id  = p_ntfId
2328   AND    wn.message_name     = wma.message_name
2329   AND    wma.message_type    = p_itemType
2330   AND    wma.name            = 'EDIT_TXN_URL';
2331  --
2332   l_messageAttr  varchar2(4000);
2333 BEGIN
2334  --
2335   IF ( cur_ntf%ISOPEN ) THEN
2336       CLOSE cur_ntf;
2337   END IF;
2338   --
2339   OPEN  cur_ntf;
2340   FETCH cur_ntf INTO l_messageAttr;
2341   CLOSE cur_ntf ;
2342  --
2343   RETURN l_messageAttr;
2344  --
2345 END get_message_attr_name;
2346 --
2347 --
2348 PROCEDURE get_edit_link(
2349       document_id   in     varchar2,
2350       display_type  in     varchar2,
2351       document      in out nocopy varchar2,
2352       document_type in out nocopy varchar2) IS
2353   --
2354   --
2355    l_profileValue   VARCHAR2(1);
2356 --   l_profileName    VARCHAR2(30);
2357    l_ntfId          NUMBER(15);
2358    l_itemType       VARCHAR2(30);
2359    l_itemKey        VARCHAR2(30);
2360 --   l_effectiveDate  VARCHAR2(20);
2361 --   l_personId       VARCHAR2(15);
2362 --   l_assignmentId   VARCHAR2(15);
2363    l_editUrl        VARCHAR2(400);
2364    l_urlLabel       VARCHAR2(80);
2365    l_checkProfile   VARCHAR2(10);
2366    l_status         VARCHAR2(10);
2367  --
2368    CURSOR cur_txn (c_itemType VARCHAR2, c_itemKey VARCHAR2) IS
2369    SELECT   -- to_char(NVL(transaction_effective_date,sysdate),g_date_format),
2370             -- assignment_id, selected_person_id,
2371             NVL(status,'N'), NVL(fnd_profile.value('PQH_ALLOW_APPROVER_TO_EDIT_TXN'),'N')
2372    FROM     hr_api_transactions
2373    WHERE    item_type   = c_itemType
2374    AND      item_key    = c_itemKey;
2375  --
2376  BEGIN
2377      document_type  := wf_notification.doc_html;
2378      l_ntfId        := document_id;
2379 
2380 --     l_ntfId        := SUBSTR(document_id,1,INSTR(document_id,':')-1);
2381 --     l_checkProfile := SUBSTR(document_id,INSTR(document_id,':')+1);
2382 
2383 --     IF (l_checkProfile = 'Y' ) THEN
2384 --         l_profileValue := NVL(fnd_profile.value(l_profileName),'N');
2385 --     END IF;
2386 
2387 --dbms_output.put_line('NtfId: '||l_ntfId);
2388 
2389         get_item_type_and_key (
2390                 p_ntfId    => l_ntfId
2391                ,p_itemType => l_itemType
2392                ,p_itemKey  => l_itemKey );
2393         --
2394 --dbms_output.put_line('itemType: '||l_itemType||'  itemKey: '||l_itemKey);
2395         IF ( cur_txn%ISOPEN ) THEN
2396           CLOSE cur_txn;
2397         END IF;
2398         --
2399         OPEN  cur_txn (l_itemType, l_itemKey);
2400         FETCH cur_txn INTO  l_status, l_profileValue;
2401 --        FETCH cur_txn INTO l_effectiveDate, l_assignmentId, l_personId, l_status, l_profileValue;
2402         CLOSE cur_txn;
2403         --
2404         --
2405      -- No need to check profile option (i.e. must render edit link)
2406      -- in following cases
2407      IF (INSTR(l_status,'S') > 0 OR l_status IN ('RI','N','C','W') ) THEN
2408          l_checkProfile := 'N';
2409      END IF;
2410 
2411      IF (l_checkProfile = 'N' OR l_profileValue ='Y' ) THEN
2412         l_urlLabel   := get_message_attr_name (
2413                          p_ntfId    => l_ntfId
2414                         ,p_itemType => l_itemType );
2415 
2416 
2417         l_editUrl    := '<a href='||g_OA_HTML||
2418            'OA.jsp?page=/oracle/apps/pqh/selfservice/common/webui/EffectiveDatePG&retainAM=Y&NtfId=&#NID>'||
2419                           l_urlLabel||'</a>';
2420         document :=
2421             '<tr><td> '||
2422             '<IMG SRC="'||g_OA_MEDIA||'afedit.gif"/>'||
2423             '</td><td>'||
2424               l_editUrl||
2425             '</td></tr> ';
2426 
2427      ELSE
2428         document := null;
2429      END IF;
2430   --
2431   EXCEPTION
2432       WHEN OTHERS THEN
2433           hr_utility.trace(' exception in  '||g_package||'.get_edit_link : ' || sqlerrm);
2434           raise;
2435   --
2436  END get_edit_link;
2437 --
2438 --
2439 -- This procedure will  check if the date option is A - As of final approval
2440 -- it will set the effective date to the system date.
2441 PROCEDURE set_date_if_as_of_approval (
2442       itemtype        IN     VARCHAR2,
2443       itemkey         IN     VARCHAR2,
2444       actid           IN     NUMBER,
2445       funcmode        IN     VARCHAR2,
2446       result          OUT NOCOPY    VARCHAR2 )  IS
2447 --
2448       CURSOR cur_txn IS
2449       SELECT transaction_id, NVL(effective_date_option,'X')
2450       FROM   hr_api_transactions
2451       WHERE  item_type     = itemType
2452       AND    item_key      = itemKey;
2453 --
2454    l_txnId         NUMBER(15);
2455    l_effDateOption VARCHAR2(10);
2456    l_effectiveDate DATE;
2457    --
2458 BEGIN
2459 --
2460       IF ( cur_txn%ISOPEN ) THEN
2461        CLOSE cur_txn;
2462       END IF;
2463       --
2464       OPEN  cur_txn;
2465       FETCH cur_txn INTO l_txnId, l_effDateOption;
2466       CLOSE cur_txn;
2467 
2468       IF ( l_effDateOption = 'A' ) THEN
2469            l_effectiveDate := sysdate;
2470 
2471            HR_TRANSACTION_API.update_transaction (
2472              p_transaction_id               => l_txnId
2473             ,p_transaction_effective_date   => l_effectiveDate );
2474            --
2475            wf_engine.setItemAttrText
2476                           (itemtype => itemType
2477                           ,itemkey  => itemKey
2478                           ,aname    => 'P_EFFECTIVE_DATE'
2479                           ,avalue   => TO_CHAR(l_effectiveDate,g_date_format) );
2480 -- Bug 4243314 starts.
2481            wf_engine.setItemAttrDate
2482                           (itemtype => itemType
2483                           ,itemkey  => itemKey
2484                           ,aname    => 'CURRENT_EFFECTIVE_DATE'
2485                           ,avalue   =>l_effectiveDate);
2486 -- Bug 4243314 ends.
2487            --
2488            --
2489            -- ==================================================================
2490            -- Bug 3044048: On final approval set sysdate as, As Of Approval Date
2491            -- If it is decided that reassigned and newly assigned reports are to
2492            -- have current date if as of approval is chosen, then use the where
2493            -- clause name like 'P%DATE%'.
2494            -- If it is decided that notified date must be as of approval then
2495            -- then add the where clause api_name = 'HR_TERMINATION_SS.PROCESS_API'
2496            -- ==================================================================
2497            UPDATE  hr_api_transaction_values
2498            SET     date_value          = l_effectiveDate
2499            WHERE   datatype            = 'DATE'
2500            AND     name                = 'P_PASSED_EFFECTIVE_DATE'
2501            AND     transaction_step_id = (
2502                    SELECT transaction_step_id
2503                    FROM   hr_api_transaction_steps
2504                    WHERE  transaction_id = l_txnId
2505                    AND    api_name       = 'HR_SUPERVISOR_SS.PROCESS_API' );
2506            --
2507       END IF;
2508       --
2509   --
2510   EXCEPTION
2511       WHEN OTHERS THEN
2512           hr_utility.trace(' exception in  '||g_package||'.set_date_if_as_of_approval : ' || sqlerrm);
2513           Wf_Core.Context(g_package, 'set_date_if_as_of_approval', itemType, itemKey);
2514           raise;
2515   --
2516 END set_date_if_as_of_approval;
2517 --
2518 FUNCTION add_message (
2519 	 p_message_type    IN VARCHAR2
2520         ,p_apps_short_name IN VARCHAR2
2521         ,p_message_name    IN VARCHAR2
2522         ,p_called_from     IN VARCHAR2
2523         ,p_addToPub        IN VARCHAR2 DEFAULT 'NO'
2524         ,p_token_name      IN VARCHAR2 DEFAULT NULL
2525         ,p_token_value     IN VARCHAR2 DEFAULT NULL) RETURN VARCHAR2 IS
2526 --
2527 l_message   VARCHAR2(4000);
2528 l_text      VARCHAR2(8000);
2529 l_icon	    VARCHAR2(40);
2530 l_css       VARCHAR2(40);
2531 ln_app_id   fnd_application.application_id%type;
2532 cursor c1  is
2533      select fa.application_id
2534      from   fnd_application  fa
2535      where  fa.application_short_name = p_apps_short_name ;
2536 
2537 BEGIN
2538 --
2539      fnd_message.set_name(p_apps_short_name,p_message_name);
2540 --     l_message  := fnd_message.get_string(p_apps_short_name,p_message_name);
2541      IF (p_token_name IS NOT NULL AND p_token_value IS NOT NULL ) THEN
2542          fnd_message.set_token(p_token_name,p_token_value);
2543      END IF;
2544      l_message  := fnd_message.get;
2545      --
2546      -- No need to format the message if called from final validation
2547      IF (NVL(p_called_from,'X') = 'FINAL_VALIDATION') THEN
2548          return l_message;
2549      END IF;
2550 
2551      IF (p_message_type = 'ERR') THEN
2552         l_icon	:= 'erroricon_active.gif';
2553         l_css   := 'OraErrorText';
2554      ELSE
2555 	l_icon	:= 'warningicons_active.gif';
2556         l_css   := 'OraTipText';
2557      END IF;
2558 
2559      l_text     := '<tr><td> '||
2560                    '<IMG SRC="'||g_OA_MEDIA||l_icon||'"/>'||
2561                    '</td><td>'||
2562                    '<a class='||l_css||'>'||l_message||'</a>'||
2563                    '</td></tr> ';
2564 
2565      IF (p_addToPub <> 'NO') THEN
2566         open c1 ;
2567         fetch c1 into ln_app_id ;
2568         close c1 ;
2569         hr_utility.set_message(ln_app_id,p_message_name);
2570         IF (p_token_name IS NOT NULL AND p_token_value IS NOT NULL ) THEN
2571             hr_utility.set_message_token(p_token_name,p_token_value);
2572         END IF;
2573         IF ( p_message_type = 'ERR') THEN
2574             hr_multi_message.add( p_message_type => hr_multi_message.G_ERROR_MSG);
2575         ELSE
2576             hr_multi_message.add( p_message_type => hr_multi_message.G_WARNING_MSG);
2577         END IF;
2578      END IF;
2579 
2580      return l_text;
2581   --
2582   EXCEPTION
2583       WHEN OTHERS THEN
2584            hr_utility.trace(' exception in  '||g_package||'.add_message : ' || sqlerrm);
2585            raise;
2586   --
2587 END add_message;
2588 --
2589 
2590 FUNCTION get_errors_and_warnings (
2591       p_itemType     IN        VARCHAR2,
2592       p_itemKey      IN        VARCHAR2,
2593       p_calledFrom   IN        VARCHAR2  DEFAULT NULL,
2594       p_addToPub     IN        VARCHAR2  DEFAULT 'NO',
2595       p_sendToHr    OUT NOCOPY VARCHAR2,
2596       p_hasErrors   OUT NOCOPY VARCHAR2) RETURN VARCHAR2 IS
2597 --
2598 l_state           VARCHAR2(10);
2599 l_status          VARCHAR2(10);
2600 l_terminationDate DATE;
2601 --
2602 l_stepId          NUMBER(15);
2603 l_txnId           NUMBER(15);
2604 l_bgId            NUMBER(15);
2605 l_rptgGrpId       NUMBER(15);
2606 l_planId          NUMBER(15);
2607 l_personId        VARCHAR2(15);
2608 l_assignmentId    VARCHAR2(15);
2609 l_cpersonId       VARCHAR2(15);
2610 --
2611 l_editAllowed     VARCHAR2(10);
2612 l_futureChange    VARCHAR2(10);
2613 l_pendingTxn      VARCHAR2(10);
2614 l_interAction     VARCHAR2(10);
2615 l_isPersonElig    VARCHAR2(10);
2616 l_dtParmFound     VARCHAR2(10);
2617 l_rtParmFound     VARCHAR2(10);
2618 l_slParmFound     VARCHAR2(10);
2619 l_terminateFlag   VARCHAR2(30);
2620 --
2621 l_effDateOption   VARCHAR2(20);
2622 l_effectiveDate   VARCHAR2(20);
2623 --
2624 l_profileValue    VARCHAR2(100);
2625 l_processName     VARCHAR2(200);
2626 --
2627 l_rateMsg         VARCHAR2(100)  ;
2628 l_errorWarnings   VARCHAR2(20000);
2629 l_errorMsg        VARCHAR2(10000)  := '';
2630 l_warningMsg      VARCHAR2(10000)  := '';
2631 --
2632 l_whatChecks      VARCHAR2(10);
2633 lb_istxnowner     boolean;
2634 
2635 --
2636 BEGIN
2637 --
2638      -- By default check Intervening/Future, Pending and Eligibility
2639      l_whatChecks      := 'IPG';
2640      p_sendToHr		:= 'N';
2641      p_hasErrors	:= 'N';
2642 
2643      IF (p_addToPub = 'YES') THEN
2644         hr_multi_message.enable_message_list;
2645         p_hasErrors := set_developer_ntf_msg(p_itemType, p_itemKey);
2646      END IF;
2647 
2648      -- If non-approval process and final_validation is being performed,
2649      -- then only check for future dated changes.
2650      IF (NVL(p_calledFrom,'X') = 'FINAL_VALIDATION' ) THEN
2651         BEGIN
2652         IF wf_engine.GetItemAttrText(
2653              itemtype => p_itemType,
2654              itemkey  => p_itemKey,
2655              aname    => 'HR_RUNTIME_APPROVAL_REQ_FLAG')
2656                               NOT IN ('YES','YES_DYNAMIC') THEN
2657             l_whatChecks    := 'F';
2658         END IF;
2659         EXCEPTION
2660           WHEN OTHERS THEN -- if wf attribute is not found
2661             l_whatChecks    := 'F';
2662         END;
2663      END IF;
2664      --
2665 
2666      l_effectiveDate := NVL( wf_engine.getItemAttrText (
2667                             itemtype => p_itemType
2668                            ,itemkey  => p_itemKey
2669                            ,aname    => 'P_EFFECTIVE_DATE'),to_char(sysdate,g_date_format));
2670 
2671      get_transaction_info (
2672         p_itemType       => p_itemType
2673        ,p_itemKey        => p_itemKey
2674        ,p_loginPerson    => l_personId
2675        ,p_whatchecks     => l_whatChecks
2676        ,p_calledFrom     => p_calledFrom --added for bug 13416339
2677        ,p_personId       => l_personId
2678        ,p_assignmentId   => l_assignmentId
2679        ,p_state          => l_state
2680        ,p_status         => l_status
2681        ,p_txnId          => l_txnId
2682        ,p_businessGrpId  => l_bgId
2683        ,p_editAllowed    => l_editAllowed
2684        ,p_futureChange   => l_futureChange
2685        ,p_pendingTxn     => l_pendingTxn
2686        ,p_interAction    => l_interAction
2687        ,p_effDateOption  => l_effDateOption
2688        ,p_effectiveDate  => l_effectiveDate
2689        ,p_isPersonElig   => l_isPersonElig
2690        ,p_rptgGrpId      => l_rptgGrpId
2691        ,p_planId         => l_planId
2692        ,p_processName    => l_processName
2693        ,p_dateParmExist  => l_dtParmFound
2694        ,p_rateParmExist  => l_rtParmFound
2695        ,p_slryParmExist  => l_slParmFound
2696        ,p_rateMessage    => l_rateMsg
2697        ,p_terminateFlag  => l_terminateFlag);
2698 
2699         --fix for the bug 7640649
2700         l_cpersonId := NVL( wf_engine.getItemAttrText (
2701                             itemtype => p_itemType
2702                            ,itemkey  => p_itemKey
2703                            ,aname    => 'CREATOR_PERSON_ID'),-1);
2704 
2705         if hr_multi_tenancy_pkg.is_multi_tenant_system then
2706           hr_multi_tenancy_pkg.set_context_for_person(l_cpersonId);
2707         end if;
2708 
2709        begin
2710        lb_istxnowner := nvl(hr_transaction_swi.istxnowner(l_txnId,null),false);
2711        exception
2712        when others then
2713           lb_istxnowner := false;
2714        end;
2715 
2716        -- Bug 3025523: If the logged in manager does not secured access to the selected person
2717        -- then display appropriate message, no other message will be displayed in this
2718        -- case
2719         IF ( l_editAllowed = 'NS' ) THEN
2720             --
2721             p_hasErrors  := 'Y';
2722             l_errorMsg   := l_errorMsg||add_message('ERR','PQH','PQH_SS_ACCESS_TO_EMP_REC_ERR',p_calledFrom,p_addToPub);
2723             --
2724         END IF;
2725         --
2726         IF (    l_futureChange = 'Y' OR
2727 		l_interAction  = 'Y' OR
2728 		l_interAction  = 'YC' OR
2729 		l_pendingTxn   = 'Y' OR
2730 		l_editAllowed  = 'NS' OR
2731 		l_terminateFlag <> 'NO' OR
2732                 l_rateMsg IS NOT NULL OR
2733 		l_isPersonElig = 'N' ) THEN
2734 
2735          -- Termination Check
2736          IF ( l_terminateFlag IN ('ASGN','PRSN') ) THEN
2737             --
2738             p_hasErrors  := 'Y';
2739 --          l_errorMsg   := l_errorMsg||add_message('ERR','PER','HR_HR_MESG38_WEB',p_calledFrom);
2740             l_errorMsg   := l_errorMsg||add_message('ERR','PQH','PQH_SS_PRSN_TERMINATED_NTF_ERR',p_calledFrom,p_addToPub);
2741             --
2742          --If termination date is returned then, check if current or future termination
2743          ELSIF ( NVL(l_terminateFlag,'NO')<> 'NO' ) THEN
2744             --
2745           BEGIN
2746             l_terminationDate := to_date(l_terminateFlag,g_date_format);
2747             --
2748             -- if future termination then check profile and set error or warning
2749            IF ( l_terminationDate > trunc(sysdate) ) THEN
2750               p_sendToHr     := 'Y'; -- so that it is send to hr rep
2751               l_profileValue := NVL(fnd_profile.value('PQH_DT_RULE_FUTUR_CHANGE_FOUND'),'ERROR');
2752               --
2753               IF ( l_profileValue = 'ERROR' OR l_slParmFound= 'Y' ) THEN
2754                  p_hasErrors := 'Y';  -- To send error notification
2755                  l_errorMsg  := l_errorMsg||add_message('ERR','PQH','PQH_SS_FUT_TERM_EXISTS_ERR',
2756                                             p_calledFrom,p_addToPub,'TERM_DATE',l_terminationDate);
2757               ELSE
2758                  l_errorMsg  := l_errorMsg||add_message('WRN','PQH','PQH_SS_FUT_TERM_EXISTS_WRN',
2759                                             p_calledFrom,p_addToPub,'TERM_DATE',l_terminationDate);
2760               END IF;
2761               --
2762             END IF;
2763             --
2764           EXCEPTION
2765              -- In case a termination date is not returned, some value other than
2766              -- NO, ASGN or PRSN is returned
2767              WHEN OTHERS THEN Null;
2768           END;
2769          END IF;
2770 
2771          --Bug 3003754 Salary Change
2772          IF ( l_rtParmFound = 'Y' AND l_rateMsg IS NOT NULL) THEN
2773             --
2774             l_stepId := pqh_ss_utility.get_transaction_step_id (
2775                         p_itemType          => p_itemType
2776                       , p_itemKey           => p_itemKey
2777                       , p_apiName           => 'HR_PAY_RATE_SS.PROCESS_API' );
2778             --
2779             -- Display message only if the payrate step exists
2780             if ( l_stepId IS NULL ) THEN
2781                 l_rateMsg := null;
2782             else
2783                 l_errorMsg := l_errorMsg||add_message('ERR','PQH',l_rateMsg,p_calledFrom,p_addToPub);
2784             end if;
2785             --
2786          END IF;
2787 
2788          IF ( l_interAction in ('YC', 'Y') ) THEN
2789             -- In case of approving, an intervening action is always an error.
2790             -- so no need to check the profile in that case
2791             p_hasErrors     := 'Y';
2792 
2793             IF (p_calledFrom = 'FINAL_VALIDATION') THEN
2794               l_errorMsg := l_errorMsg||add_message('ERR','PQH','PQH_SS_INTRVN_ACTN_NTF_ERR',p_calledFrom,p_addToPub);
2795             ELSE
2796               l_profileValue  := NVL(fnd_profile.value('PQH_ALLOW_TRANSACTION_REFRESH'),'N');
2797               --
2798               IF (l_profileValue = 'N') THEN
2799 
2800                 l_errorMsg := l_errorMsg||
2801 					add_message('ERR','PQH','PQH_SS_INTRVN_ACTN_NTF_ERR',p_calledFrom,p_addToPub);
2802               ELSE
2803                   -- check if the login user is initiator or approver
2804                 if(lb_istxnowner) then
2805                  l_warningMsg := l_warningMsg||
2806 				 add_message('WRN','PQH','PQH_SS_INTRVN_ACTN_NTF_WRN',p_calledFrom,p_addToPub);
2807 				 else
2808 				  -- check the profile if the system is configured for approvers editing
2809                   --IF ( nvl(fnd_profile.value('PQH_ALLOW_APPROVER_TO_EDIT_TXN'),'N') = 'Y' AND l_editAllowed='Y') THEN
2810                     IF ( nvl(fnd_profile.value('PQH_ALLOW_APPROVER_TO_EDIT_TXN'),'N') = 'Y' ) THEN
2811 				     l_warningMsg := l_warningMsg||
2812   				    add_message('WRN','PER','HR_INTRVN_ACTN_NTF_WRN_AE',p_calledFrom,p_addToPub);
2813   				   null;
2814                   else
2815 				    l_warningMsg := l_warningMsg||
2816   				    add_message('WRN','PER','HR_INTRVN_ACTN_NTF_WRN_ANE',p_calledFrom,p_addToPub);
2817   				   null;
2818                   end if;-- edit profile check.
2819    	        end if;
2820               END IF;
2821             END IF;
2822 	      --
2823          END IF;
2824          --
2825          IF ( l_futureChange = 'Y' ) THEN
2826                 l_profileValue  := NVL(fnd_profile.value('PQH_DT_RULE_FUTUR_CHANGE_FOUND'),'ERROR');
2827                 if (l_profileValue = 'APPROVE_ONLY' AND NVL(l_slParmFound,'X') <> 'Y' ) THEN
2828                    -- if it's final validation and intervening changes are found, then the txn will
2829                    -- not be routed to HR Rep, intead Transaction error notification will be sent
2830                    -- When that happens no need to show the warning "Future change exist, txn will
2831                    -- be routed to HR Rep".
2832                    IF ( p_calledFrom = 'FINAL_VALIDATION' AND l_interAction in ('YC','Y')) THEN
2833  	               p_hasErrors := 'Y';
2834                    ELSIF (NOT isHrRepNtf(p_itemType, p_itemKey)) THEN
2835                       p_sendToHr   := 'Y';
2836                       if(lb_istxnowner) then
2837                        l_warningMsg := l_warningMsg||
2838 				  add_message('WRN','PQH','PQH_SS_FUTURE_CHNG_EXIST_WRN',p_calledFrom,p_addToPub);
2839 		      else
2840 		        l_warningMsg := l_warningMsg||
2841 				   add_message('WRN','PER','HR_FUTURE_CHNG_EXIST_WRN_APR',p_calledFrom,p_addToPub);
2842 		      end if;
2843                    END IF;
2844                 ELSE
2845  	           p_hasErrors := 'Y';
2846                    if(lb_istxnowner) then
2847                     l_errorMsg := l_errorMsg||
2848 					add_message('ERR','PQH','PQH_SS_FUTURE_CHNG_EXIST_ERR',p_calledFrom,p_addToPub);
2849                    else
2850          	    l_errorMsg := l_errorMsg||
2851  					 add_message('ERR','PER','HR_FUTURE_CHNG_EXIST_ERR_APR',p_calledFrom,p_addToPub);
2852   		   end if;
2853                 END IF;
2854           --
2855          END IF;
2856          -- Pending Transaction Found
2857          IF ( l_pendingTxn = 'Y' ) THEN
2858               l_profileValue  := NVL(fnd_profile.value('PQH_ALLOW_CONCURRENT_TXN'),'N');
2859               IF (l_profileValue = 'N') THEN
2860 		            p_hasErrors     := 'Y';
2861                 l_errorMsg := l_errorMsg||
2862 					add_message('ERR','PQH','PQH_SS_PENDING_TXN_NTF_ERR',p_calledFrom,p_addToPub);
2863               ELSE
2864                 l_warningMsg  := l_warningMsg ||
2865 					add_message('WRN','PQH','PQH_SS_PENDING_TXN_NTF_WRN',p_calledFrom,p_addToPub);
2866               END IF;
2867          END IF;
2868          -- Person is Ineligible
2869          IF ( l_isPersonElig = 'N' ) THEN -- Person Ineligible
2870               l_profileValue := NVL(fnd_profile.value('PQH_ENABLE_INELIGIBLE_ACTIONS'),'N');
2871               IF (l_profileValue = 'N') THEN
2872 		        p_hasErrors     := 'Y';
2873                 l_errorMsg := l_errorMsg||
2874 					add_message('ERR','PQH','PQH_SS_PERSON_INELIG_NTF_ERR',p_calledFrom,p_addToPub);
2875               ELSE
2876                 l_warningMsg  := l_warningMsg ||
2877 					add_message('WRN','PQH','PQH_SS_PERSON_INELIG_NTF_WRN',p_calledFrom,p_addToPub);
2878               END IF;
2879          END IF;
2880          --
2881          -- Concatinate Errors first and then Warnings
2882          -- They are kept in separate variable, for future use.
2883          l_errorWarnings := l_errorWarnings||l_errorMsg||l_warningMsg;
2884 
2885             --No formatting if called from final validation
2886             IF (l_errorWarnings IS NOT NULL AND NVL(p_calledFrom,'X') <> 'FINAL_VALIDATION') THEN
2887                l_errorWarnings :=  '<TABLE border=0> '||l_errorWarnings||'</TABLE>';
2888             END IF;
2889 
2890          ELSE
2891           l_errorWarnings := NULL;
2892         END IF;
2893 	IF (p_addToPub = 'YES' AND l_errorWarnings is NOT NULL AND length(l_errorWarnings) >0) THEN
2894             p_hasErrors := 'Y';
2895         END IF;
2896         IF (p_addToPub = 'YES') THEN
2897             hr_multi_message.disable_message_list;
2898         END IF;
2899         RETURN l_errorWarnings;
2900   --
2901   EXCEPTION
2902       WHEN OTHERS THEN
2903            hr_utility.trace(' exception in  '||g_package||'.get_errors_and_warnings : ' || sqlerrm);
2904            raise;
2905   --
2906 END  get_errors_and_warnings;
2907 
2908 --
2909 --
2910 PROCEDURE validation_on_final_approval (
2911       itemtype        IN     VARCHAR2,
2912       itemkey         IN     VARCHAR2,
2913       actid           IN     NUMBER,
2914       funcmode        IN     VARCHAR2,
2915       result          OUT NOCOPY    VARCHAR2 )  IS
2916 --
2917 l_errorWarnings   VARCHAR2(20000);
2918 l_hasErrors	  VARCHAR2(5);
2919 l_sendToHr 	  VARCHAR2(5);
2920 l_txnId           NUMBER;
2921 BEGIN
2922 --
2923 /*
2924  * 1. Get another flag which tells whethar intervening action has taken place
2925  * 2. Based on the flag see if the error flag is not set (no change if set)
2926  * 3. Sent out a different result if InterveningFlag=Y and ErrorFlag = N
2927  */
2928      l_errorWarnings :=
2929 	     get_errors_and_warnings (
2930 			p_itemType  => itemType
2931 		       ,p_itemKey   => itemKey
2932                        ,p_calledFrom=> 'FINAL_VALIDATION'
2933 		       ,p_hasErrors => l_hasErrors
2934 		       ,p_sendToHr  => l_sendToHr );
2935      --
2936      IF ( l_errorWarnings IS NULL OR l_hasErrors <> 'Y') THEN -- If no messages or only warnings
2937         result := 'COMPLETE:SUCCESS';
2938      ELSE  -- if errors are found
2939 
2940      -- Bug 3035702: Allow starting new transaction if existing transaction is in error
2941      -- Set transaction status to 'E - Error' so that it does not block any other transaction
2942      -- and can be picked up for cleanup.
2943         hr_transaction_api.update_transaction(
2944                p_transaction_id    => get_transaction_id(itemType,itemKey),
2945                p_status            => 'E');
2946 
2947 -- Fix for bug 8334527 :
2948 
2949     wf_engine.setitemattrtext
2950       (itemtype => itemtype
2951       ,itemkey  => itemkey
2952       ,aname    => 'TRAN_SUBMIT'
2953       ,avalue   => 'E');
2954 
2955         result := 'COMPLETE:FAILURE';
2956         wf_engine.SetItemAttrText(
2957                  itemtype => itemType
2958                , itemkey  => itemKey
2959                , aname    => 'ERROR_MESSAGE'  -- Bug 2962967: changed from ERROR_MESSAGE_TEXT
2960                , avalue   => l_errorWarnings );
2961      END IF;
2962      --
2963      -- Set send to HR rep attribute
2964      wf_engine.SetItemAttrText(
2965                  itemtype => itemType
2966                , itemkey  => itemKey
2967                , aname    => 'SEND_TO_HR_REP'
2968                , avalue   => l_sendToHr );
2969 --
2970   --
2971   EXCEPTION
2972       WHEN OTHERS THEN
2973            hr_utility.trace(' exception in  '||g_package||'.validation_on_final_approval : ' || sqlerrm);
2974            Wf_Core.Context(g_package, 'validation_on_final_approval', itemType, itemKey);
2975            raise;
2976   --
2977 END validation_on_final_approval;
2978 --
2979 --
2980 PROCEDURE check_for_warning_error (
2981       document_id   in     varchar2,
2982       display_type  in     varchar2,
2983       document      in out nocopy varchar2,
2984       document_type in out nocopy varchar2) IS
2985 --
2986 l_itemType        VARCHAR2(30);
2987 l_itemKey         VARCHAR2(30);
2988 --
2989 l_errorWarnings   VARCHAR2(20000);
2990 l_hasErrors	  VARCHAR2(5);
2991 l_sendToHr 	  VARCHAR2(5);
2992 BEGIN
2993 --
2994      -- No need to check for errors if notification is closed.
2995      if ( is_notification_closed(document_id) = 'Y') then
2996         return;
2997      end if;
2998      --
2999      document_type  := wf_notification.doc_html;
3000 
3001      -- Document will only have the notification id
3002      -- fetch the wf itemType and key from notification
3003      get_item_type_and_key (
3004                 p_ntfId    => document_id
3005                ,p_itemType => l_itemType
3006                ,p_itemKey  => l_itemKey );
3007      --
3008      l_errorWarnings :=
3009 	     get_errors_and_warnings (
3010 			p_itemType  => l_itemType
3011 		       ,p_itemKey   => l_itemKey
3012 		       ,p_hasErrors => l_hasErrors
3013 		       ,p_sendToHr  => l_sendToHr );
3014      --
3015      document   := l_errorWarnings;
3016      --
3017 EXCEPTION
3018   WHEN OTHERS THEN
3019            hr_utility.trace(' exception in  '||g_package||'.check_for_warning_error : ' || sqlerrm);
3020            document  := '<a class=OraErrorText>Exception in  '||g_package||'.check_for_warning_error : '||
3021                 sqlerrm||'</a>';
3022 --
3023 END check_for_warning_error ;
3024 --
3025 --
3026 FUNCTION is_notification_closed (
3027       p_ntfId        IN VARCHAR2 ) RETURN VARCHAR2 IS
3028 --
3029 l_isClosed  VARCHAR2(10) := 'N';
3030 lv_ntf_role      WF_NOTIFICATIONS.RECIPIENT_ROLE%type;
3031 lv_ntf_msg_typ   WF_NOTIFICATIONS.MESSAGE_TYPE%type;
3032 lv_ntf_msg_name  WF_NOTIFICATIONS.MESSAGE_NAME%type;
3033 lv_ntf_prior     WF_NOTIFICATIONS.PRIORITY%type;
3034 lv_ntf_due       WF_NOTIFICATIONS.DUE_DATE%type;
3035 lv_ntf_status    WF_NOTIFICATIONS.STATUS%type;
3036 --
3037 BEGIN
3038    --
3039    -- Get notification recipient and status
3040   Wf_Notification.GetInfo(p_ntfId, lv_ntf_role, lv_ntf_msg_typ, lv_ntf_msg_name, lv_ntf_prior, lv_ntf_due, lv_ntf_status);
3041   if (lv_ntf_status <> 'OPEN') then
3042    l_isClosed := 'Y';
3043   else
3044    l_isClosed := 'N';
3045   end if;
3046 
3047   return  l_isClosed;
3048 --
3049   --
3050   EXCEPTION
3051       WHEN OTHERS THEN
3052            hr_utility.trace(' exception in  '||g_package||'.is_notification_closed : ' || sqlerrm);
3053            raise;
3054   --
3055 END is_notification_closed;
3056 --
3057 
3058 FUNCTION complete_custom_rfc (
3059       p_ntfId  IN VARCHAR2 ) RETURN VARCHAR2 IS
3060 --
3061 l_isCustomRFC   VARCHAR2(5);
3062 l_itemType      VARCHAR2(30);
3063 l_itemKey       VARCHAR2(240);
3064 l_activityId    NUMBER;
3065 BEGIN
3066    get_item_type_and_key (
3067                 p_ntfId    => p_ntfId
3068                ,p_itemType => l_itemType
3069                ,p_itemKey  => l_itemKey );
3070 
3071    l_isCustomRFC   :=
3072           wf_engine.GetItemAttrText(
3073                 itemtype    => l_itemType
3074                ,itemkey     => l_itemKey
3075                ,aname       => 'HR_CUSTOM_RETURN_FOR_CORR');
3076 
3077    IF (l_isCustomRFC = 'Y' ) THEN
3078        l_activityId      :=
3079              get_notified_activity(
3080                 p_itemType  => l_itemType
3081                ,p_itemKey   => l_itemKey
3082                ,p_ntfId     => p_ntfId   );
3083 
3084        complete_wf_activity (
3085           	p_itemType    => l_itemtype,
3086            	p_itemKey     => l_itemkey,
3087             p_activity    => l_activityId,
3088             p_otherAct    => 'THIS',
3089            	p_resultCode  => 'RETURNEDFORCORRECTION' ) ;
3090    END IF;
3091 
3092    RETURN l_isCustomRFC;
3093   --
3094   EXCEPTION
3095       WHEN OTHERS THEN
3096            hr_utility.trace(' exception in  '||g_package||'.complete_custom_rfc : ' || sqlerrm);
3097            raise;
3098   --
3099 END complete_custom_rfc;
3100 --
3101 --
3102 procedure delete_txn_notification(
3103         p_itemType      IN VARCHAR2
3104        ,p_itemKey       IN VARCHAR2
3105        ,p_transactionId IN VARCHAR2
3106        ) is
3107 l_activity_id number;
3108 l_notificationId number;
3109 begin
3110   --
3111   l_notificationId  := get_notification_id (
3112         p_itemType      => p_itemType
3113        ,p_itemKey       => p_itemKey
3114        );
3115   --
3116   if l_notificationId is not null then
3117     l_activity_id := get_notified_activity (
3118         p_itemType      => p_itemType
3119        ,p_itemKey       => p_itemKey
3120        ,p_ntfId         => l_notificationId
3121        );
3122   --
3123   complete_wf_activity (
3124         p_itemType    => p_itemType,
3125         p_itemKey     => p_itemKey,
3126         p_activity    => l_activity_id,
3127         p_otherAct    => 'THIS',
3128         p_resultCode  => 'DEL' );
3129   elsif p_transactionId is not null then
3130     hr_transaction_api.rollback_transaction(p_transactionId);
3131   end if;
3132   --
3133 /*
3134   exception
3135     when others then
3136      hr_transaction_api.rollback_transaction
3137                  (p_transaction_id => p_transactionid);
3138 */
3139 end;
3140 --
3141 PROCEDURE set_hr_rep_role (
3142       itemtype        IN     VARCHAR2,
3143       itemkey         IN     VARCHAR2,
3144       actid           IN     NUMBER,
3145       funcmode        IN     VARCHAR2,
3146       result          OUT NOCOPY    VARCHAR2 )  IS
3147 
3148 l_roleType    PQH_ROLES.role_type_cd%TYPE   := 'HR_REP';
3149 l_PersonId    NUMBER(15);
3150 l_bgId        NUMBER(15);
3151 l_flag        VARCHAR2(1);
3152 l_roleId      NUMBER(15);
3153 l_roleName    PQH_ROLES.role_name%TYPE;
3154 
3155  CURSOR cur_wfrole  (p_role_id NUMBER) IS
3156  SELECT name
3157  FROM   wf_roles
3158  WHERE  orig_system    = 'PQH_ROLE'
3159  AND    orig_system_id = p_role_id ;
3160 
3161 BEGIN
3162 
3163     l_personId     := wf_engine.GetItemAttrText(
3164                                itemtype => itemtype,
3165                                itemkey  => itemkey,
3166                                aname    => 'CURRENT_PERSON_ID');
3167 
3168     l_bgId         := PQH_SS_UTILITY.get_business_group_id ( l_PersonId, sysdate);
3169 
3170     PQH_SS_UTILITY.get_Role_Info (
3171         p_roleTypeCd       => l_roleType
3172        ,p_businessGroupId  => l_bgId
3173        ,p_globalRoleFlag   => l_flag
3174        ,p_roleName         => l_roleName
3175        ,p_roleId           => l_roleId  );
3176 
3177 /*    if l_roleName is null then
3178        Wf_Core.Token('TYPE', itemtype);
3179        Wf_Core.Token('ACTID', to_char(actid));
3180        Wf_Core.Raise('WFENG_NOTIFICATION_PERFORMER');
3181     end if;
3182 */
3183     IF ( l_roleId IS NULL ) THEN
3184       --
3185       result := 'COMPLETE:FAILURE';
3186       --
3187     ELSE  -- Role id is not null
3188       --
3189       IF ( cur_wfrole%ISOPEN ) THEN
3190           CLOSE cur_wfrole;
3191       END IF;
3192       --
3193       OPEN  cur_wfrole (l_roleId) ;
3194       FETCH cur_wfrole INTO l_roleName ;
3195       CLOSE cur_wfrole;
3196       --
3197       IF ( l_roleName IS NULL ) THEN
3198          --
3199          result := 'COMPLETE:FAILURE';
3200          --
3201       ELSE
3202          --
3203          wf_engine.SetItemAttrText(
3204               itemtype => itemtype,
3205               itemkey  => itemkey,
3206               aname    => 'HR_REP_ROLE',
3207               avalue   => l_roleName);
3208         --
3209         result := 'COMPLETE:SUCCESS';
3210         --
3211       END IF;
3212       --
3213    END IF;
3214    --
3215    IF ( result = 'COMPLETE:FAILURE') THEN
3216      --
3217      -- Bug 3035702: Allow starting new transaction if existing transaction is in error
3218      -- Set transaction status to 'E - Error' so that it does not block any other transaction
3219      -- and can be picked up for cleanup.
3220      hr_transaction_api.update_transaction(
3221                p_transaction_id    => get_transaction_id(itemType,itemKey),
3222                p_status            => 'E');
3223   END IF;
3224   --
3225   EXCEPTION
3226       WHEN OTHERS THEN
3227            hr_utility.trace(' exception in  '||g_package||'.set_hr_rep_role : ' || sqlerrm);
3228            Wf_Core.Context(g_package, 'set_hr_rep_role', itemType, itemKey);
3229            raise;
3230 
3231 END set_hr_rep_role;
3232 
3233 procedure approval_block(itemtype   in varchar2,
3234                itemkey    in varchar2,
3235                actid      in number,
3236                funcmode   in varchar2,
3237                resultout  in out nocopy varchar2)
3238 is
3239 begin
3240   -- Do nothing in cancel or timeout mode
3241   if (funcmode <> wf_engine.eng_run) then
3242     resultout := wf_engine.eng_null;
3243     return;
3244   end if;
3245 
3246   -- Set the Approval process version to distinguish it
3247   -- it from old approval process.
3248   wf_engine.SetItemAttrText(
3249          itemtype => itemType
3250        , itemkey  => itemKey
3251        , aname    => 'HR_APPROVAL_PRC_VERSION'
3252        , avalue   => 'V5' );
3253                --
3254   resultout := wf_engine.eng_notified||':'||wf_engine.eng_null||
3255                  ':'||wf_engine.eng_null;
3256 exception
3257   when others then
3258            hr_utility.trace(' exception in  '||g_package||'.approval_block : ' || sqlerrm);
3259            Wf_Core.Context(g_package, 'approval_block', itemType, itemKey);
3260            raise;
3261 end approval_block;
3262 --
3263 
3264 
3265 /* ============== APPROVAL HISTORY ==========================
3266  * Procedure to build the notification history, that is added
3267  * to the bottom of approval notifications. It also considers
3268  * RFC notifications and includes the record in building the
3269  * Workflow History.
3270  * This procedure internally uses two procedures copied from
3271  * WF_notifications package with some modifications to cater
3272  * to our specific need
3273  */
3274 PROCEDURE approval_history (
3275       document_id   in     varchar2,
3276       display_type  in     varchar2,
3277       document      in out nocopy varchar2,
3278       document_type in out nocopy varchar2) IS
3279 
3280 --
3281 -- Wf_Ntf_History
3282 --   Construct a history table for a notification activity.
3283 -- NOTE
3284 --   Consist of three sections:
3285 --   1. Current Notification
3286 --   2. Past Notifications in the history table
3287 --   3. The owner role as the submitter and begin date for such item
3288 --
3289 
3290 
3291 l_x  varchar2(32000);
3292 type tdType is table of varchar2(4005) index by binary_integer;
3293 
3294 table_width        varchar2(8)  := '100%';
3295 table_border       varchar2(2)  := '0';
3296 table_cellpadding  varchar2(2)  := '3';
3297 table_cellspacing  varchar2(2)  := '1';
3298 table_bgcolor      varchar2(7)  := 'white';
3299 th_bgcolor         varchar2(7)  := '#cccc99';
3300 th_fontcolor       varchar2(7)  := '#336699';
3301 th_fontface        varchar2(80) := 'Arial, Helvetica, Geneva, sans-serif';
3302 th_fontsize        varchar2(2)  := '2';
3303 td_bgcolor         varchar2(7)  := '#f7f7e7';
3304 td_fontcolor       varchar2(7)  := 'black';
3305 td_fontface        varchar2(80) := 'Arial, Helvetica, Geneva, sans-serif';
3306 td_fontsize        varchar2(2)  := '2';
3307 
3308 
3309 
3310 procedure NTF_Table(cells in tdType,
3311                     col   in pls_integer,
3312                     type  in varchar2,  -- 'V'ertical or 'H'orizontal
3313                     rs    in out nocopy varchar2)
3314 is
3315   i pls_integer;
3316   colon pls_integer;
3317   modv pls_integer;
3318   alignv   varchar2(1);
3319   l_align  varchar2(8);
3320   l_width  varchar2(3);
3321   l_text   varchar2(4000);
3322   l_type   varchar2(1);
3323   l_dir    varchar2(1);
3324   l_dirAttr varchar2(10);
3325 
3326   -- Define a local set and initialize with the default
3327   l_table_width  varchar2(8) := table_width;
3328   l_table_border varchar2(2) := table_border;
3329   l_table_cellpadding varchar2(2) := table_cellpadding;
3330   l_table_cellspacing varchar2(2) := table_cellspacing;
3331   l_table_bgcolor varchar2(7) := table_bgcolor;
3332   l_th_bgcolor varchar2(7) := th_bgcolor;
3333   l_th_fontcolor varchar2(7) := th_fontcolor;
3334   l_th_fontface varchar2(80) := th_fontface;
3335   l_th_fontsize varchar2(2) := th_fontsize;
3336   l_td_bgcolor varchar2(7) := td_bgcolor;
3337   l_td_fontcolor varchar2(7) := td_fontcolor;
3338   l_td_fontface varchar2(80) := td_fontface;
3339   l_td_fontsize varchar2(2) := td_fontsize;
3340 
3341 begin
3342   if length(type) > 1 then
3343      l_type := substrb(type, 1, 1);
3344      l_dir := substrb(type,2, 1);
3345   else
3346      l_type := type;
3347      l_dir := 'L';
3348   end if;
3349 
3350   if l_dir = 'L' then
3351      l_dirAttr := NULL;
3352   else
3353      l_dirAttr := 'dir="RTL"';
3354   end if;
3355 
3356   if (l_type = 'N') then
3357      -- Notification format. Alter the default colors.
3358      l_table_bgcolor := '#FFFFFF';
3359      l_th_bgcolor := '#FFFFFF';
3360      l_th_fontcolor := '#000000';
3361      l_td_bgcolor := '#FFFFFF';
3362      l_td_fontcolor := '#000000';
3363      l_table_cellpadding := '1';
3364      l_table_cellspacing := '1';
3365   end if;
3366 
3367   if (cells.COUNT = 0) then
3368     rs := null;
3369     return;
3370   end if;
3371   rs := '<table width=100% border=0 cellpadding=0 cellspacing=0 '||l_dirAttr||
3372         '><tr><td>';
3373   rs := rs||wf_core.newline||'<table sumarry="" width='||l_table_width||
3374             ' border='||l_table_border||
3375             ' cellpadding='||l_table_cellpadding||
3376             ' cellspacing='||l_table_cellspacing||
3377             ' bgcolor='||l_table_bgcolor||' '||l_dirAttr||'>';
3378 
3379 -- ### implement as generic log in the future
3380 --  if (wf_notification.debug) then
3381 --    dbms_output.put_line(to_char(cells.LAST));
3382 --  end if;
3383 
3384   for i in 1..cells.LAST loop
3385 --    if (wf_notification.debug) then
3386 --      dbms_output.put_line(substrb('('||to_char(i)||')='||cells(i),1,254));
3387 --    end if;
3388     modv := mod(i, col);
3389     if (modv = 1) then
3390       rs := rs||wf_core.newline||'<tr>';
3391     end if;
3392 
3393     alignv := substrb(cells(i), 1, 1);
3394     if (alignv = 'R') then
3395       l_align := 'RIGHT';
3396     elsif (alignv = 'L') then
3397       l_align := 'LEFT';
3398     elsif (alignv = 'S') then
3399       if (l_dir = 'L') then
3400          l_align := 'LEFT';
3401       else
3402          l_align := 'RIGHT';
3403       end if;
3404     elsif (alignv = 'E') then
3405       if (l_dir = 'L') then
3406          l_align := 'RIGHT';
3407       else
3408          l_align := 'LEFT';
3409       end if;
3410     else
3411       l_align := 'CENTER';
3412     end if;
3413 
3414 --    if (wf_notification.debug) then
3415 --      dbms_output.put_line('modv = '||to_char(modv));
3416 --    end if;
3417 
3418     colon := instrb(cells(i),':');
3419     l_width := substrb(cells(i), 2, colon-2);
3420     l_text  := substrb(cells(i), colon+1);   -- what is after the colon
3421 
3422     if ((l_type = 'V' and modv = 1) or (l_type = 'N' and modv = 1)
3423         or  (l_type = 'H' and i <= col)) then
3424       if (l_type = 'N') then
3425          rs := rs||wf_core.newline||'<td';
3426       else
3427          -- this is a header
3428          rs := rs||wf_core.newline||'<th';
3429       end if;
3430       if (l_type = 'V') then
3431          rs := rs||' scope=row';
3432       else
3433          rs := rs||' scope=col';
3434       end if;
3435 
3436       if (l_width is not null) then
3437         rs := rs||' width='||l_width;
3438       end if;
3439       rs := rs||' align='||l_align||' valign=baseline bgcolor='||
3440               l_th_bgcolor||'>';
3441       rs := rs||'<font color='||l_th_fontcolor||' face="'||l_th_fontface||'"'
3442               ||' size='||l_th_fontsize||'>';
3443       rs := rs||l_text||'</font>';
3444       if (l_type = 'N') then
3445         rs := rs||'</td>';
3446       else
3447         rs := rs||'</th>';
3448       end if;
3449     else
3450       -- this is regular data
3451       rs := rs||wf_core.newline||'<td';
3452       if (l_width is not null) then
3453         rs := rs||' width='||l_width;
3454       end if;
3455       rs := rs||' align='||l_align||' valign=baseline bgcolor='||
3456               l_td_bgcolor||'>';
3457       rs := rs||'<font color='||td_fontcolor||' face="'||l_td_fontface||'"'
3458               ||' size='||l_td_fontsize||'>';
3459       if (l_type = 'N') then
3460         rs := rs||'<b>'||l_text||'</b></font></td>';
3461       else
3462         rs := rs||l_text||'</font></td>';
3463       end if;
3464     end if;
3465     if (modv = 0) then
3466       rs := rs||wf_core.newline||'</tr>';
3467     end if;
3468   end loop;
3469   rs := rs||wf_core.newline||'</table>'||wf_core.newline||'</td></tr></table>';
3470 
3471 exception
3472   when OTHERS then
3473     wf_core.context('Wf_Notification', 'NTF_Table',to_char(col),l_type);
3474     raise;
3475 end NTF_Table;
3476 
3477 
3478 function wf_ntf_history(nid      in number,
3479                         disptype in varchar2)
3480 return varchar2
3481 is
3482   -- current notification
3483   cursor hist0c(x_item_type varchar2, x_item_key varchar2, x_actid number) is
3484 
3485 SELECT  rownum h_sequence
3486        ,h_notification_id
3487        ,h_from_role
3488        ,h_action
3489        ,h_comment
3490        ,h_action_date
3491 FROM    (
3492         SELECT  h_notification_id
3493                ,h_from_role
3494                ,h_action
3495                ,h_comment
3496                ,h_action_date
3497         FROM    (
3498                 SELECT  99999999 h_sequence
3499                        ,ias.notification_id h_notification_id
3500                        ,ias.assigned_user h_from_role
3501                        ,wf_core.activity_result (a.result_type
3502                                                 ,ias.activity_result_code) h_action
3503                        ,
3504                         (
3505                         SELECT  text_value
3506                         FROM    wf_notification_attributes
3507                         WHERE   notification_id = ias.notification_id
3508                         AND     name = 'WF_NOTE'
3509                         ) h_comment
3510                        ,nvl (ias.end_date
3511                             ,ias.begin_date) h_action_date
3512                 FROM    wf_item_activity_statuses ias
3513                        ,wf_activities a
3514                        ,wf_process_activities pa
3515                        ,wf_items i
3516                        ,WF_ITEM_TYPES IT
3517    where IAS.ITEM_TYPE        = 'HRSSA'
3518      and IAS.ITEM_KEY         = '15018'
3519      and IAS.NOTIFICATION_ID  is not null
3520      and nvl(RESULT_TYPE,'*') NOT IN ( '*','HR_DONE')
3521      and IAS.ITEM_TYPE        = I.ITEM_TYPE
3522      and IAS.ITEM_KEY         = I.ITEM_KEY
3523      and I.BEGIN_DATE between A.BEGIN_DATE and nvl(A.END_DATE, I.BEGIN_DATE)
3524      and I.ITEM_TYPE          = IT.NAME
3525      and IAS.PROCESS_ACTIVITY = PA.INSTANCE_ID
3526      and PA.ACTIVITY_NAME     = A.NAME
3527      and PA.ACTIVITY_ITEM_TYPE= A.ITEM_TYPE
3528      and (IAS.ACTIVITY_RESULT_CODE is null or IAS.ACTIVITY_RESULT_CODE not in ('SFL','#NULL'))
3529 
3530                 UNION ALL
3531                 SELECT  99999999 h_sequence
3532                        ,ias.notification_id h_notification_id
3533                        ,ias.assigned_user h_from_role
3534                        ,wf_core.activity_result (a.result_type
3535                                                 ,ias.activity_result_code) h_action
3536                        ,
3537                         (
3538                         SELECT  text_value
3539                         FROM    wf_notification_attributes
3540                         WHERE   notification_id = ias.notification_id
3541                         AND     name = 'WF_NOTE'
3542                         ) h_comment
3543                        ,nvl (ias.end_date
3544                             ,ias.begin_date) h_action_date
3545                 FROM    wf_item_activity_statuses_h ias
3546                        ,wf_activities a
3547                        ,wf_process_activities pa
3548                        ,wf_items i
3549                        ,WF_ITEM_TYPES IT
3550    where IAS.ITEM_TYPE        = 'HRSSA'
3551      and IAS.ITEM_KEY         = '15018'
3552      and IAS.NOTIFICATION_ID  is not null
3553      and (IAS.ACTIVITY_RESULT_CODE is null or IAS.ACTIVITY_RESULT_CODE not in ('SFL','#NULL'))
3554      and nvl(RESULT_TYPE,'*') NOT IN ( '*','HR_DONE')
3555      and IAS.ITEM_TYPE        = I.ITEM_TYPE
3556      and IAS.ITEM_KEY         = I.ITEM_KEY
3557      and I.BEGIN_DATE between A.BEGIN_DATE and nvl(A.END_DATE, I.BEGIN_DATE)
3558      and I.ITEM_TYPE          = IT.NAME
3559      and IAS.PROCESS_ACTIVITY = PA.INSTANCE_ID
3560      and PA.ACTIVITY_NAME     = A.NAME
3561      and PA.ACTIVITY_ITEM_TYPE= A.ITEM_TYPE
3562 
3563                 UNION ALL
3564                 SELECT  c.sequence h_sequence
3565                        ,c.notification_id h_notification_id
3566                        ,c.from_role h_from_role
3567                        ,wf_core.translate (c.action) h_action
3568                        ,c.user_comment h_comment
3569                        ,c.comment_date h_action_date
3570                 FROM    wf_item_activity_statuses ias
3571                        ,wf_comments c
3572                 WHERE   ias.item_type = x_item_type
3573                 AND     ias.item_key = x_item_key
3574 --                AND     ias.process_activity = x_actid
3575                 AND     ias.notification_id = c.notification_id
3576                 AND     c.action NOT IN ('RESPOND','RESPOND_WA','RESPOND_RULE'
3577                                         ,'SEND','CANCEL')
3578                 UNION ALL
3579                 SELECT  c.sequence h_sequence
3580                        ,c.notification_id h_notification_id
3581                        ,c.from_role h_from_role
3582                        ,wf_core.translate (c.action) h_action
3583                        ,c.user_comment h_comment
3584                        ,c.comment_date h_action_date
3585                 FROM    wf_item_activity_statuses_h ias
3586                        ,wf_comments c
3587                 WHERE   ias.item_type = x_item_type
3588                 AND     ias.item_key = x_item_key
3589 --                AND     ias.process_activity = x_actid
3590                 AND     ias.notification_id = c.notification_id
3591                 AND     c.action NOT IN ('RESPOND','RESPOND_WA','RESPOND_RULE'
3592                                         ,'SEND','CANCEL')
3593                 )
3594         ORDER BY h_action_date desc
3595                 ,h_notification_id desc
3596                 ,h_sequence desc
3597         );
3598 
3599 
3600   l_itype varchar2(30);
3601   l_ikey  varchar2(240);
3602   l_actid number;
3603   l_result_type varchar2(30);
3604   l_result_code varchar2(30);
3605   l_action varchar2(80);
3606   l_owner_role  varchar2(320);
3607   l_owner       varchar2(320);
3608   l_begin_date  date;
3609   i pls_integer;
3610   j pls_integer;
3611   role_info_tbl wf_directory.wf_local_roles_tbl_type;
3612 
3613   l_delim     varchar2(1) := ':';
3614   cells       tdType;
3615   result      varchar2(32000) := '';
3616 begin
3617   wf_notification.getNtfActInfo(nid, l_itype, l_ikey, l_actid);
3618 
3619 hr_utility.set_location(' kck nid : ' || nid, 666);
3620 hr_utility.set_location(' kck l_itype : ' || l_itype, 666);
3621 hr_utility.set_location(' kck l_ikey : ' || l_ikey, 666);
3622 hr_utility.set_location(' kck l_actid : ' || l_actid, 666);
3623 
3624 l_actid := null;
3625 
3626 
3627   j := 1;
3628   -- title
3629   cells(j) := wf_core.translate('SEQUENCE');
3630   if (disptype = wf_notification.doc_html) then
3631     cells(j) := 'L10%:'||cells(j);
3632   end if;
3633   j := j+1;
3634   cells(j) := wf_core.translate('WHO');
3635   if (disptype = wf_notification.doc_html) then
3636     cells(j) := 'L:'||cells(j);
3637   end if;
3638   j := j+1;
3639   cells(j) := wf_core.translate('ACTION');
3640   if (disptype = wf_notification.doc_html) then
3641     cells(j) := 'L:'||cells(j);
3642   end if;
3643   j := j+1;
3644   cells(j) := wf_core.translate('DATE');
3645   if (disptype = wf_notification.doc_html) then
3646     cells(j) := 'L:'||cells(j);
3647   end if;
3648   j := j+1;
3649   cells(j) := wf_core.translate('NOTE');
3650   if (disptype = wf_notification.doc_html) then
3651     cells(j) := 'L:'||cells(j);
3652   end if;
3653   j := j+1;
3654 
3655   begin
3656     select OWNER_ROLE, BEGIN_DATE
3657       into l_owner_role, l_begin_date
3658       from WF_ITEMS
3659      where ITEM_TYPE = l_itype
3660        and ITEM_KEY = l_ikey;
3661   exception
3662     when OTHERS then
3663       raise;
3664   end;
3665 
3666 
3667   i := 0;
3668   for histr in hist0c(l_itype, l_ikey, l_actid) loop
3669 
3670 hr_utility.set_location(' kck histr.h_sequence : ' || histr.h_sequence, 666);
3671 hr_utility.set_location(' kck histr.h_from_role : ' || histr.h_from_role, 666);
3672 hr_utility.set_location(' kck histr.h_action : ' || histr.h_action, 666);
3673 hr_utility.set_location(' kck histr.h_action_date : ' || histr.h_action_date, 666);
3674 hr_utility.set_location(' kck histr.h_comment : ' || histr.h_comment, 666);
3675 
3676 if ((NOT (l_owner_role <> histr.h_from_role AND histr.h_action = 'Submit' )) AND
3677      (NOT ( histr.h_from_role = l_owner_role and NVL(histr.h_action,'X') = 'Approve'))) then
3678 
3679    -- skip if first record was sfl and submitted
3680     cells(j) := to_char(histr.h_sequence);
3681     j := j+1;
3682     wf_directory.GetRoleInfo2(histr.h_from_role, role_info_tbl);
3683 
3684     if (disptype = wf_notification.doc_html) then
3685       cells(j) := 'L:'||role_info_tbl(1).display_name;
3686     else
3687       cells(j) := role_info_tbl(1).display_name;
3688     end if;
3689     j := j+1;
3690 
3691     if (disptype = wf_notification.doc_html) then
3692       if (histr.h_action is null) then
3693         cells(j) := 'L: ';
3694       else
3695         cells(j) := 'L:'||histr.h_action;
3696       end if;
3697     else
3698       cells(j) := histr.h_action;
3699     end if;
3700     j := j+1;
3701 
3702 if (disptype = wf_notification.doc_html) then
3703       cells(j) := 'L:'||to_char(histr.h_action_date);
3704     else
3705       cells(j) := to_char(histr.h_action_date);
3706     end if;
3707     j := j+1;
3708 
3709     begin
3710         cells(j) := histr.h_comment;
3711     exception
3712       when OTHERS then
3713         cells(j) := null;
3714         wf_core.clear;
3715     end;
3716     if (disptype = wf_notification.doc_html) then
3717       if (cells(j) is null) then
3718         cells(j) := 'L: ';
3719       else
3720         cells(j) := 'L:'||cells(j);
3721       end if;
3722     end if;
3723     j := j+1;
3724 
3725     i := i+1;
3726 end if;
3727 end loop;
3728 
3729   -- calculate the sequence
3730   -- Only after we know the number of rows, then we can put the squence
3731   -- number on for each row.
3732   for k in 0..i-1 loop
3733     if (disptype = wf_notification.doc_html) then
3734       cells((k+1)*5+1) := 'C:'||to_char(i-k);
3735     else
3736       cells((k+1)*5+1) := to_char(i-k);
3737     end if;
3738   end loop;
3739 
3740 
3741 
3742   if (disptype = wf_notification.doc_html) then
3743     table_width := '100%';
3744 
3745     NTF_Table(
3746               cells  => cells,
3747               col    => 5,
3748               type   => 'H',
3749               rs     => result  );
3750   else
3751     for k in 1..cells.LAST loop
3752       if (mod(k, 5) <> 0) then
3753         result := result||cells(k)||' '||l_delim||' ';
3754       else
3755         result := result||cells(k)||wf_core.newline;
3756       end if;
3757     end loop;
3758   end if;
3759 
3760   return(result);
3761 exception
3762   when OTHERS then
3763     wf_core.context('Wf_Notification', 'Wf_NTF_History', to_char(nid));
3764     raise;
3765 end wf_ntf_history;
3766 
3767 
3768 BEGIN
3769 
3770 
3771 hr_utility.set_location('document_id passed : ' || document_id, 666);
3772   --
3773   document_type  := wf_notification.doc_html;
3774   document       := wf_ntf_history(document_id, document_type);
3775   --
3776 END approval_history;
3777 --
3778 --
3779 
3780 PROCEDURE reset_process_section_attr (
3781       itemtype        IN     VARCHAR2,
3782       itemkey         IN     VARCHAR2,
3783       actid           IN     NUMBER,
3784       funcmode        IN     VARCHAR2,
3785       result          OUT NOCOPY    VARCHAR2 ) IS
3786 BEGIN
3787       wf_engine.SetItemAttrText(
3788             itemtype => itemType
3789           , itemkey  => itemKey
3790           , aname    => 'HR_PERINFO_PROCESS_SECTION'
3791           , avalue   => NULL );
3792 END reset_process_section_attr ;
3793 --
3794 --
3795 PROCEDURE set_image_source (
3796       itemtype        IN     VARCHAR2,
3797       itemkey         IN     VARCHAR2,
3798       actid           IN     NUMBER,
3799       funcmode        IN     VARCHAR2,
3800       result          OUT NOCOPY    VARCHAR2 ) IS
3801 --
3802 l_viewImage    VARCHAR2(100);
3803 l_rfcImage     VARCHAR2(100);
3804 --
3805 BEGIN
3806   --
3807   l_viewImage    :=  wf_engine.GetActivityAttrText(
3808                             itemtype    => itemType
3809                            ,itemkey     => itemKey
3810                            ,actid       => actId
3811                            ,aname       => 'VIEW_IMAGE_NAME' );
3812   if ( l_viewImage IS NULL ) then
3813        l_viewImage := 'previewscreen_enabled.gif';
3814   end if;
3815   --
3816   l_rfcImage     :=  wf_engine.GetActivityAttrText(
3817                             itemtype    => itemType
3818                            ,itemkey     => itemKey
3819                            ,actid       => actId
3820                            ,aname       => 'RFC_IMAGE_NAME' );
3821   --
3822   if ( l_rfcImage IS NULL ) then
3823        l_rfcImage := 'backarro.gif';
3824   end if;
3825   --
3826   --
3827   wf_engine.SetItemAttrText(
3828        itemtype => itemType
3829      , itemkey  => itemKey
3830      , aname    => 'IMG_VIEW_ACTION'
3831      , avalue   => g_OA_MEDIA||l_viewImage
3832   );
3833   --
3834   --
3835   wf_engine.SetItemAttrText(
3836        itemtype => itemType
3837      , itemkey  => itemKey
3838      , aname    => 'IMG_RFC_ACTION'
3839      , avalue   => g_OA_MEDIA||l_rfcImage
3840   );
3841   --
3842   result := 'COMPLETE:SUCCESS';
3843   --
3844 EXCEPTION
3845   WHEN OTHERS THEN
3846      null;
3847 END set_image_source;
3848 
3849 
3850 FUNCTION set_developer_ntf_msg(
3851 	p_itemType    IN VARCHAR2,
3852 	p_itemKey     IN VARCHAR2) RETURN VARCHAR IS
3853 l_ntfId     NUMBER;
3854 l_ntf_identifier VARCHAR2(100) := 'HR_NTF_IDENTIFIER';
3855 l_ntf_name VARCHAR2(100);
3856 l_error_message VARCHAR2(2000);
3857 l_sal_basis_change_token VARCHAR2(100);
3858 l_current_person_display_name VARCHAR2(100);
3859 l_process_display_name VARCHAR2(100);
3860 l_note_from_requestor VARCHAR2(2000);
3861 l_note_from_approver VARCHAR2(2000);
3862 l_errors VARCHAR2(100);
3863 l_ntf_err_text VARCHAR2(20000);
3864 BEGIN
3865   l_ntfId := get_notification_id(p_itemType,p_itemKey);
3866   BEGIN
3867     l_ntf_name := WF_NOTIFICATION.getattrtext(l_ntfId,l_ntf_identifier);
3868     EXCEPTION
3869     WHEN OTHERS THEN
3870       NULL;
3871   END;
3872   -- For Commit system errors this item attribute gets populated
3873   BEGIN
3874     l_ntf_err_text := wf_engine.GetItemAttrText(
3875                                  itemtype => p_itemType,
3876                                  itemkey  => p_itemKey,
3877                                  aname    => 'ERROR_MESSAGE_TEXT');
3878     EXCEPTION
3879     WHEN OTHERS THEN
3880         NULL;
3881   END;
3882   l_errors := 'N';
3883   IF (l_ntf_err_text is not NULL)
3884   THEN
3885     l_errors := 'Y';
3886     hr_utility.set_message(800, 'HRSSA_TXN_ERROR_MSG');
3887     hr_utility.set_message_token('ERROR_MESSAGE', l_ntf_err_text);
3888     hr_multi_message.add( p_message_type => hr_multi_message.G_ERROR_MSG);
3889   END IF;
3890   IF (l_ntf_name = 'HR_EMBED_NTF_PAY_CONTACT_MSG')
3891   THEN
3892     l_sal_basis_change_token := wf_engine.GetItemAttrText(
3893                                  itemtype => p_itemType,
3894                                  itemkey  => p_itemKey,
3895                                  aname    => 'HR_SALARY_BASIS_CHANGE_TOKEN');
3896     l_current_person_display_name := wf_engine.GetItemAttrText(
3897                                  itemtype => p_itemType,
3898                                  itemkey  => p_itemKey,
3899                                  aname    => 'CURRENT_PERSON_DISPLAY_NAME');
3900     l_process_display_name := wf_engine.GetItemAttrText(
3901                                  itemtype => p_itemType,
3902                                  itemkey  => p_itemKey,
3903                                  aname    => 'PROCESS_DISPLAY_NAME');
3904     l_note_from_requestor := wf_engine.GetItemAttrText(
3905                                  itemtype => p_itemType,
3906                                  itemkey  => p_itemKey,
3907                                  aname    => 'APPROVAL_COMMENT_COPY');
3908 
3909     hr_utility.set_message(800, 'HRSSA_MID_PAY_PERIOD_MSG');
3910     hr_utility.set_message_token('SALARY_BASIS_CHANGE_TOKEN', l_sal_basis_change_token);
3911     hr_utility.set_message_token('CURRENT_PERSON_DISPLAY_NAME', l_current_person_display_name);
3912     hr_utility.set_message_token('PROCESS_DISPLAY_NAME',l_process_display_name);
3913     hr_multi_message.add( p_message_type => hr_multi_message.G_INFORMATION_MSG);
3914 
3915     hr_utility.set_message(800, 'HRSSA_NOTE_FROM_REQUESTOR');
3916     hr_utility.set_message_token('NOTE_FROM_REQUESTOR', l_note_from_requestor);
3917     hr_multi_message.add( p_message_type => hr_multi_message.G_INFORMATION_MSG);
3918     l_errors := 'Y';
3919   ELSIF (l_ntf_name = 'HR_EMBED_ON_APPR_NTFY_HR_REP')
3920   THEN
3921     hr_utility.set_message(800, 'HRSSA_INTRVN_ACTION_MSG');
3922     hr_multi_message.add( p_message_type => hr_multi_message.G_INFORMATION_MSG);
3923     hr_utility.set_message(800, 'HRSSA_CANCEL_ACTION_MSG');
3924     hr_multi_message.add( p_message_type => hr_multi_message.G_INFORMATION_MSG);
3925     l_errors := 'Y';
3926   ELSIF (l_ntf_name = 'HR_EMBED_V5_RFC_OTHER' or l_ntf_name = 'HR_EMBED_V5_RFC_INITIATOR')
3927   THEN
3928     l_note_from_approver := wf_engine.GetItemAttrText(
3929                                  itemtype => p_itemType,
3930                                  itemkey  => p_itemKey,
3931                                  aname    => 'NOTE_FROM_APPR');
3932     hr_utility.set_message(800, 'HRSSA_NOTE_FROM_APPR');
3933     hr_utility.set_message_token('NOTE_FROM_APPR', l_note_from_approver);
3934     hr_multi_message.add( p_message_type => hr_multi_message.G_INFORMATION_MSG);
3935     l_errors := 'Y';
3936   ELSIF (l_ntf_name = 'HR_EMBED_TXN_ERROR_MSG')
3937   THEN
3938     l_error_message := wf_engine.GetItemAttrText(
3939                                  itemtype => p_itemType,
3940                                  itemkey  => p_itemKey,
3941                                  aname    => 'ERROR_MESSAGE');
3942     hr_utility.set_message(800, 'HRSSA_TXN_ERROR_MSG');
3943     hr_utility.set_message_token('ERROR_MESSAGE', l_error_message);
3944     hr_multi_message.add( p_message_type => hr_multi_message.G_ERROR_MSG);
3945     hr_utility.set_message(800, 'HRSSA_CANCEL_ACTION_MSG');
3946     hr_multi_message.add( p_message_type => hr_multi_message.G_INFORMATION_MSG);
3947     l_errors := 'Y';
3948   END IF;
3949 
3950   hr_approval_ss.checktransactionstate(wf_engine.getitemattrnumber
3951                                             (itemtype => p_itemType
3952                                             ,itemkey  => p_itemKey
3953                                           ,aname    => 'TRANSACTION_ID'));
3954 
3955   if(hr_utility.check_warning) Then
3956    l_errors := 'Y';
3957    hr_utility.clear_warning;
3958   end if;
3959 
3960   RETURN l_errors;
3961 END set_developer_ntf_msg;
3962 
3963 PROCEDURE get_curr_notified_activity (
3964         p_itemType      IN VARCHAR2
3965        ,p_itemKey       IN VARCHAR2
3966        ,p_activityId    OUT NOCOPY NUMBER
3967        ) IS
3968 --
3969 l_activityId    NUMBER(20);
3970 
3971 
3972   CURSOR cur_wf IS
3973    SELECT process_activity
3974             FROM   WF_ITEM_ACTIVITY_STATUSES IAS
3975              WHERE  ias.item_type          = p_itemType
3976                AND    ias.item_key           = p_itemKey
3977                AND    ias.activity_status    = 'NOTIFIED'
3978                ORDER BY begin_date DESC, execution_time DESC;
3979 --
3980   BEGIN
3981        IF ( cur_wf%ISOPEN ) THEN
3982          CLOSE cur_wf;
3983        END IF;
3984        --
3985        OPEN  cur_wf;
3986        FETCH cur_wf  INTO l_activityId;
3987        CLOSE cur_wf;
3988 
3989        p_activityId := l_activityId;
3990   --
3991   EXCEPTION
3992       WHEN OTHERS THEN
3993            raise;
3994   --
3995   END get_curr_notified_activity;
3996 END; -- Package Body PQH_SS_WORKFLOW;