DBA Data[Home] [Help]

PACKAGE BODY: APPS.AMW_PROC_APPROVAL_PKG

Source


1 PACKAGE BODY AMW_PROC_APPROVAL_PKG as
2 /*$Header: amwapprb.pls 120.3 2006/04/04 09:15:14 appldev noship $*/
3 
4 G_PKG_NAME CONSTANT VARCHAR2(30):= 'AMW_PROC_APPROVAL_PKG';
5 G_FILE_NAME CONSTANT VARCHAR2(12) := 'amwapprb.pls';
6 G_USER_ID NUMBER := FND_GLOBAL.USER_ID;
7 G_LOGIN_ID NUMBER := FND_GLOBAL.CONC_LOGIN_ID;
8 
9 -- process submitted for approval
10 -- change status to PA and lock subprocesses
11 --NPANANDI 11.26.2004, ADDED P_WEBADI_CALL PARAMETER
12 --BECAUSE WHEN THIS IS CALLED FROM WEBADI, WE DON'T WANT TO CALL
13 --CHECK_HIER_APPROVED PROCEDURE
14 procedure sub_for_approval (
15    p_process_id in number
16   ,p_webadi_call in varchar2 := NULL) is
17 approv_choice varchar2(10);
18 dummy1 varchar2(1);
19 dummy2 varchar2(1000);
20 begin
21 
22 -- get the approval parameter for risk library
23     approv_choice := amw_utility_pvt.get_parameter(-1, 'PROCESS_APPROVAL_OPTION');
24 
25 -- error out if at least one risk or control associated with this process
26 -- does not have any approved revision.
27     prod_err_unapr_obj_ass_ex (p_process_id, approv_choice, 'Y', dummy1, dummy2);
28 
29 -- assuming that the process is in Draft status, otherwise you can't submit it for approval.
30     update amw_process
31     set approval_status = 'PA'
32     where process_id = p_process_id
33     and end_date is null;
34 
35 -- approval choice cases:
36 -- (1) approve everything below
37 --          lock the process and all processes below,
38 --          note that the status of the downward processes do not change
39 -- (2) approve the process independently
40 --          lock only the process and its children
41 -- (3) don't approve unless everything below is approved.
42 --          same as (1)
43 
44     insert into amw_process_locks
45     (organization_id,
46     locking_process_id,
47     locked_process_id,
48     LAST_UPDATE_DATE,
49     LAST_UPDATED_BY,
50     LAST_UPDATE_LOGIN,
51     CREATION_DATE,
52     CREATED_BY,
53     object_version_number)
54     values
55     (
56     -1,
57     p_process_id,
58     p_process_id,
59     sysdate,
60     G_USER_ID,
61     G_LOGIN_ID,
62     sysdate,
63     G_USER_ID,
64     1
65     );
66 
67     if (approv_choice = 'B') then
68 
69         insert into amw_process_locks
70         (organization_id,
71         locking_process_id,
72         locked_process_id,
73 	LAST_UPDATE_DATE,
74 	LAST_UPDATED_BY,
75 	LAST_UPDATE_LOGIN,
76 	CREATION_DATE,
77 	CREATED_BY,
78 	object_version_number)
79         (select -1, p_process_id, parent_child_id, sysdate, G_USER_ID, G_LOGIN_ID,
80 sysdate, G_USER_ID, 1
81         from amw_proc_hierarchy_denorm
82         where process_id = p_process_id
83         and up_down_ind = 'D'
84         and hierarchy_type = 'L');
85 
86     elsif (approv_choice = 'A') then
87 
88         insert into amw_process_locks
89         (organization_id,
90         locking_process_id,
91         locked_process_id,
92 	LAST_UPDATE_DATE,
93 	LAST_UPDATED_BY,
94 	LAST_UPDATE_LOGIN,
95 	CREATION_DATE,
96 	CREATED_BY,
97 	object_version_number)
98         (select -1, p_process_id, child_process_id, sysdate, G_USER_ID, G_LOGIN_ID,
99 sysdate, G_USER_ID, 1
100         from amw_latest_hierarchy_rl_v
101         where parent_process_id = p_process_id);
102 
103     elsif (approv_choice = 'C') then
104 
105 	    --NPANANDI 11.26.2004, ADDED P_WEBADI_CALL PARAMETER
106 		--BECAUSE WHEN THIS IS CALLED FROM WEBADI, WE DON'T WANT TO CALL
107 		--CHECK_HIER_APPROVED PROCEDURE
108 	    IF(P_WEBADI_CALL IS NULL) THEN
109            check_hier_approved(p_process_id);
110 		END IF;
111 
112         insert into amw_process_locks
113         (organization_id,
114         locking_process_id,
115         locked_process_id,
116 	LAST_UPDATE_DATE,
117 	LAST_UPDATED_BY,
118 	LAST_UPDATE_LOGIN,
119 	CREATION_DATE,
120 	CREATED_BY,
121 	object_version_number)
122         (select -1, p_process_id, parent_child_id,  sysdate, G_USER_ID, G_LOGIN_ID,
123 sysdate, G_USER_ID, 1
124         from amw_proc_hierarchy_denorm
125         where process_id = p_process_id
126         and up_down_ind = 'D'
127         and hierarchy_type = 'L');
128     end if;
129 
130 end sub_for_approval;
131 
132 
133 -- process approved: update amw_process, change status to A
134 -- unlock process(es)
135 -- write into amw_approved_hierarchy
136 -- update the association_tables
137 -- update amw_proc_hierarchy_denorm table where hierarchy_type = 'A'
138 procedure approve(p_process_id in number) is
139 
140 rev_num number;
141 approv_choice varchar2(10);
142 curr_app_status  varchar2(10);
143 
144  cursor c1 (p_process_id number) is
145 /*
146  * ko .. We need to update only draft children
147  * select parent_child_id
148         from amw_proc_hierarchy_denorm
149         where process_id = p_process_id
150         and up_down_ind = 'D'
151         and hierarchy_type = 'L';
152 */
153 	select ah.parent_child_id
154         from amw_proc_hierarchy_denorm ah,
155             amw_process ap
156         where ah.process_id = p_process_id
157         and ah.up_down_ind = 'D'
158         and ah.hierarchy_type = 'L'
159         and ah.parent_child_id = ap.process_id
160         and ap.end_date is null
161         and ap.approval_date is null;
162 
163  c1_rec c1%rowtype;
164 
165 begin
166 
167     APPROV_TXN_DATE := sysdate;
168 -- check if the process is already approved, in that case, return
169     select approval_status
170     into curr_app_status
171     from amw_process
172     where process_id = p_process_id
173     and end_date is null;
174 
175     if curr_app_status = 'A' then
176         return;
177     end if;
178 
179 
180 -- release locks
181     approv_choice := amw_utility_pvt.get_parameter(-1, 'PROCESS_APPROVAL_OPTION');
182 
183     delete from amw_process_locks
184     where organization_id = -1
185     and locking_process_id = p_process_id;
186 
187     update amw_process
188     set approval_status = 'A',
189     approval_date = APPROV_TXN_DATE
190     where process_id = p_process_id
191     and end_date is null
192     returning revision_number into rev_num;
193 
194     if rev_num > 1 then
195         update amw_process
196         set approval_end_date = APPROV_TXN_DATE
197         where process_id = p_process_id
198         and revision_number = (rev_num-1);
199     end if;
200 
201 
202     --kosriniv ..Need to update the org count...
203     AMW_RL_HIERARCHY_PKG.update_org_count(p_process_id => p_process_id);
204     approve_associations(p_process_id);
205     write_approved_hierarchy(p_process_id, 2);
206 
207 
208     if (approv_choice = 'B') then
209 
210       for c1_rec in c1(p_process_id) loop
211     	  exit when c1%notfound;
212                 update amw_process
213                 set approval_status = 'A',
214                 approval_date = APPROV_TXN_DATE
215                 where process_id = c1_rec.parent_child_id
216                 and end_date is null
217                 returning revision_number into rev_num;
218 
219                 if rev_num > 1 then
220                     update amw_process
221                     set approval_end_date = APPROV_TXN_DATE
222                     where process_id = c1_rec.parent_child_id
223                     and revision_number = (rev_num-1);
224                 end if;
225 		--kosriniv ..Need to update the org count...
226 		AMW_RL_HIERARCHY_PKG.update_org_count(p_process_id => c1_rec.parent_child_id );
227                 approve_associations(c1_rec.parent_child_id);
228                 write_approved_hierarchy(p_process_id, 2);
229       end loop;
230 
231     end if;
232 
233     write_approved_hierarchy(p_process_id, 1);
234     amw_rl_hierarchy_pkg.update_approved_denorm(-1);
235     amw_rl_hierarchy_pkg.update_appr_control_counts;
236     amw_rl_hierarchy_pkg.update_appr_risk_counts;
237 
238 end approve;
239 
240 
241 -- process approval rejected
242 -- change status D and unlock
243 procedure reject (p_process_id in number) is
244 
245 begin
246     update amw_process
247     set approval_status = 'D'
248     where process_id = p_process_id
249     and end_date is null;
250 
251     delete from amw_process_locks
252     where organization_id = -1
253     and locking_process_id = p_process_id;
254 
255 end reject;
256 
257 
258 -- check that all processes below are approved, else produce error
259 procedure check_hier_approved(p_process_id in number) is
260 
261 unappr_xst_excpt exception;
262 err_msg varchar2(4000);
263 l_dummy number;
264 
265 begin
266 
267     begin
268         select 1 --parent_child_id, a.approval_status
269         into l_dummy
270         from amw_proc_hierarchy_denorm d, amw_process a
271         where d.process_id = p_process_id
272         and up_down_ind = 'D'
273         and hierarchy_type = 'L'
274         and a.process_id = d.parent_child_id
275         and a.end_date is null
276         and a.approval_status <> 'A';
277 
278         raise unappr_xst_excpt;
279     exception
280         when no_data_found then
281             null;
282 
283         when too_many_rows then
284             raise unappr_xst_excpt;
285     end;
286 
287 exception
288 
289     when unappr_xst_excpt then
290          rollback;
291          fnd_message.set_name('AMW','AMW_UNAPPROV_PROC_DOWN');
292          err_msg := fnd_message.get;
293          fnd_msg_pub.add_exc_msg(p_pkg_name  =>    'amw_proc_approval_pkg',
294                    	     p_procedure_name =>   'check_hier_approved',
295   	                     p_error_text => err_msg);
296          raise;
297 
298 end check_hier_approved;
299 
300 
301 procedure approve_associations(p_process_id in number) is
302 
303 begin
304     update amw_risk_associations
305     set approval_date = APPROV_TXN_DATE
306     where pk1 = p_process_id
307     and object_type = 'PROCESS'
308     and approval_date is null;
309 
310     update amw_risk_associations
311     set deletion_approval_date = APPROV_TXN_DATE
312     where pk1 = p_process_id
313     and object_type = 'PROCESS'
314     and deletion_date is not null
315     and deletion_approval_date is null;
316 
317     update amw_control_associations
318     set approval_date = APPROV_TXN_DATE
319     where pk1 = p_process_id
320     and object_type = 'RISK'
321     and approval_date is null;
322 
323     update amw_control_associations
324     set deletion_approval_date = APPROV_TXN_DATE
325     where pk1 = p_process_id
326     and object_type = 'RISK'
327     and deletion_date is not null
328     and deletion_approval_date is null;
329 
330     update amw_acct_associations
331     set approval_date = APPROV_TXN_DATE
332     where pk1 = p_process_id
333     and object_type = 'PROCESS'
334     and approval_date is null;
335 
336     update amw_acct_associations
337     set deletion_approval_date = APPROV_TXN_DATE
338     where pk1 = p_process_id
339     and object_type = 'PROCESS'
340     and deletion_date is not null
341     and deletion_approval_date is null;
342 
343     update amw_objective_associations
344     set approval_date = APPROV_TXN_DATE
345     where pk1 = p_process_id
346     and object_type in ('PROCESS', 'CONTROL')
347     and approval_date is null;
348 
349     update amw_objective_associations
350     set deletion_approval_date = APPROV_TXN_DATE
351     where pk1 = p_process_id
352     and object_type in ('PROCESS', 'CONTROL')
353     and deletion_date is not null
357     set approval_date = APPROV_TXN_DATE
354     and deletion_approval_date is null;
355 
356     update amw_significant_elements
358     where pk1 = p_process_id
359     and object_type = 'PROCESS'
360     and approval_date is null;
361 
362     update amw_significant_elements
363     set deletion_approval_date = APPROV_TXN_DATE
364     where pk1 = p_process_id
365     and object_type = 'PROCESS'
366     and deletion_date is not null
367     and deletion_approval_date is null;
368 
369 end approve_associations;
370 
371 
372 
373 -- this procedure has three steps, for execution of three cursors that are explained below.
374 procedure write_approved_hierarchy(
375    p_process_id in number,
376    p_step in number) is
377 
378             -- "approved" links that are in the latest hierarchy but not in the approved
379             -- hierarchy => links to be transferred to the approved hierarchy.
380             -- the assumption is that we do not manipulate the order_number data,
381             -- i.e. we faithfully store the exact number the sequence generates or user enters
382             -- and copy that number to the approved hierarchy.
383             -- executed when step = 1
384             CURSOR c1 is
385                (select parent_process_id,
386 			           child_process_id,
387 					   child_order_number
388                   from (select *
389 				          from amw_latest_hierarchy_rl_v
390 						 where parent_approval_status = 'A'
391 						   and child_approval_status = 'A')
392                   start with parent_process_id = -1
393                 connect by prior child_process_id = parent_process_id)
394                 MINUS
395                 (select parent_process_id,
396 				        child_process_id,
397 						child_order_number
398 				   from AMW_CURR_APP_HIERARCHY_RL_V);
399 
400             -- these links must be deleted from the approved hierarchy
401             -- executed when step = 2
402 			CURSOR c2 is
403 			 (select parent_process_id,
404 			         child_process_id
405 			    from AMW_CURR_APP_HIERARCHY_RL_V
406 			   where parent_process_id = p_process_id)
407 			 MINUS
408 			 (select parent_process_id,
409 			         child_process_id
410 				from amw_latest_hierarchy_rl_v
411 			   where parent_process_id = p_process_id);
412 
413 
414 			-- 05.11.2005 npanandi: added below cursor for WebADI call
415 			-- c2_1 is the same as c2 above, exception that it does not
416 			-- take pProcessId as a bind variable
417 			CURSOR c2_1 is
418 			 (select parent_process_id,
419 			         child_process_id
420 			    from AMW_CURR_APP_HIERARCHY_RL_V)
421 			 MINUS
422 			 (select parent_process_id,
423 			         child_process_id
424 				from amw_latest_hierarchy_rl_v);
425 
426 
427 			-- as a result of the children being removed in c2 some links may become
428             -- defunct in the approved hierarchy ... we must remove those links
429             -- executed when step = 1
430 			CURSOR c3 is
431 			  (select parent_process_id,
432 			          child_process_id
433 				 from AMW_CURR_APP_HIERARCHY_RL_V
434                 where parent_process_id is not null)
435 			  MINUS
436 			  (select parent_process_id,
437 			          child_process_id
438 				 from AMW_CURR_APP_HIERARCHY_RL_V
439 			    start with parent_process_id = -1
440 			  connect by prior child_process_id = parent_process_id);
441 BEGIN
442    if ( (p_step = 1) or (p_step = 0) ) then
443       for a_link in c1 loop
444          insert into amw_approved_hierarchies(
445 		    organization_id,
446 			parent_id,
447 			child_id,
448 			start_date,
449 			child_order_number,
450 			LAST_UPDATE_DATE,
451 			LAST_UPDATED_BY,
452 			LAST_UPDATE_LOGIN,
453 			CREATION_DATE,
454 			CREATED_BY,
455 			object_version_number
456 		 )values(
457 		    -1,
458 			a_link.parent_process_id,
459 			a_link.child_process_id,
460 			APPROV_TXN_DATE,
461 			a_link.child_order_number,
462 			sysdate,
463 			G_USER_ID,
464 			G_LOGIN_ID,
465 			sysdate,
466 			G_USER_ID,
467 			1
468 		 );
469       end loop;
470    end if;
471 
472    if p_step = 2 then
473       for defunct_link in c2 loop
474 		 update amw_approved_hierarchies
475 		    set end_date = APPROV_TXN_DATE,
476 		        object_version_number = object_version_number + 1
477 		  where organization_id = -1
478 		    and parent_id = defunct_link.parent_process_id
479 		    and child_id = defunct_link.child_process_id
480 		    and end_date is null;
481       end loop;
482    end if;
483 
484    if ( (p_step = 1) or (p_step = 3) ) then
485       for defunct_link in c3 loop
486          update amw_approved_hierarchies
487 			set end_date = APPROV_TXN_DATE,
488 			    object_version_number = object_version_number + 1
489 		  where organization_id = -1
490 			and parent_id = defunct_link.parent_process_id
491 			and child_id = defunct_link.child_process_id
492 			and end_date is null;
493       end loop;
494    end if;
495 
496    ---05.11.2005 npanandi: added below step to club the above actions
497    ---when calling this procedure from WebADI
498    if(p_step=4) then
499       for a_link in c1 loop
500          insert into amw_approved_hierarchies(
501 		    organization_id,
502 			parent_id,
503 			child_id,
504 			start_date,
505 			child_order_number,
506 			LAST_UPDATE_DATE,
507 			LAST_UPDATED_BY,
508 			LAST_UPDATE_LOGIN,
509 			CREATION_DATE,
510 			CREATED_BY,
511 			object_version_number
512 		 )values(
513 		    -1,
514 			a_link.parent_process_id,
518 			sysdate,
515 			a_link.child_process_id,
516 			APPROV_TXN_DATE,
517 			a_link.child_order_number,
519 			G_USER_ID,
520 			G_LOGIN_ID,
521 			sysdate,
522 			G_USER_ID,
523 			1
524 		 );
525       end loop;
526 
527 	  for defunct_link in c2_1 loop
528 		 update amw_approved_hierarchies
529 		    set end_date              = APPROV_TXN_DATE
530 		       ,object_version_number = object_version_number + 1
531 			   ,last_update_date      = sysdate
532 			   ,last_updated_by       = G_USER_ID
533 			   ,last_update_login     = G_LOGIN_ID
534 		  where organization_id = -1
535 		    and parent_id = defunct_link.parent_process_id
536 		    and child_id = defunct_link.child_process_id
537 		    and end_date is null;
538       end loop;
539 
540 	  for defunct_link in c3 loop
541          update amw_approved_hierarchies
542 			set end_date              = APPROV_TXN_DATE,
543 			    object_version_number = object_version_number + 1
544 			   ,last_update_date      = sysdate
545 			   ,last_updated_by       = G_USER_ID
546 			   ,last_update_login     = G_LOGIN_ID
547 		  where organization_id = -1
548 			and parent_id = defunct_link.parent_process_id
549 			and child_id = defunct_link.child_process_id
550 			and end_date is null;
551       end loop;
552    end if; --end of check for step = 4
553 end write_approved_hierarchy;
554 
555 
556 procedure prod_err_unapr_obj_ass_ex (p_process_id in number,
557                                      approve_option in varchar2,
558                                      raise_ex in varchar2,
559                                      p_result out nocopy varchar2,
560                                      p_out_mesg out nocopy varchar2 ) is
561 
562 cursor process_list (pid number) is
563         select parent_child_id
564         from amw_proc_hierarchy_denorm
565         where process_id = pid
566         and up_down_ind = 'D'
567         and hierarchy_type = 'L'
568         union
569         select pid from dual;
570 
571 cursor ass_risks (pid number) is
572     select risk_id from amw_risk_associations where pk1 = pid and object_type = 'PROCESS';
573 
574 cursor ass_controls (pid number) is
575     select control_id from amw_control_associations where pk1 = pid and object_type = 'RISK';
576 
577 l_dummy number;
578 unappr_obj_exception  exception;
579 err_msg varchar2(4000);
580 
581 begin
582 
583     p_result := 'Y';
584     p_out_mesg := null;
585 
586     if approve_option = 'B' then
587 
588    			for process_list_rec in process_list(p_process_id) loop
589 
590     			for ass_risks_rec in ass_risks(process_list_rec.parent_child_id) loop
591 
592                     begin
593                         select 1
594                         into l_dummy
595                         from amw_risks_b
596                         where risk_id = ass_risks_rec.risk_id
597                         and approval_status = 'A';
598 
599                     exception
600                         when too_many_rows then
601                                 null;
602                         when no_data_found then
603                                 raise unappr_obj_exception;
604                     end;
605 
606     			end loop;
607 
608 
609     			for ass_controls_rec in ass_controls(process_list_rec.parent_child_id) loop
610 
611                     begin
612                         select 1
613                         into l_dummy
614                         from amw_controls_b
615                         where control_id = ass_controls_rec.control_id
616                         and approval_status = 'A';
617 
618                     exception
619                         when too_many_rows then
620                                 null;
621                         when no_data_found then
622                                 raise unappr_obj_exception;
623                     end;
624 
625     			end loop;
626 
627             end loop;
628     else
629     			for ass_risks_rec in ass_risks(p_process_id) loop
630 
631                     begin
632                         select 1
633                         into l_dummy
634                         from amw_risks_b
635                         where risk_id = ass_risks_rec.risk_id
636                         and approval_status = 'A';
637 
638                     exception
639                         when too_many_rows then
640                                 null;
641                         when no_data_found then
642                                 raise unappr_obj_exception;
643                     end;
644 
645     			end loop;
646 
647 
648     			for ass_controls_rec in ass_controls(p_process_id) loop
649 
650                     begin
651                         select 1
652                         into l_dummy
653                         from amw_controls_b
654                         where control_id = ass_controls_rec.control_id
655                         and approval_status = 'A';
656 
657                     exception
658                         when too_many_rows then
659                                 null;
660                         when no_data_found then
661                                 raise unappr_obj_exception;
662                     end;
663 
664     			end loop;
665 
666     end if;
667 
668 exception
669 
670     when unappr_obj_exception then
671          fnd_message.set_name('AMW','AMW_UNAPPRV_ASSOC');
672          err_msg := fnd_message.get;
673          if raise_ex = 'Y' then
674              fnd_msg_pub.add_exc_msg(p_pkg_name  =>    'AMW_PROC_APPROVAL_PKG',
675                    	     p_procedure_name =>   'prod_err_unapr_obj_ass_ex',
676   	                     p_error_text => err_msg);
677              raise;
678          else
679              p_result := 'N';
680              p_out_mesg := err_msg;
681          end if;
682 
683 end prod_err_unapr_obj_ass_ex;
684 
685 
686 
687 procedure autoapprove(
688 p_process_id            in number,
689 p_commit			    in varchar2 := FND_API.G_FALSE,
690 p_validation_level		IN NUMBER := FND_API.G_VALID_LEVEL_FULL,
691 p_init_msg_list			IN VARCHAR2 := FND_API.G_FALSE,
692 x_return_status			out nocopy varchar2,
693 x_msg_count			    out nocopy number,
694 x_msg_data			    out nocopy varchar2 )
695 
696 is
697 
698 L_API_NAME CONSTANT VARCHAR2(30) := 'autoapprove';
699 l_return_status	 varchar2(10);
700 l_msg_count	 number;
701 l_msg_data	 varchar2(4000);
702 
703 begin
704 
705   x_return_status := FND_API.G_RET_STS_SUCCESS;
706   IF FND_API.to_Boolean( p_init_msg_list )  THEN
707      FND_MSG_PUB.initialize;
708   END IF;
709   IF FND_GLOBAL.User_Id IS NULL THEN
710     AMW_Utility_PVT.Error_Message(p_message_name => 'USER_PROFILE_MISSING');
711     RAISE FND_API.G_EXC_ERROR;
712   END IF;
713 
714     sub_for_approval (p_process_id);
715     approve(p_process_id);
716 
717 exception
718 
719   WHEN FND_API.G_EXC_ERROR THEN
720      ROLLBACK;
721      x_return_status := FND_API.G_RET_STS_ERROR;
722      FND_MSG_PUB.Count_And_Get(p_encoded => FND_API.G_FALSE,p_count =>
723 x_msg_count,p_data => x_msg_data);
724 
725   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
726      ROLLBACK;
727      x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
728      FND_MSG_PUB.Count_And_Get(p_encoded => FND_API.G_FALSE,p_count =>
729 x_msg_count,p_data => x_msg_data);
730 
731   WHEN OTHERS THEN
732      ROLLBACK;
733      x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
734      IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
735      THEN
736         FND_MSG_PUB.Add_Exc_Msg(G_PKG_NAME,l_api_name);
737      END IF;
738      FND_MSG_PUB.Count_And_Get (p_encoded => FND_API.G_FALSE,p_count => x_msg_count,
739 p_data => x_msg_data);
740 
741 end autoapprove;
742 
743 
744 -- check that all processes below are approved, else produce error
745 -- overloaded so as not to produce an expection
746 procedure check_hier_approved(p_process_id in number,
747                               p_result out nocopy varchar2,
748                               p_out_mesg out nocopy varchar2) is
749 
750 unappr_xst_excpt exception;
751 err_msg varchar2(4000);
752 l_dummy number;
753 
754 begin
755     p_result := 'Y';
756     p_out_mesg := null;
757     begin
758         select 1 --parent_child_id, a.approval_status
759         into l_dummy
760         from amw_proc_hierarchy_denorm d, amw_process a
761         where d.process_id = p_process_id
762         and up_down_ind = 'D'
763         and hierarchy_type = 'L'
764         and a.process_id = d.parent_child_id
765         and a.end_date is null
766         and a.approval_status <> 'A';
767 
768         raise unappr_xst_excpt;
769     exception
770         when no_data_found then
771             null;
772 
773         when too_many_rows then
774             raise unappr_xst_excpt;
775     end;
776 
777 exception
778 
779     when unappr_xst_excpt then
780          fnd_message.set_name('AMW','AMW_UNAPPROV_PROC_DOWN');
781          err_msg := fnd_message.get;
782          p_result := 'N';
783          p_out_mesg := err_msg;
784 
785 end check_hier_approved;
786 
787 --port
788 /*
789 Produce error if:
790 1. approval option says "Don't approve this unless everything below is approved". There's at least one process below that is NOT approved.
791 2. there's at least one risk associated (to this process / any process in the downward hierarchy, depending on the approval option) that does not have an approved revision.
792 3. there's at least one control associated (to this process / any process in the downward hierarchy, depending on the approval option) that does not have an approved revision.
793 4. the process is non-standard, and the standard variation does not have an approved revision.
794 5. the process is non-standard and the list of children in the latest hierarchy is not the same as the list of children recorded in the variations table.
795 */
796 procedure check_approval_subm_eligib(
797 p_process_id            in number,
798 p_result                out nocopy varchar2,
799 p_out_mesg              out nocopy varchar2,
800 p_commit			    in varchar2 := FND_API.G_FALSE,
801 p_validation_level		IN NUMBER := FND_API.G_VALID_LEVEL_FULL,
802 p_init_msg_list			IN VARCHAR2 := FND_API.G_FALSE,
803 x_return_status			out nocopy varchar2,
804 x_msg_count			    out nocopy number,
805 x_msg_data			    out nocopy varchar2 )
806 
807 is
808 
809 L_API_NAME CONSTANT VARCHAR2(30) := 'check_approval_subm_eligib';
810 l_return_status	 varchar2(10);
811 l_msg_count	 number;
812 l_msg_data	 varchar2(4000);
813 approv_choice  varchar2(1);
814 std_process varchar2(1);
815 st_var_pid number;
816 
817 begin
818 
819   x_return_status := FND_API.G_RET_STS_SUCCESS;
820   IF FND_API.to_Boolean( p_init_msg_list )  THEN
821      FND_MSG_PUB.initialize;
822   END IF;
823   IF FND_GLOBAL.User_Id IS NULL THEN
824     AMW_Utility_PVT.Error_Message(p_message_name => 'USER_PROFILE_MISSING');
825     RAISE FND_API.G_EXC_ERROR;
826   END IF;
827 
828     p_result := 'Y';
829     p_out_mesg := null;
830 
831     approv_choice := amw_utility_pvt.get_parameter(-1, 'PROCESS_APPROVAL_OPTION');
832 
833     if (approv_choice = 'C') then
834           check_hier_approved(p_process_id, p_result, p_out_mesg);
835           if p_result = 'N' then
836             return;
837           end if;
838     end if;
839 
840     prod_err_unapr_obj_ass_ex (p_process_id, approv_choice, 'N', p_result, p_out_mesg);
841     if p_result = 'N' then
842         return;
843     end if;
844 
845     prod_err_unappr_nsvar (p_process_id, approv_choice, p_result, p_out_mesg);
846     if p_result = 'N' then
847         return;
848     end if;
849 
850     prod_err_modified_nschildlist (p_process_id, approv_choice, p_result, p_out_mesg);
851     if p_result = 'N' then
852         return;
853     end if;
854 
855 exception
856 
857   WHEN FND_API.G_EXC_ERROR THEN
858      ROLLBACK;
859      x_return_status := FND_API.G_RET_STS_ERROR;
860      FND_MSG_PUB.Count_And_Get(p_encoded => FND_API.G_FALSE,p_count => x_msg_count,p_data => x_msg_data);
861 
862   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
863      ROLLBACK;
864      x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
865      FND_MSG_PUB.Count_And_Get(p_encoded => FND_API.G_FALSE,p_count => x_msg_count,p_data => x_msg_data);
866 
867   WHEN OTHERS THEN
868      ROLLBACK;
869      x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
870      IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
871      THEN
872         FND_MSG_PUB.Add_Exc_Msg(G_PKG_NAME,l_api_name);
873      END IF;
874      FND_MSG_PUB.Count_And_Get (p_encoded => FND_API.G_FALSE,p_count => x_msg_count, p_data => x_msg_data);
875 
876 end check_approval_subm_eligib;
877 
878 
879 
880 procedure prod_err_unappr_nsvar(p_process_id in number,
881                                 approve_option in varchar2,
882                                 p_result out nocopy varchar2,
883                                 p_out_mesg out nocopy varchar2) is
884 
885 cursor process_list (pid number) is
886         select parent_child_id
887         from amw_proc_hierarchy_denorm
888         where process_id = pid
889         and up_down_ind = 'D'
890         and hierarchy_type = 'L'
891         union
892         select pid from dual;
893 
894 std_process varchar2(1);
895 st_var_pid number;
896 l_dummy number;
897 
898 begin
899     -- standard variation treatment
900     -- I could probably have made good use for cursor variables here
901 
902 if approve_option = 'B' then
903     for process_list_rec in process_list(p_process_id) loop
904 
905 	begin
906 
907         select a.standard_process_flag, b.process_id
908         into std_process, st_var_pid
909         from amw_process a, amw_process b
910         where a.process_id = process_list_rec.parent_child_id
911         and a.end_date is null
912         and b.process_rev_id = a.standard_variation;
913 
914 	exception
915 		when no_data_found then --process is standard/non-std but no var defined
916 			std_process := 'Y';
917 	end;
918 
919         if std_process = 'N' then -- if process is non-standard
920             begin
921                 select 1
922                 into l_dummy
923                 from amw_process
924                 where process_id = st_var_pid
925                 and approval_status = 'A';
926 
927             exception
928                 when too_many_rows then
929                      null;
930 
931                 when no_data_found then
932                      fnd_message.set_name('AMW','AMW_NS_VAR_UNAPPROVED');
933                      p_out_mesg := fnd_message.get;
934                      p_result := 'N';
935                      return;
936             end;
937         end if;  -- if process is non-standard
938 
939     end loop;
940 else
941     begin
942     select a.standard_process_flag, b.process_id
943     into std_process, st_var_pid
944     from amw_process a, amw_process b
945     where a.process_id = p_process_id
946     and a.end_date is null
947     and b.process_rev_id = a.standard_variation;
948     exception
949 	when no_data_found then --process is standard/non-std but no var defined
950 			std_process := 'Y';
951     end;
952 
953     if std_process = 'N' then -- if process is non-standard
954 
955     begin
956         select 1
957         into l_dummy
958         from amw_process
959         where process_id = st_var_pid
960         and approval_status = 'A';
961 
962     exception
963         when too_many_rows then
964              null;
965 
966         when no_data_found then
967              fnd_message.set_name('AMW','AMW_NS_VAR_UNAPPROVED');
968              p_out_mesg := fnd_message.get;
969              p_result := 'N';
970              return;
971     end;
972 
973     end if;  -- if process is non-standard
974 
975 end if;
976 
977 end prod_err_unappr_nsvar;
978 
979 
980 procedure prod_err_modified_nschildlist(p_process_id in number,
981                                         approve_option in varchar2,
982                                         p_result out nocopy varchar2,
983                                         p_out_mesg out nocopy varchar2) is
984 
985 cursor process_list (pid number) is
986         select parent_child_id
987         from amw_proc_hierarchy_denorm
988         where process_id = pid
989         and up_down_ind = 'D'
990         and hierarchy_type = 'L'
991         union
992         select pid from dual;
993 
994 std_process varchar2(1);
995 l_std_variation amw_process.STANDARD_VARIATION%TYPE;
996 l_dummy number;
997 
998 begin
999     -- standard variation treatment
1000     -- I could probably have made good use for cursor variables here
1001 
1002 if approve_option = 'B' then
1003     for process_list_rec in process_list(p_process_id) loop
1004 
1005     select standard_process_flag,standard_variation
1006     into std_process,l_std_variation
1007     from amw_process
1008     where process_id = process_list_rec.parent_child_id
1009     and end_date is null;
1010 
1011     if std_process = 'N'  and l_std_variation is not null then
1012 
1013     begin
1014         select parent_child_id
1015         into l_dummy
1016         from amw_proc_hierarchy_denorm
1017         where process_id = process_list_rec.parent_child_id
1018         and up_down_ind = 'D'
1019         and hierarchy_type = 'L'
1020         and parent_child_id not in
1021             (select NON_STD_CHILD_ID
1022             from AMW_NONSTANDARD_VARIATIONS_B
1023             where NON_STD_PROCESS_ID = process_list_rec.parent_child_id
1024             and NON_STD_PROCESS_REV_NUM = (select revision_number
1025                                            from amw_process
1026                                            where process_id = process_list_rec.parent_child_id
1027                                            and end_date is null)
1028             and END_DATE is null);
1029 
1030              fnd_message.set_name('AMW','AMW_NS_CHILDLIST_DIFF');
1031              p_out_mesg := fnd_message.get;
1032              p_result := 'N';
1033              return;
1034 
1035     exception
1036         when no_data_found then
1037             null;
1038 
1039         when too_many_rows then
1040              fnd_message.set_name('AMW','AMW_NS_CHILDLIST_DIFF');
1041              p_out_mesg := fnd_message.get;
1042              p_result := 'N';
1043              return;
1044     end;
1045 
1046     begin
1047         select NON_STD_CHILD_ID
1048         into l_dummy
1049         from AMW_NONSTANDARD_VARIATIONS_B
1050         where NON_STD_PROCESS_ID = process_list_rec.parent_child_id
1051         and NON_STD_PROCESS_REV_NUM = (select revision_number
1052                                        from amw_process
1053                                        where process_id = process_list_rec.parent_child_id
1054                                        and end_date is null)
1055         and END_DATE is null
1056         and NON_STD_CHILD_ID not in
1057                 (select parent_child_id
1058                 from amw_proc_hierarchy_denorm
1059                 where process_id = process_list_rec.parent_child_id
1060                 and up_down_ind = 'D'
1061                 and hierarchy_type = 'L');
1062 
1063              fnd_message.set_name('AMW','AMW_NS_CHILDLIST_DIFF');
1064              p_out_mesg := fnd_message.get;
1065              p_result := 'N';
1066              return;
1067 
1068     exception
1069         when no_data_found then
1070             null;
1071 
1072         when too_many_rows then
1073              fnd_message.set_name('AMW','AMW_NS_CHILDLIST_DIFF');
1074              p_out_mesg := fnd_message.get;
1075              p_result := 'N';
1076              return;
1077     end;
1078 
1079     end if;  -- if process is non-standard
1080 
1081     end loop;
1082 else
1083     select standard_process_flag,standard_variation
1084     into std_process,l_std_variation
1085     from amw_process
1086     where process_id = p_process_id
1087     and end_date is null;
1088 
1089     if std_process = 'N' and l_std_variation is not null then
1090 
1091     begin
1092         select parent_child_id
1093         into l_dummy
1094         from amw_proc_hierarchy_denorm
1095         where process_id = p_process_id
1096         and up_down_ind = 'D'
1097         and hierarchy_type = 'L'
1098         and parent_child_id not in
1099             (select NON_STD_CHILD_ID
1100             from AMW_NONSTANDARD_VARIATIONS_B
1101             where NON_STD_PROCESS_ID = p_process_id
1102             and NON_STD_PROCESS_REV_NUM = (select revision_number
1103                                            from amw_process
1104                                            where process_id = p_process_id
1105                                            and end_date is null)
1106             and END_DATE is null);
1107 
1108              fnd_message.set_name('AMW','AMW_NS_CHILDLIST_DIFF');
1109              p_out_mesg := fnd_message.get;
1110              p_result := 'N';
1111              return;
1112 
1113     exception
1114         when no_data_found then
1115             null;
1116 
1117         when too_many_rows then
1118              fnd_message.set_name('AMW','AMW_NS_CHILDLIST_DIFF');
1119              p_out_mesg := fnd_message.get;
1120              p_result := 'N';
1121              return;
1122     end;
1123 
1124     begin
1125         select NON_STD_CHILD_ID
1126         into l_dummy
1127         from AMW_NONSTANDARD_VARIATIONS_B
1128         where NON_STD_PROCESS_ID = p_process_id
1129         and NON_STD_PROCESS_REV_NUM = (select revision_number
1130                                        from amw_process
1131                                        where process_id = p_process_id
1132                                        and end_date is null)
1133         and END_DATE is null
1134         and NON_STD_CHILD_ID not in
1135                 (select parent_child_id
1136                 from amw_proc_hierarchy_denorm
1137                 where process_id = p_process_id
1138                 and up_down_ind = 'D'
1139                 and hierarchy_type = 'L');
1140 
1141              fnd_message.set_name('AMW','AMW_NS_CHILDLIST_DIFF');
1142              p_out_mesg := fnd_message.get;
1143              p_result := 'N';
1144              return;
1145 
1146     exception
1147         when no_data_found then
1148             null;
1149 
1150         when too_many_rows then
1151              fnd_message.set_name('AMW','AMW_NS_CHILDLIST_DIFF');
1152              p_out_mesg := fnd_message.get;
1153              p_result := 'N';
1154              return;
1155     end;
1156 
1157     end if;  -- if process is non-standard
1158 
1159 end if; -- approval option B
1160 
1161 end prod_err_modified_nschildlist;
1162 
1163 ---05.11.2005 npanandi: added below procedure for handling
1164 ---webadi approvals
1165 procedure webadi_approve(
1166    p_process_id in number
1167   ,p_approv_choice in varchar2)
1168 is
1169    rev_num number;
1170    approv_choice varchar2(10);
1171    curr_app_status  varchar2(10);
1172 
1173    dummy1 varchar2(1);
1174    dummy2 varchar2(1000);
1175 
1176    cursor c1 (p_process_id number) is
1177       select parent_child_id
1178         from amw_proc_hierarchy_denorm
1179        where process_id = p_process_id
1180          and up_down_ind = 'D'
1181          and hierarchy_type = 'L';
1182    c1_rec c1%rowtype;
1183 begin
1184    -- error out if at least one risk or control associated with this process
1185    -- does not have any approved revision.
1186    prod_err_unapr_obj_ass_ex (p_process_id,p_approv_choice,'Y',dummy1,dummy2);
1187 
1188 
1189    APPROV_TXN_DATE := sysdate;
1190    -- check if the process is already approved, in that case, return
1191    select approval_status
1192      into curr_app_status
1193      from amw_process
1194     where process_id = p_process_id
1195       and end_date is null;
1196 
1197    if curr_app_status = 'A' then
1198       return;
1199    end if;
1200 
1201    /**
1202    delete from amw_process_locks
1203     where organization_id = -1
1204       and locking_process_id = p_process_id;
1205 	  **/
1206 
1207    update amw_process
1208       set approval_status = 'A',
1209           approval_date = APPROV_TXN_DATE
1210     where process_id = p_process_id
1211       and end_date is null
1212    returning revision_number into rev_num;
1213 
1214    if rev_num > 1 then
1215       update amw_process
1216          set approval_end_date = APPROV_TXN_DATE
1217        where process_id = p_process_id
1218          and revision_number = (rev_num-1);
1219    end if;
1220 
1221     --kosriniv ..Need to update the org count...
1222     AMW_RL_HIERARCHY_PKG.update_org_count(p_process_id => p_process_id);
1223 
1224    approve_associations(p_process_id);
1225    ---05.11.2005 npanandi: per Amit, not needed here, since we will be calling
1226    ---write_approved_hierarchy with step # = 4
1227    ---write_approved_hierarchy(p_process_id, 2);
1228 
1229 
1230    if (p_approv_choice = 'B') then
1231       for c1_rec in c1(p_process_id) loop
1232       exit when c1%notfound;
1233          update amw_process
1234             set approval_status = 'A',
1235                 approval_date = APPROV_TXN_DATE
1236           where process_id = c1_rec.parent_child_id
1237             and end_date is null
1238          returning revision_number into rev_num;
1239 
1240          if rev_num > 1 then
1241             update amw_process
1242                set approval_end_date = APPROV_TXN_DATE
1243              where process_id = c1_rec.parent_child_id
1244                and revision_number = (rev_num-1);
1245          end if;
1246 
1247 	    --kosriniv ..Need to update the org count...
1248 	 AMW_RL_HIERARCHY_PKG.update_org_count(p_process_id => c1_rec.parent_child_id);
1249 
1250          approve_associations(c1_rec.parent_child_id);
1251 		 ---05.11.2005 npanandi: per Amit, not needed here, since we will be calling
1252          ---write_approved_hierarchy with step # = 4
1253          ---write_approved_hierarchy(p_process_id, 2);
1254       end loop;
1255    end if;
1256 
1257 
1258    ---05.11.2005 npanandi: calling this once from the main API, hence
1259    ---commenting out here
1260    /**
1261    write_approved_hierarchy(p_process_id, 1);
1262    amw_rl_hierarchy_pkg.update_approved_denorm(-1);
1263    amw_rl_hierarchy_pkg.update_appr_control_counts;
1264    amw_rl_hierarchy_pkg.update_appr_risk_counts;
1265    **/
1266 end webadi_approve;
1267 
1268 
1269 end AMW_PROC_APPROVAL_PKG;