1 package body WF_LOCAL_SYNCH as
2 /* $Header: WFLOCALB.pls 120.39.12020000.6 2013/03/24 12:32:41 skandepu ship $ */
3 ------------------------------------------------------------------------------
4 -- Global Private Variables
5
6 g_wf_schema VARCHAR2(320);
7 g_parallel NUMBER;
8 g_logging VARCHAR2(10);
9 g_BaseLanguage VARCHAR2(30) := 'AMERICAN';
10 g_BaseTerritory VARCHAR2(30) := 'AMERICA';
11 g_temptablespace VARCHAR2(30);
12 g_modulePkg varchar2(100) := 'wf.plsql.WF_LOCAL_SYNCH';
13 g_trustedRoles WF_DIRECTORY.roleTable;
14 g_trustTimeStamp DATE;
15
16 ------------------------------------------------------------------------------
17 -- Role variables
18 --
19 g_name VARCHAR2(320);
20 g_displayName VARCHAR2(360);
21 g_origSystem VARCHAR2(240);
22 g_origSystemID NUMBER;
23 g_parentOrigSys VARCHAR2(240);
24 g_parentOrigSysID NUMBER;
25 g_ownerTag VARCHAR2(50);
26 g_oldOrigSystemID NUMBER;
27 g_language VARCHAR2(30);
28 g_territory VARCHAR2(30);
29 g_description VARCHAR2(1000);
30 g_notificationPref VARCHAR2(8);
31 g_emailAddress VARCHAR2(320);
32 g_fax VARCHAR2(240);
33 g_status VARCHAR2(8);
34 g_employeeID NUMBER;
35 g_expDate DATE;
36 g_delete BOOLEAN;
37 g_updateOnly BOOLEAN;
38 g_raiseErrors BOOLEAN;
39 g_overWrite BOOLEAN;
40 g_overWrite_UserRoles BOOLEAN; -- <6817561> this exposes a switch to update
41 -- standard user/role table columns
42 g_oldName VARCHAR2(320);
43 g_ppID NUMBER;
44 g_lastUpdateDate DATE;
45 g_lastUpdatedBy NUMBER;
46 g_creationDate DATE;
47 g_createdBy NUMBER;
48 g_lastUpdateLogin NUMBER;
49 g_attributes WF_PARAMETER_LIST_T;
50 ------------------------------------------------------------------------------
51 /*
52 ** seedAttributes - <private>
53 **
54 ** This routine opens a parameter list and seeds role variables.
55 */
56 procedure seedAttributes (p_attributes in wf_parameter_list_t,
57 p_origSystem in VARCHAR2,
58 p_origSystemID in NUMBER,
59 p_expDate in DATE) is
60
61 l_sql VARCHAR2(2000);
62 l_modulePkg varchar2(240) := g_modulePkg||'.seedAttributes';
63
64 begin
65 -- Log only
66 -- BINDVAR_SCAN_IGNORE[5]
67 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
68 'Begin seedAttributes(p_attributes '||
69 '(wf_parameter_list_t), '||p_origSystem||', '||
70 to_char(p_origSystemID)||', '||
71 to_char(p_expDate, WF_CORE.canonical_date_mask)||')');
72
73 g_name := NULL;
74 g_displayName := NULL;
75 g_origSystem := NULL;
76 g_origSystemID := NULL;
77 g_parentOrigSys := NULL;
78 g_parentOrigSysID := NULL;
79 g_ownerTag := NULL;
80 g_language := NULL;
81 g_territory := NULL;
82 g_description := NULL;
83 g_notificationPref := NULL;
84 g_emailAddress := NULL;
85 g_fax := NULL;
86 g_employeeID := NULL;
87 g_status := NULL;
88 g_expDate := NULL;
89 g_delete := FALSE;
90 g_updateOnly := FALSE;
91 g_raiseErrors := FALSE;
92 g_overWrite := FALSE;
93 g_overWrite_UserRoles := FALSE; -- <6817561>
94 g_oldName := NULL;
95 g_ppID := NULL;
96 g_lastUpdateDate := sysdate;
97 g_lastUpdatedBy := WFA_SEC.user_id;
98 g_creationDate := sysdate;
99 g_createdBy := WFA_SEC.user_id;
100 g_lastUpdateLogin := WFA_SEC.login_id;
101 g_Attributes := wf_parameter_list_t();
102
103
104 FOR i in p_attributes.FIRST..p_attributes.LAST loop
105 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
106 'Processing parameter: '||p_attributes(i).getName());
107 begin
108 if (upper(p_attributes(i).getName()) = 'USER_NAME') then
109 g_name := p_attributes(i).getValue();
110
111 elsif (upper(p_attributes(i).getName()) = 'DISPLAYNAME') then
112 g_displayName := p_attributes(i).getValue();
113
114 elsif (upper(p_attributes(i).getName()) = 'ORCLWFORIGSYSTEM') then
115 g_origSystem := UPPER(p_attributes(i).getValue());
116
117 elsif (upper(p_attributes(i).getName()) = 'ORCLWFORIGSYSTEMID') then
118 g_origSystemID := to_number(p_attributes(i).getValue());
119
120 elsif (upper(p_attributes(i).getName()) = 'ORCLWFPARENTORIGSYS') then
121 g_parentOrigSys := p_attributes(i).getValue();
122
123 elsif (upper(p_attributes(i).getName()) = 'ORCLWFPARENTORIGSYSID') then
124 g_parentOrigSysID := to_number(p_attributes(i).getValue());
125
126 elsif (upper(p_attributes(i).getName()) = 'OWNER_TAG') then
127 g_ownerTag := p_attributes(i).getValue();
128
129 elsif (upper(p_attributes(i).getName()) = 'PREFERREDLANGUAGE') then
130 g_language := p_attributes(i).getValue();
131
132 elsif (upper(p_attributes(i).getName()) = 'ORCLNLSTERRITORY') then
133 g_territory := p_attributes(i).getValue();
134
135 elsif (upper(p_attributes(i).getName()) = 'DESCRIPTION') then
136 g_description := p_attributes(i).getValue();
137
138 elsif (upper(p_attributes(i).getName()) =
139 'ORCLWORKFLOWNOTIFICATIONPREF') then
140 g_notificationPref := upper(p_attributes(i).getValue());
141
142 elsif (upper(p_attributes(i).getName()) = 'MAIL') then
143 g_emailAddress := p_attributes(i).getValue();
144
145 elsif (upper(p_attributes(i).getName()) = 'FACSIMILETELEPHONENUMBER') then
146 g_fax := p_attributes(i).getValue();
147
148 elsif (upper(p_attributes(i).getName()) = 'ORCLISENABLED') then
149 g_status := p_attributes(i).getValue();
150
151 elsif (upper(p_attributes(i).getName()) = 'EXPIRATIONDATE') then
152 g_expDate := to_date(p_attributes(i).getValue(), WF_ENGINE.Date_Format);
153
154 elsif (upper(p_attributes(i).getName()) = 'PER_PERSON_ID') then
155 g_employeeID := p_attributes(i).getValue();
156
157 elsif (upper(p_attributes(i).getName()) = 'DELETE') then
158 if (upper(p_attributes(i).getValue()) = 'TRUE') then
159 g_delete := TRUE;
160 end if;
161
162 elsif (upper(p_attributes(i).getName()) = 'UPDATEONLY') then
163 if (upper(p_attributes(i).getValue()) = 'TRUE') then
164 g_updateOnly := TRUE;
165 end if;
166
167
168 elsif (upper(p_attributes(i).getName()) = 'RAISEERRORS') then
169 if (upper(p_attributes(i).getValue()) = 'TRUE') then
170 g_raiseErrors := TRUE;
171
172 end if;
173
174 elsif (upper(p_attributes(i).getName()) = 'WFSYNCH_OVERWRITE') then
175 if (upper(p_attributes(i).getValue()) = 'TRUE') then
176 g_overWrite := TRUE;
177 end if;
178
179 elsif (upper(p_attributes(i).getName()) = 'WFSYNCH_OVERWRITE_USERROLES') then
180 if (upper(p_attributes(i).getValue()) = 'TRUE') then
181 g_overWrite_UserRoles := true;
182 end if;
183
184 elsif (upper(p_attributes(i).getName()) = 'OLD_USER_NAME') then
185 g_oldName := p_attributes(i).getValue();
186
187 elsif (upper(p_attributes(i).getName()) = 'PERSON_PARTY_ID') then
188 g_ppID := to_number(p_attributes(i).getValue());
189
190 elsif (upper(p_attributes(i).getName()) = 'LAST_UPDATED_BY') then
191 g_lastUpdatedBy := to_number(p_attributes(i).getValue());
192
193 elsif (upper(p_attributes(i).getName()) = 'LAST_UPDATE_DATE') then
194 g_lastUpdateDate := to_date(p_attributes(i).getValue(),
195 WF_CORE.canonical_date_mask);
196
197 elsif (upper(p_attributes(i).getName()) = 'LAST_UPDATE_LOGIN') then
198 g_lastUpdateLogin := to_number(p_attributes(i).getValue());
199
200 elsif (upper(p_attributes(i).getName()) = 'CREATED_BY') then
201 g_createdBy := to_number(p_attributes(i).getValue());
202
203
204 elsif (upper(p_attributes(i).getName()) = 'CREATION_DATE') then
205 g_creationDate := to_date(p_attributes(i).getValue(),
206 WF_CORE.canonical_date_mask);
207
208 else
209 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
210 'Parameter: '||p_attributes(i).getName()||
211 'is ignored by seedAttributes.');
212
213 WF_EVENT.addParameterToList(upper(p_attributes(i).getName()),
214 p_attributes(i).getValue(),g_attributes);
215 end if;
216
217
218
219
220 exception
221 when OTHERS then
222 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED, l_modulePkg,
223 'Exception: '||sqlerrm||
224 ' continuing to retrieve attributes.');
225 null; --We need to attempt to get all attributes.
226
227 end;
228
229 end loop;
230
231 if (p_expDate is not NULL) then
232 --Explicit expiration date parameter will override attribute.
233 g_expDate := p_expDate;
234
235 end if;
236
237 --If the expiration date is now or earlier, then we will set inactive.
238 --The expirationdate attribute will override the delete attribute.
239
240 if (g_expDate is NOT NULL) then
241 if (g_expDate <= sysdate) then
242 g_status := 'INACTIVE';
243 end if;
244 g_delete := FALSE;
245 end if;
246
247
248 if ((g_delete) and (g_expDate is NULL)) then
249 --If delete=true then we will set inactive immediately. However if
250 --there is an expiration date, that will override the delete.
251 g_expDate := sysdate;
252 g_updateOnly := TRUE;
253 g_status := 'INACTIVE';
254
255 end if;
256
257 --p_origSystem and p_origSystemID will override attribute settings.
258 if (p_origSystem is NOT NULL) then
259 g_origSystem := p_origSystem;
260
261 end if;
262
263 if (p_origSystemID is NOT NULL) then
264 g_origSystemID := p_origSystemID;
265
266 end if;
267
268 if (g_ppID is NOT NULL) then
269 g_parentOrigSys := 'HZ_PARTY';
270 g_parentOrigSysID := g_ppID;
271
272 elsif ((g_parentOrigSys is NULL) or
273 (g_parentOrigSysID is NULL)) then
274 if g_employeeID is NOT NULL then -- PER users
275 g_parentOrigSys := 'PER';
276 g_parentOrigSysID := g_employeeID;
277 else
278 g_parentOrigSys := g_origSystem;
279 g_parentOrigSysID := g_origSystemID;
280 end if;
281
282 end if;
283
284 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
285 'End seedAttributes(p_attributes '||
286 '(wf_parameter_list_t), '||p_origSystem||', '||
287 to_char(p_origSystemID)||', '||
288 to_char(p_expDate, WF_CORE.canonical_date_mask)||')');
289
290 exception
291 when OTHERS then
292 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED, l_modulePkg,
293 'Exception: '||sqlerrm);
294 WF_CORE.Context('WF_LOCAL_SYNCH', 'seedAttributes', p_origSystem,
295 to_char(p_origSystemID), to_char(p_expDate,
296 WF_CORE.canonical_date_mask));
297 raise;
298
299
300 end;
301
302 ------------------------------------------------------------------------------
303 /*
304 ** wf_schema - <private>
305 **
306 */
307 function wf_schema return varchar2 is
308 begin
309 if (g_wf_schema is NULL) then
310 g_wf_schema := WF_CORE.Translate('WF_SCHEMA');
311 end if;
312
313 return g_wf_schema;
314
315 end;
316
317
318 ------------------------------------------------------------------------------
319 /*
320 ** update_entmgr - <private>
321 **
322 ** This routine encapsulates the bit that keeps entmgr in the loop
323 */
324 PROCEDURE update_entmgr(p_entity_type in varchar2,
325 p_entity_key_value in varchar2,
326 p_attributes in wf_parameter_list_t,
327 p_source in varchar2) is
328 i number;
329 l_modulePkg varchar2(240) := g_modulePkg||'.update_entmgr';
330
331 begin
332 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
333
334 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
335 'Begin update_entmgr('|| p_entity_type||', '||
336 p_entity_key_value||', '||
337 'p_attributes (wf_parameter_list_t)'||', '||
338 p_source||')');
339
340
341 end if;
342
343 if (p_attributes is not null) then
344 i := p_attributes.FIRST;
345 while (i <= p_attributes.LAST) loop
346 wf_entity_mgr.put_attribute_value(p_entity_type,
347 p_entity_key_value,
348 p_attributes(i).getName(),
349 p_attributes(i).getValue());
350 i := p_attributes.NEXT(i);
351 end loop;
352 wf_entity_mgr.process_changes(p_entity_type,
353 p_entity_key_value,
354 p_source);
355 end if;
356
357 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
358
359 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
360 'End update_entmgr('||p_entity_type||', '||
361 p_entity_key_value||', '||
362 'p_attributes(wf_parameter_list_t)'||', '||
363 p_source||')');
364
365 end if;
366
367
368
369 end;
370
371 ------------------------------------------------------------------------------
372 /*
373 ** Create_Stage_Indexes - <private>
374 **
375 ** This routine examines the base table provided and creates matching indexes
376 ** on the stage table.
377 */
378 PROCEDURE Create_Stage_Indexes (p_sourceTable in VARCHAR2,
379 p_targetTable in VARCHAR2) is
380
381 type OwnerList is table of varchar2(30);
382 type IndexList is table of varchar2(30);
383 type TableList is table of varchar2(30);
384 type IndTypList is table of varchar2(8);
385
386 l_owners OwnerList;
387 l_indexes IndexList;
388 l_tables TableList;
389 l_indtypes IndTypList;
390 l_modulePkg varchar2(240) := g_modulePkg||'.Create_Stage_Indexes';
391
392
393 CURSOR stageIndexes (tableOwner varchar2, tableName varchar2,
394 indexOwner varchar2) IS
395 SELECT di.OWNER,
396 di.index_name,
397 di.table_name,
398 decode(di.uniqueness, 'UNIQUE', ' UNIQUE ', ' ')
399 FROM dba_indexes di
400 WHERE di.table_owner = tableOwner
401 AND di.owner = indexOwner
402 AND di.table_name = tableName;
403
404 CURSOR stageIndParts (indexOwner varchar2, indexName varchar2) IS
405 SELECT dip.tablespace_name,
406 dip.ini_trans,
407 dip.max_trans,
408 dip.initial_extent,
409 dip.next_extent,
410 dip.min_extent,
411 dip.max_extent,
412 dip.pct_increase,
413 dip.pct_free,
414 dip.freelists,
415 dip.freelist_groups,
416 decode (dip.compression, 'ENABLED', 'COMPRESS', null) compression
417 FROM dba_ind_partitions dip
418 WHERE dip.index_owner = indexOwner
419 AND dip.index_name = indexName
420 AND dip.partition_name = 'WF_LOCAL_ROLES';
421
422 CURSOR indexColumns (indexOwner varchar2, indexName varchar2,
423 tableName varchar2) IS
424 SELECT column_name, column_position
425 FROM dba_ind_columns
426 WHERE index_owner = indexOwner
427 AND index_name = indexName
428 AND table_name = tableName
429 ORDER BY column_position;
430
431 ObjectExists EXCEPTION;
432 pragma exception_init(ObjectExists, -955);
433
434 l_columnList VARCHAR2(2000);
435 l_columnExpr VARCHAR2(2000);
436 l_sql VARCHAR2(4000);
437 l_newindex varchar2(80);
438 l_storage VARCHAR2(4000);
439
440 begin
441
442 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
443 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
444 l_modulePkg,
445 'Begin Create_Stage_Indexes('||p_sourceTable||', '||
446 p_targetTable||')');
447 end if;
448
449 --Bulding indexes on stage table as determined by the base table.
450 open stageIndexes(wf_schema, p_sourceTable, wf_schema);
451 fetch stageIndexes bulk collect into
452 l_owners, l_indexes, l_tables, l_indtypes;
453 close stageIndexes;
454
455 if (l_owners.COUNT > 0) then
456 for i in l_owners.FIRST..l_owners.LAST loop
457 for a in stageIndParts(l_owners(i), l_indexes(i)) loop
458 if (l_tables(i) = 'WF_USER_ROLE_ASSIGNMENTS') then
459 l_newindex := l_owners(i)||'.'||REPLACE(l_indexes(i),
460 'USER_ROLE_ASSIGNMENTS',
461 'UR_ASSIGNMENTS_STAGE');
462 else
463 l_newindex := l_owners(i)||'.'||REPLACE(l_indexes(i), 'ROLES',
464 'ROLES_STAGE');
465 end if;
466
467 l_sql := 'CREATE'||l_indtypes(i)||'INDEX '||l_newindex||' ON '||
468 wf_schema||'.'||p_targetTable||' (';
469
470 l_ColumnList := NULL; --Clear the column list.
471 for b in indexColumns (l_owners(i), l_indexes(i), l_tables(i)) loop
472 if (b.column_name like 'SYS_%') then --Functional index
473 select COLUMN_EXPRESSION
474 into l_ColumnExpr
475 from dba_ind_expressions
476 where INDEX_NAME = l_indexes(i)
477 and INDEX_OWNER = l_owners(i)
478 and COLUMN_POSITION = b.column_position;
479
480 l_ColumnList := l_ColumnList||REPLACE(l_ColumnExpr, '"', '')||', ';
481 else
482 l_ColumnList := l_ColumnList||b.column_name||', ';
483 end if;
484 end loop; --Column Loop
485 --Need to trim the last comma and close the column list.
486 l_columnList := rtrim(l_columnList, ', ');
487
488 l_sql := l_sql||l_columnList||')';
489
490 --Bug 2931877
491 --Add the tablespace detail if provided to the storage clause
492 if (g_temptablespace is not NULL) then
493 l_sql := l_sql||' TABLESPACE '||g_temptablespace||' ';
494 end if;
495
496 if (a.initial_extent is not null) then
497 l_storage := 'INITIAL '||to_char(a.initial_extent);
498 else
499 l_storage := '';
500 end if;
501
502 if (a.next_extent is not null) then
503 l_storage := l_storage||' NEXT '||to_char(a.next_extent);
504 end if;
505
506 if (a.min_extent is not null) then
507 l_storage := l_storage||' MINEXTENTS '||to_char(a.min_extent);
508 end if;
509
510 if (a.max_extent is not null) then
511 l_storage := l_storage||' MAXEXTENTS '||to_char(a.max_extent);
512 end if;
513
514 if (a.pct_increase is not null) then
515 l_storage := l_storage||' PCTINCREASE '||to_char(a.pct_increase);
516 end if;
517
518 if ((a.freelist_groups is not null) AND (a.freelists is not null)) then
519 l_storage :=l_storage||' FREELIST GROUPS '||to_char(a.freelist_groups);
520 l_storage :=l_storage||' FREELISTS '||to_char(a.freelists);
521 end if;
522
523 if (l_storage is not null) then
524 l_sql := l_sql||' STORAGE ('||l_storage||')';
525 end if;
526
527 if (a.pct_free is not null) then
528 l_sql := l_sql||' PCTFREE '||to_char(a.pct_free);
529 end if;
530
531 if (a.ini_trans is not null) then
532 l_sql := l_sql||' INITRANS '||to_char(a.ini_trans);
533 end if;
534
535 if (a.max_trans is not null) then
536 l_sql := l_sql||' MAXTRANS '||to_char(a.max_trans);
537 end if;
538
539 -- Bug 9193984. Compress the index if the base object is compressed.
540 l_sql := l_sql||' '||g_logging ||' PARALLEL '||to_char(g_parallel)||
541 ' COMPUTE STATISTICS '||a.compression;
542
543 begin
544 execute IMMEDIATE l_sql;
545
546 exception
547 when ObjectExists then
548 null;
549 end;
550
551 if ((g_logging = 'NOLOGGING') or (g_parallel > 1)) then
552 execute IMMEDIATE 'alter index '||l_newindex||' LOGGING NOPARALLEL';
553
554 end if;
555 end loop; -- IndParts (index partitions) Loop
556 end loop; --Index (l_owners index) Loop
557 end if; -- (l_owners.COUNT > 0);
558
559 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
560 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
561 l_modulePkg,
562 'End Create_Stage_Indexes('||p_sourceTable||', '||
563 p_targetTable||')');
564 end if;
565
566 exception
567 when OTHERS then
568
569 if (wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
570 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED, l_modulePkg,
571 'Exception: '||sqlerrm);
572
573 end if;
574
575
576 WF_CORE.Context('WF_LOCAL_SYNCH', 'Create_Stage_Indexes',
577 p_sourceTable, p_targetTable);
578 raise;
579
580 end;
581
582 ------------------------------------------------------------------------------
583 /*
584 ** BuildQuery - <private>
585 **
586 ** This routine dynamically builds a column and select list based on a
587 ** comparison of the stage table and the seeding view.
588 */
589 function BuildQuery (p_orig_system in VARCHAR2,
590 p_stage_table in VARCHAR2,
591 p_seed_view in VARCHAR2,
592 p_columnList in out NOCOPY VARCHAR2,
593 p_selectList in out NOCOPY VARCHAR2) return BOOLEAN is
594
595 l_seedCursor NUMBER;
596 l_seedViewDesc DBMS_SQL.DESC_TAB;
597 l_stageCursor NUMBER;
598 l_stageTableDesc DBMS_SQL.DESC_TAB;
599 l_rowCount NUMBER;
600 l_colCount PLS_INTEGER;
601 l_colExists BOOLEAN;
602 l_colName VARCHAR2(30);
603 l_partitionID NUMBER;
604 l_partitionName VARCHAR2(30);
605 l_sql VARCHAR2(2000);
606 l_modulePkg VARCHAR2(240) := g_modulePkg||'.BuildQuery';
607
608 stageIND PLS_INTEGER;
609 seedIND PLS_INTEGER;
610
611 noTable EXCEPTION;
612 pragma exception_init(noTable, -942);
613
614 begin
615 -- Log only
616 -- BINDVAR_SCAN_IGNORE[3]
617 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
618 'Begin BuildQuery('||p_orig_system||', '||p_stage_table||
619 ', '||p_seed_view||')');
620 --Prepend space to the lists.
621 p_columnList := ' ';
622 p_selectList := ' ';
623
624 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
625 'Obtaining the description of the stage table');
626 --First we will get a description of the staging table in its current form
627 --Open the Stage Cursor
628 l_stageCursor := DBMS_SQL.open_cursor;
629
630 --Select one row to get the description.
631 -- p_stage_table came from table wf_directory_partitions
632 -- also l_sql is not to be run, but to get the columns
633 -- BINDVAR_SCAN_IGNORE
634 l_sql := 'select * from '||p_stage_table||' where rownum < 2';
635 DBMS_SQL.parse(c=>l_stageCursor, statement=>l_sql,
636 language_flag=>DBMS_SQL.native);
637
638 --Obtain the column list
639 DBMS_SQL.describe_columns(l_stageCursor, l_colCount, l_stageTableDesc);
640
641 --Close the Stage Cursor
642 DBMS_SQL.close_cursor(l_stageCursor);
643
644 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
645 'Obtaining the description of the seeding view');
646 --Now we will get a description of the seeding view in its current form
647 --Open the Seed Cursor
648 l_seedCursor := DBMS_SQL.open_cursor;
649
650 --Select one row to get the description.
651 -- p_seed_view came from table wf_directory_partitions
652 -- also l_sql is not to be run, but to get the columns
653 -- BINDVAR_SCAN_IGNORE
654 l_sql := 'select * from '||p_seed_view||' where rownum < 2';
655 DBMS_SQL.parse(c=>l_seedCursor, statement=>l_sql,
656 language_flag=>DBMS_SQL.native);
657
658 --Obtain the column list
659 DBMS_SQL.describe_columns(l_seedCursor, l_colCount, l_seedViewDesc);
660
661 --Close the Stage Cursor
662 DBMS_SQL.close_cursor(l_seedCursor);
663
664 --Retrieve the partition id.
665 select PARTITION_ID, ORIG_SYSTEM
666 into l_partitionID, l_partitionName
667 from WF_DIRECTORY_PARTITIONS
668 where ORIG_SYSTEM = upper(p_orig_system);
669
670 --We now have two description tables that we can compare and build our
671 --column and select lists. We will also apply the special rules in this api
672 --that were in the calling apis.
673 --First, we can build the column list from the stage table description.
674 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
675 'Populating p_columnList');
676 for l_colCount in l_stageTableDesc.FIRST..l_stageTableDesc.LAST loop
677 p_columnList := p_columnList||l_stageTableDesc(l_colCount).COL_NAME||', ';
678 end loop;
679
680 --Now we will trim the last comma to end the column list.
681 p_columnList := rtrim(p_columnList, ', ');
682 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
683 'p_columnList is: ' ||p_columnList);
684
685 --Populating the select list is more involved. First we need to see if the
686 --seeding view populates the column, then we need to apply any business
687 --rules such as controlling the partition_id.
688 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
689 'Populating the select list...');
690 <<StageLoop>>
691 for stageIND in l_stageTableDesc.FIRST..l_stageTableDesc.LAST loop
692 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
693 'Determing if the seeding view provides column: '||
694
695 l_stageTableDesc(stageIND).COL_NAME);
696 l_colExists := FALSE;
697 <<SeedLoop>>
698 for seedIND in l_seedViewDesc.FIRST..l_seedViewDesc.LAST loop
699 if (l_seedViewDesc(seedIND).col_name =
700 l_stageTableDesc(stageIND).col_name) then
701 --Our current stage table column is provided by the view so it can be
702 --used in our select and insert.
703 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
704 'Column found, applying business rules.');
705 l_colExists := TRUE;
706 l_colName := l_seedViewDesc(seedIND).COL_NAME;
707 exit SeedLoop;
708 end if;
709 end loop SeedLoop;
710
711 --------------------------------------------------------------------------
712 --- Business Rules Processing | ---
713 ---------------------------------+ ---
714 --- For each column we need to consider the business rules we have ---
715 --- in place. These rules range from controlling the partition_id ---
716 --- to handling the situation where the column is not provided by ---
717 --- the seeding view. We do duplicate the nullable column rule ---
718 --- because we split the rules by tables to aid performance. ---
719 --------------------------------------------------------------------------
720 if NOT (l_colExists) then
721 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
722 'Seeding View does not provide column ['||
723 l_stageTableDesc(stageIND).COL_NAME||
724 '] applying business rules for missing column.');
725 end if;
726
727 if ((l_stageTableDesc(stageIND).COL_NAME = 'LANGUAGE') and
728 (p_stage_table <> 'WF_LOCAL_ROLES_TL_STAGE')) then
729 if (p_orig_system IN ('PER_ROLE', 'ENG_LIST', 'FND_RESP', 'GBX') OR
730 NOT l_colExists) then
731 p_selectList := (p_selectList||''''||g_BaseLanguage||''''||', ');
732 else
733 p_selectList := (p_selectList||
734 'nvl(LANGUAGE, '''||g_BaseLanguage||'''), ');
735 end if;
736
737 elsif (l_stageTableDesc(stageIND).COL_NAME = 'PARENT_ORIG_SYSTEM') then
738 if (NOT l_colExists) then
739 if (p_stage_table = 'WF_UR_ASSIGNMENTS_STAGE') then
740 p_selectList := (p_selectList||'ROLE_ORIG_SYSTEM, ');
741 else
742 p_selectList := (p_selectList||'ORIG_SYSTEM, ');
743 end if;
744 else
745 if (p_stage_table = 'WF_UR_ASSIGNMENTS_STAGE') then
746 p_selectList := (p_selectList||
747 'nvl(PARENT_ORIG_SYSTEM, ROLE_ORIG_SYSTEM), ');
748 else
749 p_selectList := (p_selectList||
750 'nvl(PARENT_ORIG_SYSTEM, ORIG_SYSTEM), ');
751 end if;
752 end if;
753
754 elsif (l_stageTableDesc(stageIND).COL_NAME =
755 'PARENT_ORIG_SYSTEM_ID') then
756 if (NOT l_colExists) then
757 if (p_stage_table = 'WF_UR_ASSIGNMENTS_STAGE') then
758 p_selectList := (p_selectList||'ROLE_ORIG_SYSTEM_ID, ');
759 else
760 p_selectList := (p_selectList||'ORIG_SYSTEM_ID, ');
761 end if;
762 else
763 if (p_stage_table = 'WF_UR_ASSIGNMENTS_STAGE') then
764 p_selectList := (p_selectList||
765 'nvl(PARENT_ORIG_SYSTEM_ID, ROLE_ORIG_SYSTEM_ID), ');
766 else
767 p_selectList := (p_selectList||
768 'nvl(PARENT_ORIG_SYSTEM_ID, ORIG_SYSTEM_ID), ');
769 end if;
770 end if;
771
772 elsif (l_stageTableDesc(stageIND).COL_NAME = 'TERRITORY') then
773 if (p_orig_system IN ('PER_ROLE', 'ENG_LIST', 'FND_RESP', 'GBX') OR
774 NOT l_colExists) then
775 p_selectList := (p_selectList||''''||g_BaseTerritory||''''||', ');
776 else
777 p_selectList := (p_selectList||
778 'nvl(TERRITORY, '''||g_BaseTerritory||'''), ');
779 end if;
780
781 elsif (l_stageTableDesc(stageIND).COL_NAME = 'USER_FLAG') then
782 if ((p_orig_system in ('FND_USR', 'HZ_PARTY') AND l_colExists)) then
783 p_selectList := (p_selectList||'USER_FLAG, ');
784 else
785 p_selectList := (p_selectList||'''N'', ');
786 end if;
787
788 elsif (l_stageTableDesc(stageIND).COL_NAME = 'PARTITION_ID') then
789 p_selectList := (p_selectList||''''||to_char(l_partitionID)||''', ');
790
791 elsif ((l_stageTableDesc(stageIND).COL_NAME = 'CREATED_BY') and
792 (NOT l_colExists)) then
793 p_selectList := (p_selectList||to_char(FND_GLOBAL.user_id)||', ');
794
795 elsif ((l_stageTableDesc(stageIND).COL_NAME = 'LAST_UPDATED_BY') and
796 (NOT l_colExists)) then
797 p_selectList := (p_selectList||to_char(FND_GLOBAL.user_id)||', ');
798
799 elsif ((l_stageTableDesc(stageIND).COL_NAME = 'LAST_UPDATE_LOGIN') and
800 (NOT l_colExists)) then
801 p_selectList := (p_selectList||to_char(FND_GLOBAL.login_id)||', ');
802
803 elsif ((l_stageTableDesc(stageIND).COL_NAME = 'LAST_UPDATE_DATE') and
804 (NOT l_colExists)) then
805 p_selectList := (p_selectList||'sysdate, ');
806
807 elsif ((l_stageTableDesc(stageIND).COL_NAME = 'CREATION_DATE') and
808 (NOT l_colExists)) then
809 p_selectList := (p_selectList||'sysdate, ');
810
811 elsif ((l_stageTableDesc(stageIND).COL_NAME = 'RELATIONSHIP_ID') and
812 (NOT l_colExists)) then
813 p_selectList := (p_selectList||'-1, ');
814
815 elsif ((l_stageTableDesc(stageIND).COL_NAME = 'ASSIGNING_ROLE') and
816 (NOT l_colExists)) then
817 p_selectList := (p_selectList||'ROLE_NAME, ');
818
819 elsif ((l_stageTableDesc(stageIND).COL_NAME = 'END_DATE') and
820 (NOT l_colExists)) then
821 p_selectList := (p_selectList||'EXPIRATION_DATE, ');
822
823 -------------------------------------------
824 -- Final Business Rules that take effect --
825 -- only if none of the rules above were --
826 -- triggered. --
827 -------------------------------------------
828 elsif (NOT l_colExists) then
829 if (l_stageTableDesc(stageIND).COL_NULL_OK) then
830 p_selectList := (p_selectList||'NULL, ');
831 else
832 WF_CORE.Token('COLNAME', l_stageTableDesc(stageIND).COL_NAME);
833 WF_CORE.Token('VIEWNAME', p_seed_view);
834 WF_CORE.Token('STAGETABLE', p_stage_table);
835 WF_CORE.Raise('WFDS_SEED_COLUMN');
836 end if;
837
838 else
839 p_selectList := (p_selectList||l_colName||', ');
840 end if;
841
842
843
844
845 end loop StageLoop;
846 --Now we will trim the last comma to end the select list.
847 p_selectList := rtrim(p_selectList, ', ');
848 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
849 'p_select list is: '||p_selectList);
850 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
851 'End BuildQuery('||p_orig_system||', '||p_stage_table||
852 ', '||p_seed_view||') [Returning True]');
853 return TRUE;
854 exception
855 when NoTable then
856 if (substr(p_seed_view, 1, 3) = 'WF_') then
857 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
858 'End BuildQuery('||p_orig_system||', '||p_stage_table||
859 ', '||p_seed_view||') [Returning False]');
860 return FALSE;
861
862 else
863 WF_CORE.Token('VIEWNAME', p_seed_view);
864 WF_CORE.Token('PARTITION_NAME', p_orig_system);
865 WF_CORE.Raise('WFDS_BSYNC_VIEW');
866 end if;
867 end;
868
869 /*
870 ** propagate_user - <described in WFLOCALS.pls>
871 */
872 PROCEDURE propagate_user(p_orig_system in varchar2,
873 p_orig_system_id in number,
874 p_attributes in wf_parameter_list_t,
875 p_start_date in date,
876 p_expiration_date in date) is
877
878 cursor linked_per_users is
879 select user_name from fnd_user
880 where employee_id = p_orig_system_id;
881
882 cursor linked_tca_users is
883 select user_name from fnd_user
884 where customer_id = p_orig_system_id;
885
886 cursor fnd_users is
887 select user_name from fnd_user
888 where user_id = p_orig_system_id;
889
890 l_partitionID NUMBER;
891 l_partitionName varchar2(30);
892 l_oldOrigSystemID NUMBER;
893 l_status VARCHAR2(8);
894
895 l_params WF_PARAMETER_LIST_T;
896 l_overWrite varchar2(2) :='N';
897 l_overWrite_UserRoles varchar2(2) :='N';
898 l_oldLastUpdDate date;
899 l_oldLastUpdLogin number;
900 l_oldLastUpdBy number;
901 l_auxLastUpdDate date;
902 l_auxLastUpdLogin number;
903 l_auxLastUpdBy number;
904 l_modulePkg varchar2(240) := g_modulePkg||'.propagate_user';
905 p_aux_start_date date;
906 p_aux_exp_date date;
907
908 BEGIN
909
910 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
911 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
912 l_modulePkg,
913 'Begin propagate_user('||p_orig_system||', '||
914 p_orig_system_id||','||
915 'p_attributes(wf_parameter_list_t)'||','||
916 to_char(p_start_date,WF_CORE.canonical_date_mask)||','||
917 to_char(p_expiration_date,WF_CORE.canonical_date_mask)||')');
918 end if;
919
920 seedAttributes(p_attributes,
921 p_orig_system,
922 p_orig_system_id,
923 p_expiration_date);
924
925 if (g_overWrite) then -- <6817561>
926 l_overWrite :='Y';
927 end if;
928 if (g_overWrite_UserRoles) then -- <6817561>
929 l_overWrite_UserRoles := 'Y';
930 end if;
931 --
932 -- tell entmgr if linked to an FND user
933 --
934 if (p_orig_system = 'FND_USR') then
935 for myuser in fnd_users loop
936 wf_local_synch.update_entmgr('USER',
937 myuser.user_name,
938 p_attributes,
939 p_orig_system);
940 end loop;
941 elsif (p_orig_system = 'PER') then
942 for myuser in linked_per_users loop
943 wf_local_synch.update_entmgr('USER',
944 myuser.user_name,
945 p_attributes,
946 p_orig_system);
947 end loop;
948 elsif (p_orig_system = 'HZ_PARTY') then
949 for myuser in linked_tca_users loop
950 wf_local_synch.update_entmgr('USER',
951 myuser.user_name,
952 p_attributes,
953 p_orig_system);
954 end loop;
955 end if;
956
957 if ( g_oldName is NOT NULL) then
958 WF_DIRECTORY.assignPartition(p_orig_system, l_partitionID,
959 l_partitionName);
960 --We inline update the role and direct user/role then raise the event so
961 --the rest of the work can be deferred.
962 if (l_partitionID = 1) then
963
964 UPDATE WF_LOCAL_ROLES
965 SET NAME = g_name
966 -- <6817561>
967 , LAST_UPDATE_DATE = decode(l_overWrite, 'Y', nvl(g_lastUpdateDate, LAST_UPDATE_DATE), LAST_UPDATE_DATE),
968 LAST_UPDATED_BY = decode(l_overWrite, 'Y', nvl(g_lastUpdatedBy, LAST_UPDATED_BY), LAST_UPDATED_BY),
969 LAST_UPDATE_LOGIN = decode(l_overWrite, 'Y', nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN), LAST_UPDATE_LOGIN)
970 -- , CREATED_BY = decode(l_overWrite, 'Y', nvl(g_createdBy, CREATED_BY), CREATED_BY)
971 -- , CREATION_DATE = decode(l_overWrite, 'Y', nvl(g_creationDate, CREATION_DATE), CREATION_DATE)
972 -- </6817561>
973 WHERE NAME = g_oldName
974 AND PARTITION_ID = l_partitionID;
975 else
976 UPDATE WF_LOCAL_ROLES
977 SET NAME = g_name
978 -- <6817561>
979 , LAST_UPDATE_DATE = decode(l_overWrite, 'Y', nvl(g_lastUpdateDate, LAST_UPDATE_DATE), LAST_UPDATE_DATE),
980 LAST_UPDATED_BY = decode(l_overWrite, 'Y', nvl(g_lastUpdatedBy, LAST_UPDATED_BY), LAST_UPDATED_BY),
981 LAST_UPDATE_LOGIN = decode(l_overWrite, 'Y', nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN), LAST_UPDATE_LOGIN)
982 -- , CREATED_BY = decode(l_overWrite, 'Y', nvl(g_createdBy, CREATED_BY), CREATED_BY)
983 -- , CREATION_DATE = decode(l_overWrite, 'Y', nvl(g_creationDate, CREATION_DATE), CREATION_DATE)
984 -- </6817561>
985 WHERE NAME = g_oldName
986 AND PARTITION_ID = l_partitionID
987 AND ORIG_SYSTEM = p_orig_system
988 AND ORIG_SYSTEM_ID = p_orig_system_id;
989 end if;
990 --Update the user reference to itself if there is one.
991 UPDATE WF_LOCAL_USER_ROLES
992 SET USER_NAME = g_name,
993 ROLE_NAME = g_name
994 -- <6817561>
995 , LAST_UPDATE_DATE = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateDate, LAST_UPDATE_DATE), LAST_UPDATE_DATE),
996 LAST_UPDATED_BY = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdatedBy, LAST_UPDATED_BY), LAST_UPDATED_BY),
997 LAST_UPDATE_LOGIN = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN), LAST_UPDATE_LOGIN)
998 -- , CREATED_BY = decode(l_overWrite_UserRoles,'Y', nvl(g_createdBy, CREATED_BY), CREATED_BY)
999 -- , CREATION_DATE = decode(l_overWrite_UserRoles,'Y', nvl(g_creationDate, CREATION_DATE), CREATION_DATE)
1000 -- </6817561>
1001 WHERE USER_NAME = g_oldName
1002 AND ROLE_NAME = g_oldName
1003 AND PARTITION_ID = l_partitionID;
1004
1005
1006 --Update the user/roles
1007 UPDATE WF_LOCAL_USER_ROLES
1008 SET USER_NAME = g_Name
1009 -- <6817561>
1010 , LAST_UPDATE_DATE = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateDate, LAST_UPDATE_DATE), LAST_UPDATE_DATE),
1011 LAST_UPDATED_BY = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdatedBy, LAST_UPDATED_BY), LAST_UPDATED_BY),
1012 LAST_UPDATE_LOGIN = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN), LAST_UPDATE_LOGIN)
1013 -- , CREATED_BY = decode(l_overWrite_UserRoles,'Y', nvl(g_createdBy, CREATED_BY), CREATED_BY)
1014 -- , CREATION_DATE = decode(l_overWrite_UserRoles,'Y', nvl(g_creationDate, CREATION_DATE), CREATION_DATE)
1015 -- </6817561>
1016 WHERE USER_NAME = g_oldName;
1017
1018 --Update the user/role assignments
1019
1020 UPDATE WF_USER_ROLE_ASSIGNMENTS
1021 SET USER_NAME=g_name,
1022 ROLE_NAME=g_name,
1023 ASSIGNING_ROLE=g_name
1024 -- <6817561>
1025 , LAST_UPDATE_DATE = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateDate, LAST_UPDATE_DATE), LAST_UPDATE_DATE),
1026 LAST_UPDATED_BY = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdatedBy, LAST_UPDATED_BY), LAST_UPDATED_BY),
1027 LAST_UPDATE_LOGIN = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN), LAST_UPDATE_LOGIN)
1028 -- , CREATED_BY = decode(l_overWrite_UserRoles,'Y', nvl(g_createdBy, CREATED_BY), CREATED_BY)
1029 -- , CREATION_DATE = decode(l_overWrite_UserRoles,'Y', nvl(g_creationDate, CREATION_DATE), CREATION_DATE)
1030 -- </6817561>
1031 WHERE ASSIGNING_ROLE=g_oldName
1032 AND USER_NAME=g_oldName
1033 AND RELATIONSHIP_ID=-1
1034 AND PARTITION_ID=l_partitionId;
1035
1036 UPDATE WF_USER_ROLE_ASSIGNMENTS
1037 SET USER_NAME = g_Name
1038 -- <6817561>
1039 , LAST_UPDATE_DATE = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateDate, LAST_UPDATE_DATE), LAST_UPDATE_DATE),
1040 LAST_UPDATED_BY = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdatedBy, LAST_UPDATED_BY), LAST_UPDATED_BY),
1041 LAST_UPDATE_LOGIN = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN), LAST_UPDATE_LOGIN)
1042 -- , CREATED_BY = decode(l_overWrite_UserRoles,'Y', nvl(g_createdBy, CREATED_BY), CREATED_BY)
1043 -- , CREATION_DATE = decode(l_overWrite_UserRoles,'Y', nvl(g_creationDate, CREATION_DATE), CREATION_DATE)
1044 -- </6817561>
1045 WHERE USER_NAME = g_oldName;
1046
1047
1048
1049 WF_EVENT.AddParameterToList('OLD_USER_NAME', g_oldName, l_params);
1050 WF_EVENT.AddParameterToList('USER_NAME', g_name, l_params);
1051 WF_EVENT.AddParameterToList('ORIG_SYSTEM',p_orig_system,l_params);
1052 WF_EVENT.AddParameterToList('ORIG_SYSTEM_ID',to_char(p_orig_system_id),l_params);
1053 if(g_attributes.count>0) then
1054 for i in g_attributes.first..g_attributes.last loop
1055 WF_EVENT.AddParameterToList(upper(g_attributes(i).getName()),
1056 g_attributes(i).getValue(),l_params);
1057 end loop;
1058 end if;
1059 WF_EVENT.Raise(p_event_name=>'oracle.apps.fnd.wf.ds.user.nameChanged',
1060 p_event_key=>'NameChanged:'||p_orig_system||':'||
1061 to_char(p_orig_system_id)||'|'||
1062 to_char(SYSDATE, wf_core.canonical_date_mask) ,
1063 p_parameters=>l_params);
1064 end if;
1065
1066 -- If the calling orig_system is 'FND_USR' and g_employeeID is not null, we
1067 -- need to check for one of two situations.
1068 --
1069 -- First, a new FND_USER might be created with the association to an employee
1070 -- in the same transaction.
1071 --
1072 -- Second, an FND_USER might be updated to be associated with the employee.
1073 --
1074 -- If there is an employee id, fnd_usr is required to populate the
1075 -- employeeID attribute for every call to WF_LOCAL_SYNCH.
1076 --
1077 -- If there is no employee associated, then employeeID is null.
1078 -- The same will hold true for a dis-association, so we will
1079 -- always need to check for that.
1080 --Case 1: There is an employee ID.
1081 if ((p_orig_system = 'FND_USR') and
1082 (g_employeeID is not NULL)) then
1083 --FND_USR is propagating an employee association.
1084 --Update the Orig_system and Orig_system id for a PER record.
1085 g_origSystem := 'PER';
1086 g_origSystemID := g_employeeID;
1087
1088 --We first need to make sure that the employee id was not merely changed
1089 --Such as user SYSADMIN associated to employee 1, is now associated to
1090 --employee 2. The way we can detect this is to check for a PER role that
1091 --has the same username, but a different origSystemID.
1092 --Attempt to delete any other employee that might be still associated
1093 --to this user. Then we will proceed to update/create the user. Finally
1094 --we will reassign any user/roles from the previous 'PER' role to the
1095 --new 'PER' role.
1096 DELETE from WF_LOCAL_ROLES PARTITION (FND_USR) WR
1097 WHERE WR.ORIG_SYSTEM = 'PER'
1098 AND WR.NAME = g_name
1099 AND WR.ORIG_SYSTEM_ID <> g_employeeID
1100 Returning WR.ORIG_SYSTEM_ID , last_update_date, last_update_login, last_updated_by
1101 into l_oldOrigSystemID, l_oldLastUpdDate, l_oldLastUpdLogin, l_oldLastUpdBy -- <6817561>
1102 ;
1103
1104 begin
1105 Select WR.EMAIL_ADDRESS, WR.DISPLAY_NAME, WR.DESCRIPTION,
1106 WR.STATUS
1107 into g_emailAddress, g_displayName, g_description, g_status
1108 From WF_LOCAL_ROLES PARTITION (PER_ROLE) WR
1109 Where WR.ORIG_SYSTEM = 'PER_ROLE'
1110 And WR.ORIG_SYSTEM_ID = g_employeeID;
1111 exception
1112 when NO_DATA_FOUND then
1113 --The PER_ROLE does not yet exist so we will just use the data provided
1114 --by FND until the HR data is propagated.
1115 null;
1116 end;
1117
1118 begin
1119 WF_DIRECTORY.SetUserAttr( user_name=>g_name,
1120 orig_system=>g_origSystem,
1121 orig_system_id=>g_origSystemID,
1122 display_name=>g_displayName,
1123 description=>g_description,
1124 notification_preference=>g_notificationPref,
1125 language=>g_language,
1126 territory=>g_territory,
1127 email_address=>g_emailAddress,
1128 fax=>g_fax,
1129 expiration_date=>g_expDate,
1130 status=>g_status,
1131 start_date=>p_start_date,
1132 overWrite=>g_overWrite,
1133 parent_orig_system=>g_parentOrigSys,
1134 parent_orig_system_id=>g_parentOrigSysID,
1135 owner_tag=>g_ownerTag,
1136 last_updated_by=>g_lastUpdatedBy,
1137 last_update_login=>g_lastUpdateLogin,
1138 last_update_date=>g_lastUpdateDate,
1139 eventParams=>g_attributes);
1140
1141 exception
1142 when OTHERS then
1143 if (WF_CORE.error_name = 'WF_INVALID_USER') then
1144 WF_CORE.Clear;
1145 if NOT (g_delete) then --No reason to create a deleted user.
1146 l_status := nvl(g_status,'ACTIVE');
1147
1148 -- <6817561>
1149 if (not g_overWrite) then
1150 -- a potential problem here is that after processing (user create),
1151 -- Last_update_date < creation_date for the created user. This is
1152 -- just a consequence of the g_overWrite flag value
1153 l_auxLastUpdDate := l_oldLastUpdDate;
1154 l_auxLastUpdLogin := l_oldLastUpdLogin;
1155 l_auxLastUpdBy:= l_oldLastUpdBy;
1156 else
1157 l_auxLastUpdDate := g_lastUpdateDate;
1158 l_auxLastUpdLogin := g_lastUpdateLogin;
1159 l_auxLastUpdBy:= g_lastUpdatedBy;
1160 end if; -- </6817561>
1161 -- <Bug 8337430>. Save the current role dates for later creation
1162 select decode(l_overWrite, 'Y', nvl(g_expDate, p_expiration_date), WR.EXPIRATION_DATE),
1163 nvl(p_start_date, WR.START_DATE)
1164 into p_aux_exp_date, p_aux_start_date
1165 from WF_LOCAL_ROLES PARTITION (PER_ROLE) WR
1166 where WR.ORIG_SYSTEM_ID = g_employeeID;
1167 WF_DIRECTORY.CreateUser( name=>g_name,
1168 display_name=>g_displayName,
1169 orig_system=>g_origSystem,
1170 orig_system_id=>g_origSystemID,
1171 language=>g_language,
1172 territory=>g_territory,
1173 description=>g_description,
1174 notification_preference=>g_notificationPref,
1175 email_address=>g_emailAddress,
1176 fax=>g_fax,
1177 status=>g_status,
1178 expiration_date=>p_aux_exp_date,
1179 start_date=>p_aux_start_date,
1180 parent_orig_system=>g_parentOrigSys,
1181 parent_orig_system_id=>g_parentOrigSysID,
1182 owner_tag=>g_ownerTag,
1183 created_by=>g_createdBy,
1184 last_updated_by=>l_auxLastUpdBy,
1185 last_update_login=>l_auxLastUpdLogin,
1186 creation_date=>g_creationDate,
1187 last_update_date=>l_auxLastUpdDate);
1188 end if;
1189 else
1190 raise;
1191 end if;
1192 end;
1193
1194 -- We will attempt to delete an FND_USR row, if there is one to
1195 -- delete then we will need to re-associate any user_roles as well.
1196
1197 if (g_employeeID is NOT NULL) then
1198 Delete from WF_LOCAL_ROLES PARTITION (FND_USR) WR
1199 Where WR.ORIG_SYSTEM = p_orig_system
1200 And WR.ORIG_SYSTEM_ID = p_orig_system_id
1201 returning last_update_date, last_update_login, last_updated_by
1202 into l_oldLastUpdDate, l_oldLastUpdLogin, l_oldLastUpdBy -- <6817561>
1203 ;
1204
1205 end if;
1206
1207 if (sql%rowcount > 0) then
1208 -- If we were able to delete an fnd_user from wf_local_roles then
1209 -- We can change any wf_local_user_roles over to PER.
1210
1211 -- We will now reassign all active user/role relationships.
1212 WF_DIRECTORY.ReassignUserRoles(g_name, p_orig_system,
1213 p_orig_system_id, g_origSystem,
1214 g_origSystemID, g_lastUpdateDate,
1215 g_lastUpdatedBy, g_lastUpdateLogin
1216 , g_overWrite_UserRoles -- <6817561>
1217 );
1218
1219 -- <6817561> case when we need to keep the std WHO columns old values
1220 if (not g_overWrite) then
1221
1222 update wf_local_roles
1223 set last_update_date = l_oldLastUpdDate,
1224 last_updated_by = l_oldLastUpdBy,
1225 last_update_login = l_oldLastUpdLogin
1226 where name = g_name
1227 and orig_system = g_origSystem
1228 and orig_system_id = g_origSystemID;
1229
1230 end if; -- </6817561>
1231 elsif (g_overWrite_UserRoles) then -- <6817561> needed to update std WHO columns
1232
1233 update wf_local_user_roles
1234 set last_update_date = nvl(g_lastUpdateDate,last_update_date),
1235 last_updated_by = nvl(g_lastUpdatedBy, last_updated_by),
1236 last_update_login = nvl(g_lastUpdateLogin, last_update_login)
1237 where user_name = g_name
1238 and user_orig_system=g_origSystem
1239 and user_orig_system_id= g_origSystemID;
1240
1241 update wf_user_role_assignments
1242 set last_update_date = nvl(g_lastUpdateDate,last_update_date),
1243 last_updated_by = nvl(g_lastUpdatedBy, last_updated_by),
1244 last_update_login = nvl(g_lastUpdateLogin, last_update_login)
1245 where user_name = g_name
1246 and user_orig_system=g_origSystem
1247 and user_orig_system_id= g_origSystemID; -- </6817561>
1248
1249 end if;
1250
1251 --We now need to reassign any userRoles that may be associated to
1252 --an old PER role (This occurs in the case of an FND_USR being
1253 --switched from one employee to another).
1254 if (l_oldOrigSystemID is NOT NULL) then
1255 -- First, we must expire the existing User/Role relationship
1256 -- from the user to itself.
1257 /* WF_DIRECTORY.ReassignUserRoles was updated to handle the
1258 self-references
1259 begin
1260 WF_DIRECTORY.SetUserRoleAttr(user_name=>g_name,
1261 role_name=>g_name,
1262 start_date=>to_date(NULL),
1263 end_date=>sysdate,
1264 user_orig_system=>'PER',
1265 user_orig_system_id=>l_oldOrigSystemID,
1266 role_orig_system=>'PER',
1267 role_orig_system_id=>l_oldOrigSystemID,
1268 OverWrite=>FALSE,
1269 last_updated_by=>g_lastUpdatedBy,
1270 last_update_login=>g_lastUpdateLogin,
1271 last_update_date=>g_lastUpdateDate);
1272 exception
1273 when OTHERS then
1274 if (WF_CORE.error_name = 'WF_INVAL_USER_ROLE') then
1275 null; --Nothing to expire
1276 else
1277 raise;
1278 end if;
1279 end;
1280 */
1281 -- Now we can reassign any active user/role relationships.
1282 WF_DIRECTORY.ReassignUserRoles(g_name, g_origSystem,
1283 l_oldOrigSystemID, g_origSystem,
1284 g_origSystemID, g_lastUpdateDate,
1285 g_lastUpdatedBy, g_lastUpdateLogin
1286 , g_overWrite_UserRoles -- <6817561>
1287 );
1288 end if;
1289
1290 elsif ((p_orig_system = 'FND_USR') and (g_employeeID is NULL)) then
1291 -- FND_USR is either propagating a user who is not associated with
1292 -- an employee or is dis-associating one. We will check to see if a
1293 --dis-association has just occured, the PER record will still exist.
1294 Delete from WF_LOCAL_ROLES PARTITION (FND_USR) WR
1295 Where WR.ORIG_SYSTEM = 'PER'
1296 And WR.NAME = g_name
1297 Returning WR.ORIG_SYSTEM_ID, last_update_date, last_update_login, last_updated_by
1298 into g_employeeID, l_oldLastUpdDate, l_oldLastUpdLogin, l_oldLastUpdBy; -- <6817561>
1299
1300 if (sql%rowcount > 0) then
1301 l_status := nvl(g_status,'ACTIVE');
1302
1303 -- <6817561>
1304 if (not g_overWrite) then
1305 -- again, maybe last_update_date < creation_date after processing
1306 l_auxLastUpdDate := l_oldLastUpdDate;
1307 l_auxLastUpdLogin := l_oldLastUpdLogin;
1308 l_auxLastUpdBy:= l_oldLastUpdBy;
1309 else
1310 l_auxLastUpdDate := g_lastUpdateDate;
1311 l_auxLastUpdLogin := g_lastUpdateLogin;
1312 l_auxLastUpdBy:= g_lastUpdatedBy;
1313 end if; -- </6817561>
1314
1315 WF_DIRECTORY.CreateUser( name=>g_name,
1316 display_name=>g_displayName,
1317 orig_system=>g_origSystem,
1318 orig_system_id=>g_origSystemID,
1319 language=>g_language,
1320 territory=>g_territory,
1321 description=>g_description,
1322 notification_preference=>g_notificationPref,
1323 email_address=>g_emailAddress,
1324 fax=>g_fax,
1325 status=>l_status,
1326 expiration_date=>g_expDate,
1327 start_date=>p_start_date,
1328 parent_orig_system=>g_parentOrigSys,
1329 parent_orig_system_id=>g_parentOrigSysID,
1330 owner_tag=>g_ownerTag,
1331 created_by=>g_createdBy,
1332 last_updated_by=>l_auxLastUpdBy,
1333 last_update_login=>l_auxLastUpdLogin,
1334 creation_date=>g_creationDate,
1335 last_update_date=>l_auxLastUpdDate);
1336
1337 -- Expire the old user/role relationship with itself.
1338 /* WF_DIRECTORY.ReassignUserRoles was updated to handle the
1339 self-references
1340 begin
1341 WF_DIRECTORY.SetUserRoleAttr(user_name=>g_name,
1342 role_name=>g_name,
1343 end_date=>sysdate,
1344 user_orig_system=>'PER',
1345 user_orig_system_id=>g_employeeID,
1346 role_orig_system=>'PER',
1347 role_orig_system_id=>g_employeeID,
1348 OverWrite=>FALSE,
1349 last_updated_by=>g_lastUpdatedBy,
1350 last_update_login=>g_lastUpdateLogin,
1351 last_update_date=>g_lastUpdateDate);
1352 exception
1353 when OTHERS then
1354 if (WF_CORE.error_name = 'WF_INVAL_USER_ROLE') then
1355 null; --Nothing to expire
1356 else
1357 raise;
1358 end if;
1359 end;
1360 */
1361 -- Now we need to update all of the user_roles back to the fnd_user.
1362 WF_DIRECTORY.ReassignUserRoles(g_name, 'PER', g_employeeID,
1363 p_orig_system, p_orig_system_id,
1364 g_lastUpdateDate, g_lastUpdatedBy,
1365 g_lastUpdateLogin
1366 , g_overWrite_UserRoles -- <6817561>
1367 );
1368
1369 else
1370 --FND_USER is propagating a user that is not associated with an employee.
1371 g_origSystem := p_orig_system;
1372 g_origSystemID := p_orig_system_id;
1373
1374 begin
1375 WF_DIRECTORY.SetUserAttr( user_name=>g_name,
1376 orig_system=>g_origSystem,
1377 orig_system_id=>g_origSystemID,
1378 display_name=>g_displayName,
1379 description=>g_description,
1380 notification_preference=>g_notificationPref,
1381 language=>g_language,
1382 territory=>g_territory,
1383 email_address=>g_emailAddress,
1384 fax=>g_fax,
1385 expiration_date=>g_expDate,
1386 status=>g_status,
1387 overWrite=>g_overWrite,
1388 start_date=>p_start_date,
1389 parent_orig_system=>g_parentOrigSys,
1390 parent_orig_system_id=>g_parentOrigSysID,
1391 owner_tag=>g_ownerTag,
1392 last_updated_by=>g_lastUpdatedBy,
1393 last_update_login=>g_lastUpdateLogin,
1394 last_update_date=>g_lastUpdateDate,
1395 eventParams=>g_attributes);
1396
1397 exception
1398 when OTHERS then
1399 if (WF_CORE.error_name = 'WF_INVALID_USER') then
1400 WF_CORE.Clear;
1401 if NOT (g_delete) then
1402 l_status := nvl(g_status,'ACTIVE');
1403
1404 WF_DIRECTORY.CreateUser( name=>g_name,
1405 display_name=>g_displayName,
1406 orig_system=>g_origSystem,
1407 orig_system_id=>g_origSystemID,
1408 language=>g_language,
1409 territory=>g_territory,
1410 description=>g_description,
1411 notification_preference=>
1412 g_notificationPref,
1413 email_address=>g_emailAddress,
1414 fax=>g_fax,
1415 status=>l_status,
1416 expiration_date=>g_expDate,
1417 start_date=>p_start_date,
1418 parent_orig_system=>g_parentOrigSys,
1419 parent_orig_system_id=>g_parentOrigSysID,
1420 owner_tag=>g_ownerTag,
1421 created_by=>g_createdBy,
1422 last_updated_by=>g_lastUpdatedBy,
1423 last_update_login=>g_lastUpdateLogin,
1424 creation_date=>g_creationDate,
1425 last_update_date=>g_lastUpdateDate );
1426
1427 end if;
1428 else
1429 raise;
1430
1431 end if;
1432 end;
1433
1434 -- <6817561>
1435 if (g_overWrite_UserRoles) then
1436 update wf_local_user_roles
1437 set last_update_date = nvl(g_lastUpdateDate,last_update_date),
1438 last_updated_by = nvl(g_lastUpdatedBy, last_updated_by),
1439 last_update_login = nvl(g_lastUpdateLogin, last_update_login)
1440 where user_name = g_name
1441 and user_orig_system=g_origSystem
1442 and user_orig_system_id= g_origSystemID;
1443
1444 update wf_user_role_assignments
1445 set last_update_date = nvl(g_lastUpdateDate,last_update_date),
1446 last_updated_by = nvl(g_lastUpdatedBy, last_updated_by),
1447 last_update_login = nvl(g_lastUpdateLogin, last_update_login)
1448 where user_name = g_name
1449 and user_orig_system=g_origSystem
1450 and user_orig_system_id= g_origSystemID;
1451 end if;
1452 -- </6817561>
1453 end if;
1454 elsif (p_orig_system = 'HZ_PARTY') then --<rwunderl:2729190> HZ_PARTY
1455 g_origSystem := p_orig_system; --persons are now users.
1456 g_origSystemID := p_orig_system_id;
1457
1458 begin
1459 WF_DIRECTORY.SetUserAttr( user_name=>g_name,
1460 orig_system=>g_origSystem,
1461 orig_system_id=>g_origSystemID,
1462 display_name=>g_displayName,
1463 description=>g_description,
1464 notification_preference=>g_notificationPref,
1465 language=>g_language,
1466 territory=>g_territory,
1467 email_address=>g_emailAddress,
1468 fax=>g_fax,
1469 expiration_date=>g_expDate,
1470 status=>g_status,
1471 overWrite=>g_overWrite,
1472 start_date=>p_start_date,
1473 parent_orig_system=>g_parentOrigSys,
1474 parent_orig_system_id=>g_parentOrigSysID,
1475 owner_tag=>g_ownerTag,
1476 last_updated_by=>g_lastUpdatedBy,
1477 last_update_login=>g_lastUpdateLogin,
1478 last_update_date=>g_lastUpdateDate,
1479 eventParams=>g_attributes );
1480
1481 exception
1482 when OTHERS then
1483 if (WF_CORE.error_name = 'WF_INVALID_USER') then
1484 WF_CORE.Clear;
1485 if NOT (g_delete) then
1486 l_status := nvl(g_status,'ACTIVE');
1487
1488 WF_DIRECTORY.CreateUser( name=>g_name,
1489 display_name=>g_displayName,
1490 orig_system=>g_origSystem,
1491 orig_system_id=>g_origSystemID,
1492 language=>g_language,
1493 territory=>g_territory,
1494 description=>g_description,
1495 notification_preference=>
1496 g_notificationPref,
1497 email_address=>g_emailAddress,
1498 fax=>g_fax,
1499 status=>l_status,
1500 expiration_date=>g_expDate,
1501 start_date=>p_start_date,
1502 parent_orig_system=>g_parentOrigSys,
1503 parent_orig_system_id=>g_parentOrigSysID,
1504 owner_tag=>g_ownerTag,
1505 created_by=>g_createdBy,
1506 last_updated_by=>g_lastUpdatedBy,
1507 last_update_login=>g_lastUpdateLogin,
1508 creation_date=>g_creationDate,
1509 last_update_date=>g_lastUpdateDate );
1510
1511 end if;
1512 else
1513 raise;
1514 end if;
1515 end;
1516
1517 else --Only FND_USR, and HZ_PARTY can propagate users.
1518 g_origSystem := p_orig_system;
1519 g_origSystemID := p_orig_system_id;
1520
1521 if NOT (g_delete) then
1522 --Bug 3064439
1523 propagate_role(p_orig_system, p_orig_system_id, p_attributes,
1524 p_start_date, p_expiration_date);
1525
1526 end if;
1527 end if;
1528
1529 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
1530 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
1531 l_modulePkg,
1532 'End propagate_user('||p_orig_system||', '||
1533 p_orig_system_id||','||
1534 'p_attributes(wf_parameter_list_t)'||','||
1535 to_char(p_start_date,WF_CORE.canonical_date_mask)||','||
1536 to_char(p_expiration_date,WF_CORE.canonical_date_mask)||')');
1537
1538 end if;
1539
1540
1541 exception
1542 when OTHERS then
1543 if (wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
1544 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED, l_modulePkg,
1545 'Exception: '||sqlerrm);
1546
1547 end if;
1548
1549 if (g_raiseErrors) then
1550
1551 WF_CORE.Context('WF_LOCAL_SYNCH', 'Propagate_User',
1552 p_orig_system, p_orig_system_id);
1553 raise;
1554
1555 else
1556 null;
1557
1558 end if;
1559
1560 end;
1561
1562 ------------------------------------------------------------------------------
1563 /*
1564 ** propagate_role - <described in WFLOCALS.pls>
1565 */
1566 PROCEDURE propagate_role(p_orig_system in varchar2,
1567 p_orig_system_id in number,
1568 p_attributes in wf_parameter_list_t,
1569 p_start_date in date,
1570 p_expiration_date in date) is
1571 l_status VARCHAR2(8);
1572 l_partitionName VARCHAR2(30);
1573 l_partitionID NUMBER;
1574 l_overWrite_UserRoles varchar2(2) :='N';
1575 l_overWrite varchar2(2) :='N';
1576 l_modulePkg varchar2(240) := g_modulePkg||'.propagate_role';
1577
1578
1579 CURSOR perRoles (c_orig_system in VARCHAR2, c_orig_system_id in NUMBER) is
1580 SELECT WR.NAME, WR.NOTIFICATION_PREFERENCE, WR.LANGUAGE, WR.TERRITORY,
1581 WR.FAX, WR.START_DATE, WR.EXPIRATION_DATE
1582 FROM WF_LOCAL_ROLES PARTITION (FND_USR) WR
1583 WHERE ORIG_SYSTEM = c_orig_system
1584 AND ORIG_SYSTEM_ID = c_orig_system_id;
1585
1586 begin
1587
1588 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
1589 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
1590 l_modulePkg,
1591 'Begin propagate_role('||p_orig_system||', '||
1592 p_orig_system_id||','||
1593 'p_attributes(wf_parameter_list_t)'||','||
1594 to_char(p_start_date,WF_CORE.canonical_date_mask)||','||
1595 to_char(p_expiration_date,WF_CORE.canonical_date_mask)||')');
1596
1597 end if;
1598
1599 if (g_overWrite) then
1600 l_overWrite :='Y';
1601 end if;
1602
1603 seedAttributes(p_attributes,
1604 p_orig_system,
1605 p_orig_system_id,
1606 p_expiration_date);
1607
1608 --First check to see if a name change was communicated.
1609 if ( g_oldName is NOT NULL) then
1610 WF_DIRECTORY.assignPartition(p_orig_system, l_partitionID,
1611 l_partitionName);
1612
1613 if (g_overWrite_UserRoles) then -- <6817561>
1614 l_overWrite_UserRoles := 'Y';
1615 end if;
1616
1617 --We will use the partition id where we can to improve performance.
1618 UPDATE WF_LOCAL_ROLES
1619 SET NAME = g_name
1620 WHERE NAME = g_oldName
1621 AND PARTITION_ID = l_partitionID
1622 AND ORIG_SYSTEM = p_orig_system
1623 AND ORIG_SYSTEM_ID = p_orig_system_id;
1624
1625 UPDATE WF_LOCAL_USER_ROLES
1626 SET ROLE_NAME = g_name
1627 -- <6817561>
1628 , LAST_UPDATE_DATE = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateDate, LAST_UPDATE_DATE), LAST_UPDATE_DATE),
1629 LAST_UPDATED_BY = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdatedBy, LAST_UPDATED_BY), LAST_UPDATED_BY),
1630 LAST_UPDATE_LOGIN = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN), LAST_UPDATE_LOGIN)
1631 -- </6817561>
1632 WHERE ROLE_NAME = g_oldName
1633 AND ROLE_ORIG_SYSTEM = p_orig_system
1634 AND ROLE_ORIG_SYSTEM_ID = p_orig_system_id
1635 AND PARTITION_ID = l_partitionID;
1636
1637 UPDATE WF_USER_ROLE_ASSIGNMENTS
1638 SET ASSIGNING_ROLE = g_name
1639 -- <6817561>
1640 , LAST_UPDATE_DATE = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateDate, LAST_UPDATE_DATE), LAST_UPDATE_DATE),
1641 LAST_UPDATED_BY = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdatedBy, LAST_UPDATED_BY), LAST_UPDATED_BY),
1642 LAST_UPDATE_LOGIN = decode(l_overWrite_UserRoles,'Y', nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN), LAST_UPDATE_LOGIN)
1643 -- </6817561>
1644 WHERE ASSIGNING_ROLE = g_oldName
1645 AND PARTITION_ID = l_partitionID;
1646
1647 --These tables are not partitioned, but do have fk references and may later
1648 --be partitioned on one of these partition ids so we are specifying the
1649 --partition id here.
1650 UPDATE WF_ROLE_HIERARCHIES
1651 SET SUB_NAME = g_name
1652 WHERE SUB_NAME = g_oldName
1653 AND PARTITION_ID = l_partitionID;
1654
1655 UPDATE WF_ROLE_HIERARCHIES
1656 SET SUPER_NAME = g_name
1657 WHERE SUPER_NAME = g_oldName
1658 AND SUPERIOR_PARTITION_ID = l_partitionID;
1659
1660 --These statements cannot take advantage of the partitions.
1661 UPDATE WF_USER_ROLE_ASSIGNMENTS
1662 SET ROLE_NAME = g_name
1663 WHERE ROLE_NAME = g_oldName;
1664
1665 WF_MAINTENANCE.PropagateChangedName(OLDNAME=>g_oldName, NEWNAME=>g_name);
1666 elsif (g_overWrite_UserRoles) then -- <6817561>
1667 WF_DIRECTORY.assignPartition(p_orig_system, l_partitionID,
1668 l_partitionName);
1669
1670 --We will use the partition id where we can to improve performance.
1671 UPDATE WF_LOCAL_USER_ROLES
1672 SET
1673 LAST_UPDATE_DATE = nvl(g_lastUpdateDate, LAST_UPDATE_DATE),
1674 LAST_UPDATED_BY = nvl(g_lastUpdatedBy, LAST_UPDATED_BY),
1675 LAST_UPDATE_LOGIN = nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN)
1676 WHERE ROLE_NAME = g_name
1677 AND ROLE_ORIG_SYSTEM = p_orig_system
1678 AND ROLE_ORIG_SYSTEM_ID = p_orig_system_id
1679 AND PARTITION_ID = l_partitionID;
1680
1681 UPDATE WF_USER_ROLE_ASSIGNMENTS
1682 SET
1683 LAST_UPDATE_DATE = nvl(g_lastUpdateDate, LAST_UPDATE_DATE),
1684 LAST_UPDATED_BY = nvl(g_lastUpdatedBy, LAST_UPDATED_BY),
1685 LAST_UPDATE_LOGIN = nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN)
1686 WHERE ROLE_NAME = g_name
1687 AND ROLE_ORIG_SYSTEM = p_orig_system
1688 AND ROLE_ORIG_SYSTEM_ID = p_orig_system_id
1689 AND PARTITION_ID = l_partitionID;
1690 -- </6817561>
1691
1692 end if;
1693
1694 --Due to the association between employees and users, we have special
1695 --handling for calls coming from 'PER'. If 'PER' is inserting a new
1696 --record (creating an employee), it cannot be associated with a user
1697 --since the FND User form is responsible for that. So we will create
1698 --a 'PER_ROLE' to designate an employee that is not associated with a user.
1699 --
1700 --However, if the employee is already associated with a user, then this would
1701 --be an update call. We need to preserve the NOTIFICATION_PREFERENCE,
1702 --LANGUAGE, and TERRITORY since they were defined by FND_USR. All other
1703 --information can be changed by 'PER'
1704 if (p_orig_system = 'PER') then
1705 --If more than one FND_USR was assigned to the same employee
1706 --(user ignored warnings) then we may have multiple rows, so we use a
1707 --cursor to handle a one or many situation. If there are no PER rows,
1708 --this portion of the code will naturally not execute.
1709
1710 -- Bug 8337430. Validate the new employeeID is valid... then
1711 if (g_employeeID is not null) then
1712 update WF_LOCAL_ROLES
1713 set ORIG_SYSTEM_ID=g_employeeID
1714 where ORIG_SYSTEM_ID=p_orig_system_id
1715 and ORIG_SYSTEM=p_orig_system;
1716
1717 -- update the self-references in URA and LUR
1718 -- For self reference we just need to make sure to use the same 'who' caolumn values
1719 -- of wf_local_user_roles
1720 --if (g_overWrite or g_overWrite_UserRoles) then
1721 update WF_LOCAL_USER_ROLES
1722 set ROLE_ORIG_SYSTEM_ID = g_employeeID,
1723 USER_ORIG_SYSTEM_ID = g_employeeID,
1724 LAST_UPDATE_DATE = decode(l_overWrite,'Y', nvl(g_lastUpdateDate, LAST_UPDATE_DATE), LAST_UPDATE_DATE),
1725 LAST_UPDATED_BY = decode(l_overWrite,'Y', nvl(g_lastUpdatedBy, LAST_UPDATED_BY), LAST_UPDATED_BY),
1726 LAST_UPDATE_LOGIN = decode(l_overWrite,'Y', nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN), LAST_UPDATE_LOGIN)
1727 where USER_ORIG_SYSTEM_ID = p_orig_system_id
1728 and USER_ORIG_SYSTEM = p_orig_system
1729 and ROLE_ORIG_SYSTEM_ID = p_orig_system_id
1730 and ROLE_ORIG_SYSTEM = p_orig_system;
1731
1732 update WF_USER_ROLE_ASSIGNMENTS
1733 set ROLE_ORIG_SYSTEM_ID = g_employeeID,
1734 USER_ORIG_SYSTEM_ID = g_employeeID,
1735 LAST_UPDATE_DATE = decode(l_overWrite,'Y', nvl(g_lastUpdateDate, LAST_UPDATE_DATE), LAST_UPDATE_DATE),
1736 LAST_UPDATED_BY = decode(l_overWrite,'Y', nvl(g_lastUpdatedBy, LAST_UPDATED_BY), LAST_UPDATED_BY),
1737 LAST_UPDATE_LOGIN = decode(l_overWrite,'Y', nvl(g_lastUpdateLogin, LAST_UPDATE_LOGIN), LAST_UPDATE_LOGIN)
1738 where USER_ORIG_SYSTEM_ID = p_orig_system_id
1739 and USER_ORIG_SYSTEM = p_orig_system
1740 and ROLE_ORIG_SYSTEM_ID = p_orig_system_id
1741 and ROLE_ORIG_SYSTEM = p_orig_system;
1742 -- LUR and URA's 'who' columns are to be the same as those of wf_local_roles.
1743
1744 end if;
1745 for perRole in perRoles(p_orig_system, p_orig_system_id) loop
1746
1747 -- A 'PER' record exists (this employee is associated to at least one
1748 -- user). We preserved the NOTIFICATION_PREFERENCE, LANGUAGE and
1749 -- TERRITORY. Now we will set the origSystem and the origSystemID.
1750 -- We also can setg_updateOnly, because we know the record(s) exist(s).
1751
1752 WF_DIRECTORY.SetUserAttr( user_name=>perRole.NAME,
1753 orig_system=>g_origSystem,
1754 orig_system_id=>g_origSystemID,
1755 display_name=>g_displayName,
1756 description=>g_description,
1757 notification_preference=>
1758 perRole.NOTIFICATION_PREFERENCE,
1759 language=>perRole.LANGUAGE,
1760 territory=>perRole.TERRITORY,
1761 email_address=>g_emailAddress,
1762 fax=>perRole.FAX,
1763 expiration_date=>perRole.EXPIRATION_DATE,
1764 status=>g_status,
1765 overWrite=>g_overWrite,
1766 start_date=>perRole.START_DATE,
1767 parent_orig_system=>g_parentOrigSys,
1768 parent_orig_system_id=>g_parentOrigSysID,
1769 owner_tag=>g_ownerTag,
1770 last_updated_by=>g_lastUpdatedBy,
1771 last_update_login=>g_lastUpdateLogin,
1772 last_update_date=>g_lastUpdateDate );
1773 --Since we founde one or more PER records we can set the g_updateOnly flag
1774 --to true
1775 g_updateOnly := TRUE;
1776 end loop;
1777
1778 -- No matter what the result of the above attempt to update a PER record we
1779 -- still need to update or create the 'PER_ROLE' record.
1780
1781 g_origSystem := 'PER_ROLE';
1782 g_origSystemID := p_orig_system_id;
1783 g_name := g_origSystem||':'||g_origSystemID;
1784
1785 end if;
1786
1787 if (g_updateOnly) then
1788 begin
1789 WF_DIRECTORY.SetRoleAttr( role_name=>g_name,
1790 orig_system=>g_origSystem,
1791 orig_system_id=>g_origSystemID,
1792 display_name=>g_displayName,
1793 description=>g_description,
1794 notification_preference=>g_notificationPref,
1795 language=>g_language,
1796 territory=>g_territory,
1797 email_address=>g_emailAddress,
1798 fax=>g_fax,
1799 expiration_date=>g_expDate,
1800 status=>g_status,
1801 overWrite=>g_overWrite,
1802 start_date=>p_start_date,
1803 parent_orig_system=>g_parentOrigSys,
1804 parent_orig_system_id=>g_parentOrigSysID,
1805 owner_tag=>g_ownerTag,
1806 last_updated_by=>g_lastUpdatedBy,
1807 last_update_login=>g_lastUpdateLogin,
1808 last_update_date=>g_lastUpdateDate );
1809
1810 exception
1811 when OTHERS then
1812 if (WF_CORE.error_name = 'WF_INVALID_ROLE') then
1813 WF_CORE.Clear;
1814 g_updateOnly := FALSE;
1815
1816 else
1817 raise;
1818
1819 end if;
1820
1821 end;
1822 end if;
1823
1824 if ((NOT g_delete) AND (NOT g_updateOnly)) then
1825 begin
1826 l_status := nvl(g_status,'ACTIVE');
1827 WF_DIRECTORY.CreateRole( role_name=>g_name,
1828 role_display_name=>g_displayName,
1829 orig_system=>g_origSystem,
1830 orig_system_id=>g_origSystemID,
1831 language=>g_language,
1832 territory=>g_territory,
1833 role_description=>g_description,
1834 notification_preference=>g_notificationPref,
1835 email_address=>g_emailAddress,
1836 fax=>g_fax,
1837 status=>l_status,
1838 expiration_date=>g_expDate,
1839 start_date=>p_start_date,
1840 parent_orig_system=>g_parentOrigSys,
1841 parent_orig_system_id=>g_parentOrigSysID,
1842 owner_tag=>g_ownerTag,
1843 created_by=>g_createdBy,
1844 last_updated_by=>g_lastUpdatedBy,
1845 last_update_login=>g_lastUpdateLogin,
1846 creation_date=>g_creationDate,
1847 last_update_date=>g_lastUpdateDate );
1848
1849 --Add this role to the cache of newly created roles.
1850 if (g_trustedRoles.COUNT = 0) then
1851 -- Call CreateSession from WF_ROLE_HIERARCHY.AddRelationship
1852 -- instead of here
1853 -- g_trustTimeStamp := WF_ROLE_HIERARCHY.CreateSession;
1854 g_trustedRoles(0) := g_name;
1855 else
1856 g_trustedRoles(g_trustedRoles.LAST + 1) := g_name;
1857 end if;
1858
1859 exception
1860 when OTHERS then
1861 if (WF_CORE.error_name = 'WF_DUP_ROLE') then
1862 WF_CORE.Clear;
1863 --Bug 3064439
1864 --We let the wf_directory take care of nulls
1865 --We just do update no new value other than the one passed.
1866 WF_DIRECTORY.SetRoleAttr( role_name=>g_name,
1867 orig_system=>g_origSystem,
1868 orig_system_id=>g_origSystemID,
1869 display_name=>g_displayName,
1870 description=>g_description,
1871 notification_preference=>g_notificationPref,
1872 language=>g_language,
1873 territory=>g_territory,
1874 email_address=>g_emailAddress,
1875 fax=>g_fax,
1876 expiration_date=>g_expDate,
1877 status=>g_status,
1878 overWrite=>g_overWrite,
1879 start_date=>p_start_date,
1880 parent_orig_system=>g_parentOrigSys,
1881 parent_orig_system_id=>g_parentOrigSysID,
1882 owner_tag=>g_ownerTag,
1883 last_updated_by=>g_lastUpdatedBy,
1884 last_update_login=>g_lastUpdateLogin,
1885 last_update_date=>g_lastUpdateDate,
1886 eventParams=>g_attributes );
1887
1888 else
1889 raise;
1890
1891 end if;
1892 end;
1893 end if;
1894 if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
1895 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE,
1896 l_modulePkg,
1897 'End propagate_role('||p_orig_system||', '||
1898 p_orig_system_id||','||
1899 'p_attributes(wf_parameter_list_t)'||','||
1900 to_char(p_start_date,WF_CORE.canonical_date_mask)||','||
1901 to_char(p_expiration_date,WF_CORE.canonical_date_mask)||')');
1902
1903 end if;
1904
1905 exception
1906 when OTHERS then
1907 if (wf_log_pkg.level_unexpected >= fnd_log.g_current_runtime_level) then
1908 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_UNEXPECTED,l_modulePkg,
1909 'Exception: '||sqlerrm);
1910
1911 end if;
1912
1913 if (g_raiseErrors) then
1914
1915 WF_CORE.Context('WF_LOCAL_SYNCH', 'Propagate_Role',
1916 p_orig_system, p_orig_system_id);
1917 raise;
1918
1919 else
1920 null;
1921
1922 end if;
1923
1924 end;
1925
1926
1927 ------------------------------------------------------------------------------
1928 /*
1929 ** propagate_user_role - (DEPRECATED) use propagateUserRole()
1930 --Bug 2756776
1931 --Added the p_overwrite IN parameter to allow the user to reset the
1932 --nullable columns . In other propagate APIs we pass this parameter
1933 --in the attribute list.
1934
1935 --Bug 2716191
1936 --Added the p_raiseErrors IN parameter to allow the exception
1937 --to be thrown to the caller. In other propagate APIs we pass this
1938 --parameter in the attribute list.
1939 **
1940 */
1941
1942 PROCEDURE propagate_user_role(p_user_orig_system in varchar2,
1943 p_user_orig_system_id in number,
1944 p_role_orig_system in varchar2,
1945 p_role_orig_system_id in number,
1946 p_start_date in date,
1947 p_expiration_date in date,
1948 p_overwrite in boolean,
1949 p_raiseErrors in boolean ) is
1950 l_roleName varchar2(320);
1951 l_userName varchar2(320);
1952 l_origSystem varchar2(30);
1953 l_origSystemID number;
1954
1955 begin
1956
1957 SELECT name INTO l_roleName
1958 FROM wf_roles
1959 WHERE orig_system = p_role_orig_system
1960 AND orig_system_id = p_role_orig_system_id;
1961
1962 begin
1963 SELECT name INTO l_userName
1964 FROM wf_roles
1965 WHERE orig_system = p_user_orig_system
1966 AND orig_system_id = p_user_orig_system_id;
1967
1968 l_origSystem := p_user_orig_system;
1969 l_origSystemID := p_user_orig_system_id;
1970 exception
1971 when NO_DATA_FOUND then
1972 if (p_user_orig_system = 'FND_USR') then --Check for possible PER
1973 SELECT user_name, employee_id, 'PER'
1974 INTO l_userName, l_origSystemID, l_origSystem
1975 FROM FND_USER
1976 WHERE USER_ID = p_user_orig_system_id;
1977 end if;
1978 end;
1979
1980 begin
1981 WF_LOCAL_SYNCH.propagateUserRole(p_user_name=>l_userName,
1982 p_role_name=>l_roleName,
1983 p_user_orig_system=>l_origSystem,
1984 p_user_orig_system_id=>l_origSystemID,
1985 p_role_orig_system=>Propagate_user_role.p_role_orig_system,
1986 p_role_orig_system_id=>Propagate_user_role.p_role_orig_system_id,
1987 p_start_date=>Propagate_user_role.p_start_date,
1988 p_expiration_date=>Propagate_user_role.p_expiration_date,
1989 p_overwrite=>Propagate_user_role.p_overwrite,
1990 p_raiseErrors=>Propagate_user_role.p_raiseErrors);
1991 end;
1992
1993 exception
1994 when OTHERS then
1995 if (p_raiseErrors) then
1996 WF_CORE.Context('WF_LOCAL_SYNCH', 'Propagate_User_Role',
1997 p_user_orig_system, p_user_orig_system_id,
1998 p_role_orig_system, p_role_orig_system_id);
1999 raise;
2000
2001 else
2002 null;
2003
2004 end if;
2005
2006 end;
2007
2008 ------------------------------------------------------------------------------
2009 /*
2010 ** propagateUserRole - Synchronizes the WF_LOCAL_USER_ROLES table.
2011 */
2012 PROCEDURE propagateUserRole(p_user_name in varchar2,
2013 p_role_name in varchar2,
2014 p_user_orig_system in varchar2,
2015 p_user_orig_system_id in number,
2016 p_role_orig_system in varchar2,
2017 p_role_orig_system_id in number,
2018 p_start_date in date,
2019 p_expiration_date in date,
2020 p_overwrite in boolean,
2021 p_raiseErrors in boolean,
2022 p_parent_orig_system in varchar2,
2023 p_parent_orig_system_id in varchar2,
2024 p_ownerTag in varchar2,
2025 p_createdBy in number,
2026 p_lastUpdatedBy in number,
2027 p_lastUpdateLogin in number,
2028 p_creationDate in date,
2029 p_lastUpdateDate in date,
2030 p_assignmentReason in varchar2,
2031 p_UpdateWho in boolean,
2032 p_attributes in WF_PARAMETER_LIST_T)
2033 is
2034 l_uorigSys VARCHAR2(30);
2035 l_uorigSysID NUMBER;
2036 l_rorigSys VARCHAR2(30);
2037 l_rorigSysID NUMBER;
2038
2039
2040 begin
2041 --Need to check if the orig_system info is null.
2042 if ((p_user_orig_system is NULL) or (p_user_orig_system_id is NULL) or
2043 (p_role_orig_system is NULL) or (p_role_orig_system_id is NULL)) then
2044 WF_DIRECTORY.GetRoleOrigSysInfo(p_user_name, l_uorigSys, l_uorigSysID);
2045 WF_DIRECTORY.GetRoleOrigSysInfo(p_role_name, l_rorigSys, l_rorigSysID);
2046
2047 else
2048 l_uorigSys := UPPER(p_user_orig_system);
2049 l_uorigSysID := UPPER(p_user_orig_system_id);
2050 l_rorigSys := UPPER(p_role_orig_system);
2051 l_rorigSysID := UPPER(p_role_orig_system_id);
2052
2053 end if;
2054
2055
2056 WF_DIRECTORY.SetUserRoleAttr(user_name=>p_user_name,
2057 role_name=>p_role_name,
2058 start_date=>p_start_date,
2059 end_date=>p_expiration_date,
2060 user_orig_system=>l_uorigSys,
2061 user_orig_system_id=>l_uorigSysID,
2062 role_orig_system=>l_rorigSys,
2063 role_orig_system_id=>l_rorigSysID,
2064 overWrite=>p_overwrite,
2065 parent_orig_system=>p_parent_orig_system,
2066 parent_orig_system_id=>p_parent_orig_system_ID,
2067 owner_tag=>p_ownerTag,
2068 created_by=>p_createdBy,
2069 creation_date=>p_creationDate,
2070 last_updated_by=>p_lastUpdatedBy,
2071 last_update_login=>p_lastUpdateLogin,
2072 last_update_date=>p_lastUpdateDate,
2073 assignment_reason=>p_assignmentReason,
2074 updateWho=>p_UpdateWho,
2075 eventParams=>p_attributes);
2076
2077
2078 exception
2079 when OTHERS then
2080 if (WF_CORE.error_name = 'WF_INVAL_USER_ROLE') then
2081 WF_CORE.Clear;
2082 WF_DIRECTORY.CreateUserRole(user_name=>p_user_name,
2083 role_name=>p_role_name,
2084 start_date=>p_start_date,
2085 end_date=>p_expiration_date,
2086 user_orig_system=>l_uorigSys,
2087 user_orig_system_id=>l_uorigSysID,
2088 role_orig_system=>l_rorigSys,
2089 role_orig_system_id=>l_rorigSysID,
2090 parent_orig_system=>p_parent_orig_system,
2091 parent_orig_system_id=>p_parent_orig_system_ID,
2092 owner_tag=>p_ownerTag,
2093 created_by=>p_createdBy,
2094 last_updated_by=>p_lastUpdatedBy,
2095 last_update_login=>p_lastUpdateLogin,
2096 creation_date=>p_creationDate,
2097 last_update_date=>p_lastUpdateDate,
2098 assignment_reason=>p_assignmentReason,
2099 eventParams=>p_attributes );
2100
2101 else
2102 raise;
2103
2104 end if;
2105 end;
2106
2107 ------------------------------------------------------------------------------
2108 /*
2109 ** syncUsers - <private>
2110 */
2111 PROCEDURE syncUsers(p_orig_system in varchar2)
2112 is
2113 begin
2114 null; --This is obsoleted for syncRoles
2115 end;
2116
2117 ------------------------------------------------------------------------------
2118 /*
2119 ** syncRolesTL - <private>
2120 ** Pass the partition_id and roletlview so as to avoid
2121 ** additional queries we have already done in SyncRolesTL
2122 */
2123 PROCEDURE syncRolesTL(p_orig_system in varchar2,
2124 p_partitionID in number,
2125 p_partitionName in varchar2,
2126 p_roletlview in varchar2)
2127 is
2128
2129 CURSOR dbaIndexes(tabName varchar2,
2130 tabOwner varchar2) is
2131 SELECT INDEX_NAME
2132 FROM DBA_INDEXES
2133 WHERE TABLE_NAME = tabName
2134 AND TABLE_OWNER = tabOwner;
2135
2136
2137 l_sql VARCHAR2(2000);
2138 l_selectList VARCHAR2(1000);
2139 l_columnList VARCHAR2(1000);
2140 l_storageClause VARCHAR2(2000);
2141 l_importSuccess BOOLEAN;
2142 l_modulePkg VARCHAR2(240) := g_modulePkg||'.syncRolesTL';
2143
2144 begin
2145 -- Log only
2146 -- BINDVAR_SCAN_IGNORE[3]
2147 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
2148 'Begin syncRolesTL('||p_orig_system||', '|| p_partitionid||
2149 ', '||p_partitionName||', '||p_roleTLView||')');
2150
2151 --Truncate the temp table.
2152 WF_DDL.TruncateTable(TableName=>'WF_LOCAL_ROLES_TL_STAGE',
2153 Owner=>wf_schema);
2154
2155 --Drop indexes from the temp table.
2156 for c in dbaIndexes('WF_LOCAL_ROLES_TL_STAGE', wf_schema) loop
2157 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2158 'Dropping index '||c.INDEX_NAME);
2159 WF_DDL.DropIndex(IndexName=>c.INDEX_NAME,
2160 Owner=>wf_schema,
2161 IgnoreNotFound=>TRUE);
2162
2163 end loop;
2164
2165 --Enable parallel DML
2166 execute IMMEDIATE 'alter session enable parallel dml';
2167
2168 --Alter the session to set the sort_area_size and hash_area_size.
2169 execute IMMEDIATE 'alter session set sort_area_size=104857600';
2170 execute IMMEDIATE 'alter session set hash_area_size=204857600';
2171
2172 begin
2173 --Select the data from WF_<origSystem>_ROLES_TL and insert into
2174 --WF_LOCAL_ROLES_TL_STAGE.
2175
2176 if (BuildQuery (p_orig_system=>syncRolesTL.p_orig_system,
2177 p_stage_table=>'WF_LOCAL_ROLES_TL_STAGE',
2178 p_seed_view=>syncRolesTL.p_roletlview,
2179 p_columnList=>l_columnList,
2180 p_selectList=>l_selectList)) then
2181 -- l_selectList is controlled by us
2182 -- g_parallel must not be varchar
2183 -- p_roletlview came from wf_directory_partitions
2184 -- BINDVAR_SCAN_IGNORE[4]
2185 if g_logging='LOGGING' then
2186 l_sql := 'insert ';
2187 else
2188 l_sql := 'insert /*+ append parallel(T, '||to_char(g_parallel)||') */';
2189 end if;
2190 l_sql := l_sql||' into WF_LOCAL_ROLES_TL_STAGE T ('||
2191 l_columnList||') select /*+ parallel(R, '||
2192 to_char(g_parallel)||') */ '||l_selectList||
2193 ' from '||p_roletlview;
2194
2195 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2196 'Loading stage table with: '||l_sql);
2197
2198 -- g_parallel is non-varchar
2199 -- BINDVAR_SCAN_IGNORE[2]
2200 execute IMMEDIATE 'alter session force parallel query parallel '||
2201 to_char(g_parallel) ;
2202 execute IMMEDIATE l_sql;
2203 execute IMMEDIATE 'alter session disable parallel query ' ;
2204 commit;
2205 l_importSuccess := TRUE;
2206 else
2207 l_importSuccess := FALSE;
2208 end if;
2209
2210 exception
2211 when OTHERS then
2212 raise;
2213
2214 end;
2215
2216 if (l_importSuccess) then
2217 --Gather Table Statistics
2218 FND_STATS.Gather_Table_Stats(OWNNAME=>wf_schema,
2219 TABNAME=>'WF_LOCAL_ROLES_TL_STAGE',
2220 PERCENT=>10);
2221
2222 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2223 'Creating indexes on stage table.');
2224
2225 Create_Stage_Indexes (p_sourceTable=>'WF_LOCAL_ROLES_TL',
2226 p_targetTable=>'WF_LOCAL_ROLES_TL_STAGE');
2227
2228 --Get in line to lock the table for partition exchange.
2229 --BINDVAR_SCAN_IGNORE[1]
2230 execute IMMEDIATE 'lock table '||wf_schema||'.WF_LOCAL_ROLES_TL '||
2231 'in exclusive mode';
2232
2233 --Partition exchange the temp table into the wf_local_roles table.
2234 -- wf_schema came from wf_resources
2235 -- p_partitionName cames from wf_directory_partions
2236 -- BINDVAR_SCAN_IGNORE[8]
2237 l_sql := 'ALTER TABLE ' ||wf_schema||'.WF_LOCAL_ROLES_TL ' ||
2238 'EXCHANGE PARTITION ' || p_partitionName ||
2239 ' WITH TABLE ' ||wf_schema||
2240 '.WF_LOCAL_ROLES_TL_STAGE INCLUDING '||
2241 'INDEXES WITHOUT VALIDATION';
2242
2243 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2244 'Exchanging partition with: '||l_sql);
2245 execute IMMEDIATE l_sql;
2246 commit;
2247 end if;
2248 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
2249 'End syncRolesTL('||p_orig_system||', '|| p_partitionid||
2250 ', '||p_partitionName||', '||p_roleTLView||')');
2251 end;
2252 ------------------------------------------------------------------------------
2253
2254 /*
2255 ** syncRoles - <private>
2256 */
2257 PROCEDURE syncRoles(p_orig_system in varchar2)
2258 is
2259
2260 CURSOR dbaIndexes(tabName varchar2,
2261 tabOwner varchar2) is
2262 SELECT INDEX_NAME
2263 FROM DBA_INDEXES
2264 WHERE TABLE_NAME = tabName
2265 AND TABLE_OWNER = tabOwner;
2266
2267 l_partitionID NUMBER;
2268 l_partitionName VARCHAR2(30);
2269 l_roleView VARCHAR2(30);
2270 l_role_tl_view varchar2(30);
2271
2272 l_sql VARCHAR2(2000);
2273 l_storageClause VARCHAR2(2000);
2274 l_importSuccess BOOLEAN;
2275
2276 l_columnList VARCHAR2(1000);
2277 l_selectList VARCHAR2(1000);
2278 l_modulePkg VARCHAR2(240) := g_modulePkg||'.syncRoles';
2279
2280 begin
2281 -- Log only
2282 -- BINDVAR_SCAN_IGNORE[2]
2283 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
2284 'Begin syncRoles('||p_orig_system||')');
2285 --<rwunderl:3109120>
2286 --If the orig_system is FND_USR we will synch PER_ROLE first.
2287 if (p_orig_system = 'FND_USR') then
2288 syncRoles('PER_ROLE');
2289 end if;
2290
2291 --Truncate the temp table.
2292 WF_DDL.TruncateTable(TableName=>'WF_LOCAL_ROLES_STAGE',
2293 Owner=>wf_schema);
2294
2295 --Drop indexes from the temp table.
2296 for c in dbaIndexes('WF_LOCAL_ROLES_STAGE', wf_schema) loop
2297 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2298 'Dropping index '||c.INDEX_NAME);
2299 WF_DDL.DropIndex(IndexName=>c.INDEX_NAME,
2300 Owner=>wf_schema,
2301 IgnoreNotFound=>TRUE);
2302
2303 end loop;
2304
2305 --Check the partition this orig_system belongs to.
2306 WF_DIRECTORY.AssignPartition(p_orig_system,
2307 l_partitionID, l_partitionName);
2308
2309 --If we received a partition_id of 0, this p_orig_system cannot be
2310 --BulkSynched
2311 if (l_partitionID = 0) then
2312 WF_CORE.Token('ORIGSYS', p_orig_system);
2313 WF_CORE.Raise('WF_NOPART_ORIGSYS');
2314
2315 end if;
2316
2317 --Retrieve the role and the user/role view names to be used.
2318 SELECT trim(role_view) , trim(role_tl_view)
2319 INTO l_roleView ,l_role_tl_view
2320 FROM wf_directory_partitions
2321 WHERE partition_id = l_partitionID;
2322 --Enable parallel DML
2323 execute IMMEDIATE 'alter session enable parallel dml';
2324
2325 --Alter the session to set the sort_area_size and hash_area_size.
2326 execute IMMEDIATE 'alter session set sort_area_size=104857600';
2327 execute IMMEDIATE 'alter session set hash_area_size=204857600';
2328
2329 begin
2330 --Select the data from WF_<origSystem>_ROLES and insert into
2331 --WF_LOCAL_ROLES_STAGE.
2332 if (BuildQuery (p_orig_system=>l_partitionName,
2333 p_stage_table=>'WF_LOCAL_ROLES_STAGE',
2334 p_seed_view=>nvl(l_roleView,
2335 'WF_'||l_partitionName||'_ROLES'),
2336 p_columnList=>l_columnList,
2337 p_selectList=>l_selectList)) then
2338 -- g_parallel must not be varchar2
2339 -- wf_schema came from wf_resources
2340 -- l_selectList is controlled by us
2341 -- l_partitionName came from wf_directory_partitions
2342 -- BINDVAR_SCAN_IGNORE[5]
2343 if g_logging='LOGGING' then
2344 l_sql := 'insert ';
2345 else
2346 l_sql := 'insert /*+ append parallel(T, '||to_char(g_parallel)||') */';
2347 end if;
2348 l_sql := l_sql||' into WF_LOCAL_ROLES_STAGE T '||
2349 '('||l_columnList||') select /*+ parallel(R, '||
2350 to_char(g_parallel)||') */ '||l_selectList ||' from '||
2351 nvl(l_roleView, 'WF_'||l_partitionName||'_ROLES R ' );
2352
2353 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2354 'Loading stage table with: '||l_sql);
2355 execute IMMEDIATE 'alter session force parallel query parallel '||
2356 to_char(g_parallel) ;
2357 execute IMMEDIATE l_sql;
2358 execute IMMEDIATE 'alter session disable parallel query ' ;
2359 commit;
2360 l_importSuccess := TRUE;
2361 else
2362 l_importSuccess := FALSE;
2363 end if;
2364
2365 exception
2366 when OTHERS then
2367 raise;
2368
2369 end;
2370
2371 if (l_importSuccess) then
2372 --Gather Table Statistics
2373 FND_STATS.Gather_Table_Stats(OWNNAME=>wf_schema,
2374 TABNAME=>'WF_LOCAL_ROLES_STAGE',
2375 PERCENT=>10);
2376
2377 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2378 'Creating indexes on stage table.');
2379
2380 Create_Stage_Indexes (p_sourceTable=>'WF_LOCAL_ROLES',
2381 p_targetTable=>'WF_LOCAL_ROLES_STAGE');
2382
2383 --Get in line to lock the table for partition exchange.
2384 --BINDVAR_SCAN_IGNORE[1]
2385 execute IMMEDIATE 'lock table '||wf_schema||'.WF_LOCAL_ROLES '||
2386 'in exclusive mode';
2387 --Partition exchange the temp table into the wf_local_roles table.
2388 -- wf_schema came from wf_resources
2389 -- l_partitionName came from wf_directory_partitions
2390 -- BINDVAR_SCAN_IGNORE[4]
2391 l_sql := 'ALTER TABLE ' ||wf_schema||'.WF_LOCAL_ROLES ' ||
2392 'EXCHANGE PARTITION ' || l_partitionName ||
2393 ' WITH TABLE ' ||wf_schema|| '.WF_LOCAL_ROLES_STAGE INCLUDING '||
2394 'INDEXES WITHOUT VALIDATION';
2395 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2396 'Exchanging partition with: '||l_sql);
2397 execute IMMEDIATE l_sql;
2398 commit;
2399 end if;
2400
2401 --If role_tl_view is null it means the MLS is not
2402 --enabled for this orig_system lets set a global reference as FALSE
2403 --so that inserts/updates will not operate on _TL tables.
2404 if (l_role_tl_view is not NULL) then
2405 --Call SyncRolesTL to synchronise _TL table
2406 SyncRolesTL(p_orig_system, l_partitionID,l_partitionName,l_role_tl_view);
2407 end if;
2408
2409 commit;
2410 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
2411 'End syncRoles('||p_orig_system||')');
2412 end;
2413
2414
2415 ------------------------------------------------------------------------------
2416 /*
2417 ** syncUserRoles - <private>
2418 */
2419 PROCEDURE syncUserRoles(p_orig_system in varchar2)
2420 is
2421 CURSOR dbaIndexes(tabName varchar2,
2422 tabOwner varchar2) is
2423 SELECT INDEX_NAME
2424 FROM DBA_INDEXES
2425 WHERE TABLE_NAME = tabName
2426 AND TABLE_OWNER = tabOwner;
2427
2428
2429 l_partitionID NUMBER;
2430 l_partitionName VARCHAR2(30);
2431 l_userRoleView VARCHAR2(30);
2432 l_sql VARCHAR2(2000);
2433 l_storageClause VARCHAR2(2000);
2434 l_importSuccess BOOLEAN;
2435 l_columnList VARCHAR2(1000);
2436 l_selectList VARCHAR2(1000);
2437 l_modulePkg VARCHAR2(240) := g_modulePkg||'.syncUserRoles';
2438
2439 begin
2440 -- Log only
2441 -- BINDVAR_SCAN_IGNORE[2]
2442 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
2443 'Begin syncUserRoles('||p_orig_system||')');
2444
2445 l_storageClause := ('STORAGE (INITIAL 4K NEXT 512K MINEXTENTS 1 MAXEXTENTS '||
2446 'UNLIMITED PCTINCREASE 0 FREELIST GROUPS 4 FREELISTS 4) '||
2447 ' PCTFREE 10 INITRANS 11 MAXTRANS 255 '||g_logging||' PARALLEL '||
2448 to_char(g_parallel)||' COMPUTE STATISTICS' );
2449
2450 --Bug 2931877
2451 --Add the tablespace clause if its defined.
2452 if (g_temptablespace is not NULL) then
2453 l_storageClause := ' TABLESPACE '||g_temptablespace||' '||
2454 l_storageClause||' ';
2455 end if;
2456
2457 --Truncate the temp table.
2458 WF_DDL.TruncateTable(TableName=>'WF_LOCAL_USER_ROLES_STAGE',
2459 Owner=>wf_schema);
2460
2461 --Drop indexes from the temp table.
2462 for c in dbaIndexes('WF_LOCAL_USER_ROLES_STAGE', wf_schema) loop
2463 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2464 'Dropping index '||c.INDEX_NAME);
2465 WF_DDL.DropIndex(IndexName=>c.INDEX_NAME,
2466 Owner=>wf_schema,
2467 IgnoreNotFound=>TRUE);
2468
2469 end loop;
2470
2471 --Truncate the temp table.
2472 WF_DDL.TruncateTable(TableName=>'WF_UR_ASSIGNMENTS_STAGE',
2473 Owner=>wf_schema);
2474
2475 --Drop indexes from the temp table.
2476 for c in dbaIndexes('WF_UR_ASSIGNMENTS_STAGE', wf_schema) loop
2477 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2478 'Dropping index '||c.INDEX_NAME);
2479 WF_DDL.DropIndex(IndexName=>c.INDEX_NAME,
2480 Owner=>wf_schema,
2481 IgnoreNotFound=>TRUE);
2482
2483 end loop;
2484 --Check the partition this orig_system belongs to.
2485 WF_DIRECTORY.AssignPartition(p_orig_system,
2486 l_partitionID, l_partitionName);
2487
2488 --Retrieve the role and the user/role view names to be used.
2489 SELECT trim(user_role_view)
2490 INTO l_userRoleView
2491 FROM wf_directory_partitions
2492 WHERE partition_id = l_partitionID;
2493
2494 --Enable parallel DML
2495 execute IMMEDIATE 'alter session enable parallel dml';
2496
2497 --Alter the session to set the sort_area_size and hash_area_size.
2498 execute IMMEDIATE 'alter session set sort_area_size=104857600';
2499 execute IMMEDIATE 'alter session set hash_area_size=204857600';
2500
2501 begin
2502 if (BuildQuery (p_orig_system=>l_partitionName,
2503 p_stage_table=>'WF_UR_ASSIGNMENTS_STAGE',
2504 p_seed_view=>nvl(l_userRoleView,
2505 'WF_'||l_partitionName||'_UR'),
2506 p_columnList=>l_columnList,
2507 p_selectList=>l_selectList)) then
2508
2509 -- g_parallel must be number
2510 -- wf_schema came from wf_resources
2511 -- l_columnList came from DBMS_SQL.describe_columns()
2512 -- l_selectList controlled by us
2513 -- l_userRoleView came from wf_directory_partitions
2514 -- l_partitionName came from wf_directory_partitions
2515 -- BINDVAR_SCAN_IGNORE[5]
2516 if g_logging='LOGGING' then
2517 l_sql:='insert ';
2518 else
2519 l_sql := 'insert /*+ append parallel(T, '||to_char(g_parallel)||') */';
2520 end if;
2521 l_sql:=l_sql||' into WF_UR_ASSIGNMENTS_STAGE T '||
2522 '( '||l_columnList||' ) select /*+ parallel(R, '||
2523 to_char(g_parallel)||') */ ' ||l_selectList||' from '||
2524 nvl(l_userRoleView, 'WF_'||l_partitionName||'_UR R ' );
2525
2526 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2527 'Loading WF_LOCAL_USER_ROLES_STAGE with: '||l_sql);
2528
2529 -- BINDVAR_SCAN_IGNORE[2]
2530 execute IMMEDIATE 'alter session force parallel query parallel '||
2531 to_char(g_parallel) ;
2532 execute IMMEDIATE l_sql;
2533 execute IMMEDIATE 'alter session disable parallel query ' ;
2534 commit;
2535
2536 --Now we will load all the direct assignments into the
2537 --WF_UR_ASSIGNMENTS_STAGE table.
2538 -- g_parallel must be number
2539 -- wf_schema came from wf_resources
2540 -- BINDVAR_SCAN_IGNORE[6]
2541 if g_logging='LOGGING' then
2542 l_sql := 'insert ';
2543 else
2544 l_sql := 'insert /*+ append parallel(T, '||to_char(g_parallel)||') */';
2545 end if;
2546 l_sql:=l_sql||' into WF_LOCAL_USER_ROLES_STAGE T '||
2547 '( USER_NAME, ROLE_NAME, USER_ORIG_SYSTEM,USER_ORIG_SYSTEM_ID, '||
2548 'ROLE_ORIG_SYSTEM, ROLE_ORIG_SYSTEM_ID,PARENT_ORIG_SYSTEM, '||
2549 'PARENT_ORIG_SYSTEM_ID, START_DATE, EXPIRATION_DATE, CREATED_BY, '||
2550 'CREATION_DATE,LAST_UPDATED_BY, LAST_UPDATE_DATE, LAST_UPDATE_LOGIN, ';
2551 -- g_parallel must be number
2552 -- BINDVAR_SCAN_IGNORE[5]
2553 l_sql := l_sql||'USER_START_DATE, ROLE_START_DATE, '||
2554 'USER_END_DATE, ROLE_END_DATE, ASSIGNMENT_TYPE, '||
2555 'PARTITION_ID, ASSIGNMENT_REASON) '||
2556 'select /*+ parallel(R, '||
2557 ''''||to_char(g_parallel)||''') */ USER_NAME, ROLE_NAME, ';
2558 -- wf_schema came from wf_resources
2559 -- BINDVAR_SCAN_IGNORE[8]
2560 l_sql := l_sql|| 'USER_ORIG_SYSTEM, USER_ORIG_SYSTEM_ID, '||
2561 'ROLE_ORIG_SYSTEM, ROLE_ORIG_SYSTEM_ID,PARENT_ORIG_SYSTEM, '||
2562 'PARENT_ORIG_SYSTEM_ID,START_DATE,END_DATE, CREATED_BY, CREATION_DATE, '||
2563 'LAST_UPDATED_BY,LAST_UPDATE_DATE, LAST_UPDATE_LOGIN, USER_START_DATE, '||
2564 'ROLE_START_DATE, USER_END_DATE, '||
2565 'ROLE_END_DATE, ''D'', '||
2566 ''''||to_char(l_partitionID)||''', ASSIGNMENT_REASON from '||
2567 'WF_UR_ASSIGNMENTS_STAGE R';
2568
2569 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2570 'Loading WF_UR_ASSIGNMENTS_STAGE with: '||l_sql);
2571
2572 execute IMMEDIATE 'alter session force parallel query parallel '||
2573 to_char(g_parallel) ;
2574 execute IMMEDIATE l_sql;
2575 execute IMMEDIATE 'alter session disable parallel query ' ;
2576 commit;
2577 l_importSuccess := TRUE;
2578 else
2579 l_importSuccess := FALSE;
2580 end if;
2581
2582 exception
2583 when OTHERS then
2584 raise;
2585
2586 end;
2587
2588 --Under 3542997 we will add the functionality to continue populating the
2589 --WF_LOCAL_USER_ROLES_STAGE and WF_UR_ASSIGNMENTS_STAGE tables based
2590 --on the hierarchy. After 3542997 is complete, orig_systems should be able
2591 --to both participate in hierarchies and continue to bulk synchronize.
2592 --At this time, an orig_system that participates in a hierarchy cannot bulk
2593 --synchronize.
2594
2595 if (l_importSuccess) then
2596 --Gather Table Statistics
2597 FND_STATS.Gather_Table_Stats(OWNNAME=>wf_schema,
2598 TABNAME=>'WF_LOCAL_USER_ROLES_STAGE',
2599 PERCENT=>10);
2600
2601 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2602 'Creating indexes on stage table.');
2603
2604 Create_Stage_Indexes (p_sourceTable=>'WF_LOCAL_USER_ROLES',
2605 p_targetTable=>'WF_LOCAL_USER_ROLES_STAGE');
2606
2607 FND_STATS.Gather_Table_Stats(OWNNAME=>wf_schema,
2608 TABNAME=>'WF_UR_ASSIGNMENTS_STAGE',
2609 PERCENT=>10);
2610
2611 Create_Stage_Indexes (p_sourceTable=>'WF_USER_ROLE_ASSIGNMENTS',
2612 p_targetTable=>'WF_UR_ASSIGNMENTS_STAGE');
2613
2614 --Get in line to lock the table for partition exchange.
2615 --BINDVAR_SCAN_IGNORE[1]
2616 execute IMMEDIATE 'lock table '||wf_schema||'.WF_LOCAL_USER_ROLES '||
2617 'in exclusive mode';
2618 --Partition exchange the temp table into the wf_local_user_roles table.
2619 -- wf_schema came from wf_resources
2620 -- l_partitionName came from wf_directory_partitions
2621 -- BINDVAR_SCAN_IGNORE[4]
2622 l_sql := 'ALTER TABLE ' ||wf_schema||'.WF_LOCAL_USER_ROLES ' ||
2623 'EXCHANGE PARTITION ' || l_partitionName ||
2624 ' WITH TABLE ' ||wf_schema||
2625 '.WF_LOCAL_USER_ROLES_STAGE INCLUDING INDEXES WITHOUT VALIDATION';
2626 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2627 'Exchanging partition with: '||l_sql);
2628 execute IMMEDIATE l_sql;
2629 commit;
2630
2631 --Get in line to lock the table for partition exchange.
2632 --BINDVAR_SCAN_IGNORE[1]
2633 execute IMMEDIATE 'lock table '||wf_schema||'.WF_USER_ROLE_ASSIGNMENTS '||
2634 'in exclusive mode';
2635 --Partition exchange the temp table into the wf_user_role_assignments table.
2636 l_sql := 'ALTER TABLE ' ||wf_schema||'.WF_USER_ROLE_ASSIGNMENTS ' ||
2637 'EXCHANGE PARTITION ' || l_partitionName ||
2638 ' WITH TABLE ' ||wf_schema||'.WF_UR_ASSIGNMENTS_STAGE '||
2639 'INCLUDING INDEXES WITHOUT VALIDATION';
2640 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_STATEMENT, l_modulePkg,
2641 'Exchanging partition with: '||l_sql);
2642 execute IMMEDIATE l_sql;
2643
2644 end if;
2645 commit;
2646
2647 WF_LOG_PKG.String(WF_LOG_PKG.LEVEL_PROCEDURE, l_modulePkg,
2648 'End syncUserRoles('||p_orig_system||')');
2649 end;
2650 ------------------------------------------------------------------------------
2651 /*
2652 ** BulkSynchronization - <described in WFLOCALS.pls>
2653 */
2654 PROCEDURE BulkSynchronization(p_orig_system in varchar2,
2655 p_parallel_processes in number,
2656 p_logging in varchar2,
2657 p_raiseErrors in boolean,
2658 p_temptablespace in varchar2)
2659 is
2660 DuplicateKeys EXCEPTION;
2661 pragma exception_init(DuplicateKeys, -1452);
2662
2663 cursor valid_orig_systems is
2664 select distinct lookup_code name
2665 from fnd_lookup_values
2666 where lookup_type = 'FND_WF_ORIG_SYSTEMS'
2667 and language = 'US';
2668
2669 --Bug 3585554
2670 l_partitionID NUMBER;
2671 l_partitionName VARCHAR2(30);
2672
2673 begin
2674 if ((p_parallel_processes is NULL) or (p_parallel_processes < 1) or
2675 (mod(p_parallel_processes, 1) <> 0)) then
2676 -- Retrieve g_parallel.
2677 select min(to_number(value))
2678 into g_parallel
2679 from v$parameter
2680 where name in ('parallel_max_servers','cpu_count');
2681 else
2682 g_parallel := p_parallel_processes;
2683 end if;
2684
2685 if (p_logging in ('NOLOGGING','LOGGING')) then
2686 g_logging := p_logging;
2687 else
2688 g_logging := 'LOGGING';
2689 end if;
2690
2691 -- Sanity check on p_temptablespace
2692 if (p_temptablespace is not null and instr(p_temptablespace,';') = 0) then
2693 --Bug 2931877
2694 g_temptablespace := p_temptablespace;
2695 end if;
2696
2697 select NLS_LANGUAGE, NLS_TERRITORY
2698 into g_BaseLanguage, g_BaseTerritory
2699 from FND_LANGUAGES
2700 where INSTALLED_FLAG = 'B';
2701
2702 if (p_orig_system = 'ALL') then
2703 for origsys in valid_orig_systems loop
2704 --<rwunderl:3659321>: 'PER' is bulk-synched through 'FND_USR'
2705 if (origsys.name not in ('ALL', 'PER')) then
2706 begin
2707 --<rwunderl:2823630>
2708 --If the orig system is hierarchy enabled, it cannot bulk synchronize
2709 --Move this condition to after checking the assigned partition
2710 --Maximum case they will be same
2711 --Bug 3585554
2712 --Check if this orig system is attached to another
2713 --one eg : PER to fnd_usr
2714 --Checking it will avoid erroring off down the line
2715 --when you try to sync and the base orig system is
2716 --Hierarchy enabled
2717 WF_DIRECTORY.AssignPartition(origsys.name,
2718 l_partitionID, l_partitionName);
2719 if NOT (WF_ROLE_HIERARCHY.HierarchyEnabled(l_partitionName)) then
2720 syncRoles(origsys.name);
2721 syncUserRoles(origsys.name);
2722 end if;
2723
2724
2725 exception
2726 when DuplicateKeys then
2727 if (p_raiseErrors) then
2728 WF_CORE.Token('P_ORIG_SYSTEM', origsys.name);
2729 WF_CORE.Raise('WFDS_BULK_DUP_KEYS');
2730 else
2731 null;
2732
2733 end if;
2734
2735 when OTHERS then
2736 if (WF_CORE.error_name = 'WF_NOPART_ORIGSYS') then
2737 WF_CORE.Clear;
2738 null; --If we do not have a partition for this orig_system we
2739 --ignore it and continue to the next.
2740 else
2741 if (p_raiseErrors) then
2742 raise;
2743
2744 end if;
2745 end if;
2746 end;
2747
2748 end if;
2749 end loop;
2750 else
2751 begin
2752 --<rwunderl:2823630>
2753 --If the orig system is hierarchy enabled, it cannot bulk synchronize
2754
2755 --ie resolve the assigned partition and then check.
2756 --if NOT (WF_ROLE_HIERARCHY.HierarchyEnabled(p_orig_system)) then
2757
2758 --Bug 3585554
2759 --Check if this orig system is attached to another
2760 --one eg : PER to fnd_usr
2761 --Checking it will avoid erroring off down the line
2762 --when you try to sync and the base orig system is
2763 --Hierarchy enabled
2764 WF_DIRECTORY.AssignPartition(p_orig_system,
2765 l_partitionID, l_partitionName);
2766 if NOT (WF_ROLE_HIERARCHY.HierarchyEnabled(l_partitionName)) then
2767 syncRoles(p_orig_system);
2768 syncUserRoles(p_orig_system);
2769 else
2770 WF_CORE.Token('ORIG_SYSTEM', p_orig_system);
2771 WF_CORE.Raise('WFDS_ORIGSYS_HIERARCHY_ENABLED');
2772 end if;
2773 exception
2774 when DuplicateKeys then
2775 if (p_raiseErrors) then
2776 WF_CORE.Token('P_ORIG_SYSTEM', p_orig_system);
2777 WF_CORE.Raise('WFDS_BULK_DUP_KEYS');
2778 else
2779 null;
2780
2781 end if;
2782
2783 when OTHERS then
2784 if (p_raiseErrors) then
2785 raise;
2786
2787 else
2788 null;
2789
2790 end if;
2791 end;
2792 end if;
2793
2794 g_parallel := 1;
2795 g_logging := 'LOGGING';
2796
2797 end;
2798 ------------------------------------------------------------------------------
2799 /*
2800 ** BulkSynchronization_conc - <described in WFLOCALS.pls>
2801 ** Bug 2931877
2802 ** Added option to chose the tablespace
2803 */
2804 PROCEDURE BulkSynchronization_conc(errbuf out NOCOPY varchar2,
2805 retcode out NOCOPY varchar2,
2806 p_orig_system in varchar2,
2807 p_parallel_processes in varchar2,
2808 p_logging in varchar2,
2809 p_temptablespace in varchar2,
2810 p_raiseerrors in varchar2)
2811 is
2812 l_temptablespace varchar2(30);
2813 l_raiseerrors boolean;
2814 begin
2815 if ((p_temptablespace is null) OR (p_temptablespace = 'NULL')) then
2816 l_temptablespace := null;
2817 else
2818 --We do not require any validation of tablespace as
2819 --the LOV restricts the same and validates it beforehand
2820 l_temptablespace := p_temptablespace;
2821 end if;
2822
2823 if(nvl(p_raiseerrors, 'Y') = 'N') then
2824 l_raiseerrors := FALSE;
2825 else
2826 l_raiseerrors := TRUE;
2827 end if;
2828
2829
2830 wf_local_synch.BulkSynchronization(p_orig_system,
2831 to_number(p_parallel_processes),
2832 p_logging,
2833 l_raiseerrors,
2834 l_temptablespace);
2835
2836 retcode := '0'; -- (successful completion)
2837 errbuf := '';
2838
2839 --<rwunderl:3145844> We need to commit and disable parallel DML so CP won't
2840 -- choke.
2841 commit;
2842 execute IMMEDIATE 'alter session disable parallel dml';
2843
2844 exception
2845 when others then
2846 execute IMMEDIATE 'alter session disable parallel dml';
2847 if (wf_core.error_name = 'WFDS_ORIGSYS_HIERARCHY_ENABLED') then
2848 FND_FILE.PUT_LINE(FND_FILE.LOG, sqlerrm);
2849 retcode := '1'; -- (warning)
2850 else
2851 retcode := '2'; -- (error)
2852 errbuf := sqlerrm;
2853 end if;
2854 WF_CORE.Clear;
2855 end;
2856
2857
2858 ------------------------------------------------------------------------------
2859 /*
2860 ** CheckCache - <private>
2861 **
2862 ** Checks to see if a role is in the cache of recently created roles.
2863 ** IN
2864 ** p_role_name VARCHAR2
2865 ** RETURNS
2866 ** BOOLEAN
2867 */
2868 FUNCTION CheckCache (p_role_name in VARCHAR2) return boolean
2869 is
2870 roleIND PLS_INTEGER;
2871 begin
2872 if NOT (WF_ROLE_HIERARCHY.validateSession(g_trustTimeStamp)) then
2873 g_trustedRoles.DELETE;
2874 return FALSE;
2875 end if;
2876
2877 roleIND := g_trustedRoles.FIRST;
2878 while (roleIND is NOT NULL) loop
2879 if (g_trustedRoles(roleIND) = p_role_name) then
2880 return TRUE;
2881 end if;
2882 roleIND := g_trustedRoles.NEXT(roleIND);
2883 end loop;
2884
2885 --If we did not yet return true, then the name is not in cache, so we
2886 --return false.
2887 return FALSE;
2888 end;
2889
2890 ------------------------------------------------------------------------------
2891 /*
2892 ** DeleteCache - <private>
2893 **
2894 ** Removes a role from the cache of newly created roles.
2895 ** IN
2896 ** p_role_name VARCHAR2
2897 */
2898 PROCEDURE DeleteCache (p_role_name in VARCHAR2)
2899 is
2900 roleIND PLS_INTEGER;
2901 begin
2902 roleIND := g_trustedRoles.FIRST;
2903 while (roleIND is NOT NULL) loop
2904 if (g_trustedRoles(roleIND) = p_role_name) then
2905 g_trustedRoles.DELETE(roleIND);
2906 end if;
2907 roleIND := g_trustedRoles.NEXT(roleIND);
2908 end loop;
2909 end;
2910
2911 ------------------------------------------------------------------------------
2912 /*
2913 ** ValidateUserRoles - Validates and corrects denormalized user and role
2914 ** information in user/role relationships.
2915 */
2916 PROCEDURE ValidateUserRoles(p_BatchSize in NUMBER,
2917 p_username in varchar2 default null,
2918 p_rolename in varchar2 default null,
2919 p_check_dangling in BOOLEAN,
2920 p_check_missing_ura in BOOLEAN,
2921 p_UpdateWho in BOOLEAN,
2922 p_parallel_processes in number) is
2923 begin
2924 WF_MAINTENANCE.ValidateUserRoles(p_BatchSize,
2925 p_username,
2926 p_rolename,
2927 p_check_dangling,
2928 p_check_missing_ura,
2929 p_UpdateWho,
2930 p_parallel_processes);
2931 end;
2932
2933 ------------------------------------------------------------------------------
2934 /*
2935 ** ValidateUserRoles_conc - CM cover routine for ValidateUserRoles()
2936 */
2937 PROCEDURE ValidateUserRoles_conc(errbuf out NOCOPY varchar2,
2938 retcode out NOCOPY varchar2,
2939 p_BatchSize in varchar2,
2940 p_username in varchar2 default null,
2941 p_rolename in varchar2 default null,
2942 p_check_dangling in varchar2,
2943 p_check_missing_ura in varchar2,
2944 p_UpdateWho in varchar2,
2945 p_parallel_processes in number) is
2946
2947 l_checkDangling BOOLEAN;
2948 l_checkMissingURA BOOLEAN;
2949 l_UpdateWho BOOLEAN;
2950 begin
2951
2952 if(nvl(p_check_missing_ura, 'N') = 'Y') then
2953 l_checkMissingURA := TRUE;
2954 else
2955 l_checkMissingURA := FALSE;
2956 end if;
2957
2958 if(nvl(p_check_dangling, 'N') = 'Y') then
2959 l_checkDangling := TRUE;
2960 else
2961 l_checkDangling := FALSE;
2962 end if;
2963
2964 if(nvl(p_UpdateWho,'N')='Y') then
2965 l_UpdateWho := TRUE;
2966 else
2967 l_UpdateWho := FALSE;
2968 end if;
2969
2970 ValidateUserRoles(to_number(p_BatchSize), p_username, p_rolename, l_checkDangling,
2971 l_checkMissingURA,l_UpdateWho, p_parallel_processes);
2972 retcode := '0'; -- (successful completion)
2973 errbuf := '';
2974 exception
2975 when OTHERS then
2976 retcode := '2'; -- (error)
2977 errbuf := sqlerrm;
2978 end;
2979
2980 /*
2981 ** bulk_reset_ntfPref
2982 **
2983 ** ER 5748131 - Bulk resets the notification preference of all the
2984 ** users/roles DISABLED by Mailer to its previous preference value
2985 ** OUT
2986 ** errbuf VARCHAR2
2987 ** retcode VARCHAR2
2988 */
2989 PROCEDURE bulk_reset_ntfPref(errbuf out NOCOPY varchar2,
2990 retcode out NOCOPY varchar2) is
2991
2992 cursor c_fnd_users is
2993 select name, orig_system, orig_system_id
2994 from wf_local_roles
2995 where orig_system in ('FND_USR', 'PER')
2996 and notification_preference = 'DISABLED'
2997 and nvl(EXPIRATION_DATE, sysdate+1) > sysdate;
2998
2999 cursor c_other_users is
3000 select name, orig_system, orig_system_id
3001 from wf_local_roles
3002 where orig_system not in ('FND_USR', 'PER')
3003 and notification_preference = 'DISABLED'
3004 and nvl(EXPIRATION_DATE, sysdate+1) > sysdate;
3005
3006 l_parameterlist wf_parameter_list_t := wf_parameter_list_t();
3007 l_prev_preference varchar2(8) := NULL;
3008 l_userName varchar2(360) := null;
3009
3010 errname varchar2(30);
3011 errmsg varchar2(2000);
3012 errstack varchar2(4000);
3013
3014 begin
3015
3016 -- For each FND or PER DISABLED user call fnd_preference.get() to get the previous
3017 -- preference value, if exists call fnd_preference.put() to reset the same preference
3018 for fnd_usr_rec in c_fnd_users loop
3019
3020 -- Concatenate username with orig system and orig system id to make it unique
3021 -- in FND_USER_PREFERENCES table
3022 l_userName := fnd_usr_rec.name || ':' || fnd_usr_rec.orig_system || ':' ||
3023 fnd_usr_rec.orig_system_id;
3024 l_prev_preference := fnd_preference.get(l_userName, 'WF' , 'PREV_MAILTYPE');
3025
3026 if(l_prev_preference is not null) then
3027
3028 fnd_preference.put(fnd_usr_rec.name, 'WF' , 'MAILTYPE', l_prev_preference);
3029 -- remove the row from FND_USER_PREFERENCES table after reset
3030 fnd_preference.remove(l_userName, 'WF' , 'PREV_MAILTYPE');
3031
3032 end if;
3033
3034 end loop;
3035
3036 -- For each DISABLED user/role other than FND or PER, call fnd_preference.get() to get
3037 -- the previous preference value, if exists call wf_local_synch.Propagate_User
3038 -- to reset the notification preference in wf_local_roles table
3039 for user_rec in c_other_users loop
3040
3041 -- Concatenate username with orig system and orig system id to make it unique
3042 -- in FND_USER_PREFERENCES table
3043 l_userName := user_rec.name || ':' || user_rec.orig_system || ':' || user_rec.orig_system_id;
3044 l_prev_preference := fnd_preference.get(l_userName, 'WF' , 'PREV_MAILTYPE');
3045
3046 if(l_prev_preference is not null) then
3047
3048 wf_event.AddParameterToList('orclWorkFlowNotificationPref', l_prev_preference, l_parameterlist);
3049 wf_event.AddParameterToList('USER_NAME', user_rec.name, l_parameterlist);
3050 wf_event.AddParameterToList('RAISEERRORS', 'TRUE', l_parameterlist);
3051 wf_local_synch.Propagate_User(user_rec.orig_system , user_rec.orig_system_id , l_parameterlist);
3052
3053 -- remove the row from FND_USER_PREFERENCES table after reset
3054 fnd_preference.remove(l_userName, 'WF' , 'PREV_MAILTYPE');
3055
3056 end if;
3057
3058 end loop;
3059
3060 errbuf := '';
3061 retcode := '0';
3062
3063 exception
3064 when others then
3065 -- Retrieve error message into errbuf
3066 wf_core.get_error(errname, errmsg, errstack);
3067 if (errmsg is not null) then
3068 errbuf := errmsg;
3069 else
3070 errbuf := sqlerrm;
3071 end if;
3072
3073 -- Return 2 for error.
3074 retcode := '2';
3075
3076 end bulk_reset_ntfPref;
3077
3078 end WF_LOCAL_SYNCH;