1 PACKAGE BODY jtf_rs_default_groups_conc_pub AS
2 /* $Header: jtfrsbcb.pls 120.0 2005/05/11 08:19:15 appldev noship $ */
3
4 /****************************************************************************
5 This is a concurrent program to populate the data in JTF_RS_DEFAULT_GROUPS_INT,
6 JTF_RS_DEFAULT_GROUPS_STAGE and JTF_RS_DEFAULT_GROUPS. This program will create
7 primary groups for resources based on usage and rules (specified by product
8 teams) for date date range from 01/01/1900 to 12/31/4712. For a specific date
9 there will be only one primary group for a resource in JTF_RS_DEFAULT_GROUPS.
10
11 Currently, it is being used for only Field Service Application.
12
13 CREATED BY nsinghai 20-JUL-2004
14 MODIFIED BY nsinghai 20-SEP-2004 Made JTF_RS_DEFUALT_GROUPS incremental.
15 Introduced new staging table JTF_RS_DEFAULT_GROUPS_STAGE
16 Only Delta Records will be populated in
17 JTF_RS_DEFAULT_GROUPS table.
18 nsinghai 27-SEP-2004 Bug 3917477 : Defaulting to -1 group
19 should be the last consideration. If any other group
20 is present, even if it is at lower level, it should be
21 defaulted to. Modified First insert stmt to
22 exclude group with group_id = -1
23 ***************************************************************************/
24
25 /*****************************************************************************
26 This procedure will populate default groups for Field Service District (usage:
27 'FLD_SRV_DISTRICT') through concurrent program "Update Primary Districts for
28 Field Service Engineers".
29
30 Created By nsinghai 07/21/2004
31 *****************************************************************************/
32
33 PROCEDURE populate_fs_district
34 (ERRBUF OUT NOCOPY VARCHAR2,
35 RETCODE OUT NOCOPY VARCHAR2)
36 IS
37
38 TYPE default_grp_type IS RECORD
39 (p_resource_id NUMBER,
40 p_user_id NUMBER,
41 p_resource_number VARCHAR2(60),
42 p_group_id NUMBER,
43 p_start_date DATE,
44 p_end_date DATE
45 );
46
47 TYPE default_grp_tbl IS TABLE OF default_grp_type INDEX BY BINARY_INTEGER;
48
49 g_default_grp_tab default_grp_tbl;
50 temp_default_grp_tab default_grp_tbl;
51
52 l_inner_loop VARCHAR2(10) ;
53
54 i INTEGER := 0;
55 j INTEGER := 0;
56 k INTEGER := 0;
57 l INTEGER := 0;
58 m INTEGER := 0;
59 n INTEGER := 0;
60 o INTEGER := 0;
61 p INTEGER := 0;
62 q INTEGER := 0;
63
64 l_user_id NUMBER ;
65 l_sysdate DATE ;
66 l_status VARCHAR2(30);
67 l_index_owner VARCHAR2(240);
68 l_table_owner VARCHAR2(240);
69 l_index_tblspace VARCHAR2(240);
70 l_index_exists VARCHAR2(10);
71 l_prev_start_date DATE;
72 l_prev_end_date DATE;
73 l_skip_row VARCHAR2(10);
74 l_overlap VARCHAR2(10);
75 l_deletion_occured VARCHAR2(10);
76 l_usage VARCHAR2(100);
77 l_stage VARCHAR2(300);
78
79 l_jtfu varchar2(240);
80 l_jtfx varchar2(240);
81 l_jtft varchar2(240);
82
83 CURSOR c_outer IS
84 SELECT DISTINCT resource_id
85 FROM JTF_RS_DEFAULT_GROUPS_INT
86 ;
87
88 CURSOR c1 (ll_resource_id NUMBER)IS
89 SELECT resource_id, user_id, resource_number, group_id, start_date, end_date
90 FROM JTF_RS_DEFAULT_GROUPS_INT
91 WHERE resource_id = ll_resource_id
92 AND start_date <= end_date
93 ORDER BY denorm_count ASC, role_type_priority ASC, role_priority ASC, START_DATE desc;
94
95 CURSOR c_product_info IS
96 SELECT i.tablespace, i.index_tablespace, u.oracle_username
97 FROM fnd_product_installations i, fnd_application a, fnd_oracle_userid u
98 WHERE a.application_short_name = 'JTF'
99 AND a.application_id = i.application_id
100 AND u.oracle_id = i.oracle_id;
101
102 FUNCTION f_get_degree_of_parallelism RETURN NUMBER IS
103 l_parallel NUMBER;
104 BEGIN
105 l_parallel := null;
106 -- EDW : Degree of Parallelism-Source
107 l_parallel := null;
108 l_parallel := floor(fnd_profile.value('EDW_PARALLEL_SRC')); -- gets value of profile option
109
110 /* Set by the customer, return this value */
111
112 IF (l_parallel IS NOT NULL and l_parallel > 0) THEN
113 return l_parallel;
114 END IF;
115
116 /* Not set by customer, so query v$pq_sysstat */
117
118 BEGIN
119 SELECT value INTO l_parallel
120 FROM v$pq_sysstat WHERE trim(statistic) = 'Servers Idle';
121 EXCEPTION WHEN no_data_found THEN
122 l_parallel := 1;
123 END;
124
125 IF (l_parallel IS NULL) THEN
126 l_parallel:=1;
127 END IF;
128
129 l_parallel := floor(l_parallel/2);
130 IF (l_parallel = 0) THEN
131 l_parallel := 1;
132 END IF;
133
134 RETURN l_parallel;
135 END f_get_degree_of_parallelism;
136
137 BEGIN
138
139 -- putting initialization variable here because of GSCC warning File.Sql.35
140
141 l_stage := 'Stage=Initialize';
142
143 l_inner_loop := 'N';
144 l_user_id := fnd_global.user_id;
145 l_sysdate := SYSDATE;
146 l_skip_row := 'N' ;
147 l_overlap := 'N' ;
148 l_deletion_occured := 'N' ;
149 l_usage := 'FLD_SRV_DISTRICT'; -- currently not being used. For future, when more usages use this table.
150
151 retcode := '0' ;
152
153 --EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE=TRUE';
154 EXECUTE IMMEDIATE 'ALTER SESSION ENABLE PARALLEL DML';
155
156 l_stage := 'Stage=FETCH_SCHEMA_DETAILS';
157
158 --fetch user name for JTF product
159 OPEN c_product_info;
160 FETCH c_product_info INTO l_jtft,l_jtfx,l_jtfu;
161 CLOSE c_product_info;
162
163 -------- Check owner name for the tables and indexes.
164 -- keep index information so that it is easy to create them back
165 -- Check owner name for the tables and indexes.
166 BEGIN
167 SELECT owner, table_owner, tablespace_name
168 INTO l_index_owner, l_table_owner, l_index_tblspace
169 FROM ALL_INDEXES
170 WHERE TABLE_NAME = 'JTF_RS_DEFAULT_GROUPS_INT'
171 AND index_name = 'JTF_RS_DEFAULT_GROUPS_INT_N1'
172 AND table_owner= l_jtfu;
173
174 l_index_exists := 'Y' ;
175
176 EXCEPTION WHEN OTHERS THEN
177
178 l_index_exists := 'N' ;
179
180 -- Check some ther index which will definitly exist
181 SELECT owner, table_owner, tablespace_name
182 INTO l_index_owner, l_table_owner, l_index_tblspace
183 FROM ALL_INDEXES
184 WHERE TABLE_NAME = 'JTF_RS_GROUPS_DENORM'
185 AND index_name = 'JTF_RS_GROUPS_DENORM_U1'
186 AND table_owner= l_jtfu;
187 END;
188
189
190 --------- Drop Index before inserting into intermediate table ----------
191 l_stage := 'Stage=DROP_INDEX '||l_index_owner||'.JTF_RS_DEFAULT_GROUPS_INT_N1';
192
193 IF (l_index_exists = 'Y') THEN
194 EXECUTE IMMEDIATE 'DROP INDEX '||l_index_owner||'.JTF_RS_DEFAULT_GROUPS_INT_N1';
195 END IF;
196
197 -------------Insert into intermediate table ---------
198 EXECUTE IMMEDIATE 'TRUNCATE TABLE '||l_index_owner||'.JTF_RS_DEFAULT_GROUPS_INT';
199
200 COMMIT;
201
202 l_stage := 'Stage=INSERT_IN_JTF_RS_DEFAULT_GROUPS_INT_TABLE';
203
204 INSERT INTO /*+ APPEND PARALLEL(sg1) NOLOGGING */ JTF_RS_DEFAULT_GROUPS_int sg1
205 (default_groups_id, resource_id, user_id, resource_number,
206 group_id, role_type_code, role_id, role_type_priority,
207 role_priority, start_date, end_date, denorm_count, usage,
208 created_by, creation_date, last_updated_by, last_update_date )
209 SELECT JTF_RS_DEFAULT_GROUPS_STAGE_s.NEXTVAL default_groups_id,
210 x.resource_id, x.user_id, x.resource_number,
211 x.group_id,
212 x.role_type_code, x.role_id, x.role_type_priority, x.role_priority,
213 x.start_date, x.end_date, x.denorm_count, 'FLD_SRV_DISTRICT' usage,
214 l_user_id, sysdate, l_user_id, sysdate
215 FROM (
216 SELECT /*+ use_hash(rrl mem usg rol den res) PARALLEL(rrl)
217 PARALLEL(mem) PARALLEL(usg) PARALLEL(rol) PARALLEL(den)
218 PARALLEL(res) */
219 mem.resource_id
220 ,mem.group_id
221 ,res.user_id
222 ,res.resource_number
223 ,DECODE(rol.role_type_code,'CSF_REPRESENTATIVE',1,'CSF_DEBRIEF',2,
224 'CSF_DEBRIEF_REVIEWAGENT',3,'CSF_DISPATCHER',4,'CSF_PLANNER',5,
225 'CSF_DBI_DISTRICT',6,7
226 ) role_type_priority
227 ,DECODE('Y',rol.member_flag,1,rol.manager_flag,2) role_priority
228 ,rrl.start_date_active start_date
229 ,nvl(rrl.end_date_active,TO_DATE('12/31/4712','MM/DD/RRRR')) end_date
230 ,rrl.role_id
231 ,rol.role_type_code
232 ,COUNT(den.group_id) denorm_count
233 FROM jtf_rs_role_relations rrl
234 ,jtf_rs_group_members mem
235 ,jtf_rs_group_usages usg
236 ,jtf_rs_roles_b rol
237 ,jtf_rs_groups_denorm den
238 ,jtf_rs_resource_extns res
239 WHERE rrl.role_resource_type = 'RS_GROUP_MEMBER'
240 AND rrl.delete_flag = 'N'
241 AND rrl.role_resource_id = mem.group_member_id
242 AND mem.delete_flag = 'N'
243 AND mem.group_id <> -1
244 AND mem.group_id = usg.group_id
245 AND usg.usage = 'FLD_SRV_DISTRICT'
246 AND rrl.role_id = rol.role_id
247 AND rol.role_type_code IN ('CSF_REPRESENTATIVE','CSF_DEBRIEF',
248 'CSF_DEBRIEF_REVIEWAGENT','CSF_DISPATCHER','CSF_PLANNER','CSF_DBI_DISTRICT')
249 AND 'Y' IN (rol.member_flag, rol.manager_flag)
250 AND mem.resource_id = res.resource_id
251 AND mem.group_id = den.group_id
252 AND ( rrl.start_date_active BETWEEN den.start_date_active AND
253 nvl(den.end_date_active,TO_DATE('12/31/4712','MM/DD/RRRR'))
254 OR
255 den.start_date_active BETWEEN rrl.start_date_active AND
256 nvl(rrl.end_date_active,TO_DATE('12/31/4712','MM/DD/RRRR'))
257 )
258 GROUP BY mem.resource_id, res.user_id, res.resource_number,
259 mem.group_id, rrl.start_date_active, rrl.end_date_active,
260 DECODE(rol.role_type_code,'CSF_REPRESENTATIVE',1,'CSF_DEBRIEF',2,
261 'CSF_DEBRIEF_REVIEWAGENT',3,'CSF_DISPATCHER',4,'CSF_PLANNER',5,
262 'CSF_DBI_DISTRICT',6,7),
263 DECODE('Y',rol.member_flag,1,rol.manager_flag,2)
264 ,rrl.role_id, rol.role_type_code
265 ) x ;
266
267 COMMIT;
268
269 /* Insert all the rest of the Field Service Resources who do not have any group
270 assign to them along with those who have groups assigned for limited time
271 */
272
273 l_stage := 'Stage=INSERT_IN_JTF_RS_DEFAULT_GROUPS_INT_TABLE_FOR_UNASSIGNED_GROUPS';
274
275 INSERT INTO /*+ APPEND PARALLEL(sg1) NOLOGGING */ JTF_RS_DEFAULT_GROUPS_INT sg1
276 (default_groups_id, resource_id, user_id, resource_number,
277 group_id, role_type_code, role_id, role_type_priority,
278 role_priority, start_date, end_date, denorm_count, usage,
279 created_by, creation_date, last_updated_by, last_update_date )
280 SELECT JTF_RS_DEFAULT_GROUPS_STAGE_s.NEXTVAL default_groups_id,
281 x.resource_id, x.user_id, x.resource_number,
282 x.group_id,
283 x.role_type_code, x.role_id, x.role_type_priority, x.role_priority,
284 x.start_date, x.end_date, x.denorm_count, 'FLD_SRV_DISTRICT' usage,
285 l_user_id, sysdate, l_user_id, sysdate
286 FROM (
287 SELECT /*+ use_hash(rrl rol res) PARALLEL(rrl) PARALLEL(rol) PARALLEL(res)*/
288 DISTINCT
289 res.resource_id,
290 res.user_id,
291 res.resource_number,
292 -1 group_id,
293 'NONE' role_type_code,
294 -1 role_id,
295 99 role_type_priority,
296 99 role_priority,
297 TO_DATE('01/01/1900','MM/DD/RRRR') START_DATE,
298 TO_DATE('12/31/4712','MM/DD/RRRR') END_DATE,
299 99999999 denorm_count
300 FROM jtf_rs_role_relations rrl
301 ,jtf_rs_roles_b rol
302 ,jtf_rs_resource_extns res
303 WHERE rrl.role_resource_type = 'RS_INDIVIDUAL'
304 AND rrl.delete_flag = 'N'
305 AND rrl.role_id = rol.role_id
306 AND rol.role_type_code IN ('CSF_REPRESENTATIVE','CSF_DEBRIEF',
307 'CSF_DEBRIEF_REVIEWAGENT','CSF_DISPATCHER',
308 'CSF_PLANNER','CSF_DBI_DISTRICT')
309 AND rrl.role_resource_id = res.resource_id
310 ) x;
311
312 COMMIT;
313
314
315 -------------Create index and Analyze table on Intermediate table -------
316
317 l_stage := 'Stage=CREATE_INDEX_ON_JTF_RS_DEFAULT_GROUPS_INT_TABLE';
318
319 EXECUTE IMMEDIATE 'CREATE INDEX '||l_index_owner
320 ||'.JTF_RS_DEFAULT_GROUPS_INT_N1 ON '
321 ||l_table_owner||'.JTF_RS_DEFAULT_GROUPS_INT '
322 ||' (resource_id, denorm_count, role_type_priority, role_priority, start_date desc) '
323 ||' TABLESPACE '||l_index_tblspace
324 ||' NOLOGGING PARALLEL (DEGREE '||f_get_degree_of_parallelism||' ) ';
325
326
327 fnd_stats.gather_table_stats(ownname => l_table_owner, tabname => 'JTF_RS_DEFAULT_GROUPS_INT',
328 percent=>5, degree=>f_get_degree_of_parallelism, granularity=>'ALL',cascade=>TRUE);
329
330 -------------Truncate the Staging table ---------
331
332 l_stage := 'Stage=TRUNCATE_JTF_RS_DEFAULT_GROUPS_STAGE_TABLE';
333
334 EXECUTE IMMEDIATE 'TRUNCATE TABLE '||l_index_owner||'.JTF_RS_DEFAULT_GROUPS_STAGE';
335
336 COMMIT;
337
338 ------------ Start the main logic here --------
339 l_stage := 'Stage=START_PLSQL_POPULATION_LOGIC';
340
341 FOR c_get_resource_id IN c_outer
342 LOOP
343
344 l_stage := 'Stage=INSIDE_PLSQL_OUTER_LOOP_FOR RESOURCE_ID : '||c_get_resource_id.resource_id;
345
346 -- re-initialize i and dates
347 i := 0;
348 l_prev_start_date := NULL;
349 l_prev_end_date := NULL;
350 ---------------------main for loop -----------------
351 FOR c_rec IN c1 (c_get_resource_id.resource_id)
352 LOOP
353
354 l_stage := 'Stage=INSIDE_PLSQL_INNER_LOOP_FOR RESOURCE_ID : '||c_get_resource_id.resource_id;
355
356 -- we should procees further only if the date range is different
357 -- this will help in eliminating few rows and improve performance
358 IF (l_prev_start_date IS NULL) THEN
359 l_skip_row := 'N';
360 l_prev_start_date := c_rec.START_DATE;
361 l_prev_end_date := c_rec.END_DATE;
362 ELSIF
363 ((c_rec.START_DATE BETWEEN l_prev_start_date AND l_prev_end_date) AND
364 (c_rec.END_DATE BETWEEN l_prev_start_date AND l_prev_end_date)) THEN
365 l_skip_row := 'Y';
366 ELSE
367 l_skip_row := 'N';
368 l_prev_start_date := c_rec.START_DATE;
369 l_prev_end_date := c_rec.END_DATE;
370 END IF;
371
372 -------------------If i=0------------------------
373 -- proceed only if l_skip_row = N
374 IF (l_skip_row = 'N') THEN
375 IF (i = 0) THEN
376 g_default_grp_tab(i).p_resource_id := c_rec.resource_id;
377 g_default_grp_tab(i).p_user_id := c_rec.user_id;
378 g_default_grp_tab(i).p_resource_number := c_rec.resource_number;
379 g_default_grp_tab(i).p_group_id := c_rec.group_id;
380 g_default_grp_tab(i).p_start_date := c_rec.start_date;
381 g_default_grp_tab(i).p_end_date := c_rec.end_date;
382 -------------------else of If i=0------------------------
383 ELSE
384 -- loop through the plsql table to check the dates of each record
385 ------------------For outer table looop-----------------------
386 l_inner_loop := 'N';
387 l_overlap := 'N';
388 l_deletion_occured := 'N' ;
389 j := g_default_grp_tab.FIRST;
390 WHILE j IS NOT NULL
391 LOOP
392 -- if data existed in inner table
393 IF (temp_default_grp_tab.COUNT > 0) THEN
394 l_inner_loop := 'Y' ;
395 l := temp_default_grp_tab.FIRST ;
396 WHILE l IS NOT NULL
397 LOOP
398 IF ((temp_default_grp_tab(l).p_start_date < g_default_grp_tab(j).p_start_date) AND
399 (temp_default_grp_tab(l).p_end_date BETWEEN g_default_grp_tab(j).p_start_date AND g_default_grp_tab(j).p_end_date))
400 THEN
401 temp_default_grp_tab(l).p_end_date := g_default_grp_tab(j).p_start_date -1;
402 ELSIF
403 ((temp_default_grp_tab(l).p_start_date BETWEEN g_default_grp_tab(j).p_start_date AND g_default_grp_tab(j).p_end_date)
404 AND
405 (temp_default_grp_tab(l).p_end_date > g_default_grp_tab(j).p_end_date)) THEN
406 temp_default_grp_tab(l).p_start_date := g_default_grp_tab(j).p_end_date +1;
407 ELSIF
408 ((temp_default_grp_tab(l).p_start_date < g_default_grp_tab(j).p_start_date) AND
409 (temp_default_grp_tab(l).p_end_date > g_default_grp_tab(j).p_end_date)) THEN
410 -- first get temp_default_grp_tab(l).p_end_date into new record
411 -- and then modify the end date in existing record
412 m := temp_default_grp_tab.LAST + 1;
413 --insert the 2nd record for this breakup
414 temp_default_grp_tab(m).p_resource_id := temp_default_grp_tab(l).p_resource_id;
415 temp_default_grp_tab(m).p_user_id := temp_default_grp_tab(l).p_user_id;
416 temp_default_grp_tab(m).p_resource_number := temp_default_grp_tab(l).p_resource_number;
417 temp_default_grp_tab(m).p_group_id := temp_default_grp_tab(l).p_group_id;
418 temp_default_grp_tab(m).p_start_date := g_default_grp_tab(j).p_end_date +1;
419 temp_default_grp_tab(m).p_end_date := temp_default_grp_tab(l).p_end_date;
420
421 -- modify existing record
422 temp_default_grp_tab(l).p_end_date := g_default_grp_tab(j).p_start_date -1;
423 ELSIF
424 ((temp_default_grp_tab(l).p_start_date BETWEEN g_default_grp_tab(j).p_start_date AND g_default_grp_tab(j).p_end_date)
425 AND
426 (temp_default_grp_tab(l).p_end_date BETWEEN g_default_grp_tab(j).p_start_date AND g_default_grp_tab(j).p_end_date))
427 THEN
428 -- delete this row from the inner table
429 temp_default_grp_tab.DELETE(l);
430 l_deletion_occured := 'Y' ;
431 END IF; -- end of inner table date checks
432
433 l := temp_default_grp_tab.NEXT(l);
434 END LOOP;
435 ELSE
436 l_inner_loop := 'N' ;
437 END IF;
438
439 -- do not go further if the inner loop record is deleted and now
440 -- we do not have any row inside that inner that inner table
441 -- i.e. further comparison is useless and we should not insert that record.
442 IF ((temp_default_grp_tab.COUNT = 0) AND (l_deletion_occured = 'Y')) THEN
443 -- falsely set the variable so that it does not go inside at all
444 l_inner_loop := 'Y';
445 EXIT ;
446 END IF;
447
448 -- if no row was there in inner table, continue comparing dates with
449 -- cursor dates
450 IF (l_inner_loop = 'N') THEN
451 -- check if date overlaps
452 IF ((g_default_grp_tab(j).p_start_date BETWEEN c_rec.start_date AND c_rec.end_date)
453 OR (c_rec.start_date BETWEEN g_default_grp_tab(j).p_start_date AND g_default_grp_tab(j).p_end_date))
454 THEN
455 -- go deep
456 --intialize the inner table counter
457 l_overlap := 'Y';
458 k := 0;
459 IF ((c_rec.start_date < g_default_grp_tab(j).p_start_date) AND
460 (c_rec.end_date BETWEEN g_default_grp_tab(j).p_start_date AND g_default_grp_tab(j).p_end_date)) THEN
461 temp_default_grp_tab(k).p_resource_id := c_rec.resource_id;
462 temp_default_grp_tab(k).p_user_id := c_rec.user_id;
463 temp_default_grp_tab(k).p_resource_number := c_rec.resource_number;
464 temp_default_grp_tab(k).p_group_id := c_rec.group_id;
465 temp_default_grp_tab(k).p_start_date := c_rec.start_date;
466 temp_default_grp_tab(k).p_end_date := g_default_grp_tab(j).p_start_date -1;
467 ELSIF
468 ((c_rec.start_date BETWEEN g_default_grp_tab(j).p_start_date AND g_default_grp_tab(j).p_end_date) AND
469 (c_rec.end_date > g_default_grp_tab(j).p_end_date)) THEN
470 temp_default_grp_tab(k).p_resource_id := c_rec.resource_id;
471 temp_default_grp_tab(k).p_user_id := c_rec.user_id;
472 temp_default_grp_tab(k).p_resource_number := c_rec.resource_number;
473 temp_default_grp_tab(k).p_group_id := c_rec.group_id;
474 temp_default_grp_tab(k).p_start_date := g_default_grp_tab(j).p_end_date +1;
475 temp_default_grp_tab(k).p_end_date := c_rec.end_date;
476 ELSIF
477 ((c_rec.start_date < g_default_grp_tab(j).p_start_date) AND
478 (c_rec.end_date > g_default_grp_tab(j).p_end_date)) THEN
479 temp_default_grp_tab(k).p_resource_id := c_rec.resource_id;
480 temp_default_grp_tab(k).p_user_id := c_rec.user_id;
481 temp_default_grp_tab(k).p_resource_number := c_rec.resource_number;
482 temp_default_grp_tab(k).p_group_id := c_rec.group_id;
483 temp_default_grp_tab(k).p_start_date := c_rec.start_date;
484 temp_default_grp_tab(k).p_end_date := g_default_grp_tab(j).p_start_date -1;
485
486 k := k + 1;
487 temp_default_grp_tab(k).p_resource_id := c_rec.resource_id;
488 temp_default_grp_tab(k).p_user_id := c_rec.user_id;
489 temp_default_grp_tab(k).p_resource_number := c_rec.resource_number;
490 temp_default_grp_tab(k).p_group_id := c_rec.group_id;
491 temp_default_grp_tab(k).p_start_date := g_default_grp_tab(j).p_end_date +1;
492 temp_default_grp_tab(k).p_end_date := c_rec.end_date;
493 ELSIF
494 ((c_rec.start_date BETWEEN g_default_grp_tab(j).p_start_date AND g_default_grp_tab(j).p_end_date) AND
495 (c_rec.end_date BETWEEN g_default_grp_tab(j).p_start_date AND g_default_grp_tab(j).p_end_date)) THEN
496 -- break from loop because we do not want to check further
497 -- for this condition
498 EXIT;
499 END IF; -- end of outer table date checks
500
501 ELSE -- doesn't overlap with any one
502 l_overlap := 'N';
503 END IF;
504
505 END IF; -- l_inner_loop = 'N' check
506 -------------------End of outer table loop------------------------
507 j := g_default_grp_tab.NEXT(j);
508 END LOOP;
509
510 -- If there was no overlap with any previous group, insert it
511 IF (l_overlap = 'N') THEN
512 g_default_grp_tab(i).p_resource_id := c_rec.resource_id;
513 g_default_grp_tab(i).p_user_id := c_rec.user_id;
514 g_default_grp_tab(i).p_resource_number := c_rec.resource_number;
515 g_default_grp_tab(i).p_group_id := c_rec.group_id;
516 g_default_grp_tab(i).p_start_date := c_rec.start_date;
517 g_default_grp_tab(i).p_end_date := c_rec.end_date;
518 END IF;
519
520 -- move data from inner table to outer table and then delete inner table.
521 IF (temp_default_grp_tab.COUNT > 0) THEN
522 n := g_default_grp_tab.LAST;
523 p := temp_default_grp_tab.FIRST;
524
525 WHILE p IS NOT NULL
526 LOOP
527 -- do only if start_date is before or eqal to end date
528 IF (temp_default_grp_tab(p).p_start_date <= temp_default_grp_tab(p).p_end_date) THEN
529 n := n + 1;
530 g_default_grp_tab(n).p_resource_id := temp_default_grp_tab(p).p_resource_id;
531 g_default_grp_tab(n).p_user_id := temp_default_grp_tab(p).p_user_id;
532 g_default_grp_tab(n).p_resource_number := temp_default_grp_tab(p).p_resource_number;
533 g_default_grp_tab(n).p_group_id := temp_default_grp_tab(p).p_group_id;
534 g_default_grp_tab(n).p_start_date := temp_default_grp_tab(p).p_start_date;
535 g_default_grp_tab(n).p_end_date := temp_default_grp_tab(p).p_end_date;
536 END IF;
537 p := temp_default_grp_tab.NEXT(p);
538 END LOOP;
539
540 temp_default_grp_tab.DELETE;
541 END IF;
542 -------------------If i=0------------------------
543 END IF;
544 --------------End If l_skip_row = N check---------
545 END IF;
546
547 i := i + 1;
548 ---------------------main for loop -----------------
549 END LOOP;
550
551 IF (g_default_grp_tab.COUNT > 0) THEN
552
553 o := g_default_grp_tab.FIRST ;
554
555 WHILE o IS NOT NULL
556 LOOP
557 INSERT INTO /*+ APPEND PARALLEL(sg1) NOLOGGING */ JTF_RS_DEFAULT_GROUPS_STAGE sg1
558 (default_groups_id, resource_id, user_id, resource_number,
559 group_id, start_date, end_date, usage,
560 created_by, creation_date, last_updated_by, last_update_date )
561 VALUES (JTF_RS_DEFAULT_GROUPS_STAGE_S.NEXTVAL, g_default_grp_tab(o).p_resource_id,
562 g_default_grp_tab(o).p_user_id, g_default_grp_tab(o).p_resource_number,
563 g_default_grp_tab(o).p_group_id, g_default_grp_tab(o).p_start_date,
564 g_default_grp_tab(o).p_end_date, l_usage,
565 l_user_id, sysdate, l_user_id, sysdate);
566
567 o := g_default_grp_tab.NEXT(o);
568 END LOOP;
569
570 -- delete the table for next resource id
571 g_default_grp_tab.DELETE;
572 END IF;
573 COMMIT;
574
575 END LOOP; -- end of c_outer cursor
576
577 -- analyze the Main table
578 l_stage := 'Stage=ANALYZING_JTF_RS_DEFAULT_GROUPS_STAGE_TABLE';
579
580 fnd_stats.gather_table_stats(ownname => l_table_owner, tabname => 'JTF_RS_DEFAULT_GROUPS_STAGE',
581 percent=>5, degree=>f_get_degree_of_parallelism, granularity=>'ALL',cascade=>TRUE);
582
583 -- Now compare data in recently refreshed table JTF_RS_DEFAULT_GROUPS_STAGE (new) with
584 -- previously populated table JTF_RS_DEFAULT_GROUPS (old) (final incremental table)
585
586 -- If there is some data in JTF_RS_DEFAULT_GROUPS (old data) which does not exist in
587 -- recently refreshed table JTF_RS_DEFAULT_GROUPS_STAGE, it means it is STALE data and
588 -- has to be DELETED from JTF_RS_DEFAULT_GROUPS (final table)
589
590 l_stage := 'Stage=DELETE_DATA_FROM_JTF_RS_DEFAULT_GROUPS_TABLE';
591
592 DELETE FROM jtf_rs_default_groups
593 WHERE (resource_id, NVL(user_id,-84), group_id, START_DATE, end_date, usage) IN
594 (
595 SELECT resource_id, NVL(user_id,-84), group_id, START_DATE, end_date, usage
596 FROM jtf_rs_default_groups
597 MINUS
598 SELECT resource_id, NVL(user_id,-84), group_id, START_DATE, end_date, usage
599 FROM jtf_rs_default_groups_stage
600 ) ;
601
602 COMMIT;
603
604 -- If there is some data in recently refreshed table JTF_RS_DEFAULT_GROUPS_STAGE
605 -- (new data) which does not exist in final table JTF_RS_DEFAULT_GROUPS_STAGE, it
606 -- means it is NEW data and has to be INSERTED in JTF_RS_DEFAULT_GROUPS (final table)
607
608 l_stage := 'Stage=INSERT_DATA_IN_JTF_RS_DEFAULT_GROUPS_TABLE';
609
610 INSERT INTO /*+ APPEND PARALLEL(sg1) NOLOGGING */ jtf_rs_default_groups sg1
611 (default_groups_id, resource_id, user_id, resource_number,
612 group_id, start_date, end_date, usage,
613 created_by, creation_date, last_updated_by, last_update_date )
614 SELECT
615 jtf_rs_default_groups_s.NEXTVAL, resource_id, user_id, resource_number,
616 group_id, start_date, end_date, usage,
617 l_user_id created_by, SYSDATE creation_date, l_user_id last_updated_by, SYSDATE
618 FROM (
619 SELECT resource_id, user_id, resource_number, group_id, START_DATE, end_date, usage
620 FROM jtf_rs_default_groups_stage
621 MINUS
622 SELECT resource_id, user_id, resource_number, group_id, START_DATE, end_date, usage
623 FROM jtf_rs_default_groups
624 );
625
626 COMMIT;
627
628 -- analyze Staging table
629 l_stage := 'Stage=ANALYZING_JTF_RS_DEFAULT_GROUPS_TABLE';
630
631 fnd_stats.gather_table_stats(ownname => l_table_owner, tabname => 'JTF_RS_DEFAULT_GROUPS',
632 percent=>5, degree=>f_get_degree_of_parallelism, granularity=>'ALL',cascade=>TRUE);
633
634 EXECUTE IMMEDIATE 'ALTER SESSION DISABLE PARALLEL DML';
635 --EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE=FALSE';
636
637 l_stage := 'Stage=Completed';
638 errbuf := l_stage;
639
640 EXCEPTION WHEN OTHERS THEN
641 fnd_file.put_line(fnd_file.log, l_stage);
642 fnd_file.put_line(fnd_file.log, sqlcode||':'||sqlerrm);
643 retcode := '2'; -- Error
644 errbuf := l_stage||' : ERROR : '||sqlerrm;
645 --dbms_output.put_line(l_stage||': Error : '||SQLERRM);
646 END populate_fs_district; -- end procedure
647
648 /****************************************************************************
649 This Function is used to fetch default group for specific usage given a
650 resource_id, date and usage as input parameter. This function will fetch data
651 only if data is populated in jtf_rs_default_groups table for that usage.
652
653 Created By nsinghai 07/21/2004
654 Modified By
655
656 *****************************************************************************/
657
658 FUNCTION get_default_group
659 (p_resource_id IN NUMBER,
660 p_usage IN VARCHAR2,
661 p_date IN DATE
662 ) RETURN NUMBER
663 IS
664 l_date DATE ;
665 l_group_id NUMBER;
666
667 BEGIN
668 l_date := TRUNC(NVL(p_date, SYSDATE));
669
670 SELECT group_id
671 INTO l_group_id
672 FROM jtf_rs_default_groups
673 WHERE resource_id = p_resource_id
674 AND usage = p_usage
675 AND l_date BETWEEN start_date AND end_date;
676
677 RETURN l_group_id;
678
679 -- if too_many_rows or no_data_found then return -1
680 EXCEPTION WHEN OTHERS THEN
681 RETURN -1;
682
683 END get_default_group;
684
685 END jtf_rs_default_groups_conc_pub; -- end package body