1 package body Fnd_User_Resp_Groups_api as
2 /* $Header: AFSCURGB.pls 120.16.12020000.4 2013/03/25 19:50:40 fskinner 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 assignment_type in ('D', 'B')
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 assignment_type in ('I', 'B')
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 -- Else part has been added for bug 14709898 as null in l_update_who
751 -- is defaulted to TRUE by the WF team.
752 else
753 l_update_who := FALSE;
754 end if;
755
756
757 -- Bug4747169 - Removed passing in the parameters p_created_by and
758 -- p_creation_date as this is the update processing.
759
760 wf_local_synch.PropagateUserRole
761 (p_user_name=>username,
762 p_role_name=>rolename,
763 p_user_orig_system=>l_user_orig_system,
764 p_user_orig_system_id=>l_user_orig_system_id,
765 p_role_orig_system=>'FND_RESP',
766 p_role_orig_system_id=>responsibility_id,
767 p_start_date=>start_date,
768 p_expiration_date=>end_date,
769 p_overwrite=>TRUE,
770 p_raiseErrors=>TRUE,
771 p_parent_orig_system => 'FND_RESP',
772 p_parent_orig_system_id => responsibility_id,
773 p_ownerTag => appsname,
774 p_createdBy => l_created_by,
775 p_creationDate => l_creation_date, /*Bug3626390 sysdate*/
776 p_lastUpdatedate=> l_last_update_date,
777 p_lastUpdatedBy => l_last_updated_by,
778 p_lastUpdateLogin => l_last_update_login,
779 p_assignmentReason=>description,
780 p_updatewho => l_update_who); -- Bug5467610
781
782 --
783 -- Need to propagate the old role name
784 --
785
786 wf_local_synch.PropagateUserRole
787 (p_user_name=>username,
788 p_role_name=>old_rolename,
789 p_user_orig_system=>l_user_orig_system,
790 p_user_orig_system_id=>l_user_orig_system_id,
791 p_role_orig_system=>'FND_RESP'||responsibility_application_id,
792 p_role_orig_system_id=>responsibility_id,
793 p_start_date=>start_date,
794 p_expiration_date=>end_date,
795 p_overwrite=>TRUE,
796 p_raiseErrors=>TRUE,
797 p_parent_orig_system => 'FND_RESP'||responsibility_application_id,
798 p_parent_orig_system_id => responsibility_id,
799 p_ownerTag => appsname,
800 p_createdBy => l_created_by,
801 p_creationDate => l_creation_date, /*Bug3626390 sysdate*/
802 p_lastUpdatedate=> l_last_update_date,
803 p_lastUpdatedBy => l_last_updated_by,
804 p_lastUpdateLogin => l_last_update_login,
805 p_assignmentReason=>description,
806 p_updatewho => l_update_who); -- Bug5467610
807
808
809 wf_event.raise('oracle.apps.fnd.security.user.assignment.change',
810 Update_Assignment.user_id||':'||
811 Update_Assignment.responsibility_id,
812 null, null);
813 --Raise the invalidation event attached to the USER_INFO_CACHE
814 --(ideally this should be done by the wf API once the propagation
815 --has been sucessful) / or if they are not doing it then we should attach
816 --our business event to the CACHE as we do not really know what
817 --subscriptions are attcahed to the wf event.
818 --o.k putting our event (but we need to change the b3664848.ldt
819 --and the event-subscription file to attach this event to the
820 --bes control group.
821 wf_event.addparametertolist(p_name => 'FND_USER_ID',
822 p_value => Update_Assignment.user_id,
823 p_parameterlist => l_parameters);
824
825 wf_event.addparametertolist(p_name => 'FND_RESPONSIBILITY_ID',
826 p_value => Update_Assignment.responsibility_id,
827 p_parameterlist => l_parameters);
828
829 wf_event.addparametertolist(p_name => 'FND_APPS_SHORT_NAME',
830 p_value => appsname,
831 p_parameterlist => l_parameters);
832
833 wf_event.addparametertolist(p_name => 'FND_RESPONSIBILITY_APPS_ID',
834 p_value => Update_Assignment.responsibility_application_id,
835 p_parameterlist => l_parameters);
836
837 wf_event.raise(p_event_name => 'oracle.apps.fnd.user.role.update',
838 p_event_key => to_char(Update_Assignment.user_id)||':'||to_char(Update_Assignment.responsibility_id)||':'||appsname||':'||to_char(Update_Assignment.responsibility_application_id),
839 p_event_data => NULL,
840 p_parameters => l_parameters,
841 p_send_date => Sysdate);
842
843 exception
844 when others then
845 Generic_Error('FND_USER_RESP_GROUPS_API.UPDATE_ASSIGNMENT',
846 sqlcode, sqlerrm);
847
848 end Update_Assignment;
849
850 procedure LOAD_ROW (
851 X_USER_NAME in VARCHAR2,
852 X_RESP_KEY in VARCHAR2,
853 X_APP_SHORT_NAME in VARCHAR2,
854 X_SECURITY_GROUP in VARCHAR2,
855 X_OWNER in VARCHAR2,
856 X_START_DATE in VARCHAR2,
857 X_END_DATE in VARCHAR2,
858 X_DESCRIPTION in VARCHAR2,
859 X_LAST_UPDATE_DATE in DATE default sysdate) is
860 u_id number;
861 app_id number;
862 resp_id number;
863 sgroup_id number;
864 l_end_date varchar2(4000);
865 l_owner number;
866 rolename varchar2(4000);
867 l_user_orig_system varchar2(30);
868 l_user_orig_system_id number;
869 old_rolename varchar2(4000);
870
871 begin
872 select user_id into u_id
873 from fnd_user
874 where user_name = X_USER_NAME;
875
876 select application_id into app_id
877 from fnd_application
878 where application_short_name = X_APP_SHORT_NAME;
879
880 select responsibility_id into resp_id
881 from fnd_responsibility
882 where responsibility_key = X_RESP_KEY
883 and application_id = app_id;
884
885 select security_group_id into sgroup_id
886 from fnd_security_groups
887 where security_group_key = X_SECURITY_GROUP;
888
889 select decode(X_END_DATE,
890 fnd_load_util.null_value, null,
891 null, X_END_DATE,
892 X_END_DATE)
893 into l_end_date
894 from dual;
895
896 -- bug3649874 Modified to use fnd_load_util to get the owner_id
897
898 l_owner := fnd_load_util.owner_id(X_OWNER);
899
900 fnd_user_resp_groups_api.UPLOAD_ASSIGNMENT(
901 USER_ID => u_id,
902 RESPONSIBILITY_ID => resp_id,
903 RESPONSIBILITY_APPLICATION_ID => app_id,
904 SECURITY_GROUP_ID => sgroup_id,
905 START_DATE => to_date(X_START_DATE, 'YYYY/MM/DD'),
906 END_DATE => to_date(l_end_date, 'YYYY/MM/DD'),
907 DESCRIPTION => X_DESCRIPTION);
908
909 --------------------------------------------------------------------------
910 -- The upload_assignment routine uses fnd_global.user_id and
911 -- fnd_global.login_id which is not what we want for loader updates.
912 -- Also upload_assignment only updates created_by if the row was just
913 -- created.
914 -- Added call to PropagateUserRole to correctly set the who columns.
915 --------------------------------------------------------------------------
916 rolename := Role_Name_from_Resp_name(
917 X_RESP_KEY,
918 X_APP_SHORT_NAME,
919 X_SECURITY_GROUP);
920 --
921 -- Generate old role name for backwards compatibility.
922 --
923
924 old_rolename := 'FND_RESP'||app_id||
925 ':'||resp_id;
926
927 -- Bug3649874 propagate the who columns
928
929 wf_directory.GetRoleOrigSysInfo(x_user_name,
930 l_user_orig_system,
931 l_user_orig_system_id);
932
933 wf_local_synch.PropagateUserRole
934 (p_user_name=>x_user_name,
935 p_role_name=>rolename,
936 p_user_orig_system=>l_user_orig_system,
937 p_user_orig_system_id=>l_user_orig_system_id,
938 p_role_orig_system=>'FND_RESP',
939 p_role_orig_system_id=>resp_id,
940 p_start_date=> to_date(X_START_DATE, 'YYYY/MM/DD'),
941 p_expiration_date=>to_date(l_end_date, 'YYYY/MM/DD'),
942 p_overwrite=>TRUE,
943 p_raiseErrors=>TRUE,
944 p_parent_orig_system => 'FND_RESP',
945 p_parent_orig_system_id => resp_id,
946 p_ownerTag => X_APP_SHORT_NAME,
947 p_createdBy => l_owner,
948 p_creationDate => sysdate, /*Bug3626390 sysdate*/
949 p_lastUpdatedate=> x_last_update_date,
950 p_lastUpdatedBy => l_owner,
951 p_lastUpdateLogin => 0,
952 p_assignmentReason=>X_DESCRIPTION);
953
954
955 --
956 -- Need to propagate the old role name
957 --
958
959 wf_local_synch.PropagateUserRole
960 (p_user_name=>x_user_name,
961 p_role_name=>old_rolename,
962 p_user_orig_system=>l_user_orig_system,
963 p_user_orig_system_id=>l_user_orig_system_id,
964 p_role_orig_system=>'FND_RESP'||app_id,
965 p_role_orig_system_id=>resp_id,
966 p_start_date=> to_date(X_START_DATE, 'YYYY/MM/DD'),
967 p_expiration_date=>to_date(l_end_date, 'YYYY/MM/DD'),
968 p_overwrite=>TRUE,
969 p_raiseErrors=>TRUE,
970 p_parent_orig_system => 'FND_RESP'||app_id,
971 p_parent_orig_system_id => resp_id,
972 p_ownerTag => X_APP_SHORT_NAME,
973 p_createdBy => l_owner,
974 p_lastUpdatedBy => l_owner,
975 p_lastUpdateLogin => 0,
976 p_creationDate => sysdate, /*Bug3626390 sysdate*/
977 p_lastUpdatedate=> x_last_update_date,
978 p_assignmentReason=>X_DESCRIPTION);
979
980 end LOAD_ROW;
981
982 --
983 -- Upload_Assignment
984 -- Update user/resp/group assignment if it exists,
985 -- otherwise insert new assignment.
986 -- IN
987 -- user_id - User to get assignment
988 -- responsibility_id - Responsibility to be assigned
989 -- responsibility_application_id - Resp Application to be assigned
990 -- security_group_id - Security Group to be assigned
991 -- start_date - Start date of assignment
992 -- end_date - End date of assignment
993 -- description - Optional comment
994 -- update_who_columns- pass 'Y' or 'N' ('Y' is default if not passed)
995 -- 'N' = leave old who vals. 'Y'= update who cols to current user/date
996
997 --
998 procedure Upload_Assignment(
999 user_id in number,
1000 responsibility_id in number,
1001 responsibility_application_id in number,
1002 security_group_id in number,
1003 start_date in date,
1004 end_date in date,
1005 description in varchar2,
1006 update_who_columns in varchar2 default null
1007 /* 'N' = leave old who vals. 'Y' (default) = update who to current*/)
1008 is
1009 sgid number;
1010 begin
1011
1012 if (security_group_id is null) then
1013 sgid := fnd_global.security_group_id;
1014 else
1015 sgid := security_group_id;
1016 end if;
1017
1018 if (Fnd_User_Resp_Groups_Api.Assignment_Exists(
1019 Upload_Assignment.user_id,
1020 Upload_Assignment.responsibility_id,
1021 Upload_Assignment.responsibility_application_id,
1022 Upload_Assignment.sgid,
1023 'D'))
1024 then
1025 Fnd_User_Resp_Groups_Api.Update_Assignment(
1026 Upload_Assignment.user_id,
1027 Upload_Assignment.responsibility_id,
1028 Upload_Assignment.responsibility_application_id,
1029 Upload_Assignment.sgid,
1030 Upload_Assignment.start_date,
1031 Upload_Assignment.end_date,
1032 Upload_Assignment.description,
1033 update_who_columns);
1034 else
1035 Fnd_User_Resp_Groups_Api.Insert_Assignment(
1036 Upload_Assignment.user_id,
1037 Upload_Assignment.responsibility_id,
1038 Upload_Assignment.responsibility_application_id,
1039 Upload_Assignment.sgid,
1040 Upload_Assignment.start_date,
1041 Upload_Assignment.end_date,
1042 Upload_Assignment.description);
1043 end if;
1044 exception
1045 when others then
1046 Generic_Error('FND_USER_RESP_GROUPS_API.UPLOAD_ASSIGNMENT',
1047 sqlcode, sqlerrm);
1048 end Upload_Assignment;
1049
1050 --
1051 -- Sync_roles_one_resp_secgrp
1052 -- Sync the role for a particular resp and security group.
1053 --
1054 procedure sync_roles_one_resp_secgrp(
1055 respid in number,
1056 appid in number,
1057 respkey in varchar2,
1058 secgrpid in number,
1059 secgrpkey in varchar2,
1060 startdate in date,
1061 enddate in date)
1062 is
1063 l_respkey varchar2(30);
1064 l_secgrpkey varchar2(30);
1065 applsname varchar2(50);
1066 role_name varchar2(320);
1067 role_display_name varchar2(1000);
1068 secgrp_name varchar2(80);
1069 resp_name varchar2(100);
1070 descr varchar2(240);
1071 wf_parameters wf_parameter_list_t;
1072 old_rolename varchar2(320);
1073 -- Bug4507634 - Parameters needed to determine WF STATUS.
1074 my_exp date;
1075 my_start date;
1076 my_creationdate date;
1077 my_lastupdatedate date;
1078 my_createdby number;
1079 my_lastupdatedby number;
1080 my_lastupdatelogin number;
1081
1082 begin
1083
1084 --
1085 -- Generate old role name for backwards compatibility.
1086 --
1087
1088 old_rolename := 'FND_RESP'||appid||
1089 ':'||respid;
1090
1091 /* If caller didn't have respkey to pass, get it from respid/appid */
1092 if (respkey is null) then
1093 begin
1094 select responsibility_key
1095 into l_respkey
1096 from fnd_responsibility
1097 where responsibility_id = respid
1098 and application_id = appid;
1099 exception
1100 when no_data_found then
1101 return; /* Bad foreign key; we can't build a role. Return. */
1102 end;
1103 else
1104 l_respkey := respkey;
1105 end if;
1106
1107 /* If caller didn't have secgrpkey to pass, get it from secgrpid */
1108 if (secgrpkey is null) then
1109 begin
1110 select security_group_key
1111 into l_secgrpkey
1112 from fnd_security_groups
1113 where security_group_id = secgrpid;
1114 exception
1115 when no_data_found then
1116 return; /* Bad foreign key; we can't build a role. Return. */
1117 end;
1118 else
1119 l_secgrpkey := secgrpkey;
1120 end if;
1121
1122 /* Get the application short name for role name */
1123 begin
1124 select application_short_name
1125 into applsname
1126 from fnd_application
1127 where application_id = appid;
1128
1129 role_name := fnd_user_resp_groups_api.role_name_from_resp_name(
1130 respkey, applsname, secgrpkey);
1131
1132 exception
1133 when no_data_found then
1134 /* invalid foreign key to a nonexistant app. Skip. */
1135 role_name := null;
1136 applsname := null;
1137 return;
1138 end;
1139
1140 /* Get the responsibility name of base language for role display name */
1141 begin
1142 select responsibility_name, description
1143 into resp_name, descr
1144 from fnd_responsibility_tl
1145 where responsibility_id = respid
1146 and application_id = appid
1147 and language = (select language_code
1148 from fnd_languages
1149 where installed_flag = 'B');
1150 exception
1151 when no_data_found then
1152 /* This shouldn't normally happen, it's just for bad TL tables*/
1153 resp_name := applsname ||':'||respkey;
1154 descr := NULL;
1155 end;
1156
1157 /* Get the security group name of base language for role display name */
1158 /* Don't need the name for STANDARD, so skip the select */
1159 if (secgrpid <> 0) then
1160 begin
1161 select security_group_name
1162 into secgrp_name
1163 from fnd_security_groups_tl
1164 where security_group_id = secgrpid
1165 and language = (select language_code
1166 from fnd_languages
1167 where installed_flag = 'B');
1168 exception
1169 when no_data_found then
1170 /* This shouldn't normally happen, it's just for bad TL tables*/
1171 secgrp_name := secgrpkey;
1172 end;
1173 end if;
1174
1175 -- Bug4507634 Need to attain values for start/end date in order to
1176 -- correctly update the status in WF.
1177
1178 -- Bug4864465 Added getting the WHO column data also.
1179
1180 begin
1181 select start_date, end_date,
1182 created_by, creation_date,
1183 last_updated_by, last_update_date, last_update_login
1184 into my_start, my_exp, my_createdby, my_creationdate,
1185 my_lastupdatedby, my_lastupdatedate, my_lastupdatelogin
1186 from fnd_responsibility
1187 where responsibility_id = respid
1188 and application_id = appid;
1189 exception
1190 when no_data_found then
1191 return; /* Bad foreign key; we can't build a role. Return. */
1192 end;
1193
1194 -- Insert or update role in workflow.
1195 -- Need to do this even if role already exists, to update
1196 -- attribute values.
1197 wf_parameters := NULL;
1198 wf_event.AddParameterToList('USER_NAME',
1199 role_name , wf_parameters);
1200 if(secgrpkey = 'STANDARD') then
1201 role_display_name := resp_name;
1202 else
1203 role_display_name := resp_name||':'||secgrp_name;
1204 end if;
1205
1206 wf_event.AddParameterToList('DISPLAYNAME',
1207 role_display_name, wf_parameters);
1208 wf_event.AddParameterToList('DESCRIPTION',
1209 descr, wf_parameters);
1210 wf_event.AddParameterToList('OWNER_TAG',
1211 applsname, wf_parameters);
1212 wf_event.AddParameterToList('RAISEERRORS',
1213 'TRUE', wf_parameters);
1214
1215 -- Bug4507634 added WFSYNCH_OVERWRITE and ORCLISENABLED parameters.
1216
1217 wf_event.AddParameterToList('WFSYNCH_OVERWRITE',
1218 'TRUE', wf_parameters);
1219 if ((my_exp is null) OR
1220 (trunc(sysdate) between my_start and my_exp)) then
1221 wf_event.AddParameterToList('ORCLISENABLED', 'ACTIVE', wf_parameters);
1222 else
1223 wf_event.AddParameterToList('ORCLISENABLED', 'INACTIVE', wf_parameters);
1224 end if;
1225
1226 -- Bug4864465 Adding the WHO column values to be propagated.
1227
1228 wf_event.AddParameterToList('LAST_UPDATED_BY',my_lastupdatedby,wf_parameters);
1229
1230 -- Bug5729583 - Updated date values to use WF_CORE.canonical_date_mask.
1231
1232 wf_event.AddParameterToList('LAST_UPDATE_DATE',
1233 to_char(my_lastupdatedate,WF_CORE.canonical_date_mask),wf_parameters);
1234 wf_event.AddParameterToList('CREATED_BY',my_createdby,wf_parameters);
1235
1236 -- Bug5729583 - Updated date values to use WF_CORE.canonical_date_mask.
1237
1238 wf_event.AddParameterToList('CREATION_DATE',to_char(my_creationdate,WF_CORE.canonical_date_mask),wf_parameters);
1239 wf_event.AddParameterToList('LAST_UPDATE_LOGIN',
1240 my_lastupdatelogin,wf_parameters);
1241
1242 wf_local_synch.propagate_role(p_orig_system=>'FND_RESP',
1243 p_orig_system_id=>respid,
1244 p_attributes=> wf_parameters,
1245 p_start_date=>startdate,
1246 p_expiration_date=>enddate);
1247
1248 -- Insert or update role in workflow for old_rolename.
1249 wf_parameters := NULL;
1250 wf_event.AddParameterToList('USER_NAME',
1251 old_rolename , wf_parameters);
1252
1253 role_display_name := resp_name||':Any security group';
1254
1255 wf_event.AddParameterToList('DISPLAYNAME',
1256 role_display_name, wf_parameters);
1257 wf_event.AddParameterToList('DESCRIPTION',
1258 descr, wf_parameters);
1259 wf_event.AddParameterToList('OWNER_TAG',
1260 applsname, wf_parameters);
1261 wf_event.AddParameterToList('RAISEERRORS',
1262 'TRUE', wf_parameters);
1263
1264 -- Bug4507634 added WFSYNCH_OVERWRITE parameter.
1265
1266 wf_event.AddParameterToList('WFSYNCH_OVERWRITE',
1267 'TRUE', wf_parameters);
1268
1269 -- Bug4699363 added parameter for ORCLISENABLED.
1270
1271 if ((my_exp is null) OR
1272 (trunc(sysdate) between my_start and my_exp)) then
1273 wf_event.AddParameterToList('ORCLISENABLED', 'ACTIVE', wf_parameters);
1274 else
1275 wf_event.AddParameterToList('ORCLISENABLED', 'INACTIVE', wf_parameters);
1276 end if;
1277
1278 -- Bug4864465 Adding the WHO column values to be propagated.
1279
1280 wf_event.AddParameterToList('LAST_UPDATED_BY',my_lastupdatedby,wf_parameters);
1281
1282 -- Bug5729583 - Updated date values to use WF_CORE.canonical_date_mask.
1283
1284 wf_event.AddParameterToList('LAST_UPDATE_DATE',
1285 to_char(my_lastupdatedate,WF_CORE.canonical_date_mask), wf_parameters);
1286 wf_event.AddParameterToList('CREATED_BY',my_createdby, wf_parameters);
1287 wf_event.AddParameterToList('CREATION_DATE',to_char(my_creationdate,WF_CORE.canonical_date_mask),wf_parameters);
1288 wf_event.AddParameterToList('LAST_UPDATE_LOGIN',
1289 my_lastupdatelogin, wf_parameters);
1290
1291 wf_local_synch.propagate_role(p_orig_system=>'FND_RESP'||appid,
1292 p_orig_system_id=>respid,
1293 p_attributes=> wf_parameters,
1294 p_start_date=>startdate,
1295 p_expiration_date=>enddate);
1296
1297 end sync_roles_one_resp_secgrp;
1298
1299 --
1300 -- sync_roles_all_secgrps
1301 -- For a given resp, sync roles for all security groups
1302 -- NOTE: This is intended to be called whenever a responsibility
1303 -- is inserted or updated.
1304 --
1305
1306 procedure sync_roles_all_secgrps(
1307 respid in number,
1308 appid in number,
1309 respkey in varchar2,
1310 startdate in date,
1311 enddate in date)
1312 is
1313 cursor get_secgrp is
1314 select security_group_id,
1315 security_group_key
1316 from fnd_security_groups;
1317
1318 begin
1319
1320 if (check_secgrp_enabled(respid, appid) = 'N') then
1321 -- Security Groups not enabled for this resp,
1322 -- only create a role for the STANDARD sec grp.
1323 sync_roles_one_resp_secgrp( respid=> respid,
1324 appid=> appid,
1325 respkey=> respkey,
1326 secgrpid=> 0,
1327 secgrpkey=> 'STANDARD',
1328 startdate=> startdate,
1329 enddate=> enddate);
1330 else
1331 -- Security Groups are enabled, create one role for
1332 -- every resp/secgrp pair.
1333 for secrec in get_secgrp loop
1334 sync_roles_one_resp_secgrp(
1335 respid => respid,
1336 appid => appid,
1337 respkey => respkey,
1338 secgrpid => secrec.security_group_id,
1339 secgrpkey => secrec.security_group_key,
1340 startdate => startdate,
1341 enddate => enddate);
1342 end loop;
1343 end if;
1344
1345 end sync_roles_all_secgrps;
1346
1347 --
1348 -- sync_roles_all_resps
1349 -- For a given security group, sync roles for all responsibilities
1350 -- NOTE: This is intended to be called whenever a security group
1351 -- is inserted or updated.
1352 -- ### Security groups can be deleted, should also sync that.
1353 --
1354 procedure sync_roles_all_resps(secgrpid in varchar2,
1355 secgrpkey in varchar2) is
1356 cursor get_resp is
1357 select application_id,
1358 responsibility_id,
1359 responsibility_key,
1360 start_date,
1361 end_date
1362 from fnd_responsibility;
1363 begin
1364 for resprec in get_resp loop
1365 -- If secgrp is STANDARD, then create resp/secgrp role for all resps.
1366 -- Otherwise, only create roles for resps with security groups enabled.
1367 if ((secgrpid = 0) or
1368 (check_secgrp_enabled(resprec.responsibility_id,
1369 resprec.application_id) = 'Y'))
1370 then
1371 sync_roles_one_resp_secgrp(
1372 resprec.responsibility_id,
1373 resprec.application_id,
1374 resprec.responsibility_key,
1375 secgrpid,
1376 secgrpkey,
1377 resprec.start_date,
1378 resprec.end_date);
1379 end if;
1380 end loop;
1381
1382 end sync_roles_all_resps;
1383
1384 --
1385 -- sync_roles_all_resp_secgrps
1386 -- Create roles for all resp/security group pairs.
1387 --
1388 -- Bug4349774 - Added sync_all_flag to default to previous behavior
1389 -- where if TRUE is passed then updates and inserts are
1390 -- processed otherwise only inserts are done.
1391
1392 procedure sync_roles_all_resp_secgrps (sync_all_flag in boolean default FALSE)
1393 is
1394 cursor get_resp is
1395 select application_id,
1396 responsibility_id,
1397 responsibility_key,
1398 start_date,
1399 end_date
1400 from fnd_responsibility;
1401 begin
1402
1403 if (sync_all_flag = TRUE) then
1404 for resprec in get_resp loop
1405 sync_roles_all_secgrps(respid=> resprec.responsibility_id,
1406 appid=> resprec.application_id,
1407 respkey=> resprec.responsibility_key,
1408 startdate=> resprec.start_date,
1409 enddate=> resprec.end_date);
1410 commit;
1411 end loop;
1412 else
1413 -- Bug4322412 changed call to internal procedure so that if the role
1414 -- exists we do not waste time updating again.
1415
1416 for resprec in get_resp loop
1417 sync_roles_all_secgrps_int(respid=> resprec.responsibility_id,
1418 appid=> resprec.application_id,
1419 respkey=> resprec.responsibility_key,
1420 startdate=> resprec.start_date,
1421 enddate=> resprec.end_date);
1422 commit;
1423 end loop;
1424 end if;
1425
1426 end sync_roles_all_resp_secgrps;
1427
1428
1429 --
1430 -- Moves old data from fnd_user_resp_groups table to new workflow tables.
1431 -- This routine is exposed so that it can be called from a one time
1432 -- upgrade script, and it should never need to be run after that.
1433 -- Running it unnecessarily might invalidate work that
1434 -- admins have done to split assignments out into roles
1435 --
1436 -- Before calling this, make sure you have called
1437 -- sync_roles_all_resp_secgrps() in order to get the roles in place that
1438 -- this routine will depend on.
1439 --
1440 -- OBSOLETE: This functionality is now in the bulk sync of FND_RESP
1441 -- which is called from the affurgol.sql script.
1442 -- This code is just here in case the bulk sync fails as a last ditch
1443 -- effort this code could be called.
1444 procedure one_time_furg_to_wf_upgrade is /* THIS ROUTINE IS OBSOLETE */
1445 begin
1446 null; /* ### Stubbed ### */
1447 /*
1448 l_api_name CONSTANT VARCHAR2(30) := 'one_time_furg_to_wf_upgrade';
1449 cursor get_old_row is
1450 select fu.user_name,
1451 secgrp.security_group_key,
1452 app.application_short_name,
1453 resp.responsibility_key,
1454 resp.start_date resp_start_date,
1455 resp.end_date resp_end_date,
1456 furgo.user_id,
1457 furgo.responsibility_id,
1458 furgo.responsibility_application_id,
1459 furgo.start_date,
1460 furgo.end_date,
1461 furgo.security_group_id,
1462 furgo.created_by,
1463 furgo.creation_date,
1464 furgo.last_updated_by,
1465 furgo.last_update_date,
1466 furgo.last_update_login
1467 from fnd_user_resp_groups_old furgo,
1468 fnd_user fu,
1469 fnd_application app,
1470 fnd_responsibility resp,
1471 fnd_security_groups secgrp
1472 where furgo.user_id = fu.user_id
1473 and furgo.responsibility_id = resp.responsibility_id
1474 and furgo.responsibility_application_id
1475 = resp.application_id
1476 and furgo.responsibility_application_id
1477 = app.application_id
1478 and furgo.security_group_id = secgrp.security_group_id;
1479 resp_name varchar2(100);
1480 descr varchar2(240);
1481 secgrp_name varchar2(80);
1482 dummy varchar2(255);
1483 wf_parameters wf_parameter_list_t;
1484 l_user_orig_system varchar2(30);
1485 l_user_orig_system_id number;
1486 rolename varchar2(1000);
1487 resp_key varchar2(100);
1488 begin
1489 if (fnd_log.LEVEL_PROCEDURE >= fnd_log.g_current_runtime_level) then
1490 fnd_log.string(FND_LOG.LEVEL_PROCEDURE,
1491 c_log_head || l_api_name || '.begin',
1492 c_pkg_name || '.' ||l_api_name);
1493 end if;
1494
1495 for rowrec in get_old_row loop
1496
1497 resp_key := rowrec.responsibility_key;
1498
1499 rolename := role_name_from_resp_name( resp_key,
1500 rowrec.application_short_name,
1501 rowrec.security_group_key);
1502
1503 if (fnd_log.LEVEL_STATEMENT >= fnd_log.g_current_runtime_level) then
1504 fnd_log.string(FND_LOG.LEVEL_STATEMENT,
1505 c_log_head || l_api_name || '.processing',
1506 'Processing role:'|| rolename ||' for user_id:'||
1507 rowrec.user_id ||' user_name:'||rowrec.user_name);
1508 end if;
1509 begin
1510 select name
1511 into dummy
1512 from wf_local_roles partition (FND_RESP)
1513 where name = rolename
1514 and rownum = 1;
1515 exception -- This shouldnt be necessary since the roles should already
1516 when no_data_found then -- have been created, but be safe.
1517 if (fnd_log.LEVEL_STATEMENT >= fnd_log.g_current_runtime_level) then
1518 fnd_log.string(FND_LOG.LEVEL_STATEMENT,
1519 c_log_head || l_api_name || '.need_to_create_role',
1520 'Creating role:'|| rolename);
1521 end if;
1522 fnd_user_resp_groups_api.sync_roles_one_resp_secgrp(
1523 rowrec.responsibility_id,
1524 rowrec.responsibility_application_id,
1525 rowrec.responsibility_key,
1526 rowrec.security_group_id,
1527 rowrec.security_group_key,
1528 rowrec.resp_start_date,
1529 rowrec.resp_end_date);
1530 end;
1531
1532 begin
1533 select role_name
1534 into dummy
1535 from wf_all_user_roles waur
1536 where waur.role_name = rolename
1537 and waur.user_name = rowrec.user_name
1538 and ( (waur.start_date = rowrec.start_date)
1539 OR((waur.start_date is NULL) AND (rowrec.start_date is NULL)))
1540 and ( (waur.expiration_date = rowrec.end_date)
1541 OR((waur.expiration_date is NULL) AND(rowrec.end_date is NULL)));
1542 if (fnd_log.LEVEL_STATEMENT >= fnd_log.g_current_runtime_level) then
1543 fnd_log.string(FND_LOG.LEVEL_STATEMENT,
1544 c_log_head || l_api_name || '.ur_exists',
1545 'USER_ROLE FOUND. Not inserting.');
1546 end if;
1547 exception
1548 when no_data_found then
1549 if (fnd_log.LEVEL_EXCEPTION >= fnd_log.g_current_runtime_level) then
1550 fnd_log.string(FND_LOG.LEVEL_EXCEPTION,
1551 c_log_head || l_api_name || '.ur_notfound',
1552 'USER_ROLE Not FOUND. Need to insert');
1553 end if;
1554 -- We cant just assume that the orig system is FND_USR. It could
1555 -- be PER because the row in wf_users/wf_roles is one or the other
1556 wf_directory.GetRoleOrigSysInfo(rowrec.user_name,
1557 l_user_orig_system,
1558 l_user_orig_system_id);
1559 -- In case there is no WF user, sync this user up so there is one.
1560 -- Should never happen but be safe in case sync wasnt perfect in past
1561 if( (l_user_orig_system is NULL)
1562 and (l_user_orig_system_id is NULL)) then
1563 if (fnd_log.LEVEL_EXCEPTION >= fnd_log.g_current_runtime_level) then
1564 fnd_log.string(FND_LOG.LEVEL_EXCEPTION,
1565 c_log_head || l_api_name || '.orig_notfound',
1566 'Orig system and id not found. Trying to sync user:'||
1567 rowrec.user_name);
1568 end if;
1569 fnd_user_pkg.user_synch(rowrec.user_name);
1570 wf_directory.GetRoleOrigSysInfo(rowrec.user_name,
1571 l_user_orig_system,
1572 l_user_orig_system_id);
1573 end if;
1574 if (fnd_log.LEVEL_STATEMENT >= fnd_log.g_current_runtime_level) then
1575 fnd_log.string(FND_LOG.LEVEL_STATEMENT,
1576 c_log_head || l_api_name || '.got_orig',
1577 'Looked up orig: l_user_orig_system:'||
1578 l_user_orig_system ||' l_user_orig_system_id:'||
1579 l_user_orig_system_id);
1580 end if;
1581 end;
1582
1583 -- Sync the User/Role (but not if there is no wf_user)
1584 if( (l_user_orig_system is not NULL)
1585 or (l_user_orig_system_id is not NULL)) then
1586 begin
1587 wf_local_synch.PropagateUserRole
1588 (p_user_name=>rowrec.user_name,
1589 p_role_name=>rolename,
1590 p_user_orig_system=>l_user_orig_system,
1591 p_user_orig_system_id=>l_user_orig_system_id,
1592 p_role_orig_system=>'FND_RESP',
1593 p_role_orig_system_id=>rowrec.responsibility_id,
1594 p_start_date=>rowrec.start_date,
1595 p_expiration_date=>rowrec.end_date,
1596 p_overwrite=>TRUE,
1597 p_raiseErrors=>TRUE,
1598 p_parent_orig_system => 'FND_RESP',
1599 p_parent_orig_system_id =>rowrec.responsibility_id,
1600 p_ownerTag => rowrec.application_short_name,
1601 p_createdBy => fnd_global.user_id,
1602 p_lastUpdatedBy => fnd_global.user_id,
1603 p_lastUpdateLogin => 0,
1604 p_creationDate => sysdate,
1605 p_lastUpdatedate=> sysdate);
1606
1607 if (fnd_log.LEVEL_STATEMENT >= fnd_log.g_current_runtime_level) then
1608 fnd_log.string(FND_LOG.LEVEL_STATEMENT,
1609 c_log_head || l_api_name || '.called_prop',
1610 'Successfully called wf_local_synch.PropagateUserRole');
1611 end if;
1612 exception when others then
1613 if (fnd_log.LEVEL_EXCEPTION >= fnd_log.g_current_runtime_level) then
1614 fnd_log.string(FND_LOG.LEVEL_EXCEPTION,
1615 c_log_head || l_api_name || '.propagate_fail',
1616 'PropogateUserRole call failed with exception for user:'||
1617 rowrec.user_name || ' role:'||rolename ||
1618 ' sql code:'||sqlcode ||
1619 ' sql errm:'||sqlerrm);
1620 end if;
1621 end;
1622 else
1623 if (fnd_log.LEVEL_EXCEPTION >= fnd_log.g_current_runtime_level) then
1624 fnd_log.string(FND_LOG.LEVEL_EXCEPTION,
1625 c_log_head || l_api_name || '.orig_notfound',
1626 'Did not propogate role because Orig System not found for user:'||
1627 rowrec.user_name);
1628 end if;
1629 end if;
1630
1631 commit;
1632
1633 end loop;
1634
1635 if (fnd_log.LEVEL_PROCEDURE >= fnd_log.g_current_runtime_level) then
1636 fnd_log.string(FND_LOG.LEVEL_PROCEDURE,
1637 c_log_head || l_api_name || '.end',
1638 c_pkg_name || '.' ||l_api_name );
1639 end if;
1640 */
1641 end one_time_furg_to_wf_upgrade;
1642
1643 -- sync_roles_all_secgrps_int
1644 --
1645 -- Bug4322412
1646 -- For a given resp, sync roles for all security groups if the role
1647 -- does not already exist.
1648 --
1649 -- NOTE:This routine does not update existing roles. To update existing roles
1650 -- the routine sync_roles_all_secgrps should be used.
1651 --
1652 procedure sync_roles_all_secgrps_int(
1653 respid in number,
1654 appid in number,
1655 respkey in varchar2,
1656 startdate in date,
1657 enddate in date)
1658 is
1659 cursor get_secgrp is
1660 select security_group_id,
1661 security_group_key
1662 from fnd_security_groups;
1663
1664 rolename varchar2(320);
1665 dummy number;
1666
1667 begin
1668
1669 if (check_secgrp_enabled(respid, appid) = 'N') then
1670 -- Security Groups not enabled for this resp,
1671 -- only create a role for the STANDARD sec grp.
1672 sync_roles_one_resp_secgrp( respid=> respid,
1673 appid=> appid,
1674 respkey=> respkey,
1675 secgrpid=> 0,
1676 secgrpkey=> 'STANDARD',
1677 startdate=> startdate,
1678 enddate=> enddate);
1679 else
1680 -- Security Groups are enabled, create one role for
1681 -- every resp/secgrp pair.
1682
1683 for secrec in get_secgrp loop
1684
1685 begin
1686 rolename := role_name_from_resp(respid, appid,
1687 secrec.security_group_id);
1688 select null
1689 into dummy
1690 from wf_local_roles
1691 where name = rolename
1692 and partition_id = 2
1693 and rownum = 1;
1694
1695 exception
1696 when no_data_found then
1697 sync_roles_one_resp_secgrp(
1698 respid => respid,
1699 appid => appid,
1700 respkey => respkey,
1701 secgrpid => secrec.security_group_id,
1702 secgrpkey => secrec.security_group_key,
1703 startdate => startdate,
1704 enddate => enddate);
1705 end;
1706 end loop;
1707 end if;
1708
1709 end sync_roles_all_secgrps_int;
1710
1711
1712 end Fnd_User_Resp_Groups_Api;