1 package body Fnd_User_Resp_Groups_api as
2 /* $Header: AFSCURGB.pls 120.14.12000000.3 2007/02/12 16:36:58 jvalenti ship $ */
3
4 C_PKG_NAME CONSTANT VARCHAR2(30) := 'FND_USER_RESP_GROUPS_API';
5 C_LOG_HEAD CONSTANT VARCHAR2(240)
6 := 'fnd.plsql.FND_USER_RESP_GROUPS_API.';
7
8 -- This is a one level cache used in check_secgrp_enabled.
9 G_ENABLED_RESPID NUMBER := null;
10 G_ENABLED_APPID NUMBER := null;
11 G_ENABLED_RETVAL varchar2(1) := null;
12
13
14 --
15 -- Generic_Error (Internal)
16 --
17 -- Set error message and raise exception for unexpected sql errors.
18 --
19 procedure Generic_Error(
20 routine in varchar2,
21 errcode in number,
22 errmsg in varchar2)
23 is
24 begin
25 fnd_message.set_name('FND', 'SQL_PLSQL_ERROR');
26 fnd_message.set_token('ROUTINE', routine);
27 fnd_message.set_token('ERRNO', errcode);
28 fnd_message.set_token('REASON', errmsg);
29 app_exception.raise_exception;
30 end Generic_Error;
31
32 --
33 -- Returns 'Y' if security groups are enabled for this app, 'N' otherwise.
34 --
35 function check_secgrp_enabled(respid in number, appid in number)
36 return varchar2
37 is
38 prof_value varchar2(240);
39 begin
40 /* Check one level cache first */
41 if ( (G_ENABLED_RESPID = respid)
42 and (G_ENABLED_APPID = appid)) then
43 return G_ENABLED_RETVAL;
44 end if;
45
46 prof_value := nvl(fnd_profile.value_specific(
47 'ENABLE_SECURITY_GROUPS',
48 NULL,
49 respid,
50 appid),
51 'N');
52
53 if (prof_value = 'N') then
54 G_ENABLED_RETVAL := 'N';
55 else
56 G_ENABLED_RETVAL := 'Y';
57 end if;
58
59 G_ENABLED_RESPID := respid;
60 G_ENABLED_APPID := appid;
61
62 return G_ENABLED_RETVAL;
63 end check_secgrp_enabled;
64
65
66 --
67 -- Role_Name_from_Resp_name -
68 --
69 -- Returns role name in the format FND_RESP|SECGRPKEY|APPSNAME|RESPKEY
70 -- from the names passed in
71 --
72 function Role_Name_from_Resp_name(
73 x_respkey in varchar2,
74 x_applsname in varchar2,
75 x_secgrpkey in varchar2) return varchar2 is
76 rolename varchar2(1000);
77 begin
78
79 rolename := 'FND_RESP'||'|'||
80 x_applsname||'|'||
81 x_respkey||'|'||
82 x_secgrpkey;
83
84 /* Colons are a special character that is currently not allowed in */
85 /* workflow so we work around this by replacing it with the string %col.*/
86 /* See bug 3591913. If that is fixed we might be able to remove this. */
87 rolename := replace(rolename, ':', '%col');
88
89 if(LENGTHB(rolename) > 320) then
90 /* This should never happen, but if it does, show what went wrong.*/
91 rolename := substrb('UNEXPECTED_ERROR:KEYTOOBIG:Role_Name_from_Resp:'||
92 rolename, 1, 320);
93
94 end if;
95
96 return rolename;
97 end Role_Name_from_Resp_name;
98
99 --
100 -- Role_Name_from_Resp (INTERNAL ONLY)-
101 --
102 -- Returns role name in the format FND_RESP|APPSNAME|RESPKEY|SECGRPKEY
103 -- from the security group and resp passed in.
104 --
105 function Role_Name_from_Resp(
106 x_resp_id in number,
107 x_resp_appl_id in number,
108 x_secgrp_id in number)
109 return varchar2 is
110 rolename varchar2(1000);
111 secgrpkey varchar2(30);
112 appsname varchar2(50);
113 respkey varchar2(30);
114 begin
115
116 select security_group_key
117 into secgrpkey
118 from fnd_security_groups
119 where security_group_id = x_secgrp_id;
120
121 select application_short_name
122 into appsname
123 from fnd_application
124 where application_id = x_resp_appl_id;
125
126 select responsibility_key
127 into respkey
128 from fnd_responsibility
129 where application_id = x_resp_appl_id
130 and responsibility_id = x_resp_id;
131
132 return Role_Name_from_Resp_name(respkey, appsname, secgrpkey);
133 end Role_Name_from_Resp;
134
135
136 /* This is a version of role_name_from_resp which won't return errors, */
137 /* to be used when calling from somewhere that errors can't be trapped */
138 /* like inline inside a SQL select statement */
139 function Role_Name_from_Resp_No_Exc(
140 x_resp_id in number,
141 x_resp_appl_id in number,
142 x_secgrp_id in number)
143 return varchar2 is
144 begin
145
146 return fnd_user_resp_groups_api.Role_Name_from_Resp(
147 x_resp_id,
148 x_resp_appl_id,
149 x_secgrp_id);
150
151 exception
152 when no_data_found then
153 return 'BAD_FK:'||x_resp_id||':'|| x_resp_appl_id ||':'||x_secgrp_id;
154 when others then
155 return 'ERROR:'||x_resp_id||':'|| x_resp_appl_id ||':'||x_secgrp_id;
156 end Role_Name_from_Resp_No_Exc;
157
158 -- Upgrade_Resp_Role
159 -- Converts role names from FND_RESPX:Y format to FND_RESP|A|B|C format
160 -- if necessary. returns upgraded role name or original.
161 function upgrade_resp_role(respid in number,
162 appid in number) return varchar2 is
163 new_role_name varchar2(255);
164 begin
165
166 begin
167 new_role_name := fnd_user_resp_groups_api.Role_Name_from_Resp(
168 x_resp_id => respid,
169 x_resp_appl_id => appid,
170 x_secgrp_id => 0);
171
172 exception
173 when no_data_found then /* If invalid foreign keys, bail. */
174 return 'INVALID_FK_APPID_'||appid||'_RESPID_'||respid;
175 end;
176
177 return new_role_name;
178 end upgrade_resp_role;
179
180 --
181 -- Assignment_Check (INTERNAL routine only)
182 --
183 -- Check whether a particular assignment of a user to a role exists,
184 -- regardless of start/end date. This is different from
185 -- wf_directory.IsPerformer which only operates for current sysdate.
186 -- In: username- user name
187 -- In: rolename- role name
188 --
189 function Assignment_Check(username in varchar2,
190 rolename in varchar2,
191 direct_flag in varchar2)
192 return boolean is
193 result boolean;
194 dummy number;
195 begin
196
197 if(direct_flag = 'E') then
198 begin
199 select null
200 into dummy
201 from wf_all_user_roles
202 where user_name = username
203 and role_name = rolename
204 and rownum = 1;
205 result := TRUE;
206 exception
207 when no_data_found then
208 result := FALSE;
209 when others then
210 Generic_Error('FND_USER_RESP_GROUPS_API.ASSIGNMENT_CHECK(E)',
211 sqlcode, sqlerrm);
212 end;
213 elsif (direct_flag = 'D') then
214 begin
215 select null
216 into dummy
217 from wf_all_user_roles
218 where user_name = username
219 and role_name = rolename
220 and direct_flag = 'D'
221 and rownum = 1;
222 result := TRUE;
223 exception
224 when no_data_found then
225 result := FALSE;
226 when others then
227 Generic_Error('FND_USER_RESP_GROUPS_API.ASSIGNMENT_CHECK(D)',
228 sqlcode, sqlerrm);
229 end;
230 elsif (direct_flag = 'I') then
231 begin
232 select null
233 into dummy
234 from wf_all_user_roles
235 where user_name = username
236 and role_name = rolename
237 and direct_flag = 'I'
238 and rownum = 1;
239 result := TRUE;
240 exception
241 when no_data_found then
242 result := FALSE;
243 when others then
244 Generic_Error('FND_USER_RESP_GROUPS_API.ASSIGNMENT_CHECK(I)',
245 sqlcode, sqlerrm);
246 end;
247 end if;
248 return result;
249 end Assignment_Check;
250
251 --
252 -- Assignment_Exists
253 -- Check if user/resp/group assignment exists. This API does not check
254 -- start or end dates on the user, repsonsibility, or responsibility
255 -- assignment.
256 -- IN
257 -- user_id - User to get assignment
258 -- responsibility_id - Responsibility to be assigned
259 -- responsibility_application_id - Resp Application to be assigned
260 -- security_group_id - Security Group to be assigned (default to current)
261 -- direct_flag- 'D', 'I', or 'E' (default) determines whether this checks
262 -- indirect assignments from wf_role_hierarchy or just
263 -- direct assignments.
264 -- 'D'= Direct only. Dates can be updated.
265 -- 'I'= Indirect only. Dates cannot be updated on these assignments.
266 -- 'E'= Either Direct or Indirect. (this is the default)
267 -- RETURNS
268 -- TRUE if assignment is found
269 --
270 function Assignment_Exists(
271 user_id in number,
272 responsibility_id in number,
273 responsibility_application_id in number,
274 security_group_id in number default null,
275 direct_flag in varchar2 default null /* null means 'E': Direct or Indirect*/
276 )
277 return boolean
278 is
279 dummy number;
280 sgid number;
281 rolename varchar2(320);
282 username varchar2(100);
283 l_direct_flag varchar2(1);
284 begin
285 if(direct_flag is NULL) then
286 l_direct_flag := 'E'; /* Default to 'E' meaning Either direct or indirect*/
287 else
288 l_direct_flag := direct_flag;
289 end if;
290
291 if (security_group_id is null) then
292 sgid := fnd_global.security_group_id;
293 else
294 sgid := security_group_id;
295 end if;
296
297 begin
298 select user_name
299 into username
300 from fnd_user
301 where user_id = assignment_exists.user_id;
302
303 rolename := role_name_from_resp(responsibility_id,
304 responsibility_application_id,
305 sgid);
306
307 exception /* This exception handler is new to fix bug 3573846. */
308 when no_data_found then
309 /* If some data passed is invalid, there can't be an assignment.*/
310 /* This preserves backward compatibility. */
311 return FALSE;
312 end;
313
314 return Assignment_Check(
315 username ,
316 rolename,
317 l_direct_flag);
318
319 exception
320 when others then
321 Generic_Error('FND_USER_RESP_GROUPS_API.ASSIGNMENT_EXISTS',
322 sqlcode, sqlerrm);
323 end Assignment_Exists;
324
325
326 --
327 -- Validates the security context to determine if the given user has access
328 -- to the given responsibility.
329 -- IN
330 -- p_user_id - the user id
331 -- p_resp_appl_id - the application id of the responsibility
332 -- p_responsibility_id - the responsibility id
333 -- p_security_group_id - the security group id
334 -- OUT
335 -- x_status:
336 -- 'N' if the security context is not valid
337 -- 'Y' if the security context is valid
338 --
339 procedure validate_security_context(
340 p_user_id in number,
341 p_resp_appl_id in number,
342 p_responsibility_id in number,
343 p_security_group_id in number,
344 x_status out nocopy varchar2)
345 is
346 begin
347 /* # Someday this routine could be reimplemented against the database */
348 /* objects underlying the fnd_user_resp_groups view, but not needed now.*/
349 x_status := 'N';
350
351 select 'Y'
352 into x_status
353 from dual
354 where exists
355 (select null
356 from fnd_user u,
357 fnd_user_resp_groups urg,
358 fnd_responsibility r
359 where u.user_id = p_user_id
360 and sysdate between u.start_date and nvl(u.end_date, sysdate)
361 and urg.user_id = u.user_id
362 and urg.responsibility_application_id = p_resp_appl_id
363 and urg.responsibility_id = p_responsibility_id
364 and urg.security_group_id in (-1, p_security_group_id)
365 /*NOT NEEDED: and sysdate between urg.start_date and nvl(urg.end_date,sysdate)*/
366 and r.application_id = urg.responsibility_application_id
367 and r.responsibility_id = urg.responsibility_id
368 and sysdate between r.start_date and nvl(r.end_date, sysdate));
369 exception
370 when no_data_found then
371 x_status := 'N';
372
373 end validate_security_context;
374
375
376 --
377 -- Lock_Assignment
378 -- Lock the row for an assignment (used by a UI)
379 -- IN
380 -- user_id - User
381 -- responsibility_id - Responsibility
382 -- responsibility_application_id - Resp Application
383 -- security_group_id - Security Group
384 -- start_date - Start date of assignment
385 -- end_date - End date of assignment
386 --
387 procedure Lock_Assignment(
388 x_user_id in number,
389 x_responsibility_id in number,
390 x_resp_application_id in number,
391 x_security_group_id in number,
392 x_start_date in date,
393 x_end_date in date,
394 x_description in varchar2)
395 is
396 cursor c (user varchar2, role varchar2) is
397 select start_date,
398 end_date
399 from wf_all_user_role_assignments --BUG5467610
400 where user_name = user
401 and role_name = role
402 and rownum = 1
403 for update of start_date nowait;
404 rolename varchar2(1000);
405 username varchar2(100);
406 recinfo c%rowtype;
407 begin
408
409 select user_name
410 into username
411 from fnd_user
412 where user_id = x_user_id;
413
414 rolename := role_name_from_resp(x_responsibility_id,
415 x_resp_application_id,
416 x_security_group_id);
417
418 open c(username, rolename);
419 fetch c into recinfo;
420 if (c%notfound) then
421 close c;
422 fnd_message.set_name('FND', 'FORM_RECORD_DELETED');
423 app_exception.raise_exception;
424 end if;
425 close c;
426 if ( ((recinfo.start_date = x_start_date)
427 OR ((recinfo.start_date is null) AND (x_start_date is null)))
428 AND ((recinfo.end_date = x_end_date)
429 OR ((recinfo.end_date is null) AND (x_end_date is null)))
430 ) then
431 null;
432 else
433 fnd_message.set_name('FND', 'FORM_RECORD_CHANGED');
434 app_exception.raise_exception;
435 end if;
436
437 end Lock_Assignment;
438
439
440 --
441 -- Insert_Assignment
442 -- Insert a new user/resp/group assignment
443 -- IN
444 -- user_id - User to get assignment
445 -- responsibility_id - Responsibility to be assigned
446 -- responsibility_application_id - Resp Application to be assigned
447 -- security_group_id - Security Group to be assigned
448 -- start_date - Start date of assignment
449 -- end_date - End date of assignment
450 -- description - Optional comment
451 -- EXCEPTION
452 -- If user/resp/group assignment already exists
453 --
454 procedure Insert_Assignment(
455 user_id in number,
456 responsibility_id in number,
457 responsibility_application_id in number,
458 security_group_id in number,
459 start_date in date,
460 end_date in date,
461 description in varchar2)
462 is
463 sgid number;
464 rolename varchar2(4000);
465 secgrpkey varchar2(30);
466 appsname varchar2(50);
467 respkey varchar2(30);
468 username varchar2(100);
469 l_user_orig_system varchar2(30);
470 l_user_orig_system_id number;
471 result boolean;
472 old_rolename varchar2(4000);
473 l_parameters wf_parameter_list_t := wf_parameter_list_t();
474 begin
475 if (security_group_id is null) then
476 sgid := fnd_global.security_group_id;
477 else
478 sgid := security_group_id;
479 end if;
480
481 rolename := role_name_from_resp(responsibility_id,
482 responsibility_application_id,
483 sgid);
484
485 --
486 -- Generate old role name for backwards compatibility.
487 --
488
489 old_rolename := 'FND_RESP'||responsibility_application_id||
490 ':'||responsibility_id;
491
492 select user_name
493 into username
494 from fnd_user
495 where user_id = Insert_assignment.user_id;
496
497
498 select application_short_name
499 into appsname
500 from fnd_application
501 where application_id = responsibility_application_id;
502
503
504 /* Check whether there already is a direct row; if so, */
505 /* we can't insert a duplicate. */
506 result := assignment_check(username, rolename, 'D');
507 if (result = TRUE) then
508 fnd_message.set_name('FND', 'FND_CANT_INSERT_USER_ROLE');
509 fnd_message.set_token('USERNAME', username);
510 fnd_message.set_token('ROLENAME', rolename);
511 fnd_message.set_token('ROUTINE',
512 'FND_USER_RESP_GROUPS_API.Insert_Assignment');
513 app_exception.raise_exception;
514 end if;
515
516
517 /* We can't just assume that the orig system is FND_USR. It could */
518 /* be PER because the row in wf_users/wf_roles is one or the other */
519 wf_directory.GetRoleOrigSysInfo(username,
520 l_user_orig_system,
521 l_user_orig_system_id);
522
523 /* In case there is no WF user, sync this user up so there is one.*/
524 /* Should never happen but be safe in case sync wasn't perfect in past */
525 /* # Should we remove this code and just trust the bulk sync? */
526 if( (l_user_orig_system is NULL)
527 and (l_user_orig_system_id is NULL)) then
528 fnd_user_pkg.user_synch(username);
529 wf_directory.GetRoleOrigSysInfo(username,
530 l_user_orig_system,
531 l_user_orig_system_id);
532 end if;
533
534 wf_local_synch.PropagateUserRole
535 (p_user_name=>username,
536 p_role_name=>rolename,
537 p_user_orig_system=>l_user_orig_system,
538 p_user_orig_system_id=>l_user_orig_system_id,
539 p_role_orig_system=>'FND_RESP',
540 p_role_orig_system_id=>responsibility_id,
541 p_start_date=>start_date,
542 p_expiration_date=>end_date,
543 p_overwrite=>TRUE,
544 p_raiseErrors=>TRUE,
545 p_parent_orig_system => 'FND_RESP',
546 p_parent_orig_system_id => responsibility_id,
547 p_ownerTag => appsname,
548 p_createdBy => fnd_global.user_id,/*Bug3626390*/
549 p_lastUpdatedBy => fnd_global.user_id,
550 p_lastUpdateLogin => 0,
551 p_creationDate => sysdate, /*Bug3626390 sysdate*/
552 p_lastUpdatedate=> sysdate,
553 p_assignmentReason=>description);
554
555 --
556 -- Need to propagate the old roles for backwards compatibility.
557 --
558
559 wf_local_synch.PropagateUserRole
560 (p_user_name=>username,
561 p_role_name=>old_rolename,
562 p_user_orig_system=>l_user_orig_system,
563 p_user_orig_system_id=>l_user_orig_system_id,
564 p_role_orig_system=>'FND_RESP'||responsibility_application_id,
565 p_role_orig_system_id=>responsibility_id,
566 p_start_date=>start_date,
567 p_expiration_date=>end_date,
568 p_overwrite=>TRUE,
569 p_raiseErrors=>TRUE,
570 p_parent_orig_system => 'FND_RESP'||responsibility_application_id,
571 p_parent_orig_system_id => responsibility_id,
572 p_ownerTag => appsname,
573 p_createdBy => fnd_global.user_id,/*Bug3626390*/
574 p_lastUpdatedBy => fnd_global.user_id,
575 p_lastUpdateLogin => 0,
576 p_creationDate => sysdate, /*Bug3626390 sysdate*/
577 p_lastUpdatedate=> sysdate,
578 p_assignmentReason=>description);
579
580 wf_event.raise('oracle.apps.fnd.security.user.assignment.change',
581 Insert_Assignment.user_id||':'||
582 Insert_Assignment.responsibility_id,
583 null, null);
584 --we have to raise a differnt event as for USER_INFO_CACHE
585 --the key should be just the user_id
586 wf_event.addparametertolist(p_name => 'FND_USER_ID',
587 p_value => Insert_Assignment.user_id,
588 p_parameterlist => l_parameters);
589
590 wf_event.addparametertolist(p_name => 'FND_RESPONSIBILITY_ID',
591 p_value => Insert_Assignment.responsibility_id,
592 p_parameterlist => l_parameters);
593
594 wf_event.addparametertolist(p_name => 'FND_APPS_SHORT_NAME',
595 p_value => appsname,
596 p_parameterlist => l_parameters);
597
598 wf_event.addparametertolist(p_name => 'FND_RESPONSIBILITY_APPS_ID',
599 p_value => Insert_Assignment.responsibility_application_id,
600 p_parameterlist => l_parameters);
601
602 wf_event.raise(p_event_name => 'oracle.apps.fnd.user.role.insert',
603 p_event_key => to_char(Insert_Assignment.user_id)||':'||to_char(Insert_Assignment.responsibility_id)||':'||appsname||':'||to_char(Insert_Assignment.responsibility_application_id),
604 p_event_data => NULL,
605 p_parameters => l_parameters,
606 p_send_date => Sysdate);
607
608 exception
609 when others then
610 Generic_Error('FND_USER_RESP_GROUPS_API.INSERT_ASSIGNMENT',
611 sqlcode, sqlerrm);
612 end Insert_Assignment;
613
614 --
615 -- Update_Assignment
616 -- Update an existing user/resp/group assignment
617 -- IN
618 -- KEY VALUES: These columns identify row to update
619 -- user_id - User to get assignment
620 -- responsibility_id - Responsibility to be assigned
621 -- responsibility_application_id - Resp Application to be assigned
622 -- security_group_id - Security Group to be assigned
623 -- UPDATE VALUES: These columns identify values to update
624 -- start_date - Start date of assignment
625 -- end_date - End date of assignment
626 -- description - Optional comment
627 -- FLAGS
628 -- update_who_columns- pass 'Y' or 'N' ('Y' is default if not passed)
629 -- 'N' = leave old who vals. 'Y'= update who cols to current user/date
630 -- EXCEPTION
631 -- If user/resp/group assignment does not exist
632 --
633 procedure Update_Assignment(
634 user_id in number,
635 responsibility_id in number,
636 responsibility_application_id in number,
637 security_group_id in number,
638 start_date in date,
639 end_date in date,
640 description in varchar2,
641 update_who_columns in varchar2 default null
642 /* 'N' = leave old who vals. 'Y' (default) = update who to current*/)
643 is
644 sgid number;
645 rolename varchar2(4000);
646 secgrpkey varchar2(30);
647 appsname varchar2(50);
648 respkey varchar2(30);
649 username varchar2(100);
650 l_user_orig_system varchar2(30);
651 l_user_orig_system_id number;
652 result boolean;
653 old_rolename varchar2(4000);
654 l_parameters wf_parameter_list_t := wf_parameter_list_t();
655 l_last_update_date date;
656 l_last_updated_by number;
657 l_last_update_login number;
658 l_creation_date date;
659 l_created_by number;
660 l_update_who boolean; --Bug5467610
661 begin
662
663 if (security_group_id is null) then
664 sgid := fnd_global.security_group_id;
665 else
666 sgid := security_group_id;
667 end if;
668
669 rolename := role_name_from_resp(responsibility_id,
670 responsibility_application_id,
671 sgid);
672
673 --
674 -- Generate old role name for backwards compatibility.
675 --
676
677 old_rolename := 'FND_RESP'||responsibility_application_id||
678 ':'||responsibility_id;
679
680 select user_name
681 into username
682 from fnd_user
683 where user_id = Update_assignment.user_id;
684
685
686 select application_short_name
687 into appsname
688 from fnd_application
689 where application_id = responsibility_application_id;
690
691
692 /* Check whether there already is a direct row to update; if not, */
693 /* the caller probably queried an indirect row and is trying to */
694 /* update it which is not allowed. */
695 result := assignment_check(username, rolename,'D');
696 if (result = FALSE) then
697 fnd_message.set_name('FND', 'FND_CANT_UPDATE_USER_ROLE');
698 fnd_message.set_token('USERNAME', username);
699 fnd_message.set_token('ROLENAME', rolename);
700 fnd_message.set_token('ROUTINE',
701 'FND_USER_RESP_GROUPS_API.Update_Assignment');
702 app_exception.raise_exception;
703 end if;
704
705 /* We can't just assume that the orig system is FND_USR. It could */
706 /* be PER because the row in wf_users/wf_roles is one or the other */
707 wf_directory.GetRoleOrigSysInfo(username,
708 l_user_orig_system,
709 l_user_orig_system_id);
710
711 /* In case there is no WF user, sync this user up so there is one.*/
712 /* Should never happen but be safe in case sync wasn't perfect in past */
713 /* # Should we remove this code and just trust bulk sync?*/
714 if( (l_user_orig_system is NULL)
715 and (l_user_orig_system_id is NULL)) then
716 fnd_user_pkg.user_synch(username);
717 wf_directory.GetRoleOrigSysInfo(username,
718 l_user_orig_system,
719 l_user_orig_system_id);
720 end if;
721
722 /* Get the old who values. Note that there is no exception handler around*/
723 /* this because the assignment_check() above should have already verified */
724 /* that we have the row. */
725 /* NOTE: Workflow has added support for '*NOCHANGE*' for the who */
726 /* parameters for RUP4. This SQL will be removed and this option */
727 /* will be used */
728 -- Bug5121512 - Replaced SQL to eliminate the case where it is returning
729 -- a 1422.
730 -- Bug5467610 Removing the following SQL as it is no longer needed and adding
731 -- the p_updatewho parameter to the wf_local_synch.PropagateUserRole call.
732
733 -- select created_by, creation_date, last_updated_by,
734 -- last_update_date, last_update_login
735 -- into l_created_by, l_creation_date, l_last_updated_by,
736 -- l_last_update_date, l_last_update_login
737 -- from wf_all_user_roles
738 -- where user_name = Update_Assignment.username
739 -- and role_orig_system_id = Update_Assignment.responsibility_id
740 -- and role_name = Update_Assignment.rolename
741 -- and role_orig_system = 'FND_RESP';
742
743 /* If we passed the flag saying to update the who columns */
744 /* then we set the last_update who columns to current user/date. */
745 if (update_who_columns = 'Y') then
746 l_last_updated_by := fnd_global.user_id;
747 l_last_update_login := 0;
748 l_last_update_date := sysdate;
749 l_update_who := TRUE; -- Bug5467610 update who columns.
750 end if;
751
752
753 -- Bug4747169 - Removed passing in the parameters p_created_by and
754 -- p_creation_date as this is the update processing.
755
756 wf_local_synch.PropagateUserRole
757 (p_user_name=>username,
758 p_role_name=>rolename,
759 p_user_orig_system=>l_user_orig_system,
760 p_user_orig_system_id=>l_user_orig_system_id,
761 p_role_orig_system=>'FND_RESP',
762 p_role_orig_system_id=>responsibility_id,
763 p_start_date=>start_date,
764 p_expiration_date=>end_date,
765 p_overwrite=>TRUE,
766 p_raiseErrors=>TRUE,
767 p_parent_orig_system => 'FND_RESP',
768 p_parent_orig_system_id => responsibility_id,
769 p_ownerTag => appsname,
770 p_createdBy => l_created_by,
771 p_creationDate => l_creation_date, /*Bug3626390 sysdate*/
772 p_lastUpdatedate=> l_last_update_date,
773 p_lastUpdatedBy => l_last_updated_by,
774 p_lastUpdateLogin => l_last_update_login,
775 p_assignmentReason=>description,
776 p_updatewho => l_update_who); -- Bug5467610
777
778 --
779 -- Need to propagate the old role name
780 --
781
782 wf_local_synch.PropagateUserRole
783 (p_user_name=>username,
784 p_role_name=>old_rolename,
785 p_user_orig_system=>l_user_orig_system,
786 p_user_orig_system_id=>l_user_orig_system_id,
787 p_role_orig_system=>'FND_RESP'||responsibility_application_id,
788 p_role_orig_system_id=>responsibility_id,
789 p_start_date=>start_date,
790 p_expiration_date=>end_date,
791 p_overwrite=>TRUE,
792 p_raiseErrors=>TRUE,
793 p_parent_orig_system => 'FND_RESP'||responsibility_application_id,
794 p_parent_orig_system_id => responsibility_id,
795 p_ownerTag => appsname,
796 p_createdBy => l_created_by,
797 p_creationDate => l_creation_date, /*Bug3626390 sysdate*/
798 p_lastUpdatedate=> l_last_update_date,
799 p_lastUpdatedBy => l_last_updated_by,
800 p_lastUpdateLogin => l_last_update_login,
801 p_assignmentReason=>description,
802 p_updatewho => l_update_who); -- Bug5467610
803
804
805 wf_event.raise('oracle.apps.fnd.security.user.assignment.change',
806 Update_Assignment.user_id||':'||
807 Update_Assignment.responsibility_id,
808 null, null);
809 --Raise the invalidation event attached to the USER_INFO_CACHE
810 --(ideally this should be done by the wf API once the propagation
811 --has been sucessful) / or if they are not doing it then we should attach
812 --our business event to the CACHE as we do not really know what
813 --subscriptions are attcahed to the wf event.
814 --o.k putting our event (but we need to change the b3664848.ldt
815 --and the event-subscription file to attach this event to the
816 --bes control group.
817 wf_event.addparametertolist(p_name => 'FND_USER_ID',
818 p_value => Update_Assignment.user_id,
819 p_parameterlist => l_parameters);
820
821 wf_event.addparametertolist(p_name => 'FND_RESPONSIBILITY_ID',
822 p_value => Update_Assignment.responsibility_id,
823 p_parameterlist => l_parameters);
824
825 wf_event.addparametertolist(p_name => 'FND_APPS_SHORT_NAME',
826 p_value => appsname,
827 p_parameterlist => l_parameters);
828
829 wf_event.addparametertolist(p_name => 'FND_RESPONSIBILITY_APPS_ID',
830 p_value => Update_Assignment.responsibility_application_id,
831 p_parameterlist => l_parameters);
832
833 wf_event.raise(p_event_name => 'oracle.apps.fnd.user.role.update',
834 p_event_key => to_char(Update_Assignment.user_id)||':'||to_char(Update_Assignment.responsibility_id)||':'||appsname||':'||to_char(Update_Assignment.responsibility_application_id),
835 p_event_data => NULL,
836 p_parameters => l_parameters,
837 p_send_date => Sysdate);
838
839 exception
840 when others then
841 Generic_Error('FND_USER_RESP_GROUPS_API.UPDATE_ASSIGNMENT',
842 sqlcode, sqlerrm);
843
844 end Update_Assignment;
845
846 procedure LOAD_ROW (
847 X_USER_NAME in VARCHAR2,
848 X_RESP_KEY in VARCHAR2,
849 X_APP_SHORT_NAME in VARCHAR2,
850 X_SECURITY_GROUP in VARCHAR2,
851 X_OWNER in VARCHAR2,
852 X_START_DATE in VARCHAR2,
853 X_END_DATE in VARCHAR2,
854 X_DESCRIPTION in VARCHAR2,
855 X_LAST_UPDATE_DATE in DATE default sysdate) is
856 u_id number;
857 app_id number;
858 resp_id number;
859 sgroup_id number;
860 l_end_date varchar2(4000);
861 l_owner number;
862 rolename varchar2(4000);
863 l_user_orig_system varchar2(30);
864 l_user_orig_system_id number;
865 old_rolename varchar2(4000);
866
867 begin
868 select user_id into u_id
869 from fnd_user
870 where user_name = X_USER_NAME;
871
872 select application_id into app_id
873 from fnd_application
874 where application_short_name = X_APP_SHORT_NAME;
875
876 select responsibility_id into resp_id
877 from fnd_responsibility
878 where responsibility_key = X_RESP_KEY
879 and application_id = app_id;
880
881 select security_group_id into sgroup_id
882 from fnd_security_groups
883 where security_group_key = X_SECURITY_GROUP;
884
885 select decode(X_END_DATE,
886 fnd_load_util.null_value, null,
887 null, X_END_DATE,
888 X_END_DATE)
889 into l_end_date
890 from dual;
891
892 -- bug3649874 Modified to use fnd_load_util to get the owner_id
893
894 l_owner := fnd_load_util.owner_id(X_OWNER);
895
896 fnd_user_resp_groups_api.UPLOAD_ASSIGNMENT(
897 USER_ID => u_id,
898 RESPONSIBILITY_ID => resp_id,
899 RESPONSIBILITY_APPLICATION_ID => app_id,
900 SECURITY_GROUP_ID => sgroup_id,
901 START_DATE => to_date(X_START_DATE, 'YYYY/MM/DD'),
902 END_DATE => to_date(l_end_date, 'YYYY/MM/DD'),
903 DESCRIPTION => X_DESCRIPTION);
904
905 --------------------------------------------------------------------------
906 -- The upload_assignment routine uses fnd_global.user_id and
907 -- fnd_global.login_id which is not what we want for loader updates.
908 -- Also upload_assignment only updates created_by if the row was just
909 -- created.
910 -- Added call to PropagateUserRole to correctly set the who columns.
911 --------------------------------------------------------------------------
912 rolename := Role_Name_from_Resp_name(
913 X_RESP_KEY,
914 X_APP_SHORT_NAME,
915 X_SECURITY_GROUP);
916 --
917 -- Generate old role name for backwards compatibility.
918 --
919
920 old_rolename := 'FND_RESP'||app_id||
921 ':'||resp_id;
922
923 -- Bug3649874 propagate the who columns
924
925 wf_directory.GetRoleOrigSysInfo(x_user_name,
926 l_user_orig_system,
927 l_user_orig_system_id);
928
929 wf_local_synch.PropagateUserRole
930 (p_user_name=>x_user_name,
931 p_role_name=>rolename,
932 p_user_orig_system=>l_user_orig_system,
933 p_user_orig_system_id=>l_user_orig_system_id,
934 p_role_orig_system=>'FND_RESP',
935 p_role_orig_system_id=>resp_id,
936 p_start_date=> to_date(X_START_DATE, 'YYYY/MM/DD'),
937 p_expiration_date=>to_date(l_end_date, 'YYYY/MM/DD'),
938 p_overwrite=>TRUE,
939 p_raiseErrors=>TRUE,
940 p_parent_orig_system => 'FND_RESP',
941 p_parent_orig_system_id => resp_id,
942 p_ownerTag => X_APP_SHORT_NAME,
943 p_createdBy => l_owner,
944 p_creationDate => sysdate, /*Bug3626390 sysdate*/
945 p_lastUpdatedate=> x_last_update_date,
946 p_lastUpdatedBy => l_owner,
947 p_lastUpdateLogin => 0,
948 p_assignmentReason=>X_DESCRIPTION);
949
950
951 --
952 -- Need to propagate the old role name
953 --
954
955 wf_local_synch.PropagateUserRole
956 (p_user_name=>x_user_name,
957 p_role_name=>old_rolename,
958 p_user_orig_system=>l_user_orig_system,
959 p_user_orig_system_id=>l_user_orig_system_id,
960 p_role_orig_system=>'FND_RESP'||app_id,
961 p_role_orig_system_id=>resp_id,
962 p_start_date=> to_date(X_START_DATE, 'YYYY/MM/DD'),
963 p_expiration_date=>to_date(l_end_date, 'YYYY/MM/DD'),
964 p_overwrite=>TRUE,
965 p_raiseErrors=>TRUE,
966 p_parent_orig_system => 'FND_RESP'||app_id,
967 p_parent_orig_system_id => resp_id,
968 p_ownerTag => X_APP_SHORT_NAME,
969 p_createdBy => l_owner,
970 p_lastUpdatedBy => l_owner,
971 p_lastUpdateLogin => 0,
972 p_creationDate => sysdate, /*Bug3626390 sysdate*/
973 p_lastUpdatedate=> x_last_update_date,
974 p_assignmentReason=>X_DESCRIPTION);
975
976 end LOAD_ROW;
977
978 --
979 -- Upload_Assignment
980 -- Update user/resp/group assignment if it exists,
981 -- otherwise insert new assignment.
982 -- IN
983 -- user_id - User to get assignment
984 -- responsibility_id - Responsibility to be assigned
985 -- responsibility_application_id - Resp Application to be assigned
986 -- security_group_id - Security Group to be assigned
987 -- start_date - Start date of assignment
988 -- end_date - End date of assignment
989 -- description - Optional comment
990 -- update_who_columns- pass 'Y' or 'N' ('Y' is default if not passed)
991 -- 'N' = leave old who vals. 'Y'= update who cols to current user/date
992
993 --
994 procedure Upload_Assignment(
995 user_id in number,
996 responsibility_id in number,
997 responsibility_application_id in number,
998 security_group_id in number,
999 start_date in date,
1000 end_date in date,
1001 description in varchar2,
1002 update_who_columns in varchar2 default null
1003 /* 'N' = leave old who vals. 'Y' (default) = update who to current*/)
1004 is
1005 sgid number;
1006 begin
1007
1008 if (security_group_id is null) then
1009 sgid := fnd_global.security_group_id;
1010 else
1011 sgid := security_group_id;
1012 end if;
1013
1014 if (Fnd_User_Resp_Groups_Api.Assignment_Exists(
1015 Upload_Assignment.user_id,
1016 Upload_Assignment.responsibility_id,
1017 Upload_Assignment.responsibility_application_id,
1018 Upload_Assignment.sgid,
1019 'D'))
1020 then
1021 Fnd_User_Resp_Groups_Api.Update_Assignment(
1022 Upload_Assignment.user_id,
1023 Upload_Assignment.responsibility_id,
1024 Upload_Assignment.responsibility_application_id,
1025 Upload_Assignment.sgid,
1026 Upload_Assignment.start_date,
1027 Upload_Assignment.end_date,
1028 Upload_Assignment.description,
1029 update_who_columns);
1030 else
1031 Fnd_User_Resp_Groups_Api.Insert_Assignment(
1032 Upload_Assignment.user_id,
1033 Upload_Assignment.responsibility_id,
1034 Upload_Assignment.responsibility_application_id,
1035 Upload_Assignment.sgid,
1036 Upload_Assignment.start_date,
1037 Upload_Assignment.end_date,
1038 Upload_Assignment.description);
1039 end if;
1040 exception
1041 when others then
1042 Generic_Error('FND_USER_RESP_GROUPS_API.UPLOAD_ASSIGNMENT',
1043 sqlcode, sqlerrm);
1044 end Upload_Assignment;
1045
1046 --
1047 -- Sync_roles_one_resp_secgrp
1048 -- Sync the role for a particular resp and security group.
1049 --
1050 procedure sync_roles_one_resp_secgrp(
1051 respid in number,
1052 appid in number,
1053 respkey in varchar2,
1054 secgrpid in number,
1055 secgrpkey in varchar2,
1056 startdate in date,
1057 enddate in date)
1058 is
1059 l_respkey varchar2(30);
1060 l_secgrpkey varchar2(30);
1061 applsname varchar2(50);
1062 role_name varchar2(320);
1063 role_display_name varchar2(1000);
1064 secgrp_name varchar2(80);
1065 resp_name varchar2(100);
1066 descr varchar2(240);
1067 wf_parameters wf_parameter_list_t;
1068 old_rolename varchar2(320);
1069 -- Bug4507634 - Parameters needed to determine WF STATUS.
1070 my_exp date;
1071 my_start date;
1072 my_creationdate date;
1073 my_lastupdatedate date;
1074 my_createdby number;
1075 my_lastupdatedby number;
1076 my_lastupdatelogin number;
1077
1078 begin
1079
1080 --
1081 -- Generate old role name for backwards compatibility.
1082 --
1083
1084 old_rolename := 'FND_RESP'||appid||
1085 ':'||respid;
1086
1087 /* If caller didn't have respkey to pass, get it from respid/appid */
1088 if (respkey is null) then
1089 begin
1090 select responsibility_key
1091 into l_respkey
1092 from fnd_responsibility
1093 where responsibility_id = respid
1094 and application_id = appid;
1095 exception
1096 when no_data_found then
1097 return; /* Bad foreign key; we can't build a role. Return. */
1098 end;
1099 else
1100 l_respkey := respkey;
1101 end if;
1102
1103 /* If caller didn't have secgrpkey to pass, get it from secgrpid */
1104 if (secgrpkey is null) then
1105 begin
1106 select security_group_key
1107 into l_secgrpkey
1108 from fnd_security_groups
1109 where security_group_id = secgrpid;
1110 exception
1111 when no_data_found then
1112 return; /* Bad foreign key; we can't build a role. Return. */
1113 end;
1114 else
1115 l_secgrpkey := secgrpkey;
1116 end if;
1117
1118 /* Get the application short name for role name */
1119 begin
1120 select application_short_name
1121 into applsname
1122 from fnd_application
1123 where application_id = appid;
1124
1125 role_name := fnd_user_resp_groups_api.role_name_from_resp_name(
1126 respkey, applsname, secgrpkey);
1127
1128 exception
1129 when no_data_found then
1130 /* invalid foreign key to a nonexistant app. Skip. */
1131 role_name := null;
1132 applsname := null;
1133 return;
1134 end;
1135
1136 /* Get the responsibility name of base language for role display name */
1137 begin
1138 select responsibility_name, description
1139 into resp_name, descr
1140 from fnd_responsibility_tl
1141 where responsibility_id = respid
1142 and application_id = appid
1143 and language = (select language_code
1144 from fnd_languages
1145 where installed_flag = 'B');
1146 exception
1147 when no_data_found then
1148 /* This shouldn't normally happen, it's just for bad TL tables*/
1149 resp_name := applsname ||':'||respkey;
1150 descr := NULL;
1151 end;
1152
1153 /* Get the security group name of base language for role display name */
1154 /* Don't need the name for STANDARD, so skip the select */
1155 if (secgrpid <> 0) then
1156 begin
1157 select security_group_name
1158 into secgrp_name
1159 from fnd_security_groups_tl
1160 where security_group_id = secgrpid
1161 and language = (select language_code
1162 from fnd_languages
1163 where installed_flag = 'B');
1164 exception
1165 when no_data_found then
1166 /* This shouldn't normally happen, it's just for bad TL tables*/
1167 secgrp_name := secgrpkey;
1168 end;
1169 end if;
1170
1171 -- Bug4507634 Need to attain values for start/end date in order to
1172 -- correctly update the status in WF.
1173
1174 -- Bug4864465 Added getting the WHO column data also.
1175
1176 begin
1177 select start_date, end_date,
1178 created_by, creation_date,
1179 last_updated_by, last_update_date, last_update_login
1180 into my_start, my_exp, my_createdby, my_creationdate,
1181 my_lastupdatedby, my_lastupdatedate, my_lastupdatelogin
1182 from fnd_responsibility
1183 where responsibility_id = respid
1184 and application_id = appid;
1185 exception
1186 when no_data_found then
1187 return; /* Bad foreign key; we can't build a role. Return. */
1188 end;
1189
1190 -- Insert or update role in workflow.
1191 -- Need to do this even if role already exists, to update
1192 -- attribute values.
1193 wf_parameters := NULL;
1194 wf_event.AddParameterToList('USER_NAME',
1195 role_name , wf_parameters);
1196 if(secgrpkey = 'STANDARD') then
1197 role_display_name := resp_name;
1198 else
1199 role_display_name := resp_name||':'||secgrp_name;
1200 end if;
1201
1202 wf_event.AddParameterToList('DISPLAYNAME',
1203 role_display_name, wf_parameters);
1204 wf_event.AddParameterToList('DESCRIPTION',
1205 descr, wf_parameters);
1206 wf_event.AddParameterToList('OWNER_TAG',
1207 applsname, wf_parameters);
1208 wf_event.AddParameterToList('RAISEERRORS',
1209 'TRUE', wf_parameters);
1210
1211 -- Bug4507634 added WFSYNCH_OVERWRITE and ORCLISENABLED parameters.
1212
1213 wf_event.AddParameterToList('WFSYNCH_OVERWRITE',
1214 'TRUE', wf_parameters);
1215 if ((my_exp is null) OR
1216 (trunc(sysdate) between my_start and my_exp)) then
1217 wf_event.AddParameterToList('ORCLISENABLED', 'ACTIVE', wf_parameters);
1218 else
1219 wf_event.AddParameterToList('ORCLISENABLED', 'INACTIVE', wf_parameters);
1220 end if;
1221
1222 -- Bug4864465 Adding the WHO column values to be propagated.
1223
1224 wf_event.AddParameterToList('LAST_UPDATED_BY',my_lastupdatedby,wf_parameters);
1225
1226 -- Bug5729583 - Updated date values to use WF_CORE.canonical_date_mask.
1227
1228 wf_event.AddParameterToList('LAST_UPDATE_DATE',
1229 to_char(my_lastupdatedate,WF_CORE.canonical_date_mask),wf_parameters);
1230 wf_event.AddParameterToList('CREATED_BY',my_createdby,wf_parameters);
1231
1232 -- Bug5729583 - Updated date values to use WF_CORE.canonical_date_mask.
1233
1234 wf_event.AddParameterToList('CREATION_DATE',to_char(my_creationdate,WF_CORE.canonical_date_mask),wf_parameters);
1235 wf_event.AddParameterToList('LAST_UPDATE_LOGIN',
1236 my_lastupdatelogin,wf_parameters);
1237
1238 wf_local_synch.propagate_role(p_orig_system=>'FND_RESP',
1239 p_orig_system_id=>respid,
1240 p_attributes=> wf_parameters,
1241 p_start_date=>startdate,
1242 p_expiration_date=>enddate);
1243
1244 -- Insert or update role in workflow for old_rolename.
1245 wf_parameters := NULL;
1246 wf_event.AddParameterToList('USER_NAME',
1247 old_rolename , wf_parameters);
1248
1249 role_display_name := resp_name||':Any security group';
1250
1251 wf_event.AddParameterToList('DISPLAYNAME',
1252 role_display_name, wf_parameters);
1253 wf_event.AddParameterToList('DESCRIPTION',
1254 descr, wf_parameters);
1255 wf_event.AddParameterToList('OWNER_TAG',
1256 applsname, wf_parameters);
1257 wf_event.AddParameterToList('RAISEERRORS',
1258 'TRUE', wf_parameters);
1259
1260 -- Bug4507634 added WFSYNCH_OVERWRITE parameter.
1261
1262 wf_event.AddParameterToList('WFSYNCH_OVERWRITE',
1263 'TRUE', wf_parameters);
1264
1265 -- Bug4699363 added parameter for ORCLISENABLED.
1266
1267 if ((my_exp is null) OR
1268 (trunc(sysdate) between my_start and my_exp)) then
1269 wf_event.AddParameterToList('ORCLISENABLED', 'ACTIVE', wf_parameters);
1270 else
1271 wf_event.AddParameterToList('ORCLISENABLED', 'INACTIVE', wf_parameters);
1272 end if;
1273
1274 -- Bug4864465 Adding the WHO column values to be propagated.
1275
1276 wf_event.AddParameterToList('LAST_UPDATED_BY',my_lastupdatedby,wf_parameters);
1277
1278 -- Bug5729583 - Updated date values to use WF_CORE.canonical_date_mask.
1279
1280 wf_event.AddParameterToList('LAST_UPDATE_DATE',
1281 to_char(my_lastupdatedate,WF_CORE.canonical_date_mask), wf_parameters);
1282 wf_event.AddParameterToList('CREATED_BY',my_createdby, wf_parameters);
1283 wf_event.AddParameterToList('CREATION_DATE',to_char(my_creationdate,WF_CORE.canonical_date_mask),wf_parameters);
1284 wf_event.AddParameterToList('LAST_UPDATE_LOGIN',
1285 my_lastupdatelogin, wf_parameters);
1286
1287 wf_local_synch.propagate_role(p_orig_system=>'FND_RESP'||appid,
1288 p_orig_system_id=>respid,
1289 p_attributes=> wf_parameters,
1290 p_start_date=>startdate,
1291 p_expiration_date=>enddate);
1292
1293 end sync_roles_one_resp_secgrp;
1294
1295 --
1296 -- sync_roles_all_secgrps
1297 -- For a given resp, sync roles for all security groups
1298 -- NOTE: This is intended to be called whenever a responsibility
1299 -- is inserted or updated.
1300 --
1301
1302 procedure sync_roles_all_secgrps(
1303 respid in number,
1304 appid in number,
1305 respkey in varchar2,
1306 startdate in date,
1307 enddate in date)
1308 is
1309 cursor get_secgrp is
1310 select security_group_id,
1311 security_group_key
1312 from fnd_security_groups;
1313
1314 begin
1315
1316 if (check_secgrp_enabled(respid, appid) = 'N') then
1317 -- Security Groups not enabled for this resp,
1318 -- only create a role for the STANDARD sec grp.
1319 sync_roles_one_resp_secgrp( respid=> respid,
1320 appid=> appid,
1321 respkey=> respkey,
1322 secgrpid=> 0,
1323 secgrpkey=> 'STANDARD',
1324 startdate=> startdate,
1325 enddate=> enddate);
1326 else
1327 -- Security Groups are enabled, create one role for
1328 -- every resp/secgrp pair.
1329 for secrec in get_secgrp loop
1330 sync_roles_one_resp_secgrp(
1331 respid => respid,
1332 appid => appid,
1333 respkey => respkey,
1334 secgrpid => secrec.security_group_id,
1335 secgrpkey => secrec.security_group_key,
1336 startdate => startdate,
1337 enddate => enddate);
1338 end loop;
1339 end if;
1340
1341 end sync_roles_all_secgrps;
1342
1343 --
1344 -- sync_roles_all_resps
1345 -- For a given security group, sync roles for all responsibilities
1346 -- NOTE: This is intended to be called whenever a security group
1347 -- is inserted or updated.
1348 -- ### Security groups can be deleted, should also sync that.
1349 --
1350 procedure sync_roles_all_resps(secgrpid in varchar2,
1351 secgrpkey in varchar2) is
1352 cursor get_resp is
1353 select application_id,
1354 responsibility_id,
1355 responsibility_key,
1356 start_date,
1357 end_date
1358 from fnd_responsibility;
1359 begin
1360 for resprec in get_resp loop
1361 -- If secgrp is STANDARD, then create resp/secgrp role for all resps.
1362 -- Otherwise, only create roles for resps with security groups enabled.
1363 if ((secgrpid = 0) or
1364 (check_secgrp_enabled(resprec.responsibility_id,
1365 resprec.application_id) = 'Y'))
1366 then
1367 sync_roles_one_resp_secgrp(
1368 resprec.responsibility_id,
1369 resprec.application_id,
1370 resprec.responsibility_key,
1371 secgrpid,
1372 secgrpkey,
1373 resprec.start_date,
1374 resprec.end_date);
1375 end if;
1376 end loop;
1377
1378 end sync_roles_all_resps;
1379
1380 --
1381 -- sync_roles_all_resp_secgrps
1382 -- Create roles for all resp/security group pairs.
1383 --
1384 -- Bug4349774 - Added sync_all_flag to default to previous behavior
1385 -- where if TRUE is passed then updates and inserts are
1386 -- processed otherwise only inserts are done.
1387
1388 procedure sync_roles_all_resp_secgrps (sync_all_flag in boolean default FALSE)
1389 is
1390 cursor get_resp is
1391 select application_id,
1392 responsibility_id,
1393 responsibility_key,
1394 start_date,
1395 end_date
1396 from fnd_responsibility;
1397 begin
1398
1399 if (sync_all_flag = TRUE) then
1400 for resprec in get_resp loop
1401 sync_roles_all_secgrps(respid=> resprec.responsibility_id,
1402 appid=> resprec.application_id,
1403 respkey=> resprec.responsibility_key,
1404 startdate=> resprec.start_date,
1405 enddate=> resprec.end_date);
1406 commit;
1407 end loop;
1408 else
1409 -- Bug4322412 changed call to internal procedure so that if the role
1410 -- exists we do not waste time updating again.
1411
1412 for resprec in get_resp loop
1413 sync_roles_all_secgrps_int(respid=> resprec.responsibility_id,
1414 appid=> resprec.application_id,
1415 respkey=> resprec.responsibility_key,
1416 startdate=> resprec.start_date,
1417 enddate=> resprec.end_date);
1418 commit;
1419 end loop;
1420 end if;
1421
1422 end sync_roles_all_resp_secgrps;
1423
1424
1425 --
1426 -- Moves old data from fnd_user_resp_groups table to new workflow tables.
1427 -- This routine is exposed so that it can be called from a one time
1428 -- upgrade script, and it should never need to be run after that.
1429 -- Running it unnecessarily might invalidate work that
1430 -- admins have done to split assignments out into roles
1431 --
1432 -- Before calling this, make sure you have called
1433 -- sync_roles_all_resp_secgrps() in order to get the roles in place that
1434 -- this routine will depend on.
1435 --
1436 -- OBSOLETE: This functionality is now in the bulk sync of FND_RESP
1437 -- which is called from the affurgol.sql script.
1438 -- This code is just here in case the bulk sync fails as a last ditch
1439 -- effort this code could be called.
1440 procedure one_time_furg_to_wf_upgrade is /* THIS ROUTINE IS OBSOLETE */
1441 begin
1442 null; /* ### Stubbed ### */
1443 /*
1444 l_api_name CONSTANT VARCHAR2(30) := 'one_time_furg_to_wf_upgrade';
1445 cursor get_old_row is
1446 select fu.user_name,
1447 secgrp.security_group_key,
1448 app.application_short_name,
1449 resp.responsibility_key,
1450 resp.start_date resp_start_date,
1451 resp.end_date resp_end_date,
1452 furgo.user_id,
1453 furgo.responsibility_id,
1454 furgo.responsibility_application_id,
1455 furgo.start_date,
1456 furgo.end_date,
1457 furgo.security_group_id,
1458 furgo.created_by,
1459 furgo.creation_date,
1460 furgo.last_updated_by,
1461 furgo.last_update_date,
1462 furgo.last_update_login
1463 from fnd_user_resp_groups_old furgo,
1464 fnd_user fu,
1465 fnd_application app,
1466 fnd_responsibility resp,
1467 fnd_security_groups secgrp
1468 where furgo.user_id = fu.user_id
1469 and furgo.responsibility_id = resp.responsibility_id
1470 and furgo.responsibility_application_id
1471 = resp.application_id
1472 and furgo.responsibility_application_id
1473 = app.application_id
1474 and furgo.security_group_id = secgrp.security_group_id;
1475 resp_name varchar2(100);
1476 descr varchar2(240);
1477 secgrp_name varchar2(80);
1478 dummy varchar2(255);
1479 wf_parameters wf_parameter_list_t;
1480 l_user_orig_system varchar2(30);
1481 l_user_orig_system_id number;
1482 rolename varchar2(1000);
1483 resp_key varchar2(100);
1484 begin
1485 if (fnd_log.LEVEL_PROCEDURE >= fnd_log.g_current_runtime_level) then
1486 fnd_log.string(FND_LOG.LEVEL_PROCEDURE,
1487 c_log_head || l_api_name || '.begin',
1488 c_pkg_name || '.' ||l_api_name);
1489 end if;
1490
1491 for rowrec in get_old_row loop
1492
1493 resp_key := rowrec.responsibility_key;
1494
1495 rolename := role_name_from_resp_name( resp_key,
1496 rowrec.application_short_name,
1497 rowrec.security_group_key);
1498
1499 if (fnd_log.LEVEL_STATEMENT >= fnd_log.g_current_runtime_level) then
1500 fnd_log.string(FND_LOG.LEVEL_STATEMENT,
1501 c_log_head || l_api_name || '.processing',
1502 'Processing role:'|| rolename ||' for user_id:'||
1503 rowrec.user_id ||' user_name:'||rowrec.user_name);
1504 end if;
1505 begin
1506 select name
1507 into dummy
1508 from wf_local_roles partition (FND_RESP)
1509 where name = rolename
1510 and rownum = 1;
1511 exception -- This shouldnt be necessary since the roles should already
1512 when no_data_found then -- have been created, but be safe.
1513 if (fnd_log.LEVEL_STATEMENT >= fnd_log.g_current_runtime_level) then
1514 fnd_log.string(FND_LOG.LEVEL_STATEMENT,
1515 c_log_head || l_api_name || '.need_to_create_role',
1516 'Creating role:'|| rolename);
1517 end if;
1518 fnd_user_resp_groups_api.sync_roles_one_resp_secgrp(
1519 rowrec.responsibility_id,
1520 rowrec.responsibility_application_id,
1521 rowrec.responsibility_key,
1522 rowrec.security_group_id,
1523 rowrec.security_group_key,
1524 rowrec.resp_start_date,
1525 rowrec.resp_end_date);
1526 end;
1527
1528 begin
1529 select role_name
1530 into dummy
1531 from wf_all_user_roles waur
1532 where waur.role_name = rolename
1533 and waur.user_name = rowrec.user_name
1534 and ( (waur.start_date = rowrec.start_date)
1535 OR((waur.start_date is NULL) AND (rowrec.start_date is NULL)))
1536 and ( (waur.expiration_date = rowrec.end_date)
1537 OR((waur.expiration_date is NULL) AND(rowrec.end_date is NULL)));
1538 if (fnd_log.LEVEL_STATEMENT >= fnd_log.g_current_runtime_level) then
1539 fnd_log.string(FND_LOG.LEVEL_STATEMENT,
1540 c_log_head || l_api_name || '.ur_exists',
1541 'USER_ROLE FOUND. Not inserting.');
1542 end if;
1543 exception
1544 when no_data_found then
1545 if (fnd_log.LEVEL_EXCEPTION >= fnd_log.g_current_runtime_level) then
1546 fnd_log.string(FND_LOG.LEVEL_EXCEPTION,
1547 c_log_head || l_api_name || '.ur_notfound',
1548 'USER_ROLE Not FOUND. Need to insert');
1549 end if;
1550 -- We cant just assume that the orig system is FND_USR. It could
1551 -- be PER because the row in wf_users/wf_roles is one or the other
1552 wf_directory.GetRoleOrigSysInfo(rowrec.user_name,
1553 l_user_orig_system,
1554 l_user_orig_system_id);
1555 -- In case there is no WF user, sync this user up so there is one.
1556 -- Should never happen but be safe in case sync wasnt perfect in past
1557 if( (l_user_orig_system is NULL)
1558 and (l_user_orig_system_id is NULL)) then
1559 if (fnd_log.LEVEL_EXCEPTION >= fnd_log.g_current_runtime_level) then
1560 fnd_log.string(FND_LOG.LEVEL_EXCEPTION,
1561 c_log_head || l_api_name || '.orig_notfound',
1562 'Orig system and id not found. Trying to sync user:'||
1563 rowrec.user_name);
1564 end if;
1565 fnd_user_pkg.user_synch(rowrec.user_name);
1566 wf_directory.GetRoleOrigSysInfo(rowrec.user_name,
1567 l_user_orig_system,
1568 l_user_orig_system_id);
1569 end if;
1570 if (fnd_log.LEVEL_STATEMENT >= fnd_log.g_current_runtime_level) then
1571 fnd_log.string(FND_LOG.LEVEL_STATEMENT,
1572 c_log_head || l_api_name || '.got_orig',
1573 'Looked up orig: l_user_orig_system:'||
1574 l_user_orig_system ||' l_user_orig_system_id:'||
1575 l_user_orig_system_id);
1576 end if;
1577 end;
1578
1579 -- Sync the User/Role (but not if there is no wf_user)
1580 if( (l_user_orig_system is not NULL)
1581 or (l_user_orig_system_id is not NULL)) then
1582 begin
1583 wf_local_synch.PropagateUserRole
1584 (p_user_name=>rowrec.user_name,
1585 p_role_name=>rolename,
1586 p_user_orig_system=>l_user_orig_system,
1587 p_user_orig_system_id=>l_user_orig_system_id,
1588 p_role_orig_system=>'FND_RESP',
1589 p_role_orig_system_id=>rowrec.responsibility_id,
1590 p_start_date=>rowrec.start_date,
1591 p_expiration_date=>rowrec.end_date,
1592 p_overwrite=>TRUE,
1593 p_raiseErrors=>TRUE,
1594 p_parent_orig_system => 'FND_RESP',
1595 p_parent_orig_system_id =>rowrec.responsibility_id,
1596 p_ownerTag => rowrec.application_short_name,
1597 p_createdBy => fnd_global.user_id,
1598 p_lastUpdatedBy => fnd_global.user_id,
1599 p_lastUpdateLogin => 0,
1600 p_creationDate => sysdate,
1601 p_lastUpdatedate=> sysdate);
1602
1603 if (fnd_log.LEVEL_STATEMENT >= fnd_log.g_current_runtime_level) then
1604 fnd_log.string(FND_LOG.LEVEL_STATEMENT,
1605 c_log_head || l_api_name || '.called_prop',
1606 'Successfully called wf_local_synch.PropagateUserRole');
1607 end if;
1608 exception when others then
1609 if (fnd_log.LEVEL_EXCEPTION >= fnd_log.g_current_runtime_level) then
1610 fnd_log.string(FND_LOG.LEVEL_EXCEPTION,
1611 c_log_head || l_api_name || '.propagate_fail',
1612 'PropogateUserRole call failed with exception for user:'||
1613 rowrec.user_name || ' role:'||rolename ||
1614 ' sql code:'||sqlcode ||
1615 ' sql errm:'||sqlerrm);
1616 end if;
1617 end;
1618 else
1619 if (fnd_log.LEVEL_EXCEPTION >= fnd_log.g_current_runtime_level) then
1620 fnd_log.string(FND_LOG.LEVEL_EXCEPTION,
1621 c_log_head || l_api_name || '.orig_notfound',
1622 'Did not propogate role because Orig System not found for user:'||
1623 rowrec.user_name);
1624 end if;
1625 end if;
1626
1627 commit;
1628
1629 end loop;
1630
1631 if (fnd_log.LEVEL_PROCEDURE >= fnd_log.g_current_runtime_level) then
1632 fnd_log.string(FND_LOG.LEVEL_PROCEDURE,
1633 c_log_head || l_api_name || '.end',
1634 c_pkg_name || '.' ||l_api_name );
1635 end if;
1636 */
1637 end one_time_furg_to_wf_upgrade;
1638
1639 -- sync_roles_all_secgrps_int
1640 --
1641 -- Bug4322412
1642 -- For a given resp, sync roles for all security groups if the role
1643 -- does not already exist.
1644 --
1645 -- NOTE:This routine does not update existing roles. To update existing roles
1646 -- the routine sync_roles_all_secgrps should be used.
1647 --
1648 procedure sync_roles_all_secgrps_int(
1649 respid in number,
1650 appid in number,
1651 respkey in varchar2,
1652 startdate in date,
1653 enddate in date)
1654 is
1655 cursor get_secgrp is
1656 select security_group_id,
1657 security_group_key
1658 from fnd_security_groups;
1659
1660 rolename varchar2(320);
1661 dummy number;
1662
1663 begin
1664
1665 if (check_secgrp_enabled(respid, appid) = 'N') then
1666 -- Security Groups not enabled for this resp,
1667 -- only create a role for the STANDARD sec grp.
1668 sync_roles_one_resp_secgrp( respid=> respid,
1669 appid=> appid,
1670 respkey=> respkey,
1671 secgrpid=> 0,
1672 secgrpkey=> 'STANDARD',
1673 startdate=> startdate,
1674 enddate=> enddate);
1675 else
1676 -- Security Groups are enabled, create one role for
1677 -- every resp/secgrp pair.
1678
1679 for secrec in get_secgrp loop
1680
1681 begin
1682 rolename := role_name_from_resp(respid, appid,
1683 secrec.security_group_id);
1684 select null
1685 into dummy
1686 from wf_local_roles
1687 where name = rolename
1688 and partition_id = 2
1689 and rownum = 1;
1690
1691 exception
1692 when no_data_found then
1693 sync_roles_one_resp_secgrp(
1694 respid => respid,
1695 appid => appid,
1696 respkey => respkey,
1697 secgrpid => secrec.security_group_id,
1698 secgrpkey => secrec.security_group_key,
1699 startdate => startdate,
1700 enddate => enddate);
1701 end;
1702 end loop;
1703 end if;
1704
1705 end sync_roles_all_secgrps_int;
1706
1707
1708 end Fnd_User_Resp_Groups_Api;