DBA Data[Home] [Help]

PACKAGE BODY: APPS.WF_ROLE_HIERARCHY

Source


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