DBA Data[Home] [Help]

PACKAGE BODY: APPS.PQH_SS_WORKFLOW

Source


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