1 PACKAGE BODY WF_ROLE_HIERARCHY as
2 /*$Header: WFRHIERB.pls 120.27.12010000.4 2008/11/07 16:25:48 alsosa ship $*/
3
4 ----
5 -- Private Globals
6 --
7 --
8 g_trustTimeStamp DATE;
9
10 ----
11 -- Private APIs
12 --
13 --
14
15 -- RaiseEvent (PRIVATE)
16 -- Wrapper to raise events to BES.
17 -- IN
18 -- p_eventName (VARCHAR2)
19 -- p_relationshipID (NUMBER)
20 -- p_superName (VARCHAR2)
21 -- p_subName (VARCHAR2)
22 -- p_defer (BOOLEAN)
23
24 procedure RaiseEvent( p_eventName VARCHAR2,
25 p_relationshipID NUMBER,
26 p_superName VARCHAR2,
27 p_subName VARCHAR2,
28 p_defer BOOLEAN) is
29
30 l_params WF_PARAMETER_LIST_T;
31
32 begin
33 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
34 -- Log only
35 -- BINDVAR_SCAN_IGNORE[5]
36 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
37 g_modulePkg||'.RaiseEvent',
38 'Begin RaiseEvent('||p_eventName||', '||
39 p_relationshipID||', '||p_superName||', '||
40 p_subName||')');
41 end if;
42
43 WF_EVENT.AddParameterToList('RELATIONSHIP_ID', p_relationshipID, l_params);
44 WF_EVENT.AddParameterToList('SUPER_NAME', p_superName, l_params);
45 WF_EVENT.AddParameterToList('SUB_NAME', p_subName, l_params);
46 WF_EVENT.AddParameterToList('USER_ID', WFA_SEC.USER_ID, l_params);
47 WF_EVENT.AddParameterToList('LOGIN_ID', WFA_SEC.LOGIN_ID, l_params);
48 WF_EVENT.AddParameterToList('SECURITY_GROUP_ID',
49 WFA_SEC.SECURITY_GROUP_ID, l_params);
50
51 if (p_defer) then
52 WF_EVENT.AddParameterToList('DEFER_PROPAGATION', 'TRUE', l_params);
53 else
54 WF_EVENT.AddParameterToList('DEFER_PROPAGATION', 'FALSE', l_params);
55 end if;
56
57 WF_EVENT.Raise(P_EVENT_NAME=>p_eventName,
58 P_EVENT_KEY=>p_relationshipID, P_PARAMETERS=>l_params);
59
60 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
61 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
62 g_modulePkg||'.RaiseEvent',
63 'End RaiseEvent('||p_eventName||', '||
64 p_relationshipID||', '||p_superName||', '||
65 p_subName||')');
66 end if;
67 exception
68 when OTHERS then
69 if (wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
70 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
71 g_modulePkg||'.RaiseEvent',
72 'Exception: '||sqlerrm);
73 end if;
74 WF_CORE.Context('WF_ROLE_HIERARCHY', 'RaiseEvent', p_eventName,
75 p_relationshipID, p_superName, p_subName);
76 raise;
77 end RaiseEvent;
78
79
80 --
81 -- HierarchyEnabled (PRIVATE)
82 --
83 -- IN
84 -- p_origSystem (VARCHAR2)
85 --
86 -- RETURNS
87 -- BOOLEAN
88 --
89 -- NOTES
90 -- Checks to see if p_origSystem does NOT participate in bulk synch
91 -- therefore is able to be hierarchy enabled.
92 --
93 function HierarchyEnabled (p_origSystem in VARCHAR2) return boolean
94 is
95 l_viewName VARCHAR2(30);
96 l_partitionID number;
97 l_partitionName varchar2(30);
98 l_hierarchyEnabled BOOLEAN;
99
100 begin
101 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
102 -- Log only
103 -- BINDVAR_SCAN_IGNORE[3]
104 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
105 g_modulePkg||'.HierarchyEnabled',
106 'Begin HierarchyEnabled('||p_origSystem||')');
107 end if;
108
109 WF_DIRECTORY.AssignPartition(p_origSystem, l_partitionID,
110 l_partitionName);
111
112 --First Check:If the partition is registered and the view names are
113 --set to 'NOBS' or if the partition is not registered, we return true.
114 begin
115 SELECT ROLE_VIEW
116 INTO l_viewName
117 FROM WF_DIRECTORY_PARTITIONS
118 WHERE ORIG_SYSTEM = UPPER(p_origSystem)
119 AND PARTITION_ID <> 0 --<rwunderl:3588271>
120 AND (ROLE_VIEW is NULL
121 or ROLE_VIEW <> 'NOBS');
122
123 l_hierarchyEnabled := FALSE;
124
125 exception
126 when NO_DATA_FOUND then
127 l_hierarchyEnabled := TRUE;
128 if wf_log_pkg.level_exception >= fnd_log.g_current_runtime_level then
129 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_EXCEPTION,
130 g_modulePkg||'.HierarchyEnabled',
131 p_origSystem||' is hierarchy enabled.');
132 end if;
133 end;
134
135 --Second Check: If a hierarchical relationship was created then
136 --we are hierarchy enabled.
137 if NOT (l_hierarchyEnabled) then
138 begin
139 select 'NOBS'
140 into l_viewName
141 from dual
142 where EXISTS (select NULL
143 from WF_ROLE_HIERARCHIES
144 where PARTITION_ID = l_partitionID
145 or SUPERIOR_PARTITION_ID = l_partitionID);
146
147 l_hierarchyEnabled := TRUE;
148 exception
149 when NO_DATA_FOUND then
150 l_hierarchyEnabled := FALSE;
151 end;
152 end if;
153 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
154 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
155 g_modulePkg||'.HierarchyEnabled',
156 'End HierarchyEnabled('||p_origSystem||')');
157 end if;
158 return l_HierarchyEnabled;
159
160 exception
161 when OTHERS then
162 if(wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
163 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
164 g_modulePkg||'.HierarchyEnabled',
165 'Exception: '||sqlerrm);
166 end if;
167 WF_CORE.Context('WF_ROLE_HIERARCHY', 'HierarchyEnabled', p_origSystem);
168 raise;
169
170 end HierarchyEnabled;
171
172 --
173 -- Calculate_Effective_Dates(PRIVATE)
174 --
175 -- IN
176 -- p_startDate DATE,
177 -- p_endDate DATE,
178 -- p_userStartDate DATE,
179 -- p_userEndDate DATE,
180 -- p_roleStartDate DATE,
181 -- p_roleEndDate DATE,
182 -- p_assignRoleStart DATE,
183 -- p_assignRoleEnd DATE,
184 --
185 -- IN OUT
186 -- p_effStartDate DATE
187 -- p_effEndDate DATE
188 --
189 -- NOTES
190 -- Calculates the effective start and end dates in WF_USER_ROLE_ASSIGNMENTS
191 -- from the user/role and asigning_Role start and end dates respectively
192
193 procedure Calculate_Effective_Dates(
194 p_startDate in DATE,
195 p_endDate in DATE,
196 p_userStartDate in DATE,
197 p_userEndDate in DATE,
198 p_roleStartDate in DATE,
199 p_roleEndDate in DATE,
200 p_assignRoleStart in DATE,
201 p_assignRoleEnd in DATE,
202 p_effStartDate in out NOCOPY DATE,
203 p_effEndDate in out NOCOPY DATE
204 )
205 is
206
207 begin
208
209 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
210 -- Log only
211 -- BINDVAR_SCAN_IGNORE[9]
212 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
213 g_modulePkg||'.Calculate_Effective_Dates',
214 'Begin Calculate_Effective_Dates('||
215 to_char(p_startDate,WF_CORE.canonical_date_mask)|| ', ' ||
216 to_char(p_endDate,WF_CORE.canonical_date_mask)|| ', ' ||
217 to_char(p_userStartDate,WF_CORE.canonical_date_mask)||', '||
218 to_char(p_userEndDate,WF_CORE.canonical_date_mask)||', ' ||
219 to_char(p_roleStartDate,WF_CORE.canonical_date_mask)||', '||
220 to_char(p_roleEndDate,WF_CORE.canonical_date_mask)||', '||
221 to_char(p_assignRoleStart,WF_CORE.canonical_date_mask)||', '||
222 to_char(p_assignRoleEnd,WF_CORE.canonical_date_mask)||', '||
223 to_char( p_effStartDate,WF_CORE.canonical_date_mask)||', '||
224 to_char(p_effEndDate,WF_CORE.canonical_date_mask)||')');
225 end if;
226 --Intialize effective start date to beginning of time
227 p_effStartDate := to_date(1,'J');
228 --The effective start should be the greatest of all start dates.
229 p_effStartDate := greatest(nvl(p_startDate, p_effStartDate),
230 nvl(p_userStartDate, p_effStartDate),
231 nvl(p_roleStartDate, p_effStartDate),
232 nvl(p_assignRoleStart, p_effStartDate));
233
234 --Intialize effective start date to end of time
235 p_effEndDate := to_date('9999/01/01','YYYY/MM/DD');
236 --The effective end should be the least of all end dates.
237 p_effEndDate := least(nvl(p_endDate, p_effEndDate),
238 nvl(p_userEndDate, p_effEndDate),
239 nvl(p_roleEndDate, p_effEndDate),
240 nvl(p_assignRoleEnd, p_effEndDate));
241
242
243 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
244 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
245 g_modulePkg||'.Calculate_Effective_Dates',
246 'End Calculate_Effective_Dates');
247 end if;
248 exception
249 when OTHERS then
250 if (wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
251 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
252 g_modulePkg||'.Calculate_Effective_Dates',
253 'Exception: '||sqlerrm);
254 end if;
255
256 WF_CORE.Context('WF_ROLE_HIERARCHY', 'Calculate_Effective_Dates',
257 to_char(p_startDate,WF_CORE.canonical_date_mask),
258 to_char(p_endDate,WF_CORE.canonical_date_mask),
259 to_char(p_userStartDate,WF_CORE.canonical_date_mask),
260 to_char(p_userEndDate,WF_CORE.canonical_date_mask),
261 to_char(p_roleStartDate,WF_CORE.canonical_date_mask),
262 to_char(p_roleEndDate,WF_CORE.canonical_date_mask),
263 to_char(p_assignRoleStart,WF_CORE.canonical_date_mask),
264 to_char(p_assignRoleEnd,WF_CORE.canonical_date_mask),
265 to_char(p_effStartDate,WF_CORE.canonical_date_mask),
266 to_char(p_effEndDate,WF_CORE.canonical_date_mask));
267
268 raise;
269 end Calculate_Effective_Dates;
270
271 --
272 -- AssignmentType (PRIVATE)
273 --
274 -- IN
275 -- p_UserName (VARCHAR2)
276 -- p_RoleName (VARCHAR2)
277 --
278 -- RETURNS
279 -- VARCHAR2
280 --
281 -- NOTES
282 -- Checks to see if this is a direct, indirect or both. Any exception
283 -- or failure to determine the assignment type returns 'X'.
284 --
285 function AssignmentType(p_UserName VARCHAR2,
286 p_RoleName VARCHAR2) return varchar2 is
287
288 TYPE numTAB is TABLE OF NUMBER INDEX BY BINARY_INTEGER;
289 l_relIDTAB numTAB;
290 l_assignmentType VARCHAR2(1) := 'X';
291 arIND NUMBER;
292
293 begin
294 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
295 -- Log only
296 -- BINDVAR_SCAN_IGNORE[4]
297 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
298 g_modulePkg||'.AssignmentType',
299 'Begin AssignmentType('||p_UserName||', '||
300 p_RoleName||')');
301 end if;
302 --Determine assignment type
303 SELECT RELATIONSHIP_ID
304 BULK COLLECT INTO l_relIDTAB
305 FROM WF_USER_ROLE_ASSIGNMENTS
306 WHERE ROLE_NAME = p_RoleName
307 AND USER_NAME = p_UserName
308 AND trunc(sysdate) BETWEEN
309 trunc(EFFECTIVE_START_DATE)
310 AND trunc(EFFECTIVE_END_DATE);
311
312
313
314 <<assignmentTypes>>
315 for arIND in l_relIDTAB.FIRST..l_relIDTAB.LAST loop
316 if (l_relIDTAB(arIND) = -1) then
317 --This is a direct assignment, we will check to see if an
318 --active inherited assignment was already registered.
319 if (l_assignmentType = 'I') then
320 l_assignmentType := 'B';
321
322 --We can stop the comparison because we have already
323 --determined that this assignment is both direct and
324 --inherited.
325 exit assignmentTypes;
326
327 else
328 --We are registering the direct assignment
329 l_assignmentType := 'D';
330
331 end if;
332 else
333 --This is not a direct assignment (it is inherited)
334 --we will see if an active direct assignment was already registered.
335 if (l_assignmentType = 'D') then
336 l_assignmentType := 'B';
337
338 --We can stop the comparison because we have already
339 --determined that this assignment is both direct and inherited.
340 exit assignmentTypes;
341
342 else
343 --We are registering the inherited assignment.
344 l_assignmentType := 'I';
345
346 end if;
347 end if;
348 end loop assignmentTypes;
349
350 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
351 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
352 g_modulePkg||'.AssignmentType',
353 'End AssignmentType('||p_UserName||', '||
354 p_RoleName||') returning ['||l_assignmentType||']');
355 end if;
356 return l_assignmentType;
357
358 exception
359 when OTHERS then
360 return 'X';
361
362 end AssignmentType;
363
364
365 -- Cascade_RF (PRIVATE)
366 -- Rule function to cascade changes according to the active hierarchy
367 -- when a user/role relationship is assigned or revoked.
368 -- IN
369 -- p_sub_guid (RAW)
370 -- p_event ([WF_EVENT_T])
371 -- RETURNS
372 -- VARCHAR2
373
374 function Cascade_RF ( p_sub_guid in RAW,
375 p_event in out NOCOPY WF_EVENT_T )
376 return VARCHAR2 is
377
378 TYPE dateTab IS TABLE OF DATE INDEX BY BINARY_INTEGER;
379 TYPE idTab IS TABLE OF ROWID INDEX BY BINARY_INTEGER;
380
381
382 l_subordinates WF_ROLE_HIERARCHY.relTAB;
383 l_superiors WF_ROLE_HIERARCHY.relTAB;
384 l_rowIDTAB idTab;
385 l_roleStartTAB dateTab;
386 l_roleEndTAB dateTab;
387 l_effStartTAB dateTab;
388 l_effEndTAB dateTab;
389 l_RoleName VARCHAR2(320);
390 l_UserName VARCHAR2(320);
391 l_StartDate DATE;
392 l_EndDate DATE;
393 l_UserStartDate DATE;
394 l_UserEndDate DATE;
395 l_RoleStartDate DATE;
396 l_RoleEndDate DATE;
397 l_SupStartDate DATE;
398 l_SupEndDate DATE;
399 l_EffStartDate DATE;
400 l_EffEndDate DATE;
401 l_CreatedBy NUMBER := WFA_SEC.USER_ID;
402 l_CreationDate DATE;
403 l_LastUpdatedBy NUMBER := WFA_SEC.USER_ID;
404 l_LastUpdateDate DATE;
405 l_LastUpdateLogin NUMBER := WFA_SEC.LOGIN_ID;
406 l_RoleOrigSystem VARCHAR2(30);
407 l_RoleOrigSystemID NUMBER;
408 l_UserOrigSystem VARCHAR2(30);
409 l_UserOrigSystemID NUMBER;
410 l_OwnerTag VARCHAR2(50);
411 l_assignmentType VARCHAR2(1);
412 l_assignmentReason VARCHAR2(4000);
413 l_partitionID NUMBER;
414 l_partitionName VARCHAR2(30);
415 l_count NUMBER;
416 l_rowid ROWID;
417 OverWrite BOOLEAN;
418 UpdateWho BOOLEAN := TRUE;
419
420 begin
421 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
422 -- Log only
423 -- BINDVAR_SCAN_IGNORE[4]
424 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
425 g_modulePkg||'.Cascade_RF',
426 'Begin Cascade_RF('||rawtohex(p_sub_guid)||', '||
427 p_event.getEventName||')');
428 end if;
429 --Retrieve the parameters from the event and cast to appropiate data types.
430 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
431 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
432 g_modulePkg||'.Cascade_RF',
433 'Retrieving parameters from the event.');
434 end if;
435 l_RoleName := p_event.getValueForParameter('ROLE_NAME');
436 l_StartDate := to_date(p_event.getValueForParameter('START_DATE'),
437 WF_CORE.canonical_date_mask);
438 l_EndDate := to_date(p_event.getValueForParameter('END_DATE'),
439 WF_CORE.canonical_date_mask);
440 l_UserName := p_event.getValueForParameter('USER_NAME');
441 l_UserOrigSystem := p_event.getValueForParameter('USER_ORIG_SYSTEM');
442 l_UserOrigSystemID := to_number(p_event.getValueForParameter(
443 'USER_ORIG_SYSTEM_ID'), WF_CORE.canonical_number_mask);
444 l_RoleOrigSystem := p_event.getValueForParameter('ROLE_ORIG_SYSTEM');
445 l_RoleOrigSystemID := to_number(p_event.getValueForParameter(
446 'ROLE_ORIG_SYSTEM_ID'), WF_CORE.canonical_number_mask);
447 l_OwnerTag := p_event.getValueForParameter('OWNER_TAG');
448 l_CreatedBy := to_number(p_event.getValueForParameter('CREATED_BY'),
449 WF_CORE.canonical_number_mask);
450 l_CreationDate := to_date(p_event.getValueForParameter('CREATION_DATE'),
451 WF_CORE.canonical_date_mask);
452 l_LastUpdatedBy := to_number(p_event.getValueForParameter(
453 'LAST_UPDATED_BY'), WF_CORE.canonical_number_mask);
454 l_LastUpdateDate := to_date(p_event.getValueForParameter(
455 'LAST_UPDATE_DATE'),
456 WF_CORE.canonical_date_mask);
457 l_LastUpdateLogin := to_number(p_event.getValueForParameter(
458 'LAST_UPDATE_LOGIN'), WF_CORE.canonical_number_mask);
459 l_assignmentReason := p_event.getValueForParameter('ASSIGNMENT_REASON');
460 l_rowid := chartorowid(p_event.getValueForParameter('ROWID'));
461 if (p_event.getValueForParameter('WFSYNCH_OVERWRITE') ='TRUE') then
462 OverWrite := TRUE;
463 else
464 OverWrite:= FALSE;
465 end if;
466
467 if (p_event.getValueForParameter('UPDATE_WHO') ='TRUE') then
468 UpdateWho:= TRUE;
469 else
470 UpdateWho:= FALSE;
471 end if;
472
473 --If this is not a direct assignment, we don't need to cascade
474 --the user/role creation, but we do need to validate the assignment type..
475 if (p_event.getValueForParameter('ASSIGNMENT_TYPE') <> 'D') then
476 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
477 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
478 g_modulePkg||'.Cascade_RF',
479 'This is not a direct assignment, so nothing to '||
480 'cascade. But we need to check of existing direct '||
481 'assignments that would cause the denormalized '||
482 'assignment_type to be set to B from D');
483 end if;
484 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
485 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
486 g_modulePkg||'.Cascade_RF',
487 'End Cascade_RF('||rawtohex(p_sub_guid)||', '||
488 p_event.getEventName||')');
489 end if;
490 l_assignmentType := AssignmentType(p_UserName=>l_UserName,
491 p_RoleName=>l_RoleName);
492
493 --Validate the assignment type status
494 UPDATE WF_LOCAL_USER_ROLES
495 SET ASSIGNMENT_TYPE = l_assignmentType
496 WHERE ROWID = l_rowid;
497
498 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
499 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
500 g_modulePkg||'.Cascade_RF',
501 'End Cascade_RF('||rawtohex(p_sub_guid)||', '||
502 p_event.getEventName||') returning [SUCCESS]');
503 end if;
504 return 'SUCCESS';
505
506 else
507
508 -- Since this is a direct assignment we need to retrieve the
509 -- user and role start/end dates
510
511 WF_DIRECTORY.AssignPartition(p_orig_system=>l_UserOrigSystem,
512 p_partitionID=>l_partitionID,
513 p_partitionName=>l_partitionName);
514
515 if (l_partitionID = 1) then
516 SELECT START_DATE, EXPIRATION_DATE
517 INTO l_UserStartDate, l_UserEndDate
518 FROM WF_LOCAL_ROLES
519 WHERE NAME = l_UserName
520 AND PARTITION_ID = l_partitionID
521 and rownum<2;
522 else
523 SELECT START_DATE, EXPIRATION_DATE
524 INTO l_UserStartDate, l_UserEndDate
525 FROM WF_LOCAL_ROLES
526 WHERE NAME = l_UserName
527 AND ORIG_SYSTEM= l_UserOrigSystem
528 AND ORIG_SYSTEM_ID = l_UserOrigSystemID
529 AND PARTITION_ID = l_partitionID
530 AND rownum<2;
531 end if;
532
533 WF_DIRECTORY.AssignPartition(p_orig_system=>l_RoleOrigSystem,
534 p_partitionID=>l_partitionID,
535 p_partitionName=>l_partitionName);
536 if (l_partitionID= 1) then
537 SELECT START_DATE, EXPIRATION_DATE
538 INTO l_RoleStartDate, l_RoleEndDate
539 FROM WF_LOCAL_ROLES
540 WHERE NAME = l_RoleName
541 AND PARTITION_ID = l_partitionID
542 AND rownum<2;
543 else
544 SELECT START_DATE, EXPIRATION_DATE
545 INTO l_RoleStartDate, l_RoleEndDate
546 FROM WF_LOCAL_ROLES
547 WHERE NAME = l_RoleName
548 AND ORIG_SYSTEM= l_RoleOrigSystem
549 AND ORIG_SYSTEM_ID = l_RoleOrigSystemID
550 AND PARTITION_ID = l_partitionID
551 AND rownum<2;
552 end if;
553 -- If we are updating the user/role such as setting the end_date, then
554 -- This part of the code will handle all of the assignments.
555
556 -- we need to recalculate the effective dates as well since these
557 -- might now be changed
558
559
560 SELECT ROWID, ROLE_START_DATE, ROLE_END_DATE,EFFECTIVE_START_DATE,
561 EFFECTIVE_END_DATE
562 BULK COLLECT INTO l_RowIDTAB, l_roleStartTAB,l_roleEndTAB,
563 l_effStartTAB,l_effEndTAB
564 FROM WF_USER_ROLE_ASSIGNMENTS
565 WHERE USER_NAME = l_UserName
566 AND ASSIGNING_ROLE = l_RoleName;
567
568 if (l_rowIDTAB.COUNT > 0) then
569 -- Update Assignment Reason for direct assignment
570 UPDATE WF_USER_ROLE_ASSIGNMENTS
571 SET ASSIGNMENT_REASON = l_assignmentReason
572 WHERE USER_NAME = l_UserName
573 AND ASSIGNING_ROLE = l_RoleName
574 AND RELATIONSHIP_ID = -1;
575
576 --We don't want to loop if there are no records that meet
577 --our criteria, we could stop right now.
578
579 for tabIndex in l_rowIDTAB.FIRST..l_rowIDTAB.LAST loop
580 --Now we want to calculate the effective start and end dates
581 --for this assignment.
582 Calculate_Effective_Dates(l_StartDate, l_EndDate,
583 l_UserStartDate,l_UserEndDate,
584 l_roleStartTAB(tabIndex),l_roleEndTAB(tabIndex),
585 l_RoleStartDate,l_RoleEndDate,
586 l_effStartTAB(tabIndex),l_effEndTAB(tabIndex));
587 end loop;
588 if OverWrite and UpdateWho then
589 --allow update of creation_date and created_by
590 forall tabIndex in l_rowIDTAB.FIRST..l_rowIDTAB.LAST
591 update WF_USER_ROLE_ASSIGNMENTS
592 set START_DATE = l_StartDate,
593 END_DATE = l_EndDate,
594 LAST_UPDATED_BY = nvl(l_LastUpdatedBy,WFA_SEC.USER_ID),
595 LAST_UPDATE_DATE = nvl(l_LastUpdateDate,SYSDATE),
596 LAST_UPDATE_LOGIN = nvl(l_LastUpdateLogin,WFA_SEC.LOGIN_ID),
597 CREATION_DATE = nvl(l_CreationDate,CREATION_DATE),
598 CREATED_BY = nvl(l_CreatedBy, CREATED_BY),
599 EFFECTIVE_START_DATE = l_effStartTAB(tabIndex),
600 EFFECTIVE_END_DATE = l_effEndTAB(tabIndex)
601 where rowid = l_rowIDTAB(tabIndex);
602 elsif UpdateWho then
603 forall tabIndex in l_rowIDTAB.FIRST..l_rowIDTAB.LAST
604 update WF_USER_ROLE_ASSIGNMENTS
605 set START_DATE = l_StartDate,
606 END_DATE = l_EndDate,
607 LAST_UPDATED_BY = nvl(l_LastUpdatedBy,WFA_SEC.USER_ID),
608 LAST_UPDATE_DATE = nvl(l_LastUpdateDate,SYSDATE),
609 LAST_UPDATE_LOGIN = nvl(l_LastUpdateLogin,WFA_SEC.LOGIN_ID),
610 EFFECTIVE_START_DATE = l_effStartTAB(tabIndex),
611 EFFECTIVE_END_DATE = l_effEndTAB(tabIndex)
612 where rowid = l_rowIDTAB(tabIndex);
613 else -- Donot update WHO columns
614 forall tabIndex in l_rowIDTAB.FIRST..l_rowIDTAB.LAST
615 update WF_USER_ROLE_ASSIGNMENTS
616 set START_DATE = l_StartDate,
617 END_DATE = l_EndDate,
618 EFFECTIVE_START_DATE = l_effStartTAB(tabIndex),
619 EFFECTIVE_END_DATE = l_effEndTAB(tabIndex)
620 where rowid = l_rowIDTAB(tabIndex);
621
622 end if;
623
624 if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
625 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
626 g_modulePkg||'.Cascade_RF',
627 'Assignments for assigning role: '||
628 l_RoleName||' exist for user '||l_UserName||
629 '. Updated existing assignments.');
630 end if;
631 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
632 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
633 g_modulePkg||'.Cascade_RF',
634 'End Cascade_RF('||rawtohex(p_sub_guid)||', '||
635 p_event.getEventName||')');
636 end if;
637
638
639 return 'SUCCESS';
640 end if;
641 end if;
642
643 -- We made it here so that means there are no assignments.
644 -- First, we must create the assignment record for the direct assignment.
645
646 --<rwunderl:3737114>
647 WF_DIRECTORY.AssignPartition(p_orig_system=>l_RoleOrigSystem,
648 p_partitionID=>l_partitionID,
649 p_partitionName=>l_partitionName);
650 --calculate the effective dates for the direct assignment
651
652 Calculate_Effective_Dates(l_StartDate,
653 l_EndDate,
654 l_UserStartDate,
655 l_UserEndDate,
656 l_RoleStartDate,
657 l_RoleEndDate,
658 l_RoleStartDate,
659 l_RoleEndDate,
660 l_EffStartDate,
661 l_EffEndDate);
662
663 --</rwunderl:3737114>
664
665 INSERT INTO WF_USER_ROLE_ASSIGNMENTS
666 ( USER_NAME,
667 ROLE_NAME,
668 RELATIONSHIP_ID,
669 ASSIGNING_ROLE,
670 START_DATE,
671 END_DATE,
672 ROLE_START_DATE,
673 ROLE_END_DATE,
674 USER_START_DATE,
675 USER_END_DATE,
676 ASSIGNING_ROLE_START_DATE,
677 ASSIGNING_ROLE_END_DATE,
678 CREATED_BY,
679 CREATION_DATE,
680 LAST_UPDATED_BY,
681 LAST_UPDATE_DATE,
682 LAST_UPDATE_LOGIN,
683 PARTITION_ID,
684 EFFECTIVE_START_DATE,
685 EFFECTIVE_END_DATE,
686 USER_ORIG_SYSTEM,
687 USER_ORIG_SYSTEM_ID,
688 ROLE_ORIG_SYSTEM,
689 ROLE_ORIG_SYSTEM_ID,
690 ASSIGNMENT_REASON)
691 values
692 ( l_UserName,
693 l_RoleName,
694 -1,
695 l_RoleName,
696 l_StartDate,
697 l_EndDate,
698 l_RoleStartDate,
699 l_RoleEndDate,
700 l_UserStartDate,
701 l_UserEndDate,
702 l_RoleStartDate,
703 l_RoleEndDate,
704 nvl(l_CreatedBy,WFA_SEC.User_ID),
705 nvl(l_CreationDate,SYSDATE),
706 nvl(l_LastUpdatedBy, WFA_SEC.User_ID),
707 nvl(l_LastUpdateDate,SYSDATE),
708 nvl(l_LastUpdateLogin,WFA_SEC.LOGIN_ID),
709 l_partitionID,
710 l_effStartDate,
711 l_effEndDate,
712 l_UserOrigSystem,
713 l_UserOrigSystemId,
714 l_RoleOrigSystem,
715 l_RoleOrigSystemId,
716 l_assignmentReason);
717
718
719
720 GetRelationships(p_name=>l_RoleName,
721 p_superiors=>l_superiors,
722 p_subordinates=>l_subordinates,
723 p_direction=>'SUPERIORS');
724
725 if (l_superiors.COUNT <= 0) then
726 --There is nothing to do.
727 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
728 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
729 g_modulePkg||'.Cascade_RF',
730 'There are no superiors, updates are limited to this '||
731 'user/role relationship.');
732 end if;
733 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
734 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
735 g_modulePkg||'.Cascade_RF',
736 'End Cascade_RF('||rawtohex(p_sub_guid)||', '||
737 p_event.getEventName||')');
738 end if;
739
740
741 return 'SUCCESS';
742
743 end if;
744 --If we made it here, there is hierarchy processing to do. First we need
745 --to attempt to create a user/role for l_UserName to l_Superiors(i)
746 --then we need to create a user/role assignment for l_RoleName as the
747 --assigning role.
748 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
749 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
750 g_modulePkg||'.Cascade_RF',
751 'Beginning user/role inheritance for '||l_UserName||
752 ' to the superior roles of '||l_RoleName);
753 end if;
754 for l_count in l_superiors.FIRST..l_superiors.LAST loop
755 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
756 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
757 g_modulePkg||'.Cascade_RF',
758 'Beginning user/role inheritance for '||l_UserName||
759 ' to '||l_superiors(l_count).SUPER_NAME);
760 end if;
761 --WF_DIRECTORY.GetRoleOrigSysInfo(l_superiors(l_count).SUPER_NAME,
762 -- l_roleOrigSystem, l_roleOrigSystemID);
763
764 --Get the Role Start and End Dates for the superior roles
765 SELECT ORIG_SYSTEM, ORIG_SYSTEM_ID,
766 START_DATE, EXPIRATION_DATE
767 INTO l_roleOrigSystem,l_roleOrigSystemID,
768 l_SupStartDate, l_SupEndDate
769 FROM WF_LOCAL_ROLES
770 WHERE NAME=l_superiors(l_count).SUPER_NAME
771 AND rownum<2;
772
773 --Calculate the effective_dates for each of these assignments
774
775 Calculate_Effective_Dates( l_StartDate,
776 l_EndDate,
777 l_UserStartDate,
778 l_UserEndDate,
779 l_SupStartDate,
780 l_SupEndDate,
781 l_RoleStartDate,
782 l_RoleEndDate,
783 l_EffStartDate,
784 l_EffEndDate);
785
786 --Creating the assignment record for each user/role assignment.
787 begin
788 INSERT INTO WF_USER_ROLE_ASSIGNMENTS
789 ( USER_NAME,
790 ROLE_NAME,
791 RELATIONSHIP_ID,
792 ASSIGNING_ROLE,
793 START_DATE,
794 END_DATE,
795 USER_START_DATE,
796 USER_END_DATE,
797 ROLE_START_DATE,
798 ROLE_END_DATE,
799 ASSIGNING_ROLE_START_DATE,
800 ASSIGNING_ROLE_END_DATE,
801 CREATED_BY,
802 CREATION_DATE,
803 LAST_UPDATED_BY,
804 LAST_UPDATE_DATE,
805 LAST_UPDATE_LOGIN,
806 PARTITION_ID,
807 EFFECTIVE_START_DATE,
808 EFFECTIVE_END_DATE ,
809 USER_ORIG_SYSTEM,
810 USER_ORIG_SYSTEM_ID,
811 ROLE_ORIG_SYSTEM,
812 ROLE_ORIG_SYSTEM_ID
813 )
814 values
815 ( l_UserName,
816 l_superiors(l_count).SUPER_NAME,
817 l_superiors(l_count).RELATIONSHIP_ID,
818 l_RoleName,
819 l_StartDate,
820 l_EndDate,
821 l_UserStartDate,
822 l_UserEndDate,
823 l_SupStartDate,
824 l_SupEndDate,
825 l_RoleStartDate,
826 l_RoleEndDate,
827 nvl(l_CreatedBy,WFA_SEC.User_ID),
828 nvl(l_CreationDate,SYSDATE),
829 nvl(l_LastUpdatedBy, WFA_SEC.User_ID),
830 nvl(l_LastUpdateDate,SYSDATE),
831 nvl(l_LastUpdateLogin,WFA_SEC.LOGIN_ID),
832 l_partitionID,
833 l_EffStartDate,
834 l_EffEndDate,
835 l_UserOrigSystem,
836 l_UserOrigSystemID,
837 l_RoleOrigSystem,
838 l_RoleOrigSystemID
839 );
840
841 exception
842 when DUP_VAL_ON_INDEX then
843 if (OverWrite and UpdateWho) then
844 --allow update of creation_date and created_by
845 UPDATE WF_USER_ROLE_ASSIGNMENTS
846 SET END_DATE = l_EndDate,
847 START_DATE = l_StartDate,
848 USER_START_DATE = l_UserStartDate,
849 USER_END_DATE = l_UserEndDate,
850 ROLE_START_DATE = l_SupStartDate,
851 ROLE_END_DATE = l_SupEndDate,
852 ASSIGNING_ROLE_START_DATE = l_RoleStartDate,
853 ASSIGNING_ROLE_END_DATE = l_RoleEndDate,
854 EFFECTIVE_START_DATE = l_EffStartDate,
855 EFFECTIVE_END_DATE = l_EffEndDate,
856 LAST_UPDATED_BY = nvl(l_LastUpdatedBy, WFA_SEC.User_ID),
857 LAST_UPDATE_DATE = nvl(l_LastUpdateDate,SYSDATE),
858 LAST_UPDATE_LOGIN = nvl(l_LastUpdateLogin,WFA_SEC.LOGIN_ID),
859 CREATED_BY = nvl(l_CreatedBy,CREATED_BY),
860 CREATION_DATE = nvl(l_CreationDate, CREATION_DATE)
861 WHERE RELATIONSHIP_ID = l_superiors(l_count).RELATIONSHIP_ID
862 AND USER_NAME = l_UserName
863 AND ROLE_NAME = l_superiors(l_count).SUPER_NAME
864 AND ASSIGNING_ROLE = l_RoleName;
865 elsif UpdateWho then
866 UPDATE WF_USER_ROLE_ASSIGNMENTS
867 SET END_DATE = l_EndDate,
868 START_DATE = l_StartDate,
869 USER_START_DATE = l_UserStartDate,
870 USER_END_DATE = l_UserEndDate,
871 ROLE_START_DATE = l_SupStartDate,
872 ROLE_END_DATE = l_SupEndDate,
873 ASSIGNING_ROLE_START_DATE = l_RoleStartDate,
874 ASSIGNING_ROLE_END_DATE = l_RoleEndDate,
875 EFFECTIVE_START_DATE = l_EffStartDate,
876 EFFECTIVE_END_DATE = l_EffEndDate,
877 LAST_UPDATED_BY = nvl(l_LastUpdatedBy, WFA_SEC.User_ID),
878 LAST_UPDATE_DATE = nvl(l_LastUpdateDate,SYSDATE),
879 LAST_UPDATE_LOGIN = nvl(l_LastUpdateLogin,WFA_SEC.LOGIN_ID)
880 WHERE RELATIONSHIP_ID = l_superiors(l_count).RELATIONSHIP_ID
881 AND USER_NAME = l_UserName
882 AND ROLE_NAME = l_superiors(l_count).SUPER_NAME
883 AND ASSIGNING_ROLE = l_RoleName;
884 else
885 UPDATE WF_USER_ROLE_ASSIGNMENTS
886 SET END_DATE = l_EndDate,
887 START_DATE = l_StartDate,
888 USER_START_DATE = l_UserStartDate,
889 USER_END_DATE = l_UserEndDate,
890 ROLE_START_DATE = l_SupStartDate,
891 ROLE_END_DATE = l_SupEndDate,
892 ASSIGNING_ROLE_START_DATE = l_RoleStartDate,
893 ASSIGNING_ROLE_END_DATE = l_RoleEndDate,
894 EFFECTIVE_START_DATE = l_EffStartDate,
895 EFFECTIVE_END_DATE = l_EffEndDate
896 WHERE RELATIONSHIP_ID = l_superiors(l_count).RELATIONSHIP_ID
897 AND USER_NAME = l_UserName
898 AND ROLE_NAME = l_superiors(l_count).SUPER_NAME
899 AND ASSIGNING_ROLE = l_RoleName;
900 end if;
901 when OTHERS then
902 raise;
903
904 end;
905
906 begin
907 --We will create/update the actual user/role record's timestamp only
908 --The effectivity dates will be set by the assignments.
909 WF_DIRECTORY.CreateUserRole(user_name=>l_UserName,
910 role_name=>l_superiors(l_count).SUPER_NAME,
911 start_date=>l_startDate,
912 end_date=>l_endDate,
913 user_orig_system=>l_userOrigSystem,
914 user_orig_system_id=>l_userOrigSystemID,
915 role_orig_system=>l_roleOrigSystem,
916 role_orig_system_id=>l_roleOrigSystemID,
917 validateUserRole=>TRUE,
918 created_by=>l_CreatedBy,
919 creation_date=>l_CreationDate,
920 last_updated_by=>l_LastUpdatedBy,
921 last_update_date=>l_LastUpdateDate,
922 last_update_login=>l_LastUpdateLogin,
923 assignment_type=>'I');
924
925 exception
926 when OTHERS then
927 if (WF_CORE.error_name = 'WF_DUP_USER_ROLE') then
928 --Updating the existing user/role with an assignment_type of 'X'.
929 --The recursive call to cascade_RF() will validate the
930 --assignment_type and set it to the proper value.
931 WF_CORE.Clear;
932 WF_DIRECTORY.SetUserRoleAttr(user_name=>l_UserName,
933 role_name=>l_superiors(l_count).SUPER_NAME,
934 start_date=>l_startDate,
935 end_date=>l_endDate,
936 user_orig_system=>l_userOrigSystem,
937 user_orig_system_id=>l_userOrigSystemID,
938 role_orig_system=>l_roleOrigSystem,
939 role_orig_system_id=>l_roleOrigSystemID,
940 last_updated_by=>l_LastUpdatedBy,
941 last_update_date=>l_LastUpdateDate,
942 last_update_login=>l_LastUpdateLogin,
943 assignment_type=>'X',
944 updateWho=>UpdateWho);
945
946 else
947 WF_CORE.Context('WF_ROLE_HIERARCHY','Cascade_RF',
948 p_event.getEventName( ), p_sub_guid);
949
950 WF_EVENT.setErrorInfo(p_event, 'ERROR');
951
952 return 'ERROR';
953
954 end if;
955 end;
956
957 end loop;
958 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
959 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
960 g_modulePkg||'.Cascade_RF',
961 'End Cascade_RF('||rawtohex(p_sub_guid)||', '||
962 p_event.getEventName||')');
963 end if;
964 return 'SUCCESS';
965 end Cascade_RF;
966
967
968 --
969 -- Propagate_RF (PRIVATE)
970 -- Rule function to handle events when a relationship is created or
971 -- expired
972 -- IN
973 -- p_sub_guid (RAW)
974 -- p_event ([WF_EVENT_T])
975 -- RETURNS
976 -- VARCHAR2
977
978 function Propagate_RF ( p_sub_guid in RAW,
979 p_event in out NOCOPY WF_EVENT_T )
980 return VARCHAR2 is
981
982 l_rel VARCHAR2(10);
983 l_cp_ID NUMBER;
984
985 begin
986 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
987 -- Log only
988 -- BINDVAR_SCAN_IGNORE[4]
989 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
990 g_modulePkg||'.Propagate_RF',
991 'Begin Propagate_RF('||rawtohex(p_sub_guid)||', '||
992 p_event.getEventName||')');
993 end if;
994
995 begin
996 --First check to see if we are to defer propagation.
997 if (nvl(p_event.GetValueForParameter('DEFER_PROPAGATION'),
998 'TRUE') = 'TRUE') then
999 return 'SUCCESS'; --Nothing to do since we are deferring the
1000 --propagation.
1001 end if;
1002 l_rel := nvl(p_event.GetValueForParameter('RELATIONSHIP_ID'), '-1');
1003
1004 if (l_rel = -1) then
1005 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
1006 g_modulePkg||'.Propagate_RF',
1007 'Relationship_ID is NULL!');
1008 return 'ERROR';
1009
1010 else
1011 l_cp_id := FND_REQUEST.Submit_Request(APPLICATION=>'FND',
1012 PROGRAM=>'FNDWFDSRHP',
1013 ARGUMENT1=>l_rel);
1014
1015 if (l_cp_id = -1) then
1016 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
1017 g_modulePkg||'.Propagate_RF',
1018 'Call to FND_SUBMIT failed!');
1019 return 'ERROR';
1020
1021 end if;
1022 end if;
1023 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1024 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
1025 g_modulePkg||'.Propagate_RF',
1026 'Concurrent request '||l_cp_id||
1027 ' Submitted for '||l_rel);
1028 end if;
1029 end;
1030 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
1031 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
1032 g_modulePkg||'.Propagate_RF',
1033 'End Propagate_RF('||rawtohex(p_sub_guid)||', '||
1034 p_event.getEventName||')');
1035 end if;
1036 return 'SUCCESS';
1037
1038 end Propagate_RF;
1039
1040 --
1041 -- Propagate (PRIVATE)
1042 -- Updates all existing assignments when a change occurs in a hierarchy.
1043 -- IN
1044 -- p_relationship_id (NUMBER)
1045 --
1046
1047
1048
1049 procedure Propagate (p_relationship_id in NUMBER,
1050 p_propagateDate in DATE) is
1051
1052 --Type declarations
1053 TYPE numberTAB is TABLE of NUMBER index by binary_integer;
1054 TYPE dateTAB is TABLE of DATE index by binary_integer;
1055 TYPE ownerTAB is TABLE of VARCHAR2(50) index by binary_integer;
1056 TYPE flagTAB is TABLE of VARCHAR2(1) index by binary_integer;
1057
1058 --Local Variables.
1059 l_relIDTAB numberTAB;
1060 l_userTAB WF_DIRECTORY.UserTable;
1061 l_roleTAB WF_DIRECTORY.RoleTable;
1062 l_assignTAB WF_DIRECTORY.RoleTable;
1063 l_ownerTAB WF_DIRECTORY.RoleTable;
1064 l_uorigSysTAB WF_DIRECTORY.OrigSysTable;
1065 l_uorigSysIDTAB numberTAB;
1066 l_rorigSysTAB WF_DIRECTORY.RoleTable;
1067 l_rorigSysIDTAB numberTAB;
1068 l_rpartIDTAB numberTAB;
1069 l_apartIDTAB numberTAB;
1070 l_startDateTAB dateTAB;
1071 l_endDateTAB dateTAB;
1072 l_uStartDateTAB dateTAB;
1073 l_uEndDateTAB dateTAB;
1074 l_rStartDateTAB dateTAB;
1075 l_rEndDateTAB dateTAB;
1076 l_aStartDateTAB dateTAB;
1077 l_aEndDateTAB dateTAB;
1078 l_enabledFlagTAB flagTAB;
1079 l_user VARCHAR2(320);
1080 l_role VARCHAR2(320);
1081 l_assignmentType VARCHAR2(1);
1082
1083 l_effStartDate DATE;
1084 l_effEndDate DATE;
1085 l_superName VARCHAR2(320);
1086 l_subName VARCHAR2(320);
1087 l_enabledFlag VARCHAR2(1);
1088
1089 --Index Variables
1090 subIND PLS_INTEGER;
1091 hitIND PLS_INTEGER;
1092 userIND PLS_INTEGER;
1093 roleIND PLS_INTEGER;
1094
1095 --Cursor to select expired relationships. This statement selects
1096 --the complete hierarchy then with the minus operator substracts
1097 --relationships from the active hierarchy leaving the relationship(s)
1098 --that should be expired.
1099 cursor expiredRelationships(p_subName in VARCHAR2) is
1100 select WRH1.RELATIONSHIP_ID REL_ID
1101 from WF_ROLE_HIERARCHIES WRH1
1102 connect by prior SUPER_NAME = SUB_NAME
1103 start with SUB_NAME = p_subName
1104 minus
1105 select WRH2.RELATIONSHIP_ID REL_ID
1106 from WF_ROLE_HIERARCHIES WRH2
1107 where ENABLED_FLAG = 'Y'
1108 connect by prior SUPER_NAME = SUB_NAME
1109 and prior ENABLED_FLAG = 'Y'
1110 start with SUB_NAME = p_subName;
1111
1112 cursor relationships (p_subName in VARCHAR2) is
1113 select SUPER_NAME, RELATIONSHIP_ID
1114 from WF_ROLE_HIERARCHIES
1115 where ENABLED_FLAG = 'Y'
1116 connect by prior SUPER_NAME = SUB_NAME
1117 and prior ENABLED_FLAG = 'Y'
1118 start with SUB_NAME = p_subName;
1119
1120 begin
1121 --Retrieve the relationship
1122 select SUPER_NAME, SUB_NAME, ENABLED_FLAG
1123 into l_superName, l_subName, l_enabledFlag
1124 from WF_ROLE_HIERARCHIES
1125 where RELATIONSHIP_ID = p_relationship_id;
1126
1127 --Update the propagate timestamp
1128 update WF_ROLE_HIERARCHIES
1129 set PROPAGATE_DATE = p_propagateDate
1130 where RELATIONSHIP_ID = p_relationship_id
1131 and SUPER_NAME = l_superName
1132 and SUB_NAME = l_subName;
1133
1134 if (l_enabledFlag = 'N') then
1135 --We are propagating an expired relationship
1136 --To address the issue of a relationship being shared by parallel
1137 --Branches, we retrieve the subordinate relationships, then traverse
1138 --down the hierarchy. For each subordinate relationship, we compare the
1139 --active and inactive superiors to remove truly expired hierarchy
1140 --relationships.
1141 --Retrieve the subordinates
1142 select SUB_NAME
1143 bulk collect into l_assignTAB
1144 from WF_ROLE_HIERARCHIES
1145 connect by prior SUB_NAME = SUPER_NAME
1146 start with SUPER_NAME = l_superName;
1147
1148 --Outer loop to traverse down the subordinates in the hierarchy.
1149 if (l_assignTAB.COUNT > 0) then
1150 <<Subordinates>>
1151 for subIND in l_assignTAB.FIRST..l_assignTAB.LAST loop
1152 --Reset the hitList counter.
1153 hitIND := 0;
1154 l_relIDTAB.DELETE; --Truncate the PL/SQL Table.
1155 --Inner loop to select expired relationships providing.
1156 <<ExpiredSuperiors>>
1157 for a in expiredRelationships(l_assignTAB(subIND)) loop
1158 --Load the potential relationship ids into a local table.
1159 l_relIDTAB(hitIND) := a.REL_ID;
1160 hitIND := hitIND + 1; --Advance the counter
1161 end loop ExpiredSuperiors;
1162 --Now we will perform a bulk update to expire the user/role
1163 --assignments that are based on these relationship_ids and were
1164 --assigned from this subordinate (this protects a relationship that
1165 --may be serving more than one subordinate assignment as well as any
1166 --parallel branches).
1167 if (l_relIDTAB.COUNT > 0) then
1168 <<Assignments>>
1169 forall hitIND in l_relIDTAB.FIRST..l_relIDTAB.LAST
1170 delete from WF_USER_ROLE_ASSIGNMENTS
1171 where RELATIONSHIP_ID = l_relIDTAB(hitIND)
1172 and ASSIGNING_ROLE = l_assignTAB(subIND)
1173 returning USER_NAME, ROLE_NAME
1174 bulk collect into l_userTAB, l_roleTAB;
1175
1176 if (l_userTAB.COUNT > 0) then
1177 for userIND in l_userTAB.FIRST..l_userTAB.LAST loop
1178 l_assignmentType := AssignmentType(l_userTAB(userIND),
1179 l_roleTAB(userIND));
1180
1181 select min(effective_start_Date),max(effective_end_date)
1182 into l_effStartDate, l_effEndDate
1183 from wf_user_role_assignments
1184 where user_name= l_userTAB(userIND)
1185 and role_name = l_roleTAB(userIND);
1186
1187
1188 if (l_effStartDate is null) then
1189 -- implies there are no more active inherited assignments
1190 -- to this user/role. So we can expire it. Since this was
1191 -- only an inherited assignment therefore we can safely
1192 -- remove it from WF_LOCAL_USER_ROLES knowing that only
1193 -- direct assignments are shipped.
1194
1195 delete from
1196 WF_LOCAL_USER_ROLES
1197 where USER_NAME = l_userTAB(userIND)
1198 and ROLE_NAME = l_roleTAB(userIND);
1199
1200 else
1201 -- implies the assignment is still active through
1202 -- some other branch.So we just update the effective
1203 -- dates and assignment type.
1204
1205 update WF_LOCAL_USER_ROLES
1206 set ASSIGNMENT_TYPE = l_assignmentType,
1207 EFFECTIVE_START_DATE= l_effStartDate,
1208 EFFECTIVE_END_DATE = l_effEndDate,
1209 LAST_UPDATED_BY = WFA_SEC.user_id,
1210 LAST_UPDATE_DATE = sysdate,
1211 LAST_UPDATE_LOGIN = WFA_SEC.login_id
1212 where USER_NAME = l_userTAB(userIND)
1213 and ROLE_NAME = l_roleTAB(userIND);
1214 end if;
1215 end loop;
1216 end if;
1217 -- end loop Assignments;
1218 commit; --Commiting this batch of updates.
1219 end if;
1220 end loop Subordinates;
1221 end if;
1222 else --(l_enabledFlag = 'Y')
1223 --Retrieve the superiors of this relationship.
1224 open relationships (l_subName);
1225 fetch relationships bulk collect into l_roleTAB, l_relIDTAB;
1226 close relationships;
1227
1228 --Retrieve the role information for each superior.
1229 <<Superiors_Info>>
1230 for roleIND in l_roleTAB.FIRST..l_roleTAB.LAST loop
1231 select ORIG_SYSTEM, ORIG_SYSTEM_ID, PARTITION_ID,
1232 START_DATE, EXPIRATION_DATE
1233 into l_rorigSysTAB(roleIND), l_rorigSysIDTAB(roleIND),
1234 l_rpartIDTAB(roleIND), l_rStartDateTAB(roleIND),
1235 l_rEndDateTAB(roleIND)
1236 from WF_LOCAL_ROLES
1237 where NAME = l_roleTAB(roleIND);
1238 end loop Superiors_Info;
1239
1240 --Retrieve any direct or inherited assignments to the subordinate
1241 --of this relationship.
1242 select USER_NAME, ASSIGNING_ROLE, START_DATE, END_DATE,
1243 USER_START_DATE, USER_END_DATE,
1244 ASSIGNING_ROLE_START_DATE, ASSIGNING_ROLE_END_DATE,
1245 PARTITION_ID, USER_ORIG_SYSTEM, USER_ORIG_SYSTEM_ID
1246 bulk collect into l_userTAB, l_assignTAB, l_startDateTAB, l_endDateTAB,
1247 l_uStartDateTAB, l_uEndDateTAB, l_aStartDateTAB,
1248 l_aEndDateTAB, l_apartIDTAB, l_uorigSysTAB, l_uorigSysIDTAB
1249 from WF_USER_ROLE_ASSIGNMENTS
1250 where ROLE_NAME = l_subName;
1251
1252 --We will propagate the newly inherited assignments before the
1253 --associated user/role relationships because of the functionality of the
1254 --WF_USER_ROLES view. By propagating the assignments first, when we
1255 --create the actual records in WF_LOCAL_USER_ROLES, the WF_USER_ROLES
1256 --view will immediately pickup not only the user/role, but according
1257 --to the effective date-range. If we did this the other way around,
1258 --there may possibly be a way that a user/role relationship that is
1259 --not supposed to be visable, would appear in the view.
1260
1261
1262 --Outer loop to select the superior role.
1263 <<Superiors>>
1264 for roleIND in l_roleTAB.FIRST..l_roleTAB.LAST loop
1265 --Inner loop to select select and propagate any existing assignments
1266 --up the hierarchy.
1267 <<User_Role_Assignments>>
1268 if (l_userTAB.COUNT > 0) then
1269 for userIND in l_userTAB.FIRST..l_userTAB.LAST loop
1270 begin
1271
1272 --calculate the effective start and dates
1273 calculate_effective_dates ( l_startDateTAB(userIND),
1274 l_endDateTAB(userIND),
1275 l_uStartDateTAB(userIND),
1276 l_uEndDateTAB(userIND),
1277 l_rStartDateTAB(roleIND),
1278 l_rEndDateTAB(roleIND),
1279 l_aStartDateTAB(userIND),
1280 l_aEndDateTAB(userIND),
1281 l_effStartDate,
1282 l_effEndDate);
1283
1284 insert into WF_USER_ROLE_ASSIGNMENTS (USER_NAME,
1285 ROLE_NAME,
1286 RELATIONSHIP_ID,
1287 ASSIGNING_ROLE,
1288 START_DATE,
1289 END_DATE,
1290 USER_START_DATE,
1291 USER_END_DATE,
1292 ROLE_START_DATE,
1293 ROLE_END_DATE,
1294 ASSIGNING_ROLE_START_DATE,
1295 ASSIGNING_ROLE_END_DATE,
1296 EFFECTIVE_START_DATE,
1297 EFFECTIVE_END_DATE,
1298 USER_ORIG_SYSTEM,
1299 USER_ORIG_SYSTEM_ID,
1300 ROLE_ORIG_SYSTEM,
1301 ROLE_ORIG_SYSTEM_ID,
1302 CREATED_BY,
1303 CREATION_DATE,
1304 LAST_UPDATED_BY,
1305 LAST_UPDATE_DATE,
1306 LAST_UPDATE_LOGIN,
1307 PARTITION_ID) values
1308 (
1309 l_userTAB(userIND),
1310 l_roleTAB(roleIND),
1311 l_relIDTAB(roleIND),
1312 l_assignTAB(userIND),
1313 trunc(l_startDateTAB(userIND)),
1314 trunc(l_endDateTAB(userIND)),
1315 trunc(l_uStartDateTAB(userIND)),
1316 trunc(l_uEndDateTAB(userIND)),
1317 trunc(l_rStartDateTAB(roleIND)),
1318 trunc(l_rEndDateTAB(roleIND)),
1319 trunc(l_aStartDateTAB(userIND)),
1320 trunc(l_aEndDateTAB(userIND)),
1321 l_effStartDate,
1322 l_effEndDate,
1323 l_uorigSysTAB(userIND),
1324 l_uorigSysIDTAB(userIND),
1325 l_rorigSysTAB(roleIND),
1326 l_rorigSysIDTAB(roleIND),
1327 WFA_SEC.user_id,
1328 sysdate,
1329 WFA_SEC.user_id,
1330 sysdate,
1331 WFA_SEC.login_id,
1332 l_apartIDTAB(userIND));
1333 exception
1334 when DUP_VAL_ON_INDEX then
1335 --This can happen if there is a parallel branch.
1336 --We will just update the timestamp.
1337 update WF_USER_ROLE_ASSIGNMENTS
1338 set START_DATE = trunc(l_startDateTAB(userIND)),
1339 END_DATE = trunc(l_endDateTAB(userIND)),
1340 USER_START_DATE = trunc(l_uStartDateTAB(userIND)),
1341 USER_END_DATE = trunc(l_uEndDateTAB(userIND)),
1342 ROLE_START_DATE = trunc(l_rStartDateTAB(roleIND)),
1343 ROLE_END_DATE = trunc(l_rEndDateTAB(roleIND)),
1344 ASSIGNING_ROLE_START_DATE = trunc(l_aStartDateTAB(userIND)),
1345 ASSIGNING_ROLE_END_DATE = trunc(l_aEndDateTAB(userIND)),
1346 EFFECTIVE_START_DATE = l_effStartDate,
1347 EFFECTIVE_END_DATE = l_effEndDate,
1348 LAST_UPDATED_BY = WFA_SEC.user_id,
1349 LAST_UPDATE_DATE = sysdate,
1350 LAST_UPDATE_LOGIN = WFA_SEC.login_id
1351 where USER_NAME = l_userTAB(userIND)
1352 and ROLE_NAME = l_roleTAB(roleIND)
1353 and RELATIONSHIP_ID = l_relIDTAB(roleIND)
1354 and ASSIGNING_ROLE = l_assignTAB(userIND);
1355 end;
1356 end loop User_Role_Assignments;
1357 end if;
1358 commit; --We will commit all of the user assignments to this superior.
1359 end loop Superiors;
1360
1361 --Retrieve a list of the effected users.
1362 select USER_NAME, USER_ORIG_SYSTEM, USER_ORIG_SYSTEM_ID,
1363 OWNER_TAG, USER_START_DATE, USER_END_DATE, START_DATE,
1364 EXPIRATION_DATE
1365 bulk collect into l_userTAB, l_uorigSysTAB, l_uorigSysIDTAB,
1366 l_ownerTAB, l_uStartDateTAB, l_uEndDateTAB,
1367 l_startDateTAB, l_endDateTAB
1368 from WF_LOCAL_USER_ROLES
1369 where ROLE_NAME = l_subName;
1370
1371 --We will now create the user_role records in WF_LOCAL_USER_ROLES.
1372 --Outer loop to select an effected user (IE: A user that is assigned
1373 --either directly or indirectly to the subordinate role of this
1374 --relationship.
1375 if (l_userTAB.COUNT > 0) then
1376 <<Users>>
1377 for userIND in l_userTAB.FIRST..l_userTAB.LAST loop
1378 --Inner Loop, to select each role traversing up the hierarchy that
1379 --the effected user will inherit.
1380 <<UserRoles>>
1381 for roleIND in l_roleTAB.FIRST..l_roleTAB.LAST loop
1382 begin
1383 --determine the assignment type and effective dates.
1384
1385 l_assignmentType := AssignmentType(l_userTAB(userIND),
1386 l_roleTAB(roleIND));
1387
1388 select min(effective_start_date),
1389 max(effective_end_date)
1390 into l_effStartDate, l_effEndDate
1391 from wf_user_role_Assignments
1392 where user_name=l_userTAB(userIND)
1393 and role_name = l_roleTAB(roleIND);
1394
1395 insert into WF_LOCAL_USER_ROLES (USER_NAME,
1396 ROLE_NAME,
1397 USER_ORIG_SYSTEM,
1398 USER_ORIG_SYSTEM_ID,
1399 ROLE_ORIG_SYSTEM,
1400 ROLE_ORIG_SYSTEM_ID,
1401 START_DATE,
1402 EXPIRATION_DATE,
1403 USER_START_DATE,
1404 USER_END_DATE,
1405 ROLE_START_DATE,
1406 ROLE_END_DATE,
1407 EFFECTIVE_START_DATE,
1408 EFFECTIVE_END_DATE,
1409 SECURITY_GROUP_ID,
1410 PARTITION_ID,
1411 OWNER_TAG,
1412 CREATED_BY,
1413 CREATION_DATE,
1414 LAST_UPDATED_BY,
1415 LAST_UPDATE_DATE,
1416 LAST_UPDATE_LOGIN,
1417 ASSIGNMENT_TYPE) values
1418 (l_userTAB(userIND),
1419 l_roleTAB(roleIND),
1420 l_uorigSysTAB(userIND),
1421 l_uorigSysIDTAB(userIND),
1422 l_rorigSysTAB(roleIND),
1423 l_rorigSysIDTAB(roleIND),
1424 l_startDateTAB(userIND),
1425 l_endDateTAB(userIND),
1426 trunc(l_uStartDateTAB(userIND)),
1427 trunc(l_uEndDateTAB(userIND)),
1428 trunc(l_rStartDateTAB(roleIND)),
1429 trunc(l_rEndDateTAB(roleIND)),
1430 l_effStartDate,
1431 l_effEndDate,
1432 NULL,
1433 l_rpartIDTAB(roleIND),
1434 l_ownerTAB(userIND),
1435 WFA_SEC.user_id,
1436 sysdate,
1437 WFA_SEC.user_id,
1438 sysdate,
1439 WFA_SEC.login_id,
1440 l_AssignmentType);
1441 exception
1442 when DUP_VAL_ON_INDEX then
1443 --The record already exists, so we will just update the
1444 --timestamp
1445 if (l_assignmentType = 'I') then
1446 SELECT min(start_date)
1447 INTO l_startDateTAB(userIND)
1448 FROM WF_USER_ROLE_ASSIGNMENTS_V
1449 WHERE USER_NAME = l_userTAB(userIND)
1450 AND ROLE_NAME = l_roleTAB(roleIND);
1451
1452 SELECT max(end_date)
1453 INTO l_endDateTAB(userIND)
1454 FROM WF_USER_ROLE_ASSIGNMENTS_V
1455 WHERE USER_NAME = l_userTAB(userIND)
1456 AND ROLE_NAME = l_roleTAB(roleIND);
1457
1458 end if;
1459
1460 update WF_LOCAL_USER_ROLES
1461 set START_DATE = trunc(l_startDateTAB(userIND)),
1462 EXPIRATION_DATE = trunc(l_endDateTAB(userIND)),
1463 USER_START_DATE = trunc(l_uStartDateTAB(userIND)),
1464 USER_END_DATE = trunc(l_uEndDateTAB(userIND)),
1465 ROLE_START_DATE = trunc(l_rStartDateTAB(roleIND)),
1466 ROLE_END_DATE = trunc(l_rEndDateTAB(roleIND)),
1467 EFFECTIVE_START_DATE = l_effStartDate,
1468 EFFECTIVE_END_DATE = l_effEndDate,
1469 LAST_UPDATED_BY = WFA_SEC.user_id,
1470 LAST_UPDATE_DATE = sysdate,
1471 LAST_UPDATE_LOGIN = WFA_SEC.login_id,
1472 ASSIGNMENT_TYPE = l_AssignmentType
1473 where USER_NAME = l_userTAB(userIND)
1474 and ROLE_NAME = l_roleTAB(roleIND)
1475 and USER_ORIG_SYSTEM = l_uorigSysTAB(userIND)
1476 and USER_ORIG_SYSTEM_ID = l_uorigSysIDTAB(userIND)
1477 and ROLE_ORIG_SYSTEM = l_rorigSysTAB(roleIND)
1478 and ROLE_ORIG_SYSTEM_ID = l_rorigSysIDTAB(roleIND);
1479
1480
1481 end;
1482 end loop UserRoles;
1483 commit; --Commiting the inherited user/roles for this user.
1484 end loop Users;
1485 end if;
1486 end if; --(if ENABLED_FLAG = 'N')
1487 end Propagate;
1488
1489 --
1490 -- Propagate_CP (PRIVATE)
1491 -- Concurrent program wrapper to call Propagate().
1492 -- IN
1493 -- p_relationship_id (VARCHAR2)
1494 -- retcode [VARCHAR2]
1495 -- errbuf [VARCHAR2]
1496
1497 procedure Propagate_CP (retcode out NOCOPY VARCHAR2,
1498 errbuf out NOCOPY VARCHAR2,
1499 p_relationship_id in VARCHAR2) is
1500
1501 TYPE numTAB is table of NUMBER;
1502 relIDTAB numTAB;
1503 relIND number;
1504 l_propagateDate date;
1505
1506 begin
1507 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
1508 -- Log only
1509 -- BINDVAR_SCAN_IGNORE[3]
1510 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
1511 g_modulePkg||'.Propagate_CP',
1512 'Begin Propagate_CP('||p_relationship_id||')');
1513 end if;
1514 errbuf := '';
1515 l_propagateDate := sysdate;
1516 if (p_relationship_id = 'ALL') then
1517 SELECT relationship_id
1518 BULK COLLECT INTO relIDTAB
1519 FROM WF_ROLE_HIERARCHIES
1520 WHERE (PROPAGATE_DATE is NULL or
1521 ((PROPAGATE_DATE is NOT NULL) and
1522 (PROPAGATE_DATE < LAST_UPDATE_DATE)));
1523
1524 if (relIDTAB.COUNT > 0) then
1525 for relIND in relIDTAB.FIRST..relIDTAB.LAST loop
1526 propagate(p_relationship_id=>relIDTAB(relIND),
1527 p_propagateDate=>l_propagateDate);
1528 end loop;
1529 end if;
1530 else
1531 propagate(p_relationship_id=>to_number(Propagate_CP.p_relationship_id));
1532 end if;
1533
1534 retcode := '0';
1535 commit;
1536 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
1537 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
1538 g_modulePkg||'.Propagate_CP',
1539 'End Propagate_CP('||p_relationship_id||')');
1540 end if;
1541 exception
1542 when OTHERS then
1543 if(wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
1544 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
1545 g_modulePkg||'.Propagate_CP', 'Exception: '||
1546 sqlerrm);
1547 end if;
1548
1549 retcode := '2';
1550 errbuf := sqlerrm;
1551 WF_CORE.Clear;
1552 end Propagate_CP;
1553
1554
1555 -- Denormalize_UR_Assignments(PRIVATE)
1556 -- Procedure to update the user and role dates and
1557 -- effective dates of user/role assignments.
1558 -- IN OUT
1559 -- p_event WF_EVENT_T
1560
1561
1562
1563 procedure Denormalize_UR_Assignments( p_event in out NOCOPY WF_EVENT_T)
1564 is
1565
1566
1567 l_UserName VARCHAR2(320);
1568 l_RoleName VARCHAR2(320);
1569 l_StartDate DATE;
1570 l_EndDate DATE;
1571 l_LastUpdatedBy NUMBER ;
1572 l_LastUpdateDate DATE;
1573 l_LastUpdateLogin NUMBER ;
1574 l_OrigSystem VARCHAR2(30);
1575 l_OrigSystemID NUMBER;
1576
1577 TYPE dateTab IS TABLE OF DATE INDEX BY BINARY_INTEGER;
1578 TYPE idTab IS TABLE OF ROWID INDEX BY BINARY_INTEGER;
1579 TYPE numTab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
1580 l_roleTAB WF_DIRECTORY.roleTable;
1581 l_userTAB WF_DIRECTORY.userTable;
1582 l_assigningRoleTAB WF_DIRECTORY.roleTable;
1583 l_asgStartTAB dateTab;
1584 l_asgEndTAB dateTab;
1585 l_rowIDTAB idTab;
1586 l_userStartTAB dateTab;
1587 l_roleStartTAB dateTab;
1588 l_userEndTAB dateTab;
1589 l_roleEndTAB dateTab;
1590 l_effStartTAB dateTab;
1591 l_effEndTAB dateTab;
1592 l_startTAB dateTab;
1593 l_endTAB dateTab;
1594 -- who column pl/sql source tables
1595 l_creatDtTAB dateTab;
1596 l_creatByTAB numTab;
1597 l_lastUpdDtTAB dateTab;
1598 l_lastUpdByTAB numTab;
1599 l_lastUpdLogTAB numTab;
1600
1601 cursor c_UserRoleAssignments (c_userName in varchar2,
1602 c_roleName in varchar2)
1603 is
1604 select ROWID, ROLE_NAME, USER_NAME,ASSIGNING_ROLE, START_DATE, END_DATE,
1605 ROLE_START_DATE, ROLE_END_DATE,USER_START_DATE, USER_END_DATE,
1606 ASSIGNING_ROLE_START_DATE, ASSIGNING_ROLE_END_DATE, EFFECTIVE_START_DATE,
1607 EFFECTIVE_END_DATE,CREATED_BY, CREATION_DATE, LAST_UPDATED_BY,
1608 LAST_UPDATE_DATE, LAST_UPDATE_LOGIN
1609 from WF_USER_ROLE_ASSIGNMENTS
1610 where (ROLE_NAME = c_roleName or ASSIGNING_ROLE = c_roleName)
1611 and USER_NAME=c_userName;
1612
1613 cursor c_UserRoleAssignments_u (c_userName in varchar2)
1614 is
1615 select ROWID, ROLE_NAME, USER_NAME,ASSIGNING_ROLE, START_DATE, END_DATE,
1616 ROLE_START_DATE, ROLE_END_DATE,USER_START_DATE, USER_END_DATE,
1617 ASSIGNING_ROLE_START_DATE, ASSIGNING_ROLE_END_DATE, EFFECTIVE_START_DATE,
1618 EFFECTIVE_END_DATE ,CREATED_BY, CREATION_DATE, LAST_UPDATED_BY,
1619 LAST_UPDATE_DATE, LAST_UPDATE_LOGIN
1620 from WF_USER_ROLE_ASSIGNMENTS
1621 where USER_NAME=c_userName;
1622
1623 cursor c_UserRoleAssignments_r (c_roleName in varchar2)
1624 is
1625 select ROWID, ROLE_NAME, USER_NAME,ASSIGNING_ROLE, START_DATE, END_DATE,
1626 ROLE_START_DATE, ROLE_END_DATE,USER_START_DATE, USER_END_DATE,
1627 ASSIGNING_ROLE_START_DATE, ASSIGNING_ROLE_END_DATE, EFFECTIVE_START_DATE,
1628 EFFECTIVE_END_DATE,CREATED_BY, CREATION_DATE, LAST_UPDATED_BY,
1629 LAST_UPDATE_DATE, LAST_UPDATE_LOGIN
1630 from WF_USER_ROLE_ASSIGNMENTS
1631 where ROLE_NAME = c_roleName
1632 or ASSIGNING_ROLE = c_roleName;
1633
1634 begin
1635 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
1636 -- Log only
1637 -- BINDVAR_SCAN_IGNORE[3]
1638 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
1639 g_modulePkg||'.Denormalize_UR_Assignments',
1640 'Begin Denormalize_UR_Assignments('||p_event.getEventName||')');
1641 end if;
1642
1643 l_RoleName := p_event.getValueForParameter('ROLE_NAME');
1644 l_UserName := p_event.getValueForParameter('USER_NAME');
1645 l_LastUpdatedBy := to_number(p_event.getValueForParameter(
1646 'LAST_UPDATED_BY'), WF_CORE.canonical_number_mask);
1647 l_LastUpdateDate := nvl(to_date(p_event.getValueForParameter(
1648 'LAST_UPDATE_DATE'),
1649 WF_CORE.canonical_date_mask),SYSDATE);
1650 l_LastUpdateLogin := to_number(p_event.getValueForParameter(
1651 'LAST_UPDATE_LOGIN'), WF_CORE.canonical_number_mask);
1652
1653 l_OrigSystem := p_event.getValueForParameter('ORIG_SYSTEM');
1654 l_OrigSystemID := to_number(p_event.getValueForParameter(
1655 'ORIG_SYSTEM_ID'), WF_CORE.canonical_number_mask);
1656 l_StartDate := trunc(to_date(p_event.getValueForParameter('START_DATE'),
1657 WF_CORE.canonical_date_mask));
1658 l_EndDate:= trunc(to_date(p_event.getValueForParameter('EXPIRATION_DATE'),
1659 WF_CORE.canonical_date_mask));
1660
1661 if (l_userName is NOT NULL and l_roleName is NOT NULL) then
1662 open c_userRoleAssignments (l_userName , l_roleName);
1663 elsif (l_userName is NOT NULL) then
1664 open c_userRoleAssignments_u (l_userName);
1665 elsif (l_roleName is NOT NULL) then
1666 open c_userRoleAssignments_r(l_roleName);
1667 else
1668 return;
1669 end if;
1670 loop
1671
1672 if (l_userName is NOT NULL and l_roleName is NOT NULL) then
1673 fetch c_UserRoleAssignments
1674 bulk collect into l_rowIDTAB, l_roleTAB, l_userTAB,l_assigningRoleTAB,
1675 l_startTAB,l_endTAB, l_roleStartTAB,l_roleEndTAB, l_userStartTAB,
1676 l_userEndTAB, l_asgStartTAB,l_asgEndTAB, l_effStartTAB, l_effEndTAB,
1677 l_creatbyTAB, l_creatdtTAB, l_lastupdByTAB, l_lastupdDtTAB, l_lastupdlogTAB
1678 limit g_maxRows;
1679 elsif (l_userName is NOT NULL) then
1680 fetch c_UserRoleAssignments_u
1681 bulk collect into l_rowIDTAB, l_roleTAB, l_userTAB,l_assigningRoleTAB,
1682 l_startTAB,l_endTAB, l_roleStartTAB,l_roleEndTAB, l_userStartTAB,
1683 l_userEndTAB, l_asgStartTAB,l_asgEndTAB, l_effStartTAB, l_effEndTAB,
1684 l_creatbyTAB, l_creatdtTAB, l_lastupdByTAB, l_lastupdDtTAB, l_lastupdlogTAB
1685 limit g_maxRows;
1686 elsif (l_roleName is NOT NULL) then
1687 fetch c_UserRoleAssignments_r
1688 bulk collect into l_rowIDTAB, l_roleTAB, l_userTAB,l_assigningRoleTAB,
1689 l_startTAB,l_endTAB, l_roleStartTAB,l_roleEndTAB, l_userStartTAB,
1690 l_userEndTAB, l_asgStartTAB,l_asgEndTAB, l_effStartTAB, l_effEndTAB,
1691 l_creatbyTAB, l_creatdtTAB, l_lastupdByTAB, l_lastupdDtTAB, l_lastupdlogTAB
1692 limit g_maxRows;
1693 end if;
1694
1695 --We now have pl/sql tables in memory that we can update with the new
1696 --values. So we loop through them and begin the processing.
1697
1698
1699 if (l_rowIDTAB.COUNT > 0) then
1700 ---We don't want to loop if there are no records that meet our
1701 --criteria, we could stop right now.
1702
1703 for tabIndex in l_rowIDTAB.FIRST..l_rowIDTAB.LAST loop
1704 if (l_roleName is not null and l_userName is null
1705 and l_roleTAB(tabIndex) = l_roleName) then
1706 l_roleStartTAB(tabIndex) := l_startDate;
1707 l_roleEndTAB(tabIndex) := l_endDate;
1708 end if;
1709
1710 if (l_roleName is not null and l_userName is null
1711 and l_assigningRoleTAB(tabIndex) = l_roleName) then
1712 --This was an assigning role
1713 l_asgStartTAB(tabIndex) := l_startDate;
1714 l_asgEndTAB(tabIndex) := l_endDate;
1715 end if;
1716
1717
1718 if (l_userName is not null and l_roleName is null
1719 and l_userTAB(tabIndex) = l_userName) then
1720 l_userStartTAB(tabIndex) := l_startDate;
1721 l_userEndTAB(tabIndex) := l_endDate;
1722 --Check the self reference
1723 if (l_userTAB(tabIndex) = l_roleTab(tabIndex)) then
1724 l_roleStartTAB(tabIndex) := l_startDate;
1725 l_asgStartTAB(tabIndex) := l_startDate;
1726 l_roleEndTAB(tabIndex) := l_endDate;
1727 l_asgEndTAB(tabIndex) := l_endDate;
1728 l_startTAB(tabIndex) := l_startDate;
1729 l_endTAB(tabIndex) := l_endDate;
1730 -- also update WHO columns in case of self-reference
1731 l_lastUpdLogTAB(tabIndex):=nvl(l_lastUpdateLogin,WFA_SEC.Login_ID);
1732 l_lastUpdByTAB(tabIndex):=nvl(l_lastUpdatedBy, WFA_SEC.User_ID);
1733 l_lastUpdDtTAB(tabIndex):=nvl(l_lastUpdateDate,SYSDATE);
1734 end if;
1735 end if;
1736
1737 if (l_userName is not null and l_roleName is null
1738 and l_roleTAB(tabIndex) = l_userName) then
1739 --Case when user=role
1740 l_roleStartTAB(tabIndex) := l_startDate;
1741 l_roleEndTAB(tabIndex) := l_endDate;
1742 end if;
1743
1744 --Now we want to calculate the effective start and end dates
1745 --for this assignment.
1746 Calculate_Effective_Dates(l_startTAB(tabIndex),
1747 l_endTAB(tabIndex),
1748 l_userStartTAB(tabIndex),
1749 l_userEndTAB(tabIndex),
1750 l_roleStartTAB(tabIndex),
1751 l_roleEndTAB(tabIndex),
1752 l_asgStartTAB(tabIndex),
1753 l_asgEndTAB(tabIndex),
1754 l_effStartTAB(tabIndex),
1755 l_effEndTAB(tabIndex));
1756
1757 end loop;
1758
1759 --After this point we have a complete series of pl/sql tables with
1760 --all of the start/end dates and calculated effective start/end dates
1761 --We can then issue the bulk update.
1762 forall tabIndex in l_rowIDTAB.FIRST..l_rowIDTAB.LAST
1763
1764 update WF_USER_ROLE_ASSIGNMENTS
1765 set ROLE_START_DATE = l_roleStartTAB(tabIndex),
1766 ROLE_END_DATE = l_roleEndTAB(tabIndex),
1767 USER_START_DATE = l_userStartTAB(tabIndex),
1768 USER_END_DATE = l_userEndTAB(tabIndex),
1769 EFFECTIVE_START_DATE = l_effStartTAB(tabIndex),
1770 EFFECTIVE_END_DATE = l_effEndTAB(tabIndex),
1771 START_DATE=l_startTAB(tabIndex),
1772 END_DATE=l_endTAB(tabIndex),
1773 ASSIGNING_ROLE_START_DATE = l_asgStartTAB(tabIndex),
1774 ASSIGNING_ROLE_END_DATE = l_asgEndTAB(tabIndex),
1775 LAST_UPDATED_BY = l_lastUpdByTAB(tabIndex),
1776 LAST_UPDATE_DATE = l_lastUpdDtTAB(tabIndex),
1777 LAST_UPDATE_LOGIN = l_lastUpdLogTAB(tabIndex)
1778 where rowid = l_rowIDTAB(tabIndex);
1779
1780 end if; --if (l_rowIDTAB.COUNT > 0)
1781
1782 if (l_userName is NOT NULL and l_roleName is NOT NULL) then
1783 exit when c_userRoleAssignments%notfound;
1784 elsif (l_userName is NOT NULL) then
1785 exit when c_userRoleAssignments_u%notfound;
1786 elsif (l_roleName is NOT NULL) then
1787 exit when c_userRoleAssignments_r%notfound;
1788 end if;
1789
1790 end loop;
1791
1792
1793 if (l_userName is NOT NULL and l_roleName is NOT NULL) then
1794 close c_UserRoleAssignments;
1795 elsif (l_userName is NOT NULL) then
1796 close c_UserRoleAssignments_u;
1797 elsif (l_roleName is NOT NULL) then
1798 close c_UserRoleAssignments_r;
1799 end if;
1800
1801 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
1802 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
1803 g_modulePkg||'.Denormalize_UR_Assignments',
1804 'End Denormalize_UR_Assignments');
1805 end if;
1806
1807 exception
1808 when OTHERS then
1809 if c_UserRoleAssignments%ISOPEN then
1810 close c_UserRoleAssignments;
1811 elsif c_UserRoleAssignments_u%ISOPEN then
1812 close c_UserRoleAssignments_u;
1813 elsif c_UserRoleAssignments_r%ISOPEN then
1814 close c_UserRoleAssignments_r;
1815 end if;
1816
1817 if(wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
1818 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
1819 g_modulePkg||'.Denormalize_UR_Assignments',
1820 'Exception: '||sqlerrm);
1821 end if;
1822 WF_CORE.Context('WF_ROLE_HIERARCHY', 'Denormalize_UR_Assignments',
1823 p_event.getEventName);
1824 raise;
1825
1826
1827 end Denormalize_UR_Assignments;
1828
1829
1830
1831 -- Aggregate_User_Roles_RF(PRIVATE)
1832 -- Rule Function to update WF_LOCAL_USER_ROLES as
1833 -- summary table of WF_USER_ROLE_ASSIGNMENTS
1834 -- IN
1835 -- p_sub_guid (RAW)
1836 -- p_event ([WF_EVENT_T])
1837 -- returns
1838 -- VARCHAR2
1839 function Aggregate_User_Roles_RF ( p_sub_guid in RAW,
1840 p_event in out NOCOPY WF_EVENT_T)
1841 return VARCHAR2 is
1842
1843 l_UserName VARCHAR2(320);
1844 l_RoleName VARCHAR2(320);
1845 l_RoleStartDate DATE;
1846 l_RoleEndDate DATE;
1847 l_userStartDate DATE;
1848 l_effStartDate DATE;
1849 l_effEndDate DATE;
1850 l_userEndDate DATE;
1851 l_LastUpdatedBy NUMBER;
1852 l_LastUpdateDate DATE;
1853 l_LastUpdateLogin NUMBER;
1854 l_CreatedBy NUMBER;
1855 l_CreationDate DATE;
1856 sumTabIndex NUMBER;
1857 overWrite BOOLEAN;
1858 l_AssignmentType VARCHAR2(1);
1859 l_rowid rowid;
1860
1861 TYPE charTab IS TABLE OF VARCHAR2(1) INDEX BY BINARY_INTEGER;
1862 TYPE dateTab IS TABLE OF DATE INDEX BY BINARY_INTEGER;
1863 TYPE numTab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
1864 TYPE idTab IS TABLE OF ROWID INDEX BY BINARY_INTEGER;
1865
1866 l_roleSrcTAB WF_DIRECTORY.roleTable;
1867 l_userSrcTAB WF_DIRECTORY.userTable;
1868 l_roleDestTAB WF_DIRECTORY.roleTable;
1869 l_userDestTAB WF_DIRECTORY.userTable;
1870
1871 l_rowIDTAB idTab;
1872 l_userStartSrcTAB dateTab;
1873 l_roleStartSrcTAB dateTab;
1874 l_userEndSrcTAB dateTab;
1875 l_roleEndSrcTAB dateTab;
1876 l_effStartSrcTAB dateTab;
1877 l_effEndSrcTAB dateTab;
1878 l_AssignTAB charTab;
1879 l_userStartDestTAB dateTab;
1880 l_roleStartDestTAB dateTab;
1881 l_userEndDestTAB dateTab;
1882 l_roleEndDestTAB dateTab;
1883 l_effStartDestTAB dateTab;
1884 l_effEndDestTAB dateTab;
1885 l_startSrcTAB dateTab;
1886 l_endSrcTAB dateTab;
1887 l_startDestTAB dateTab;
1888 l_endDestTAB dateTab;
1889 l_relIDTAB numTab;
1890 -- who column pl/sql source tables
1891 l_creatDtSrcTAB dateTab;
1892 l_creatBySrcTAB numTab;
1893 l_lastUpdDtSrcTAB dateTab;
1894 l_lastUpdBySrcTAB numTab;
1895 l_lastUpdLogSrcTAB numTab;
1896
1897 -- who column pl/sql summary tables
1898 l_creatDtDestTAB dateTab;
1899 l_creatByDestTAB numTab;
1900 l_lastUpdDtDestTAB dateTab;
1901 l_lastUpdByDestTAB numTab;
1902 l_lastUpdLogDestTAB numTab;
1903
1904 --retrieve all WF_USER_ROLE_ASSIGNMENTS records which need to
1905 --get summarised
1906 --A User/Role was updated.
1907
1908 --<6028394:rwunderl> Sub-select necessary to catch effected user/roles
1909 cursor c_userRoleAssignments (c_userName in varchar2,
1910 c_roleName in varchar2) is
1911 select /*+ use_concat */ ROWID, ROLE_NAME, USER_NAME, ROLE_START_DATE,
1912 ROLE_END_DATE, USER_START_DATE, USER_END_DATE, EFFECTIVE_START_DATE,
1913 EFFECTIVE_END_DATE, START_DATE, END_DATE, RELATIONSHIP_ID,
1914 LAST_UPDATE_DATE, LAST_UPDATED_BY, LAST_UPDATE_LOGIN,
1915 CREATION_DATE, CREATED_BY
1916 from WF_USER_ROLE_ASSIGNMENTS
1917 where USER_NAME=c_userName
1918 and ROLE_NAME in (select ROLE_NAME
1919 from WF_USER_ROLE_ASSIGNMENTS
1920 where ASSIGNING_ROLE = c_roleName
1921 and USER_NAME = c_userName)
1922 order by ROLE_NAME, USER_NAME;
1923
1924
1925 --A User was updated.
1926 cursor c_userRoleAssignments_u (c_userName in varchar2) is
1927
1928 select ROWID, ROLE_NAME, USER_NAME, ROLE_START_DATE,
1929 ROLE_END_DATE, USER_START_DATE, USER_END_DATE, EFFECTIVE_START_DATE,
1930 EFFECTIVE_END_DATE, START_DATE, END_DATE, RELATIONSHIP_ID,
1931 LAST_UPDATE_DATE, LAST_UPDATED_BY, LAST_UPDATE_LOGIN,
1932 CREATION_DATE, CREATED_BY
1933 from WF_USER_ROLE_ASSIGNMENTS
1934 where USER_NAME=c_userName
1935 order by ROLE_NAME, USER_NAME;
1936
1937 --A Role was updated.
1938 cursor c_userRoleAssignments_r (c_roleName in varchar2) is
1939
1940 -- <bug 6665149> replaced query to also include those rows whose user, role
1941 -- pair match the directly effected user role through the
1942 -- given assigning role (the changed role).
1943 -- select ROWID, ROLE_NAME, USER_NAME, ROLE_START_DATE,
1944 -- ROLE_END_DATE, USER_START_DATE, USER_END_DATE, EFFECTIVE_START_DATE,
1945 -- EFFECTIVE_END_DATE, START_DATE,END_DATE, RELATIONSHIP_ID,
1946 -- LAST_UPDATE_DATE, LAST_UPDATED_BY, LAST_UPDATE_LOGIN,
1947 -- CREATION_DATE, CREATED_BY
1948 -- from WF_USER_ROLE_ASSIGNMENTS
1949 -- where ROLE_NAME=c_roleName or ASSIGNING_ROLE=c_roleName
1950 -- order by ROLE_NAME, USER_NAME;
1951 select ura.ROWID, ura.ROLE_NAME, ura.USER_NAME, ura.ROLE_START_DATE,
1952 ura.ROLE_END_DATE, ura.USER_START_DATE, ura.USER_END_DATE, ura.EFFECTIVE_START_DATE,
1953 ura.EFFECTIVE_END_DATE, ura.START_DATE, ura.END_DATE, ura.RELATIONSHIP_ID,
1954 ura.LAST_UPDATE_DATE, ura.LAST_UPDATED_BY, ura.LAST_UPDATE_LOGIN,
1955 ura.CREATION_DATE, ura.CREATED_BY
1956 from WF_USER_ROLE_ASSIGNMENTS ura,
1957 WF_USER_ROLE_ASSIGNMENTS ura2
1958 where ura2.ASSIGNING_ROLE= c_roleName
1959 and ura2.ROLE_NAME= ura.ROLE_NAME
1960 and ura2.USER_NAME = ura.USER_NAME
1961 order by ura.ROLE_NAME, ura.USER_NAME;
1962 -- </bug 6665149>
1963
1964 begin
1965 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
1966 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
1967 g_modulePkg||'.Aggregate_User_Roles_RF',
1968 'Begin Aggregate_User_Roles_RF('||rawtohex(p_sub_guid)||', '||
1969 p_event.getEventName||')');
1970 end if;
1971
1972
1973
1974 l_rowid := chartorowid(p_event.getValueForParameter('ROWID'));
1975
1976 l_RoleName := p_event.getValueForParameter('ROLE_NAME');
1977 l_UserName := p_event.getValueForParameter('USER_NAME');
1978 /* l_LastUpdatedBy := to_number(p_event.getValueForParameter(
1979 'LAST_UPDATED_BY'));
1980 l_LastUpdateDate := nvl(to_date(p_event.getValueForParameter(
1981 'LAST_UPDATE_DATE'),
1982 WF_CORE.canonical_date_mask),SYSDATE);
1983 l_LastUpdateLogin := to_number(p_event.getValueForParameter(
1984 'LAST_UPDATE_LOGIN'));
1985 l_CreatedBy := to_number(p_event.getValueForParameter('CREATED_BY'));
1986 l_CreationDate := to_date(p_event.getValueForParameter('CREATION_DATE'),
1987 WF_CORE.canonical_date_mask);*/
1988
1989 if (p_event.getValueForParameter('WFSYNCH_OVERWRITE') ='TRUE') then
1990 OverWrite := TRUE;
1991 else
1992 OverWrite:= FALSE;
1993 end if;
1994
1995
1996 --First check to see if we even have to run.
1997 if ((p_event.getValueForParameter('OLD_START_DATE') = '*UNDEFINED*') and
1998 (p_event.getValueForParameter('OLD_END_DATE') = '*UNDEFINED*')) then
1999
2000 --we might need to recalculate assignment type if a user/role propagation
2001 --has trigerred this rule function
2002 if (l_userName is NOT NULL and l_roleName is NOT NULL) then
2003 l_assignmentType := AssignmentType(p_UserName=>l_userName,
2004 p_RoleName=>l_roleName);
2005
2006 --Validate the assignment type status
2007 UPDATE WF_LOCAL_USER_ROLES
2008 SET ASSIGNMENT_TYPE = l_assignmentType
2009 WHERE ROWID = l_rowid;
2010 end if;
2011
2012 return 'SUCCESS';
2013 end if;
2014
2015 ---retrieve all WF_USER_ROLE_ASSIGNMENTS records which need to
2016 --get summarized
2017
2018 if (l_userName is NOT NULL and l_roleName is NOT NULL) then
2019 open c_userRoleAssignments (l_userName , l_roleName);
2020 elsif (l_userName is NOT NULL) then
2021 open c_userRoleAssignments_u (l_userName);
2022 elsif (l_roleName is NOT NULL) then
2023 open c_userRoleAssignments_r(l_roleName);
2024 else
2025 return 'SUCCESS';
2026 end if;
2027
2028 sumTabIndex := 0;
2029
2030 loop
2031 -- fetch a new batch of records
2032 if (l_userName is NOT NULL and l_roleName is NOT NULL) then
2033 fetch c_userRoleAssignments bulk collect into
2034 l_rowIDTAB, l_roleSrcTAB, l_userSrcTAB, l_roleStartSrcTAB,
2035 l_roleEndSrcTAB,l_userStartSrcTAB, l_userEndSrcTAB, l_effStartSrcTAB,
2036 l_effEndSrcTAB, l_StartSrcTAB, l_EndSrcTAB, l_relIDTAB,
2037 l_lastUpdDtSrcTAB, l_lastUpdBySrcTAB,l_lastUpdLogSrcTAB,
2038 l_creatDtSrcTAB, l_creatBySrcTAB limit g_maxRows;
2039 elsif (l_userName is NOT NULL) then
2040 fetch c_userRoleAssignments_u bulk collect into
2041 l_rowIDTAB, l_roleSrcTAB, l_userSrcTAB, l_roleStartSrcTAB,
2042 l_roleEndSrcTAB,l_userStartSrcTAB, l_userEndSrcTAB, l_effStartSrcTAB,
2043 l_effEndSrcTAB, l_StartSrcTAB, l_EndSrcTAB, l_relIDTAB,
2044 l_lastUpdDtSrcTAB, l_lastUpdBySrcTAB,l_lastUpdLogSrcTAB,
2045 l_creatDtSrcTAB, l_creatBySrcTAB limit g_maxRows;
2046 elsif (l_roleName is NOT NULL) then
2047 fetch c_userRoleAssignments_r bulk collect into
2048 l_rowIDTAB, l_roleSrcTAB, l_userSrcTAB, l_roleStartSrcTAB,
2049 l_roleEndSrcTAB,l_userStartSrcTAB, l_userEndSrcTAB, l_effStartSrcTAB,
2050 l_effEndSrcTAB, l_StartSrcTAB, l_EndSrcTAB, l_relIDTAB,
2051 l_lastUpdDtSrcTAB, l_lastUpdBySrcTAB,l_lastUpdLogSrcTAB,
2052 l_creatDtSrcTAB, l_creatBySrcTAB limit g_maxRows;
2053 end if;
2054
2055
2056 if (l_rowIDTAB.COUNT > 0) then
2057 ---We don't want to loop if there are no records that meet our criteria
2058 --we could stop right now.
2059
2060 for tabIndex in l_rowIDTAB.FIRST..l_rowIDTAB.LAST loop
2061
2062 --we need to insert into summary table if this is the first
2063 --record to be inserted or, we have a new user/role combination
2064 --in the assignment table, which hasnt yet been inserted into the
2065 --summary table
2066 if ((tabIndex=l_rowIDTAB.FIRST and l_roleDestTab.COUNT < 1) or
2067 (l_roleDestTab.COUNT >=1 and
2068 ((l_roleSrcTAB(tabIndex) <> l_roleDestTAB(sumTabIndex))
2069 or (l_userSrcTAB(tabIndex) <> l_userDestTAB(sumTabIndex))))) then
2070
2071 -- before inserting, check whether the summarytable has
2072 -- grown too large
2073
2074 if sumTabIndex >= g_maxRows then
2075
2076 --limit reached for summary table, so perform
2077 --the bulk update and clear off the table.
2078 --We need to perform the bulk update here in addition to
2079 --bulk update after exit from the loop, so that clearing
2080 --the summary table will not lose user/role effective date
2081 --information when duplicate user/role
2082 --combinations are spread across multiple groups
2083 if (OverWrite) then
2084 --allow update of created_by and creation_date
2085 forall destTabIndex in l_roleDestTab.FIRST..l_roleDestTab.LAST
2086
2087 UPDATE WF_LOCAL_USER_ROLES wur
2088 SET
2089 ROLE_START_DATE = l_roleStartDestTAB(destTabIndex),
2090 ROLE_END_DATE = l_roleEndDestTAB(destTabIndex),
2091 USER_START_DATE = l_userStartDestTAB(destTabIndex),
2092 USER_END_DATE = l_userEndDestTAB(destTabIndex),
2093 EFFECTIVE_START_DATE = l_effStartDestTAB(destTabIndex),
2094 EFFECTIVE_END_DATE = l_effEndDestTAB(destTabIndex),
2095 START_DATE = l_startDestTAB(destTabIndex),
2096 EXPIRATION_DATE = l_endDestTAB(destTabIndex),
2097 ASSIGNMENT_TYPE = l_assignTAB(destTabIndex),
2098 LAST_UPDATED_BY = l_lastUpdByDestTAB(destTabIndex),
2099 LAST_UPDATE_LOGIN = l_lastUpdLogDestTAB(destTabIndex),
2100 CREATION_DATE = nvl(l_creatDtSrcTAB(destTabIndex),CREATION_DATE),
2101 CREATED_BY= nvl(l_creatBySrcTAB(destTabIndex), CREATED_BY),
2102 LAST_UPDATE_DATE = l_lastUpdDtDestTAB(destTabIndex)
2103 WHERE ROLE_NAME = l_roleDestTAB(destTabIndex)
2104 AND USER_NAME = l_userDestTAB(destTabIndex);
2105 else
2106 forall destTabIndex in l_roleDestTab.FIRST..l_roleDestTab.LAST
2107 UPDATE WF_LOCAL_USER_ROLES wur
2108 SET
2109 ROLE_START_DATE = l_roleStartDestTAB(destTabIndex),
2110 ROLE_END_DATE = l_roleEndDestTAB(destTabIndex),
2111 USER_START_DATE = l_userStartDestTAB(destTabIndex),
2112 USER_END_DATE = l_userEndDestTAB(destTabIndex),
2113 EFFECTIVE_START_DATE = l_effStartDestTAB(destTabIndex),
2114 EFFECTIVE_END_DATE = l_effEndDestTAB(destTabIndex),
2115 START_DATE = l_startDestTAB(destTabIndex),
2116 EXPIRATION_DATE = l_endDestTAB(destTabIndex),
2117 ASSIGNMENT_TYPE = l_assignTAB(destTabIndex),
2118 LAST_UPDATED_BY = l_lastUpdByDestTAB(destTabIndex),
2119 LAST_UPDATE_LOGIN = l_lastUpdLogDestTAB(destTabIndex),
2120 LAST_UPDATE_DATE = l_lastUpdDtDestTAB(destTabIndex)
2121 WHERE ROLE_NAME = l_roleDestTAB(destTabIndex)
2122 AND USER_NAME = l_userDestTAB(destTabIndex);
2123 end if;
2124 l_roleStartDestTAB.DELETE;
2125 l_roleEndDestTAB.DELETE;
2126 l_userStartDestTAB.DELETE;
2127 l_userEndDestTAB.DELETE;
2128 l_effStartDestTAB.DELETE;
2129 l_effEndDestTAB.DELETE;
2130 l_assignTAB.DELETE;
2131 l_roleDestTAB.DELETE;
2132 l_userDestTAB.DELETE;
2133 l_startDestTAB.DELETE;
2134 l_endDestTAB.DELETE;
2135 l_lastUpdDtDestTAB.DELETE;
2136 l_lastUpdByDestTAB.DELETE;
2137 l_lastUpdLogDestTAB.DELETE;
2138 l_creatDtDestTAB.DELETE;
2139 l_creatByDestTAB.DELETE;
2140
2141 sumTabIndex := 0;
2142
2143 end if;
2144
2145
2146 --now perform the insert
2147 sumTabIndex := sumTabIndex + 1;
2148 l_RoleDestTAB(sumTabIndex) :=l_roleSrcTAB(tabIndex);
2149 l_UserDestTAB(sumTabIndex) :=l_userSRcTAB(tabIndex);
2150 l_roleStartDestTAB(sumTabIndex):=l_roleStartSrcTAB(tabIndex);
2151 l_roleEndDestTAB(sumTabIndex) :=l_roleEndSrcTAB(tabIndex);
2152 l_userStartDestTAB(sumTabIndex):=l_userStartSrcTAB(tabIndex);
2153 l_userEndDestTAB(sumTabIndex) :=l_userEndSrcTAB(tabIndex);
2154 l_effStartDestTAB(sumTabIndex) :=l_effStartSrcTAB(tabIndex);
2155 l_effEndDestTAB(sumTabIndex) :=l_effEndSrcTAB(tabIndex);
2156 l_lastUpdDtDestTAB(sumTabIndex):=l_lastUpdDtSrcTAB(tabIndex);
2157 l_lastUpdByDestTAB(sumTabIndex):=l_lastUpdBySrcTAB(tabIndex);
2158 l_lastUpdLogDestTAB(sumTabIndex):=l_lastUpdLogSrcTAB(tabIndex);
2159 l_creatDtDestTAB(sumTabIndex) :=l_creatDtSrcTAB(tabIndex);
2160 l_creatByDestTAB(sumTabIndex) := l_creatBySrcTAB(tabIndex);
2161
2162 if l_relIDTAB(tabIndex) = -1 then
2163 l_AssignTAB(sumTabIndex):='D';
2164 l_startDestTAB(sumTabIndex) :=l_startSrcTAB(tabIndex);
2165 l_endDestTAB(sumTabIndex) :=l_endSrcTAB(tabIndex);
2166 else
2167 l_AssignTAB(sumTabIndex) :='I';
2168 l_startDestTAB(sumTabIndex) :=null;
2169 l_endDestTAB(sumTabIndex) :=null;
2170 end if;
2171
2172
2173 else
2174 -- check whether we have a duplicate user/role combination
2175 if ((l_roleSrcTAB(tabIndex) = l_roleDestTAB(sumTabIndex)) and
2176 (l_userSrcTAB(tabIndex) = l_userDestTAB(sumTabIndex))) then
2177
2178 --update effective_dates
2179
2180 if l_effStartSrcTAB(tabIndex) <
2181 l_effStartDestTAB(sumTabIndex) then
2182 l_effStartDestTAB(sumTabIndex):= l_effStartSrcTAB(tabIndex);
2183 end if;
2184
2185 if l_effEndSrcTAB(tabIndex) > l_effEndDestTAB(sumTabIndex) then
2186 l_effEndDestTAB(sumTabIndex) := l_effEndSrcTAB(tabIndex);
2187 end if;
2188
2189 -- update the last update date and last update login if it is later
2190
2191 if l_lastUpdDtSrcTAB(tabIndex) > l_lastUpdDtDestTAB(sumTabIndex) then
2192 l_lastUpdDtDestTAB(sumTabIndex):=l_lastUpdDtSrcTAB(tabIndex);
2193 l_lastUpdByDestTAB(sumTabIndex):=l_lastUpdBySrcTAB(tabIndex);
2194 l_lastUpdLogDestTAB(sumTabIndex):=l_lastUpdLogSrcTAB(tabIndex);
2195 end if;
2196 --if this is a direct assignment, the start and end dates need to
2197 --be set.
2198 if l_relIDTAB(tabIndex) = -1 then
2199
2200 l_startDestTAB(sumTabIndex) :=l_startSrcTAB(tabIndex);
2201 l_endDestTAB(sumTabIndex) :=l_endSrcTAB(tabIndex);
2202 end if;
2203
2204 --if the assignment type in summary table is Direct and
2205 --we encountered an inherited assignment in the Assignment table
2206 --or if the assignment type in summary table is inherited and we
2207 --encountered a direct assignment in the Assignment table
2208 --update the assignment_Type to Both
2209
2210 if (((l_AssignTAB(sumTabIndex) = 'D') and
2211 (l_relIDTAB(tabIndex) <> -1)) or
2212 ((l_AssignTAB(sumTabIndex) = 'I') and
2213 (l_relIDTAB(tabIndex) = -1))) then
2214
2215 l_AssignTAB(sumTabIndex) := 'B';
2216
2217 end if;
2218 end if;
2219 end if;
2220
2221 end loop;
2222 end if;
2223
2224 if (l_userName is NOT NULL and l_roleName is NOT NULL) then
2225 exit when c_userRoleAssignments%notfound;
2226 elsif (l_userName is NOT NULL) then
2227 exit when c_userRoleAssignments_u%notfound;
2228 elsif (l_roleName is NOT NULL) then
2229 exit when c_userRoleAssignments_r%notfound;
2230 end if;
2231
2232 end loop;
2233
2234 if (l_userName is NOT NULL and l_roleName is NOT NULL) then
2235 close c_UserRoleAssignments;
2236 elsif (l_userName is NOT NULL) then
2237 close c_UserRoleAssignments_u;
2238 elsif (l_roleName is NOT NULL) then
2239 close c_UserRoleAssignments_r;
2240 end if;
2241
2242 --when we reach here, we need to bulk update the leftover records ,
2243 --if any, in the summary table.
2244 if sumTabIndex> 0 then
2245 if (OverWrite) then
2246 --allow update of created_by and creation_date
2247 forall tabIndex in l_roleDestTab.FIRST..l_roleDestTab.LAST
2248
2249 UPDATE WF_LOCAL_USER_ROLES wur
2250 SET
2251 ROLE_START_DATE = l_roleStartDestTAB(tabIndex),
2252 ROLE_END_DATE = l_roleEndDestTAB(tabIndex),
2253 USER_START_DATE = l_userStartDestTAB(tabIndex),
2254 USER_END_DATE = l_userEndDestTAB(tabIndex),
2255 EFFECTIVE_START_DATE = l_effStartDestTAB(tabIndex),
2256 EFFECTIVE_END_DATE = l_effEndDestTAB(tabIndex),
2257 START_DATE = l_startDestTAB(tabIndex),
2258 EXPIRATION_DATE = l_endDestTAB(tabIndex),
2259 ASSIGNMENT_TYPE = l_assignTAB(tabIndex),
2260 LAST_UPDATED_BY = l_lastUpdByDestTAB(tabIndex),
2261 LAST_UPDATE_LOGIN = l_lastUpdLogDestTAB(tabIndex),
2262 LAST_UPDATE_DATE = l_lastUpdDtDestTAB(tabIndex),
2263 CREATION_DATE = nvl(l_creatDtSrcTAB(tabIndex),CREATION_DATE),
2264 CREATED_BY= nvl(l_creatBySrcTAB(tabIndex), CREATED_BY)
2265 WHERE ROLE_NAME = l_roleDestTAB(tabIndex)
2266 AND USER_NAME = l_userDestTAB(tabIndex);
2267 else
2268 forall tabIndex in l_roleDestTab.FIRST..l_roleDestTab.LAST
2269
2270 UPDATE WF_LOCAL_USER_ROLES wur
2271 SET
2272 ROLE_START_DATE = l_roleStartDestTAB(tabIndex),
2273 ROLE_END_DATE = l_roleEndDestTAB(tabIndex),
2274 USER_START_DATE = l_userStartDestTAB(tabIndex),
2275 USER_END_DATE = l_userEndDestTAB(tabIndex),
2276 EFFECTIVE_START_DATE = l_effStartDestTAB(tabIndex),
2277 EFFECTIVE_END_DATE = l_effEndDestTAB(tabIndex),
2278 START_DATE = l_startDestTAB(tabIndex),
2279 EXPIRATION_DATE = l_endDestTAB(tabIndex),
2280 ASSIGNMENT_TYPE = l_assignTAB(tabIndex),
2281 LAST_UPDATED_BY = l_lastUpdByDestTAB(tabIndex),
2282 LAST_UPDATE_LOGIN = l_lastUpdLogDestTAB(tabIndex),
2283 LAST_UPDATE_DATE = l_lastUpdDtDestTAB(tabIndex)
2284 WHERE ROLE_NAME = l_roleDestTAB(tabIndex)
2285 AND USER_NAME = l_userDestTAB(tabIndex);
2286 end if;
2287 end if;
2288
2289 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2290 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
2291 g_modulePkg||'.Aggregate_User_Roles_RF',
2292 'End Aggregate_User_Roles_RF('||rawtohex(p_sub_guid)||', '||
2293 p_event.getEventName||')');
2294 end if;
2295 return 'SUCCESS';
2296
2297 EXCEPTION WHEN OTHERS THEN
2298 if c_UserRoleAssignments%ISOPEN then
2299 close c_UserRoleAssignments;
2300 elsif c_UserRoleAssignments_u%ISOPEN then
2301 close c_UserRoleAssignments_u;
2302 elsif c_UserRoleAssignments_r%ISOPEN then
2303 close c_UserRoleAssignments_r;
2304 end if;
2305
2306 WF_CORE.Context('WF_ROLE_HIERARCHY', 'Aggregate_User_Roles_RF',
2307 p_event.getEventName( ), p_sub_guid);
2308
2309 WF_EVENT.setErrorInfo(p_event, 'ERROR');
2310 return 'ERROR';
2311
2312
2313 end Aggregate_User_Roles_RF;
2314
2315
2316
2317
2318
2319 -- Public APIs
2320 --
2321 --
2322
2323 --
2324 -- GetRelationships (PUBLIC)
2325 -- Retrieves the hierarchies for a given role.
2326 -- IN
2327 -- p_name (VARCHAR2)
2328 -- p_superiors (WF_ROLE_HIERARCHY.relTAB)
2329 -- p_subordinates (WF_ROLE_HIERARCHY.relTAB)
2330
2331 procedure GetRelationships (p_name in VARCHAR2,
2332 p_superiors out NOCOPY WF_ROLE_HIERARCHY.relTAB,
2333 p_subordinates out NOCOPY WF_ROLE_HIERARCHY.relTAB,
2334 p_direction in VARCHAR2 )
2335 is
2336 --<8i Support>
2337 TYPE super_name_Tab is TABLE of VARCHAR2(320);
2338 TYPE sub_name_Tab is TABLE of VARCHAR2(320);
2339 TYPE rel_ID_Tab is TABLE of NUMBER;
2340 TYPE enabled_Tab is TABLE OF VARCHAR2(1);
2341
2342 superTab super_name_Tab;
2343 subTab sub_name_Tab;
2344 relIDTAB rel_ID_Tab;
2345 enabledTab enabled_Tab;
2346 --</8i Support>
2347
2348 begin
2349 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2350 -- Log only
2351 -- BINDVAR_SCAN_IGNORE[4]
2352 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
2353 g_modulePkg||'.GetRelationships',
2354 'Begin GetRelationships('||
2355 p_name||')');
2356 end if;
2357 begin
2358
2359 /*
2360 -- <9i Support>
2361 if (p_direction in ('SUPERIORS', 'BOTH')) then
2362 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2363 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2364 g_modulePkg||'.GetRelationships',
2365 'Retrieving the superior relationships.');
2366 end if;
2367 SELECT RELATIONSHIP_ID, SUB_NAME, SUPER_NAME,
2368 ENABLED_FLAG
2369 BULK COLLECT INTO p_superiors
2370 FROM WF_ROLE_HIERARCHIES
2371 WHERE ENABLED_FLAG = 'Y'
2372 CONNECT BY PRIOR SUPER_NAME = SUB_NAME
2373 AND ENABLED_FLAG = 'Y'
2374 START WITH SUB_NAME = upper(p_name);
2375
2376 end if;
2377
2378 if (p_direction in ('SUBORDINATES', 'BOTH')) then
2379 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2380 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2381 g_modulePkg||'.GetRelationships',
2382 'Retrieving the subordinate relationships.');
2383 end if;
2384 SELECT RELATIONSHIP_ID, SUB_NAME, SUPER_NAME,
2385 ENABLED_FLAG
2386 BULK COLLECT INTO p_subordinates
2387 FROM WF_ROLE_HIERARCHIES
2388 WHERE ENABLED_FLAG = 'Y'
2389 CONNECT BY PRIOR SUB_NAME = SUPER_NAME
2390 AND ENABLED_FLAG = 'Y'
2391 START WITH SUPER_NAME = upper(p_name);
2392 end if;
2393 */
2394
2395 --<8i Support>
2396 if (p_direction in ('SUPERIORS', 'BOTH')) then
2397 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2398 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2399 g_modulePkg||'.GetRelationships',
2400 'Retrieving the superior relationships.');
2401 end if;
2402 SELECT RELATIONSHIP_ID, SUB_NAME, SUPER_NAME,
2403 ENABLED_FLAG
2404 BULK COLLECT INTO relIDTab, subTab, superTab, enabledTab
2405 FROM WF_ROLE_HIERARCHIES
2406 WHERE ENABLED_FLAG = 'Y'
2407 CONNECT BY PRIOR SUPER_NAME = SUB_NAME
2408 AND PRIOR ENABLED_FLAG = 'Y'
2409 START WITH SUB_NAME = upper(p_name);
2410
2411 if (relIDTab.COUNT > 0) then
2412 for a in relIDTab.FIRST..relIDTab.LAST loop
2413 p_superiors(a).RELATIONSHIP_ID := relIDTab(a);
2414 p_superiors(a).SUB_NAME := subTab(a);
2415 p_superiors(a).SUPER_NAME := superTab(a);
2416 p_superiors(a).ENABLED_FLAG := enabledTab(a);
2417 end loop;
2418 end if;
2419 end if;
2420
2421 if (p_direction in ('SUBORDINATES', 'BOTH')) then
2422 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2423 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2424 g_modulePkg||'.GetRelationships',
2425 'Retrieving the subordinate relationships.');
2426 end if;
2427 SELECT RELATIONSHIP_ID, SUB_NAME, SUPER_NAME,
2428 ENABLED_FLAG
2429 BULK COLLECT INTO relIDTab, subTab, superTab, enabledTab
2430 FROM WF_ROLE_HIERARCHIES
2431 WHERE ENABLED_FLAG = 'Y'
2432 CONNECT BY PRIOR SUB_NAME = SUPER_NAME
2433 AND PRIOR ENABLED_FLAG = 'Y'
2434 START WITH SUPER_NAME = upper(p_name);
2435
2436 if (relIDTab.COUNT > 0) then
2437 for a in relIDTab.FIRST..relIDTab.LAST loop
2438 p_subordinates(a).RELATIONSHIP_ID := relIDTab(a);
2439 p_subordinates(a).SUB_NAME := subTab(a);
2440 p_subordinates(a).SUPER_NAME := superTab(a);
2441 p_subordinates(a).ENABLED_FLAG := enabledTab(a);
2442 end loop;
2443 end if;
2444 end if;
2445
2446 --</8i Support>
2447
2448 end;
2449 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2450 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
2451 g_modulePkg||'.GetRelationships',
2452 'End GetRelationships('||
2453 p_name||')');
2454 end if;
2455 exception
2456 when OTHERS then
2457 if(wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
2458 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
2459 g_modulePkg||'.GetRelationships', 'Exception: '||
2460 sqlerrm);
2461 end if;
2462 WF_CORE.Context('WF_ROLE_HIERARCHY', 'GetRelationships', p_name);
2463 raise;
2464
2465 end GetRelationships;
2466
2467 --
2468 -- GetAllRelationships (PUBLIC)
2469 -- Retrieves both enabled and disabled hierarchies for a given role..
2470 -- IN
2471 -- p_name (VARCHAR2)
2472 -- p_superiors (WF_ROLE_HIERARCHY.relTAB)
2473 -- p_subordinates (WF_ROLE_HIERARCHY.relTAB)
2474
2475 procedure GetAllRelationships (p_name in VARCHAR2,
2476 p_superiors out NOCOPY WF_ROLE_HIERARCHY.relTAB,
2477 p_subordinates out NOCOPY WF_ROLE_HIERARCHY.relTAB,
2478 p_direction in VARCHAR2)
2479 is
2480 --<8i Support>
2481 TYPE super_name_Tab is TABLE of VARCHAR2(320);
2482 TYPE sub_name_Tab is TABLE of VARCHAR2(320);
2483 TYPE rel_ID_Tab is TABLE of NUMBER;
2484 TYPE enabled_Tab is TABLE OF VARCHAR2(1);
2485
2486 superTab super_name_Tab;
2487 subTab sub_name_Tab;
2488 relIDTAB rel_ID_Tab;
2489 enabledTab enabled_Tab;
2490 --</8i Support>
2491
2492 begin
2493 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2494 -- Log only
2495 -- BINDVAR_SCAN_IGNORE[4]
2496 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
2497 g_modulePkg||'.GetAllRelationships',
2498 'Begin GetAllRelationships('||
2499 p_name||')');
2500 end if;
2501 --<8i Support>
2502 if (p_direction in ('SUPERIORS', 'BOTH')) then
2503 SELECT RELATIONSHIP_ID, SUB_NAME, SUPER_NAME,
2504 ENABLED_FLAG
2505 BULK COLLECT INTO relIDTab, subTab, superTab, enabledTab
2506 FROM WF_ROLE_HIERARCHIES
2507 CONNECT BY PRIOR SUPER_NAME = SUB_NAME
2508 START WITH SUB_NAME = upper(p_name);
2509
2510 if (relIDTab.COUNT > 0) then
2511 for a in relIDTab.FIRST..relIDTab.LAST loop
2512 p_superiors(a).RELATIONSHIP_ID := relIDTab(a);
2513 p_superiors(a).SUB_NAME := subTab(a);
2514 p_superiors(a).SUPER_NAME := superTab(a);
2515 p_superiors(a).ENABLED_FLAG := enabledTab(a);
2516 end loop;
2517 end if;
2518 end if;
2519
2520 if (p_direction in ('SUBORDINATES', 'BOTH')) then
2521 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2522 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2523 g_modulePkg||'.GetAllRelationships',
2524 'Retrieving the subordinate relationships.');
2525 end if;
2526 SELECT RELATIONSHIP_ID, SUB_NAME, SUPER_NAME,
2527 ENABLED_FLAG
2528 BULK COLLECT INTO relIDTab, subTab, superTab, enabledTab
2529 FROM WF_ROLE_HIERARCHIES
2530 CONNECT BY PRIOR SUB_NAME = SUPER_NAME
2531 START WITH SUPER_NAME = upper(p_name);
2532
2533 if (relIDTab.COUNT > 0) then
2534 for a in relIDTab.FIRST..relIDTab.LAST loop
2535 p_subordinates(a).RELATIONSHIP_ID := relIDTab(a);
2536 p_subordinates(a).SUB_NAME := subTab(a);
2537 p_subordinates(a).SUPER_NAME := superTab(a);
2538 p_subordinates(a).ENABLED_FLAG := enabledTab(a);
2539 end loop;
2540 end if;
2541 end if;
2542 --</8i Support>
2543 /*--<9i Support>
2544 begin
2545 if (p_direction in ('SUPERIORS', 'BOTH')) then
2546 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2547 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2548 g_modulePkg||'.GetAllRelationships',
2549 'Retrieving the superior relationships.');
2550 end if;
2551 SELECT RELATIONSHIP_ID, SUB_NAME, SUPER_NAME,
2552 ENABLED_FLAG
2553 BULK COLLECT INTO p_superiors
2554 FROM WF_ROLE_HIERARCHIES
2555 CONNECT BY PRIOR SUPER_NAME = SUB_NAME
2556 START WITH SUB_NAME = upper(p_name);
2557 end if;
2558
2559 if (p_direction in ('SUBORDINATES', 'BOTH')) then
2560 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2561 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2562 g_modulePkg||'.GetAllRelationships',
2563 'Retrieving the subordinate relationships.');
2564 end if;
2565 SELECT RELATIONSHIP_ID, SUB_NAME, SUPER_NAME,
2566 ENABLED_FLAG
2567 BULK COLLECT INTO p_subordinates
2568 FROM WF_ROLE_HIERARCHIES
2569 CONNECT BY PRIOR SUB_NAME = SUPER_NAME
2570 START WITH SUPER_NAME = upper(p_name);
2571 end if;
2572 end;
2573 */
2574 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2575 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
2576 g_modulePkg||'.GetAllRelationships',
2577 'End GetAllRelationships('||
2578 p_name||')');
2579 end if;
2580 exception
2581 when OTHERS then
2582 if(wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
2583 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
2584 g_modulePkg||'.GetAllRelationships', 'Exception: '||
2585 sqlerrm);
2586 end if;
2587 WF_CORE.Context('WF_ROLE_HIERARCHY', 'GetAllRelationships', p_name);
2588 raise;
2589
2590 end GetAllRelationships;
2591
2592 -- AddRelationship (PUBLIC)
2593 -- Creates a super/sub role hierarchy relationship in WF_ROLE_HIERARCHIES.
2594 -- IN
2595 -- p_sub_name (VARCHAR2)
2596 -- p_super_name (VARCHAR2)
2597 -- p_deferMode (BOOLEAN)
2598 -- p_enabled (VARCHAR2)
2599 --
2600 -- RETURNS
2601 -- NUMBER
2602
2603 function AddRelationship (p_sub_name in VARCHAR2,
2604 p_super_name in VARCHAR2,
2605 p_deferMode in BOOLEAN,
2606 p_enabled in varchar2) return number is
2607 l_RelationshipID NUMBER;
2608 l_sub_origSys VARCHAR2(30);
2609 l_super_origSys VARCHAR2(30);
2610 l_roleView VARCHAR2(30);
2611
2612 l_superiors WF_ROLE_HIERARCHY.relTAB;
2613 l_subordinates WF_ROLE_HIERARCHY.relTAB;
2614
2615 HierarchyLoop EXCEPTION;
2616 pragma exception_init(HierarchyLoop, -01436);
2617
2618 --<rwunderl:3634880>
2619 trig_SavePoint EXCEPTION;
2620 pragma exception_init(trig_SavePoint, -04092);
2621 called_from_trigger BOOLEAN := FALSE;
2622 l_updateTime DATE;
2623 l_partitionID NUMBER;
2624 l_superPartitionID number;
2625
2626 --set the enabled_flag default to 'Y'
2627 l_enabled varchar2(1) := 'Y';
2628
2629 begin
2630 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2631 -- Log only
2632 -- BINDVAR_SCAN_IGNORE[4]
2633 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
2634 g_modulePkg||'.AddRelationship',
2635 'Begin AddRelationship('||
2636 p_sub_name||', '||p_super_name||')');
2637 end if;
2638 --need to serialize here to prevent potential circular loops
2639
2640 g_trustTimeStamp := WF_ROLE_HIERARCHY.CreateSession;
2641 -- Validating Roles
2642 begin
2643 begin
2644 SELECT ORIG_SYSTEM, PARTITION_ID
2645 INTO l_sub_origSys, l_partitionID
2646 FROM WF_LOCAL_ROLES
2647 WHERE NAME = p_sub_name;
2648 exception
2649 when NO_DATA_FOUND then
2650 WF_CORE.Token('NAME', p_sub_name);
2651 WF_CORE.Raise('WF_NO_ROLE');
2652 end;
2653
2654 begin
2655 SELECT ORIG_SYSTEM, PARTITION_ID
2656 INTO l_super_origSys, l_superPartitionID
2657 FROM WF_LOCAL_ROLES
2658 WHERE NAME = p_super_name;
2659 exception
2660 when NO_DATA_FOUND then
2661 WF_CORE.Token('NAME', p_super_name);
2662 WF_CORE.Raise('WF_NO_ROLE');
2663 end;
2664
2665 -- Obtain the relationship_id from WF_ROLE_HIERARCHIES_S.
2666 select WF_ROLE_HIERARCHIES_S.NEXTVAL
2667 into l_RelationshipID
2668 from dual;
2669
2670 -- Perform the insert
2671 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2672 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2673 g_modulePkg||'.AddRelationship.Insert',
2674 'Inserting record');
2675 end if;
2676 begin
2677 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2678 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2679 g_modulePkg||'.AddRelationship',
2680 'Setting savepoint loopCheck');
2681 end if;
2682 savepoint loopCheck;
2683 exception
2684 when trig_SavePoint then
2685 if(wf_log_pkg.level_exception >= fnd_log.g_current_runtime_level) then
2686 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_EXCEPTION,
2687 g_modulePkg||'.AddRelationship',
2688 'Call stack initiated from trigger, unable to set '||
2689 'savepoint. Any exception will result in complete '||
2690 'rollback.');
2691 end if;
2692 called_from_trigger := TRUE;
2693 end;
2694
2695 --Once ready to insert record verify that the enabled_flag
2696 --is essentially binay ie 'Y' or 'N'
2697 --Hence anything other than 'Y' set it to 'N'
2698 if (p_enabled <> 'Y') then
2699 l_enabled := 'N';
2700 end if;
2701
2702 insert into WF_ROLE_HIERARCHIES
2703 (RELATIONSHIP_ID,
2704 SUB_NAME,
2705 SUPER_NAME,
2706 CREATED_BY,
2707 CREATION_DATE,
2708 LAST_UPDATED_BY,
2709 LAST_UPDATE_DATE,
2710 LAST_UPDATE_LOGIN,
2711 ENABLED_FLAG,
2712 SECURITY_GROUP_ID,
2713 PARTITION_ID,
2714 SUPERIOR_PARTITION_ID)
2715 values
2716 ( l_RelationshipID,
2717 p_sub_name,
2718 p_super_name,
2719 WFA_SEC.USER_ID,
2720 sysdate,
2721 WFA_SEC.USER_ID,
2722 sysdate,
2723 WFA_SEC.LOGIN_ID,
2724 l_enabled,
2725 WFA_SEC.SECURITY_GROUP_ID,
2726 l_partitionID,
2727 l_superPartitionID);
2728 exception
2729 when DUP_VAL_ON_INDEX then
2730 -- The row already exists, if it is expired, we can update with
2731 -- with the new information, if it is active, we will raise an error.
2732 if(wf_log_pkg.level_exception >= fnd_log.g_current_runtime_level) then
2733 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_EXCEPTION,
2734 g_modulePkg||
2735 '.AddRelationship.Insert.DUP_VAL_ON_INDEX',
2736 'Updating expired relationship');
2737 end if;
2738 update WF_ROLE_HIERARCHIES set
2739 LAST_UPDATED_BY = WFA_SEC.USER_ID,
2740 LAST_UPDATE_DATE = sysdate,
2741 LAST_UPDATE_LOGIN= WFA_SEC.USER_ID,
2742 ENABLED_FLAG = 'Y',
2743 SECURITY_GROUP_ID = WFA_SEC.SECURITY_GROUP_ID
2744 where SUB_NAME = p_sub_name
2745 and SUPER_NAME = p_super_name
2746 and ENABLED_FLAG = 'N'
2747 returning RELATIONSHIP_ID into l_relationshipID;
2748
2749 if (sql%ROWCOUNT = 0) then
2750 --We already encountered a dup_val_on_index with sub/super name
2751 --so by default for the above update to not work the enabled_flag
2752 --would have to be 'Y' which is a true duplicate.
2753 if(wf_log_pkg.level_exception >= fnd_log.g_current_runtime_level) then
2754 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_EXCEPTION,
2755 g_modulePkg||
2756 '.AddRelationship.Insert.DUP_VAL_ON_INDEX.NoUpdate',
2757 'Active relationship exists, raising WFDS_DUP_HIERARCHY');
2758 end if;
2759 WF_CORE.Token('P_SUB_NAME', p_sub_name);
2760 WF_CORE.Token('P_SUPER_NAME', p_super_name);
2761 WF_CORE.Raise('WFDS_DUP_HIERARCHY');
2762 end if;
2763 end;
2764
2765 --If either the superior or the subordinate is a newly created role we
2766 --know that it is impossible to have created a loop in the hierarchy so
2767 --we only validate the hierarchy if neither is in the WF_LOCAL_SYNCH.Cache
2768 if (NOT (WF_LOCAL_SYNCH.CheckCache(p_sub_name)) and
2769 NOT (WF_LOCAL_SYNCH.CheckCache(p_super_name))) then
2770 --Access the hierarchy to make sure a loop was not created.
2771
2772 GetRelationships(p_name=>p_sub_name,
2773 p_superiors=>l_superiors,
2774 p_subordinates=>l_subordinates);
2775 else
2776 --We must be sure to delete the super and sub name from the
2777 --WF_LOCAL_SYNCH cache because they are no longer "trusted" to not
2778 --potentially cause a loop in the hierarchy.
2779 WF_LOCAL_SYNCH.DeleteCache(p_sub_name);
2780 WF_LOCAL_SYNCH.DeleteCache(p_super_name);
2781 end if;
2782
2783 --Raise the oracle.apps.wf.ds.roleHierarchy.relationshipCreated event
2784 RaiseEvent(
2785 p_eventName=>'oracle.apps.fnd.wf.ds.roleHierarchy.relationshipCreated',
2786 p_relationshipID=>l_RelationshipID,
2787 p_superName=>p_super_name,
2788 p_subName=>p_sub_name,
2789 p_defer=>p_deferMode);
2790 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2791 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, g_modulePkg||
2792 '.AddRelationship',
2793 'End AddRelationship('|| p_sub_name||', '||
2794 p_super_name||')');
2795 end if;
2796 return l_RelationshipID;
2797
2798 exception
2799 when HierarchyLoop then
2800 if(wf_log_pkg.level_exception >= fnd_log.g_current_runtime_level) then
2801 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_EXCEPTION,
2802 g_modulePkg||'.AddRelationship',
2803 'Circular reference detected in hierarchy.');
2804 end if;
2805 if (called_from_trigger) then
2806 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2807 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2808 g_modulePkg||'.AddRelationship',
2809 'Initiation from trigger prevents rollback to '||
2810 'savepoint executing complete rollback.');
2811 end if;
2812 rollback;
2813 else
2814 rollback to loopCheck;
2815 end if;
2816 if(wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
2817 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
2818 g_modulePkg||'.AddRelationship', 'Exception: '||
2819 sqlerrm);
2820 end if;
2821 WF_CORE.Context('WF_ROLE_HIERARCHY', 'AddRelationship', p_sub_name,
2822 p_super_name);
2823 WF_CORE.Raise('WFDS_HIERARCHY_LOOP');
2824
2825 when OTHERS then
2826 if(wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
2827 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
2828 g_modulePkg||'.AddRelationship', 'Exception: '||
2829 sqlerrm);
2830 end if;
2831 WF_CORE.Context('WF_ROLE_HIERARCHY', 'AddRelationship', p_sub_name,
2832 p_super_name);
2833 raise;
2834 end AddRelationship;
2835
2836 --
2837 -- ExpireRelationship(PUBLIC)
2838 -- Expires a super/sub role hierarchy relationship
2839 -- IN
2840 -- p_sub_name (VARCHAR2)
2841 -- p_super_name (VARCHAR2)
2842 -- p_deferMode (BOOLEAN)
2843 --
2844 -- RETURNS
2845 -- NUMBER
2846
2847 function ExpireRelationship (p_sub_name in VARCHAR2,
2848 p_super_name in VARCHAR2,
2849 p_defer_mode in BOOLEAN) return number is
2850
2851 l_relationshipID NUMBER;
2852
2853 begin
2854 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2855 -- Log only
2856 -- BINDVAR_SCAN_IGNORE[4]
2857 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
2858 g_modulePkg||'.ExpireRelationship',
2859 'Begin ExpireRelationship('||
2860 p_sub_name||', '||p_super_name||')');
2861 end if;
2862 begin
2863 if(wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
2864 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT,
2865 g_modulePkg||'.ExpireRelationship.Update',
2866 'Updating record');
2867 end if;
2868 update WF_ROLE_HIERARCHIES
2869 set LAST_UPDATED_BY = WFA_SEC.USER_ID,
2870 LAST_UPDATE_DATE = sysdate,
2871 LAST_UPDATE_LOGIN= WFA_SEC.USER_ID,
2872 ENABLED_FLAG = 'N'
2873 where SUB_NAME = p_sub_name
2874 and SUPER_NAME = p_super_name
2875 and ENABLED_FLAG = 'Y'
2876 returning RELATIONSHIP_ID into l_relationshipID;
2877
2878 if (sql%ROWCOUNT = 0) then
2879 -- There is no active role hierarchy relationship to expire
2880 if(wf_log_pkg.level_exception >= fnd_log.g_current_runtime_level) then
2881 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_EXCEPTION, g_modulePkg||
2882 '.ExpireRelationship.Update.NoActiveRelationship',
2883 'No Active relationship exists, '||
2884 'raising WFDS_NO_HIERARCHY');
2885 end if;
2886 WF_CORE.Token('P_SUB_NAME', p_sub_name);
2887 WF_CORE.Token('P_SUPER_NAME', p_super_name);
2888 WF_CORE.Raise('WFDS_NO_HIERARCHY');
2889 end if;
2890
2891 end;
2892
2893 --Raise the oracle.apps.wf.ds.roleHierarchy.relationshipUpdated event
2894 RaiseEvent(
2895 p_eventName=>'oracle.apps.fnd.wf.ds.roleHierarchy.relationshipUpdated',
2896 p_relationshipID=>l_RelationshipID,
2897 p_superName=>p_super_name,
2898 p_subName=>p_sub_name,
2899 p_defer=>p_defer_mode);
2900
2901 if(wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
2902 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, g_modulePkg||
2903 '.ExpireRelationship',
2904 'End ExpireRelationship('|| p_sub_name||', '||
2905 p_super_name||')');
2906 end if;
2907
2908 return l_RelationshipID;
2909
2910 exception
2911 when OTHERS then
2912 if(wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
2913 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,
2914 g_modulePkg||'.ExpireRelationship', 'Exception: '||
2915 sqlerrm);
2916 end if;
2917 WF_CORE.Context('WF_ROLE_HIERARCHY', 'ExpireRelationship', p_sub_name,
2918 p_super_name);
2919 raise;
2920 end ExpireRelationship;
2921
2922 -- Denormalize_UserRole_RF (PRIVATE)
2923 -- Rule function to update the user and role dates of user/role
2924 -- relationships as well as assignments.
2925 -- IN
2926 -- p_sub_guid (RAW)
2927 -- p_event ([WF_EVENT_T])
2928 -- RETURNS
2929 -- VARCHAR2
2930
2931 function Denormalize_User_Role_RF ( p_sub_guid in RAW,
2932 p_event in out NOCOPY WF_EVENT_T )
2933 return VARCHAR2 is
2934
2935
2936
2937 begin
2938 --First check to see if we even have to run.
2939 if ((p_event.getValueForParameter('OLD_START_DATE') = '*UNDEFINED*') and
2940 (p_event.getValueForParameter('OLD_END_DATE') = '*UNDEFINED*')) then
2941 return 'SUCCESS';
2942 end if;
2943 Denormalize_UR_Assignments(p_event);
2944
2945 return 'SUCCESS';
2946
2947 exception
2948 when OTHERS then
2949
2950 WF_CORE.Context('WF_ROLE_HIERARCHY', 'Denormalize_User_Role_RF',
2951 p_event.getEventName( ), p_sub_guid);
2952
2953 WF_EVENT.setErrorInfo(p_event, 'ERROR');
2954 return 'ERROR';
2955 end Denormalize_User_Role_RF;
2956
2957
2958
2959 ----
2960 ----
2961 -- validateSession()
2962 -- IN
2963 -- p_timeStamp DATE
2964 -- RETURNS
2965 -- BOOLEAN
2966 function validateSession (p_timeStamp in DATE) return boolean
2967 is
2968 l_updateTime DATE;
2969
2970 begin
2971 select to_date(text, WF_CORE.canonical_date_mask)
2972 into l_UpdateTime
2973 from WF_RESOURCES
2974 where TYPE='WFTKN'
2975 and NAME = 'WFDS_HIERARCHY_UPD'
2976 and LANGUAGE = 'US';
2977
2978 if ((p_timeStamp is NOT NULL) and (l_updateTime is NOT NULL) and
2979 (p_timeStamp = l_updateTime) and g_trustTimeStamp = l_updateTime) then
2980 return TRUE;
2981 else
2982 return FALSE;
2983 end if;
2984
2985 exception
2986 when NO_DATA_FOUND then
2987 return FALSE;
2988
2989 when others then
2990 raise;
2991
2992 end validateSession;
2993
2994
2995 ----
2996 ----
2997 -- createSession()
2998 -- RETURNS
2999 -- DATE
3000 function createSession return DATE
3001 is
3002 PRAGMA AUTONOMOUS_TRANSACTION;
3003
3004 begin
3005 g_trustTimeStamp := sysdate;
3006 update WF_RESOURCES
3007 set text = to_char(g_trustTimeStamp, WF_CORE.canonical_date_mask)
3008 where name = 'WFDS_HIERARCHY_UPD';
3009
3010 if (sql%rowcount = 0) then
3011 begin
3012 insert into WF_RESOURCES (TYPE,
3013 NAME,
3014 LANGUAGE,
3015 SOURCE_LANG,
3016 ID,
3017 TEXT,
3018 PROTECT_LEVEL,
3019 CUSTOM_LEVEL) values
3020 ('WFTKN',
3021 'WFDS_HIERARCHY_UPD',
3022 'US',
3023 'US',
3024 0,
3025 to_char(g_trustTimeStamp,
3026 WF_CORE.canonical_date_mask),
3027 0,
3028 0);
3029 exception
3030 when DUP_VAL_ON_INDEX then
3031 null;
3032
3033 when others then
3034 raise;
3035
3036 end;
3037 end if;
3038 commit;
3039 return g_trustTimeStamp;
3040
3041 end createSession;
3042
3043 ----
3044 ----
3045 -- removeRelationship()
3046 -- IN
3047 -- relationship_id NUMBER
3048 -- RETURNS
3049 -- BOOLEAN
3050 procedure removeRelationship (p_relationshipID in NUMBER,
3051 p_forceRemove in BOOLEAN
3052 )
3053 is
3054 l_enabled varchar2(1);
3055 l_relationshipID number;
3056 l_subName varchar2(320);
3057 l_superName varchar2(320);
3058 begin
3059
3060 --check the relationship status
3061
3062 select enabled_flag,sub_name,super_name
3063 into l_enabled, l_subName , l_superName
3064 from wf_role_hierarchies
3065 where relationship_id=p_relationshipID;
3066
3067 if (l_enabled='Y') then
3068 if (p_forceRemove is null or not p_forceRemove) then
3069 -- raise error
3070 wf_core.token('P_RELATIONSHIPID',p_relationshipID);
3071 wf_core.raise('WFDS_ACTIVE_RELN');
3072 else
3073 --call API to expire this remationship forcefully
3074 l_relationshipID:=ExpireRelationship(l_subName,l_superName);
3075
3076 --propagate the change to user role assignments
3077 propagate(l_relationshipID, SYSDATE);
3078 end if;
3079 end if;
3080
3081 --now remove the realtionship from the table
3082
3083 Delete from WF_ROLE_HIERARCHIES
3084 where relationship_id=p_relationshipID;
3085
3086
3087
3088 exception
3089 when others then
3090 raise;
3091
3092 end removeRelationship;
3093
3094 end WF_ROLE_HIERARCHY;