[Home] [Help]
PACKAGE BODY: APPS.PA_SCHEDULE_PVT
Source
1 PACKAGE BODY PA_SCHEDULE_PVT as
2 --/* $Header: PARGPVTB.pls 120.32 2010/12/15 12:08:06 smadhava ship $ */
3
4 l_out_of_range_date EXCEPTION; -- Exception variable for raising the exception when date is out of range
5 l_invalid_date_range EXCEPTION; -- Exception variable for raising the exception when date is invalid of range
6 l_empty_tab_record EXCEPTION; -- Variable to raise the exception if the passing table of records is empty
7 l_remove_conflicts_failed EXCEPTION; -- Variable to raise the exception if conflicts can not be removed because one or more conflicting assignments are locked
8 l_x_return_status VARCHAR2(50); -- variable to store the return status
9
10
11 -- This procedure will get the existing schedule for the duration shift and pattern
12 -- Input parameters
13 -- Parameters Type Required Description
14 -- P_Calendar_Id NUMBER YES Id for that calendar to which you want to get schedule
15 -- P_Start_Date DATE YES Starting date of the schedule for that calendar
16 -- P_Start_Date DATE YES Ending date of the schedule for that calendar
17 --x_difference_days NUMBER YES number of days shifted
18 --x_shift_unit_code VARCHAR2 YES Unit of Shift
19
20 --
21 -- Out parameters
22 -- X_Sch_Record_Tab SCHEDULETABTYP YES It stores schedule for that calendar
23 --
24
25 PROCEDURE get_existing_schedule ( p_calendar_id IN NUMBER,
26 p_assignment_id IN NUMBER,
27 p_start_date IN DATE,
28 p_end_date IN DATE,
29 x_sch_record_tab OUT NOCOPY PA_SCHEDULE_GLOB.ScheduleTabTyp,
30 x_difference_days IN NUMBER,
31 x_shift_unit_code IN VARCHAR2,
32 x_return_status OUT NOCOPY VARCHAR2,
33 x_msg_count OUT NOCOPY NUMBER,
34 x_msg_data OUT NOCOPY VARCHAR2 )
35 IS
36 l_I NUMBER;
37 l_J NUMBER;
38
39 l_st_dt_done BOOLEAN; -- Temp variable
40 l_end_dt_done BOOLEAN; -- Temp variable
41 l_x_sch_copy_done BOOLEAN; -- Temp variable
42 l_curr_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
43 l_out_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
44 l_temp_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
45
46
47 TYPE calendar_id_tbl IS TABLE OF PA_SCHEDULES.calendar_id%TYPE
48 INDEX BY BINARY_INTEGER;
49 TYPE start_date_tbl IS TABLE OF PA_SCHEDULES.start_date%TYPE
50 INDEX BY BINARY_INTEGER;
51 TYPE end_date_tbl IS TABLE OF PA_SCHEDULES.end_date%TYPE
52 INDEX BY BINARY_INTEGER;
53 TYPE Monday_hours_tbl IS TABLE OF PA_SCHEDULES.Monday_hours%TYPE
54 INDEX BY BINARY_INTEGER;
55 TYPE Tuesday_hours_tbl IS TABLE OF PA_SCHEDULES.Tuesday_hours%TYPE
56 INDEX BY BINARY_INTEGER;
57 TYPE Wednesday_hours_tbl IS TABLE OF PA_SCHEDULES.Wednesday_hours%TYPE
58 INDEX BY BINARY_INTEGER;
59 TYPE Thursday_hours_tbl IS TABLE OF PA_SCHEDULES.Thursday_hours%TYPE
60 INDEX BY BINARY_INTEGER;
61 TYPE Friday_hours_tbl IS TABLE OF PA_SCHEDULES.Friday_hours%TYPE
62 INDEX BY BINARY_INTEGER;
63 TYPE Saturday_hours_tbl IS TABLE OF PA_SCHEDULES.Saturday_hours%TYPE
64 INDEX BY BINARY_INTEGER;
65 TYPE Sunday_hours_tbl IS TABLE OF PA_SCHEDULES.Sunday_hours%TYPE
66 INDEX BY BINARY_INTEGER;
67
68 l_calendar_id_tbl calendar_id_tbl;
69 l_start_date_tbl start_date_tbl ;
70 l_end_date_tbl end_date_tbl ;
71 l_Monday_hours_tbl Monday_hours_tbl ;
72 l_Tuesday_hours_tbl Tuesday_hours_tbl;
73 l_Wednesday_hours_tbl Wednesday_hours_tbl ;
74 l_Thursday_hours_tbl Thursday_hours_tbl;
75 l_Friday_hours_tbl Friday_hours_tbl ;
76 l_Saturday_hours_tbl Saturday_hours_tbl ;
77 l_Sunday_hours_tbl Sunday_hours_tbl ;
78
79 l_first_index NUMBER;
80 l_last_index NUMBER;
81 i NUMBER;
82
83 l_no_days NUMBER := 0;
84 l_next_start_date Date;
85
86 BEGIN
87 l_st_dt_done := FALSE;
88 l_end_dt_done := FALSE;
89 l_x_sch_copy_done := FALSE;
90 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
91
92 SELECT calendar_id,
93 start_date,
94 end_date,
95 Monday_hours,
96 Tuesday_hours,
97 Wednesday_hours,
98 Thursday_hours,
99 Friday_hours,
100 Saturday_hours,
101 Sunday_hours
102 BULK COLLECT INTO
103 l_calendar_id_tbl ,
104 l_start_date_tbl ,
105 l_end_date_tbl ,
106 l_Monday_hours_tbl ,
107 l_Tuesday_hours_tbl ,
108 l_Wednesday_hours_tbl ,
109 l_Thursday_hours_tbl ,
110 l_Friday_hours_tbl ,
111 l_Saturday_hours_tbl ,
112 l_Sunday_hours_tbl
113 FROM PA_SCHEDULES sch
114 WHERE sch.assignment_id = p_assignment_id
115 ORDER BY sch.start_date;
116
117 l_first_index := NVL(l_start_date_tbl.first,0);
118 l_last_index := NVL(l_start_date_tbl.last,-1);
119
120 FOR i IN l_first_index .. l_last_index LOOP
121 l_curr_schedule_rec(i).start_date := l_start_date_tbl(i);
122 l_curr_schedule_rec(i).end_date := l_end_date_tbl(i);
123 l_curr_schedule_rec(i).Monday_hours := l_Monday_hours_tbl(i);
124 l_curr_schedule_rec(i).Tuesday_hours := l_Tuesday_hours_tbl(i);
125 l_curr_schedule_rec(i).Wednesday_hours := l_Wednesday_hours_tbl(i);
126 l_curr_schedule_rec(i).Thursday_hours := l_Thursday_hours_tbl(i);
127 l_curr_schedule_rec(i).Friday_hours := l_Friday_hours_tbl(i);
128 l_curr_schedule_rec(i).Saturday_hours := l_Saturday_hours_tbl(i);
129 l_curr_schedule_rec(i).Sunday_hours := l_Sunday_hours_tbl(i);
130
131
132 /* if (x_shift_unit_code = 'MONTHS') then
133 l_no_days := round(months_between(l_end_date_tbl(i), l_start_date_tbl(i))) ;
134 else
135 l_no_days := l_end_date_tbl(i) - l_start_date_tbl(i) ;
136 end if; */ /* Commented for bug 9229210 */
137
138 /* if (i = l_first_index) then */ /* Commented for bug 9229210 */
139 if (x_shift_unit_code = 'MONTHS') then
140 l_curr_schedule_rec(i).start_date := add_months(l_curr_schedule_rec(i).start_date, x_difference_days);
141 l_curr_schedule_rec(i).end_date := add_months(l_curr_schedule_rec(i).end_date, x_difference_days);
142 else
143 l_curr_schedule_rec(i).start_date := l_curr_schedule_rec(i).start_date + x_difference_days;
144 l_curr_schedule_rec(i).end_date := l_curr_schedule_rec(i).end_date + x_difference_days;
145 end if;
146 /* else
147 l_curr_schedule_rec(i).start_date := l_next_start_date;
148 end if; */ /* Commented for bug 9229210 */
149
150 /* if (x_shift_unit_code = 'MONTHS') then
151 l_curr_schedule_rec(i).end_date := add_months(l_curr_schedule_rec(i).start_date, l_no_days);
152 l_curr_schedule_rec(i).end_date := l_curr_schedule_rec(i).end_date - 1;
153 else
154 l_curr_schedule_rec(i).end_date := l_curr_schedule_rec(i).start_date + l_no_days;
155 end if;
156
157 l_next_start_date := l_curr_schedule_rec(i).end_date + 1; */ /* Commented for bug 9229210 */
158
159 END LOOP;
160
161 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
162 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_curr_schedule_rec,l_curr_schedule_rec.first,l_curr_schedule_rec.last,
163 x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
164 END IF;
165
166 x_return_status := l_x_return_status;
167
168 EXCEPTION
169 WHEN OTHERS THEN
170 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
171 x_msg_count := 1;
172 x_msg_data := SQLERRM;
173 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
174 p_procedure_name => 'get_existing_schedule');
175 raise;
176
177 END get_existing_schedule;
178
179
180
181 -- This procedure will get the calendar schedule on the basis of calendar id
182 -- Input parameters
183 -- Parameters Type Required Description
184 -- P_Calendar_Id NUMBER YES Id for that calendar to which you want to get schedule
185 -- P_Start_Date DATE YES Starting date of the schedule for that calendar
186 -- P_Start_Date DATE YES Ending date of the schedule for that calendar
187 --
188 -- Out parameters
189 -- X_Sch_Record_Tab SCHEDULETABTYP YES It stores schedule for that calendar
190 --
191
192 PROCEDURE get_calendar_schedule ( p_calendar_id IN NUMBER,
193 p_start_date IN DATE,
194 p_end_date IN DATE,
195 x_sch_record_tab OUT NOCOPY PA_SCHEDULE_GLOB.ScheduleTabTyp,
196 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
197 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
198 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
199 IS
200 l_I NUMBER;
201 l_J NUMBER;
202
203 l_st_dt_done BOOLEAN; -- Temp variable
204 l_end_dt_done BOOLEAN; -- Temp variable
205 l_x_sch_copy_done BOOLEAN; -- Temp variable
206 l_curr_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
207 l_out_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
208 l_temp_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
209
210 -- This cursor will select the schedule records of the passing calendar
211 /* Bug - 1846658- Following lines are commented to incorporate the BULK SELECT to enhance the performance*/
212
213 -- CURSOR C1 IS SELECT calendar_id,start_date,end_date,Monday_hours,Tuesday_hours,Wednesday_hours,Thursday_hours,
214 -- Friday_hours,Saturday_hours,Sunday_hours
215 -- FROM PA_SCHEDULES sch
216 -- WHERE sch.calendar_id = p_calendar_id
217 -- AND sch.schedule_type_code = 'CALENDAR'
218 -- AND ( ( p_start_date BETWEEN sch.start_date AND sch.end_date)
219 -- OR ( p_end_date BETWEEN sch.start_date AND sch.end_date)
220 -- OR ( p_start_date < sch.start_date AND p_end_date > sch.end_date) ) ;
221 -- ORDER BY sch.start_date
222
223 /* Bug - 1846658- Following lines are added to incorporate the BULK SELECT to enhance the performance*/
224
225 TYPE calendar_id_tbl IS TABLE OF PA_SCHEDULES.calendar_id%TYPE
226 INDEX BY BINARY_INTEGER;
227 TYPE start_date_tbl IS TABLE OF PA_SCHEDULES.start_date%TYPE
228 INDEX BY BINARY_INTEGER;
229 TYPE end_date_tbl IS TABLE OF PA_SCHEDULES.end_date%TYPE
230 INDEX BY BINARY_INTEGER;
231 TYPE Monday_hours_tbl IS TABLE OF PA_SCHEDULES.Monday_hours%TYPE
232 INDEX BY BINARY_INTEGER;
233 TYPE Tuesday_hours_tbl IS TABLE OF PA_SCHEDULES.Tuesday_hours%TYPE
234 INDEX BY BINARY_INTEGER;
235 TYPE Wednesday_hours_tbl IS TABLE OF PA_SCHEDULES.Wednesday_hours%TYPE
236 INDEX BY BINARY_INTEGER;
237 TYPE Thursday_hours_tbl IS TABLE OF PA_SCHEDULES.Thursday_hours%TYPE
238 INDEX BY BINARY_INTEGER;
239 TYPE Friday_hours_tbl IS TABLE OF PA_SCHEDULES.Friday_hours%TYPE
240 INDEX BY BINARY_INTEGER;
241 TYPE Saturday_hours_tbl IS TABLE OF PA_SCHEDULES.Saturday_hours%TYPE
242 INDEX BY BINARY_INTEGER;
243 TYPE Sunday_hours_tbl IS TABLE OF PA_SCHEDULES.Sunday_hours%TYPE
244 INDEX BY BINARY_INTEGER;
245
246 l_calendar_id_tbl calendar_id_tbl;
247 l_start_date_tbl start_date_tbl ;
248 l_end_date_tbl end_date_tbl ;
249 l_Monday_hours_tbl Monday_hours_tbl ;
250 l_Tuesday_hours_tbl Tuesday_hours_tbl;
251 l_Wednesday_hours_tbl Wednesday_hours_tbl ;
252 l_Thursday_hours_tbl Thursday_hours_tbl;
253 l_Friday_hours_tbl Friday_hours_tbl ;
254 l_Saturday_hours_tbl Saturday_hours_tbl ;
255 l_Sunday_hours_tbl Sunday_hours_tbl ;
256
257 l_first_index NUMBER;
258 l_last_index NUMBER;
259 i NUMBER;
260
261 BEGIN
262 l_st_dt_done := FALSE;
263 l_end_dt_done := FALSE;
264 l_x_sch_copy_done := FALSE;
265 -- store status success to track the error
266 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
267
268 /* Bug - 1846658- Following lines are commented to incorporate the BULK SELECT to enhance the performance*/
269
270 -- FOR v_c1 IN C1 LOOP
271 -- l_curr_schedule_rec(1).start_date := v_c1.start_date;
272 -- l_curr_schedule_rec(1).end_date := v_c1.end_date;
273 -- l_curr_schedule_rec(1).Monday_hours := v_c1.Monday_hours;
274 -- l_curr_schedule_rec(1).Tuesday_hours := v_c1.Tuesday_hours;
275 -- l_curr_schedule_rec(1).Wednesday_hours := v_c1.Wednesday_hours;
276 -- l_curr_schedule_rec(1).Thursday_hours := v_c1.Thursday_hours;
277 -- l_curr_schedule_rec(1).Friday_hours := v_c1.Friday_hours;
278 -- l_curr_schedule_rec(1).Saturday_hours := v_c1.Saturday_hours;
279 -- l_curr_schedule_rec(1).Sunday_hours := v_c1.Sunday_hours;
280
281 /* Bug - 1846658- Following lines are added to incorporate the BULK SELECT to enhance the performance*/
282
283 SELECT calendar_id,
284 start_date,
285 end_date,
286 Monday_hours,
287 Tuesday_hours,
288 Wednesday_hours,
289 Thursday_hours,
290 Friday_hours,
291 Saturday_hours,
292 Sunday_hours
293 BULK COLLECT INTO
294 l_calendar_id_tbl ,
295 l_start_date_tbl ,
296 l_end_date_tbl ,
297 l_Monday_hours_tbl ,
298 l_Tuesday_hours_tbl ,
299 l_Wednesday_hours_tbl ,
300 l_Thursday_hours_tbl ,
301 l_Friday_hours_tbl ,
302 l_Saturday_hours_tbl ,
303 l_Sunday_hours_tbl
304 FROM PA_SCHEDULES sch
305 WHERE sch.calendar_id = p_calendar_id
306 AND sch.schedule_type_code = 'CALENDAR'
307 AND ( ( p_start_date BETWEEN sch.start_date AND sch.end_date)
308 OR ( p_end_date BETWEEN sch.start_date AND sch.end_date)
309 OR ( p_start_date < sch.start_date AND p_end_date > sch.end_date) )
310 ORDER BY sch.start_date;
311
312 l_first_index := NVL(l_start_date_tbl.first,0);
313 l_last_index := NVL(l_start_date_tbl.last,-1);
314
315 FOR i IN l_first_index .. l_last_index LOOP
316
317 l_curr_schedule_rec(1).start_date := l_start_date_tbl(i);
318 l_curr_schedule_rec(1).end_date := l_end_date_tbl(i);
319 l_curr_schedule_rec(1).Monday_hours := l_Monday_hours_tbl(i);
320 l_curr_schedule_rec(1).Tuesday_hours := l_Tuesday_hours_tbl(i);
321 l_curr_schedule_rec(1).Wednesday_hours := l_Wednesday_hours_tbl(i);
322 l_curr_schedule_rec(1).Thursday_hours := l_Thursday_hours_tbl(i);
323 l_curr_schedule_rec(1).Friday_hours := l_Friday_hours_tbl(i);
324 l_curr_schedule_rec(1).Saturday_hours := l_Saturday_hours_tbl(i);
325 l_curr_schedule_rec(1).Sunday_hours := l_Sunday_hours_tbl(i);
326
327
328 -- The passing start date if greater the existing end date of the schedule or greater or
329 -- equal to the existing start date
330 IF (p_start_date > l_curr_schedule_rec(1).end_date) AND (l_st_dt_done = FALSE) THEN
331 NULL;
332 ELSE
333 IF (p_start_date = l_curr_schedule_rec(1).start_date) AND ( l_st_dt_done = FALSE) THEN
334 l_st_dt_done := TRUE;
335 ELSIF ( p_start_date > l_curr_schedule_rec(1).start_date ) AND (l_st_dt_done = FALSE) THEN
336 l_curr_schedule_rec(1).start_date := p_start_date;
337 l_st_dt_done:= TRUE;
338 END IF;
339
340 -- The passing end date if less than or equal to the existing end date of the schedule or
341 -- greater to the existing end date
342 IF ((p_end_date <= l_curr_schedule_rec(1).end_date) AND (l_end_dt_done = FALSE)) THEN
343 l_curr_schedule_rec(1).end_date := p_end_date;
344 l_end_dt_done := TRUE;
345 ELSIF (p_end_date > l_curr_schedule_rec(1).end_date ) AND (l_end_dt_done = FALSE) THEN
346 NULL;
347 END IF;
348
349
350 -- Appending the record which is being changed in above validation
351 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
352 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_curr_schedule_rec,1,1,l_out_schedule_rec,l_x_return_status,x_msg_count,
353 x_msg_data);
354 END IF;
355
356 IF (l_st_dt_done = TRUE ) AND (l_end_dt_done = TRUE) THEN
357 EXIT;
358 END IF;
359
360 END IF;
361 END LOOP;
362
363 -- The calendar has schedule record in the table of record then the following processing will occur
364 IF ( l_out_schedule_rec.count > 0 ) THEN
365 l_I := l_out_schedule_rec.first;
366 l_J := l_out_schedule_rec.Last;
367
368 -- If the start date is lower than the schedule start date the its schedule will be 0 and take the actual schedule
369 -- on the schedule start date
370 IF (p_start_date < l_out_schedule_rec(l_I).start_date) THEN
371 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
372 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,1,1,l_temp_schedule_rec,l_x_return_status,x_msg_count,
373 x_msg_data);
374 END IF;
375
376 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
377 PA_SCHEDULE_UTILS.update_sch_rec_tab(px_sch_record_tab => l_temp_schedule_rec,p_start_date =>p_start_date,
378 p_end_date =>l_out_schedule_rec(l_I).start_date -1 ,p_monday_hours =>0.00,p_tuesday_hours =>0.00,
379 p_wednesday_hours =>0.00,p_thursday_hours =>0.00,p_friday_hours =>0.00,p_saturday_hours =>0.00,
380 p_sunday_hours =>0.00,x_return_status => l_x_return_status,x_msg_count => x_msg_count,
381 x_msg_data =>x_msg_data);
382 END IF;
383
384 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
385 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_temp_schedule_rec,1,1,x_sch_record_tab,l_x_return_status,x_msg_count,
386 x_msg_data);
387 END IF;
388
389 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
390 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_out_schedule_rec,l_out_schedule_rec.first,l_out_schedule_rec.last,
391 x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
392 END IF;
393 l_x_sch_copy_done := TRUE;
394 END IF;
395 -- If the end date is beyond the end date of the schedule of the passed calendar
396 -- then its that period will be having 0 work pattern
397 IF (p_end_date > l_out_schedule_rec(l_J).end_date) THEN
398 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
399 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,1,1,l_temp_schedule_rec,l_x_return_status,
400 x_msg_count,x_msg_data);
401 END IF;
402
403 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
404 PA_SCHEDULE_UTILS.update_sch_rec_tab(px_sch_record_tab => l_temp_schedule_rec,
405 p_start_date =>l_out_schedule_rec(l_J).end_date + 1 , p_end_date => p_end_date,p_monday_hours =>0.00,
406 p_tuesday_hours =>0.00, p_wednesday_hours =>0.00,p_thursday_hours =>0.00,p_friday_hours =>0.00,
407 p_saturday_hours =>0.00,p_sunday_hours =>0.00,
408 x_return_status => l_x_return_status,x_msg_count => x_msg_count,x_msg_data =>x_msg_data);
409 END IF;
410
411 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS AND l_x_sch_copy_done <> TRUE ) THEN
412 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_out_schedule_rec,l_out_schedule_rec.first,l_out_schedule_rec.last,
413 x_sch_record_tab, l_x_return_status,x_msg_count,x_msg_data);
414 END IF;
415
416 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
417 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_temp_schedule_rec,1,1,x_sch_record_tab,l_x_return_status,x_msg_count,
418 x_msg_data);
419 END IF;
420 l_x_sch_copy_done := TRUE;
421 END IF;
422 ELSE
423 l_out_schedule_rec(1).start_date := p_start_date;
424 l_out_schedule_rec(1).end_date := p_end_date ;
425 l_out_schedule_rec(1).monday_hours := 0.00;
426 l_out_schedule_rec(1).tuesday_hours := 0.00;
427 l_out_schedule_rec(1).wednesday_hours := 0.00;
428 l_out_schedule_rec(1).thursday_hours := 0.00;
429 l_out_schedule_rec(1).friday_hours := 0.00;
430 l_out_schedule_rec(1).saturday_hours := 0.00;
431 l_out_schedule_rec(1).sunday_hours := 0.00;
432 END IF;
433
434 IF l_x_sch_copy_done = FALSE THEN
435 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
436 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,l_out_schedule_rec.first,l_out_schedule_rec.last,
437 x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
438 END IF;
439 END IF;
440 x_return_status := l_x_return_status;
441
442 EXCEPTION
443 WHEN OTHERS THEN
444 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
445 x_msg_count := 1;
446 x_msg_data := SQLERRM;
447 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
448 p_procedure_name => 'get_calendar_schedule');
449 raise;
450
451 END get_calendar_schedule;
452
453 -- This procedure will take assignment id,start_date and end date and then will get the schedule for
454 -- the passed assignment. This is an overloaded procedure.
455 -- Input parameters
456 -- Parameters Type Required Description
457 -- P_Assignment_Id NUMBER YES Id for that assignment to which you want to get schedule
458 -- P_Start_Date DATE YES Starting date of the schedule for that assignment
459 -- P_Start_Date DATE YES Ending date of the schedule for that assignment
460 --
461 -- Out parameters
462 -- X_Sch_Record_Tab SCHEDULETABTYP YES It stores schedule for that assignment
463 --
464
465 PROCEDURE get_assignment_schedule ( p_assignment_id IN NUMBER,
466 p_start_date IN DATE,
467 p_end_date IN DATE,
468 x_sch_record_tab OUT NOCOPY PA_SCHEDULE_GLOB.ScheduleTabTyp,
469 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
470 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
471 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
472 IS
473 l_I NUMBER;
474 l_J NUMBER;
475
476 l_st_dt_done BOOLEAN;
477 l_end_dt_done BOOLEAN;
478 l_x_sch_copy_done BOOLEAN;
479 l_curr_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
480 l_out_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
481 l_temp_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
482
483 -- This cursor will select only those records of passing assignment which are open or staffed.
484 -- 1561861 Added 'STAFFED_ADMIN_ASSIGNMENT' to the where clause'.
485 /* Bug - 1846658- Following lines are commented to incorporate the BULK SELECT to enhance the performance*/
486
487 -- CURSOR C1 IS SELECT schedule_id, calendar_id,
488 -- assignment_id,project_id,schedule_type_code,status_code,
489 -- system_status_code,start_date,end_date,Monday_hours,Tuesday_hours,
490 -- Wednesday_hours,Thursday_hours,
491 -- Friday_hours,Saturday_hours,Sunday_hours
492 -- FROM PA_SCHEDULES_V sch
493 -- WHERE sch.assignment_id = p_assignment_id
494 -- AND sch.schedule_type_code IN
495 -- ('OPEN_ASSIGNMENT','STAFFED_ASSIGNMENT', 'STAFFED_ADMIN_ASSIGNMENT')
496 -- AND ( ( p_start_date BETWEEN sch.start_date AND sch.end_date)
497 -- OR ( p_end_date BETWEEN sch.start_date AND sch.end_date)
498 -- OR ( p_start_date < sch.start_date AND p_end_date > sch.end_date) )
499 -- ORDER BY start_date;
500
501 /* Bug - 1846658- Following lines are added to incorporate the BULK SELECT to enhance the performance*/
502
503 TYPE schedule_id_tbl IS TABLE OF PA_SCHEDULES_V.schedule_id%TYPE
504 INDEX BY BINARY_INTEGER;
505 TYPE calendar_id_tbl IS TABLE OF PA_SCHEDULES_V.calendar_id%TYPE
506 INDEX BY BINARY_INTEGER;
507 TYPE assignment_id_tbl IS TABLE OF PA_SCHEDULES_V.assignment_id%TYPE
508 INDEX BY BINARY_INTEGER;
509 TYPE project_id_tbl IS TABLE OF PA_SCHEDULES_V.project_id%TYPE
510 INDEX BY BINARY_INTEGER;
511 TYPE schedule_type_code_tbl IS TABLE OF PA_SCHEDULES_V.schedule_type_code%TYPE
512 INDEX BY BINARY_INTEGER;
513 TYPE status_code_tbl IS TABLE OF PA_SCHEDULES_V.status_code%TYPE
514 INDEX BY BINARY_INTEGER;
515 TYPE system_status_code_tbl IS TABLE OF PA_SCHEDULES_V.system_status_code%TYPE
516 INDEX BY BINARY_INTEGER;
517 TYPE start_date_tbl IS TABLE OF PA_SCHEDULES_V.start_date%TYPE
518 INDEX BY BINARY_INTEGER;
519 TYPE end_date_tbl IS TABLE OF PA_SCHEDULES_V.end_date%TYPE
520 INDEX BY BINARY_INTEGER;
521 TYPE Monday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Monday_hours%TYPE
522 INDEX BY BINARY_INTEGER;
523 TYPE Tuesday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Tuesday_hours%TYPE
524 INDEX BY BINARY_INTEGER;
525 TYPE Wednesday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Wednesday_hours%TYPE
526 INDEX BY BINARY_INTEGER;
527 TYPE Thursday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Thursday_hours%TYPE
528 INDEX BY BINARY_INTEGER;
529 TYPE Friday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Friday_hours%TYPE
530 INDEX BY BINARY_INTEGER;
531 TYPE Saturday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Saturday_hours%TYPE
532 INDEX BY BINARY_INTEGER;
533 TYPE Sunday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Sunday_hours%TYPE
534 INDEX BY BINARY_INTEGER;
535
536 l_schedule_id_tbl schedule_id_tbl ;
537 l_calendar_id_tbl calendar_id_tbl ;
538 l_assignment_id_tbl assignment_id_tbl;
539 l_project_id_tbl project_id_tbl;
540 l_schedule_type_code_tbl schedule_type_code_tbl;
541 l_status_code_tbl status_code_tbl ;
542 l_system_status_code_tbl system_status_code_tbl;
543 l_start_date_tbl start_date_tbl ;
544 l_end_date_tbl end_date_tbl ;
545 l_Monday_hours_tbl Monday_hours_tbl ;
546 l_Tuesday_hours_tbl Tuesday_hours_tbl;
547 l_Wednesday_hours_tbl Wednesday_hours_tbl ;
548 l_Thursday_hours_tbl Thursday_hours_tbl;
549 l_Friday_hours_tbl Friday_hours_tbl ;
550 l_Saturday_hours_tbl Saturday_hours_tbl ;
551 l_Sunday_hours_tbl Sunday_hours_tbl ;
552
553 l_first_index NUMBER;
554 l_last_index NUMBER;
555 i NUMBER;
556
557 /*Bug 2335580 */
558
559 l_assignment_start_date pa_schedules.start_date%TYPE;
560 l_assignment_end_date pa_schedules.end_date%TYPE;
561 l_assignment_calendar_id pa_schedules.calendar_id%TYPE;
562
563 CURSOR CUR_ASSIGNMENT_SCHEDULE(x_assignment_id IN NUMBER) IS
564 SELECT calendar_id, min(start_date), max(end_date)
565 FROM PA_SCHEDULES
566 WHERE assignment_id = x_assignment_id
567 AND schedule_type_code='OPEN_ASSIGNMENT'
568 GROUP BY Calendar_id;
569
570
571 BEGIN
572 l_st_dt_done := FALSE;
573 l_end_dt_done := FALSE;
574 l_x_sch_copy_done := FALSE;
575 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
576
577 /* Bug - 1846658- Following lines are commented to incorporate the BULK SELECT to enhance the performance*/
578
579 -- FOR v_c1 IN C1 LOOP
580 -- l_curr_schedule_rec(1).assignment_id := v_c1.assignment_id;
581 -- l_curr_schedule_rec(1).project_id := v_c1.project_id;
582 -- l_curr_schedule_rec(1).schedule_type_code := v_c1.schedule_type_code;
583 -- l_curr_schedule_rec(1).assignment_status_code := v_c1.status_code;
584 -- l_curr_schedule_rec(1).system_status_code := v_c1.system_status_code;
585 -- l_curr_schedule_rec(1).calendar_id := v_c1.calendar_id;
586 -- l_curr_schedule_rec(1).schedule_id := v_c1.schedule_id;
587 -- l_curr_schedule_rec(1).start_date := v_c1.start_date;
588 -- l_curr_schedule_rec(1).end_date := v_c1.end_date;
589 -- l_curr_schedule_rec(1).Monday_hours := v_c1.Monday_hours;
590 -- l_curr_schedule_rec(1).Tuesday_hours := v_c1.Tuesday_hours;
591 -- l_curr_schedule_rec(1).Wednesday_hours := v_c1.Wednesday_hours;
592 -- l_curr_schedule_rec(1).Thursday_hours := v_c1.Thursday_hours;
593 -- l_curr_schedule_rec(1).Friday_hours := v_c1.Friday_hours;
594 -- l_curr_schedule_rec(1).Saturday_hours := v_c1.Saturday_hours;
595 -- l_curr_schedule_rec(1).Sunday_hours := v_c1.Sunday_hours;
596
597 /*BUG 2335580 */
598
599 OPEN CUR_ASSIGNMENT_SCHEDULE (p_assignment_id);
600 FETCH cur_assignment_schedule INTO l_assignment_calendar_id,l_assignment_start_date, l_assignment_end_date;
601 CLOSE cur_assignment_schedule;
602
603
604 /* Bug - 1846658- Following lines are added to incorporate the BULK SELECT to enhance the performance*/
605
606 SELECT schedule_id,
607 calendar_id,
608 assignment_id,
609 project_id,
610 schedule_type_code,
611 status_code,
612 system_status_code,
613 start_date,
614 end_date,
615 Monday_hours,
616 Tuesday_hours,
617 Wednesday_hours,
618 Thursday_hours,
619 Friday_hours,
620 Saturday_hours,
621 Sunday_hours
622 BULK COLLECT INTO
623 l_schedule_id_tbl,
624 l_calendar_id_tbl,
625 l_assignment_id_tbl,
626 l_project_id_tbl,
627 l_schedule_type_code_tbl,
628 l_status_code_tbl ,
629 l_system_status_code_tbl,
630 l_start_date_tbl,
631 l_end_date_tbl,
632 l_Monday_hours_tbl,
633 l_Tuesday_hours_tbl,
634 l_Wednesday_hours_tbl,
635 l_Thursday_hours_tbl,
636 l_Friday_hours_tbl,
637 l_Saturday_hours_tbl,
638 l_Sunday_hours_tbl
639 FROM PA_SCHEDULES_V sch
640 WHERE sch.assignment_id = p_assignment_id
641 AND sch.schedule_type_code IN
642 ('OPEN_ASSIGNMENT','STAFFED_ASSIGNMENT', 'STAFFED_ADMIN_ASSIGNMENT')
643 AND ( ( p_start_date BETWEEN sch.start_date AND sch.end_date)
644 OR ( p_end_date BETWEEN sch.start_date AND sch.end_date)
645 OR ( p_start_date < sch.start_date AND p_end_date > sch.end_date) )
646 ORDER BY start_date;
647
648 l_first_index := NVL(l_schedule_id_tbl.first,0);
649 l_last_index := NVL(l_schedule_id_tbl.last,-1);
650
651 FOR i IN l_first_index .. l_last_index LOOP
652 l_curr_schedule_rec(1).assignment_id := l_assignment_id_tbl(i);
653 l_curr_schedule_rec(1).project_id := l_project_id_tbl(i);
654 l_curr_schedule_rec(1).schedule_type_code := l_schedule_type_code_tbl(i);
655 l_curr_schedule_rec(1).assignment_status_code := l_status_code_tbl(i);
656 l_curr_schedule_rec(1).system_status_code := l_system_status_code_tbl(i);
657 l_curr_schedule_rec(1).calendar_id := l_calendar_id_tbl(i);
658 l_curr_schedule_rec(1).schedule_id := l_schedule_id_tbl(i);
659 l_curr_schedule_rec(1).start_date := l_start_date_tbl(i);
660 l_curr_schedule_rec(1).end_date := l_end_date_tbl(i);
661 l_curr_schedule_rec(1).Monday_hours := l_Monday_hours_tbl(i);
662 l_curr_schedule_rec(1).Tuesday_hours := l_Tuesday_hours_tbl(i);
663 l_curr_schedule_rec(1).Wednesday_hours := l_Wednesday_hours_tbl(i);
664 l_curr_schedule_rec(1).Thursday_hours := l_Thursday_hours_tbl(i);
665 l_curr_schedule_rec(1).Friday_hours := l_Friday_hours_tbl(i);
666 l_curr_schedule_rec(1).Saturday_hours := l_Saturday_hours_tbl(i);
667 l_curr_schedule_rec(1).Sunday_hours := l_Sunday_hours_tbl(i);
668
669 -- The passing start date if greater than the existing end date of the schedule or
670 -- greater or equal to the existing start date
671 IF (p_start_date > l_curr_schedule_rec(1).end_date) AND (l_st_dt_done = FALSE) THEN
672 NULL;
673 ELSE
674 IF (p_start_date = l_curr_schedule_rec(1).start_date) AND ( l_st_dt_done = FALSE) THEN
675 l_st_dt_done := TRUE;
676 ELSIF ( p_start_date > l_curr_schedule_rec(1).start_date ) AND (l_st_dt_done = FALSE) THEN
677 l_curr_schedule_rec(1).start_date := p_start_date;
678 l_st_dt_done:= TRUE;
679 END IF;
680
681 -- The passing end date if less than or equal to the existing end date of the
682 -- schedule or greater than the existing end date
683 IF ((p_end_date <= l_curr_schedule_rec(1).end_date) AND (l_end_dt_done = FALSE)) THEN
684 l_curr_schedule_rec(1).end_date := p_end_date;
685 l_end_dt_done:= TRUE;
686 ELSIF (p_end_date > l_curr_schedule_rec(1).end_date ) AND (l_end_dt_done = FALSE) THEN
687 NULL;
688 END IF;
689
690 -- Appending records in l_out_schedule_rec
691 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_curr_schedule_rec,1,1,l_out_schedule_rec,
692 l_x_return_status,x_msg_count,x_msg_data);
693
694 IF (l_st_dt_done = TRUE ) AND (l_end_dt_done = TRUE) THEN
695 EXIT;
696 END IF;
697 END IF;
698
699 END LOOP;
700
701 -- If the calendar has schedule record in the table then the following processing will occur
702 IF ( l_out_schedule_rec.count > 0 ) THEN
703 l_I := l_out_schedule_rec.first;
704 l_J := l_out_schedule_rec.Last;
705 -- If the start date is falling before the start date of the schedule then its work patern will be 0
706 IF (p_start_date < l_out_schedule_rec(l_I).start_date) THEN
707
708 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
709 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,
710 1,
711 1,
712 l_temp_schedule_rec,
713 l_x_return_status,
714 x_msg_count,
715 x_msg_data);
716 END IF;
717
718 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
719 /*bug 2335580 */
720 IF l_assignment_calendar_id IS NOT NULL THEN
721
722 PA_Schedule_Pvt.get_calendar_schedule(l_assignment_calendar_id,
723 p_start_date,
724 l_out_schedule_rec(l_I).start_date-1,
725 l_temp_schedule_rec,
726 l_x_return_status,
727 x_msg_count,
728 x_msg_data);
729 ELSE
730 PA_SCHEDULE_UTILS.update_sch_rec_tab(px_sch_record_tab => l_temp_schedule_rec,
731 p_start_date =>p_start_date,
732 p_end_date =>l_out_schedule_rec(l_I).start_date -1,
733 p_monday_hours =>0.00,
734 p_tuesday_hours =>0.00,
735 p_wednesday_hours =>0.00,
736 p_thursday_hours =>0.00,
737 p_friday_hours =>0.00,
738 p_saturday_hours =>0.00,
739 p_sunday_hours =>0.00,
740 x_return_status => l_x_return_status,
741 x_msg_count => x_msg_count,
742 x_msg_data =>x_msg_data);
743
744 END IF; --l_calendar_id is not null
745 END IF;
746
747 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
748 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_temp_schedule_rec,
749 l_temp_schedule_rec.first, -- changed for bug 7713013
750 l_temp_schedule_rec.last, -- changed for bug 7713013
751 x_sch_record_tab,
752 l_x_return_status,
753 x_msg_count,
754 x_msg_data);
755 END IF;
756
757
758 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
759 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_out_schedule_rec,
760 l_out_schedule_rec.first,
761 l_out_schedule_rec.last,
762 x_sch_record_tab,
763 l_x_return_status,
764 x_msg_count,
765 x_msg_data);
766 END IF;
767
768
769 l_x_sch_copy_done := TRUE;
770 END IF;
771
772 -- If the end date is falling after the end date of the schedule then its work patern will be 0
773 IF (p_end_date > l_out_schedule_rec(l_J).end_date) THEN
774
775 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
776 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,
777 1,
778 1,
779 l_temp_schedule_rec,
780 l_x_return_status,
781 x_msg_count,
782 x_msg_data);
783 END IF;
784
785 /*Code added for bug 2335580 */
786 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
787 IF l_assignment_calendar_id IS NOT NULL THEN
788
789 PA_Schedule_Pvt.get_calendar_schedule(l_assignment_calendar_id,
790 l_out_schedule_rec(l_J).end_date+1,
791 p_end_date,
792 l_temp_schedule_rec,
793 l_x_return_status,
794 x_msg_count,
795 x_msg_data);
796 /*End of code for Bug 2335580 */
797 ELSE
798
799 PA_SCHEDULE_UTILS.update_sch_rec_tab(px_sch_record_tab => l_temp_schedule_rec,
800 p_start_date =>l_out_schedule_rec(l_J).end_date + 1,
801 p_end_date => p_end_date,
802 p_monday_hours =>0.00,
803 p_tuesday_hours =>0.00,
804 p_wednesday_hours =>0.00,
805 p_thursday_hours =>0.00,
806 p_friday_hours =>0.00,
807 p_saturday_hours =>0.00,
808 p_sunday_hours =>0.00,
809 x_return_status => l_x_return_status,
810 x_msg_count => x_msg_count,
811 x_msg_data =>x_msg_data);
812 END IF; --l_assignment_calendar_id is not null
813 END IF;
814
815
816 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS AND l_x_sch_copy_done <> TRUE ) THEN
817 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_out_schedule_rec,
818 l_out_schedule_rec.first,
819 l_out_schedule_rec.last,
820 x_sch_record_tab,
821 l_x_return_status,
822 x_msg_count,
823 x_msg_data);
824 END IF;
825
826 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
827 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_temp_schedule_rec,
828 l_temp_schedule_rec.FIRST , --1,Modified for bug 4504473/4375409
829 l_temp_schedule_rec.Last , --1,Modified for bug 4504473/4375409
830 x_sch_record_tab,
831 l_x_return_status,
832 x_msg_count,
833 x_msg_data);
834 END IF;
835
836 l_x_sch_copy_done := TRUE;
837 END IF;
838 ELSE
839 -- If the pased calendar des not have any schedule then default schedule is created
840 x_sch_record_tab(1).start_date := p_start_date;
841 x_sch_record_tab(1).end_date := p_end_date ;
842 x_sch_record_tab(1).monday_hours := 0.00;
843 x_sch_record_tab(1).tuesday_hours := 0.00;
844 x_sch_record_tab(1).wednesday_hours := 0.00;
845 x_sch_record_tab(1).thursday_hours := 0.00;
846 x_sch_record_tab(1).friday_hours := 0.00;
847 x_sch_record_tab(1).saturday_hours := 0.00;
848 x_sch_record_tab(1).sunday_hours := 0.00;
849
850 END IF;
851
852 IF l_x_sch_copy_done = FALSE THEN
853 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
854 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,
855 l_out_schedule_rec.first,
856 l_out_schedule_rec.last,
857 x_sch_record_tab,
858 l_x_return_status,
859 x_msg_count,
860 x_msg_data);
861 END IF;
862
863 END IF;
864
865 x_return_status := l_x_return_status;
866 EXCEPTION
867 WHEN OTHERS THEN
868 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
869 x_msg_count := 1;
870 x_msg_data := SQLERRM;
871 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
872 p_procedure_name => 'get_assignment_schedule');
873 raise;
874
875 END get_assignment_schedule;
876
877 -- This procedure will take only assignment id and then generate the schedule for that assignment
878 -- In this procedure the schedule will be just the same as in the schedule tabel means no start date is passed
879 -- or end date is passed so it will pick only those records.This is an overloaded procedure.
880 -- Input parameters
881 -- Parameters Type Required Description
882 -- P_Assignment_Id NUMBER YES Id for that assignment to which you want to get schedule
883 --
884 -- Out parameters
885 -- X_Sch_Record_Tab SCHEDULETABTYP YES It stores schedule for that assignment
886 --
887
888 PROCEDURE get_assignment_schedule ( p_assignment_id IN NUMBER,
889 x_sch_record_tab OUT NOCOPY PA_SCHEDULE_GLOB.ScheduleTabTyp,
890 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
891 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
892 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
893 IS
894 I NUMBER;
895 J NUMBER;
896 l_st_dt_done BOOLEAN;
897 l_end_dt_done BOOLEAN;
898 l_x_sch_copy_done BOOLEAN;
899 l_curr_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
900 l_out_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
901 l_temp_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
902
903 -- This cursor will select the schedule records corresponding to the passing assignment id
904 -- 1561861 Added 'STAFFED_ADMIN_ASSIGNMENT' to the where clause.
905 /* Bug - 1846658- Following lines are commented to incorporate the BULK SELECT to enhance the performance*/
906
907 -- CURSOR C1 IS SELECT schedule_id, calendar_id,
908 -- assignment_id,project_id,schedule_type_code,status_code,
909 -- system_status_code,start_date,end_date,Monday_hours,Tuesday_hours,Wednesday_hours,
910 -- Thursday_hours,
911 -- Friday_hours,Saturday_hours,Sunday_hours
912 -- FROM PA_SCHEDULES_V sch
913 -- WHERE sch.assignment_id = p_assignment_id
914 -- AND sch.schedule_type_code IN
915 -- ('OPEN_ASSIGNMENT','STAFFED_ASSIGNMENT', 'STAFFED_ADMIN_ASSIGNMENT')
916 -- ORDER BY start_date;
917
918 /* Bug - 1846658- Following lines are added to incorporate the BULK SELECT to enhance the performance*/
919
920 TYPE schedule_id_tbl IS TABLE OF PA_SCHEDULES_V.schedule_id%TYPE
921 INDEX BY BINARY_INTEGER;
922 TYPE calendar_id_tbl IS TABLE OF PA_SCHEDULES_V.calendar_id%TYPE
923 INDEX BY BINARY_INTEGER;
924 TYPE assignment_id_tbl IS TABLE OF PA_SCHEDULES_V.assignment_id%TYPE
925 INDEX BY BINARY_INTEGER;
926 TYPE project_id_tbl IS TABLE OF PA_SCHEDULES_V.project_id%TYPE
927 INDEX BY BINARY_INTEGER;
928 TYPE schedule_type_code_tbl IS TABLE OF PA_SCHEDULES_V.schedule_type_code%TYPE
929 INDEX BY BINARY_INTEGER;
930 TYPE status_code_tbl IS TABLE OF PA_SCHEDULES_V.status_code%TYPE
931 INDEX BY BINARY_INTEGER;
932 TYPE system_status_code_tbl IS TABLE OF PA_SCHEDULES_V.system_status_code%TYPE
933 INDEX BY BINARY_INTEGER;
934 TYPE start_date_tbl IS TABLE OF PA_SCHEDULES_V.start_date%TYPE
935 INDEX BY BINARY_INTEGER;
936 TYPE end_date_tbl IS TABLE OF PA_SCHEDULES_V.end_date%TYPE
937 INDEX BY BINARY_INTEGER;
938 TYPE Monday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Monday_hours%TYPE
939 INDEX BY BINARY_INTEGER;
940 TYPE Tuesday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Tuesday_hours%TYPE
941 INDEX BY BINARY_INTEGER;
942 TYPE Wednesday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Wednesday_hours%TYPE
943 INDEX BY BINARY_INTEGER;
944 TYPE Thursday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Thursday_hours%TYPE
945 INDEX BY BINARY_INTEGER;
946 TYPE Friday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Friday_hours%TYPE
947 INDEX BY BINARY_INTEGER;
948 TYPE Saturday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Saturday_hours%TYPE
949 INDEX BY BINARY_INTEGER;
950 TYPE Sunday_hours_tbl IS TABLE OF PA_SCHEDULES_V.Sunday_hours%TYPE
951 INDEX BY BINARY_INTEGER;
952
953 l_schedule_id_tbl schedule_id_tbl ;
954 l_calendar_id_tbl calendar_id_tbl ;
955 l_assignment_id_tbl assignment_id_tbl;
956 l_project_id_tbl project_id_tbl;
957 l_schedule_type_code_tbl schedule_type_code_tbl;
958 l_status_code_tbl status_code_tbl ;
959 l_system_status_code_tbl system_status_code_tbl;
960 l_start_date_tbl start_date_tbl ;
961 l_end_date_tbl end_date_tbl ;
962 l_Monday_hours_tbl Monday_hours_tbl ;
963 l_Tuesday_hours_tbl Tuesday_hours_tbl;
964 l_Wednesday_hours_tbl Wednesday_hours_tbl ;
965 l_Thursday_hours_tbl Thursday_hours_tbl;
966 l_Friday_hours_tbl Friday_hours_tbl ;
967 l_Saturday_hours_tbl Saturday_hours_tbl ;
968 l_Sunday_hours_tbl Sunday_hours_tbl ;
969
970 l_first_index NUMBER;
971 l_last_index NUMBER;
972 i NUMBER;
973
974 BEGIN
975 l_st_dt_done := FALSE;
976 l_end_dt_done := FALSE;
977 l_x_sch_copy_done := FALSE;
978 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
979
980 /* Bug - 1846658- Following lines are commented to incorporate the BULK SELECT to enhance the performance*/
981
982 -- FOR v_c1 IN C1 LOOP
983 --
984 -- l_curr_schedule_rec(1).assignment_id := v_c1.assignment_id;
985 -- l_curr_schedule_rec(1).project_id := v_c1.project_id;
986 -- l_curr_schedule_rec(1).schedule_type_code := v_c1.schedule_type_code;
987 -- l_curr_schedule_rec(1).assignment_status_code := v_c1.status_code;
988 -- l_curr_schedule_rec(1).system_status_code := v_c1.system_status_code;
989 -- l_curr_schedule_rec(1).calendar_id := v_c1.calendar_id;
990 -- l_curr_schedule_rec(1).schedule_id := v_c1.schedule_id;
991 -- l_curr_schedule_rec(1).start_date := v_c1.start_date;
992 -- l_curr_schedule_rec(1).end_date := v_c1.end_date;
993 -- l_curr_schedule_rec(1).Monday_hours := v_c1.Monday_hours;
994 -- l_curr_schedule_rec(1).Tuesday_hours := v_c1.Tuesday_hours;
995 -- l_curr_schedule_rec(1).Wednesday_hours := v_c1.Wednesday_hours;
996 -- l_curr_schedule_rec(1).Thursday_hours := v_c1.Thursday_hours;
997 -- l_curr_schedule_rec(1).Friday_hours := v_c1.Friday_hours;
998 -- l_curr_schedule_rec(1).Saturday_hours := v_c1.Saturday_hours;
999 -- l_curr_schedule_rec(1).Sunday_hours := v_c1.Sunday_hours;
1000
1001
1002 /* Bug - 1846658- Following lines are added to incorporate the BULK SELECT to enhance the performance*/
1003
1004 SELECT schedule_id,
1005 calendar_id,
1006 assignment_id,
1007 project_id,
1008 schedule_type_code,
1009 status_code,
1010 system_status_code,
1011 start_date,
1012 end_date,
1013 Monday_hours,
1014 Tuesday_hours,
1015 Wednesday_hours,
1016 Thursday_hours,
1017 Friday_hours,
1018 Saturday_hours,
1019 Sunday_hours
1020 BULK COLLECT INTO
1021 l_schedule_id_tbl,
1022 l_calendar_id_tbl,
1023 l_assignment_id_tbl,
1024 l_project_id_tbl,
1025 l_schedule_type_code_tbl,
1026 l_status_code_tbl ,
1027 l_system_status_code_tbl,
1028 l_start_date_tbl,
1029 l_end_date_tbl,
1030 l_Monday_hours_tbl,
1031 l_Tuesday_hours_tbl,
1032 l_Wednesday_hours_tbl,
1033 l_Thursday_hours_tbl,
1034 l_Friday_hours_tbl,
1035 l_Saturday_hours_tbl,
1036 l_Sunday_hours_tbl
1037 FROM PA_SCHEDULES_V sch
1038 WHERE sch.assignment_id = p_assignment_id
1039 AND sch.schedule_type_code IN ('OPEN_ASSIGNMENT','STAFFED_ASSIGNMENT', 'STAFFED_ADMIN_ASSIGNMENT')
1040 ORDER BY start_date;
1041
1042 l_first_index := NVL(l_project_id_tbl.first,0);
1043 l_last_index := NVL(l_project_id_tbl.last,-1);
1044
1045 FOR i IN l_first_index .. l_last_index LOOP
1046 l_curr_schedule_rec(1).assignment_id := l_assignment_id_tbl(i);
1047 l_curr_schedule_rec(1).project_id := l_project_id_tbl(i);
1048 l_curr_schedule_rec(1).schedule_type_code := l_schedule_type_code_tbl(i);
1049 l_curr_schedule_rec(1).assignment_status_code := l_status_code_tbl(i);
1050 l_curr_schedule_rec(1).system_status_code := l_system_status_code_tbl(i);
1051 l_curr_schedule_rec(1).calendar_id := l_calendar_id_tbl(i);
1052 l_curr_schedule_rec(1).schedule_id := l_schedule_id_tbl(i);
1053 l_curr_schedule_rec(1).start_date := l_start_date_tbl(i);
1054 l_curr_schedule_rec(1).end_date := l_end_date_tbl(i);
1055 l_curr_schedule_rec(1).Monday_hours := l_Monday_hours_tbl(i);
1056 l_curr_schedule_rec(1).Tuesday_hours := l_Tuesday_hours_tbl(i);
1057 l_curr_schedule_rec(1).Wednesday_hours := l_Wednesday_hours_tbl(i);
1058 l_curr_schedule_rec(1).Thursday_hours := l_Thursday_hours_tbl(i);
1059 l_curr_schedule_rec(1).Friday_hours := l_Friday_hours_tbl(i);
1060 l_curr_schedule_rec(1).Saturday_hours := l_Saturday_hours_tbl(i);
1061 l_curr_schedule_rec(1).Sunday_hours := l_Sunday_hours_tbl(i);
1062
1063 -- appending the record
1064 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1065 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_curr_schedule_rec,1,1,l_out_schedule_rec,l_x_return_status,
1066 x_msg_count,x_msg_data);
1067 END IF;
1068
1069 END LOOP;
1070
1071 IF l_x_sch_copy_done = FALSE THEN
1072
1073 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1074 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,l_out_schedule_rec.first,l_out_schedule_rec.last,
1075 x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
1076 END IF;
1077 END IF;
1078
1079 x_return_status := l_x_return_status;
1080 EXCEPTION
1081 WHEN OTHERS THEN
1082
1083 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1084 x_msg_count := 1;
1085 x_msg_data := SQLERRM;
1086 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
1087 p_procedure_name => 'get_assignment_schedule');
1088 raise;
1089
1090 END get_assignment_schedule;
1091
1092 -- This procedure will get the resource schedule if the calendar type is resource it will pick its
1093 -- schedule from the CRM calendar which is associated with this resource
1094 -- Input parameters
1095 -- Parameters Type Required Description
1096 -- P_Source_Id NUMBER YES Source Id for getting the crm resource id
1097 -- P_Source_Type VARCHAR2 YES It is the type of the source e.g PA_PROJECT_PARTY_ID,
1098 -- PA_RESOURCE_ID
1099 -- P_Start_Date DATE YES Start date of the schedule for that resource
1100 -- P_End_Date DATE YES End date of the schedule for that resource
1101 --
1102 -- Out parameters
1103 -- X_Sch_Record_Tab SCHEDULETABTYP YES It stores schedule for that resource
1104 --
1105 PROCEDURE get_resource_schedule ( p_source_id IN NUMBER,
1106 p_source_type IN VARCHAR2,
1107 p_start_date IN DATE,
1108 p_end_date IN DATE,
1109 x_sch_record_tab IN OUT NOCOPY PA_SCHEDULE_GLOB.ScheduleTabTyp,
1110 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
1111 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
1112 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
1113 IS
1114 l_I NUMBER;
1115 l_J NUMBER;
1116 l_t_resource_id NUMBER;
1117 l_st_dt_done BOOLEAN;
1118 l_end_dt_done BOOLEAN;
1119 l_x_sch_copy_done BOOLEAN;
1120 l_t_first_record BOOLEAN;
1121 l_last_end_date DATE;
1122 l_t_end_date DATE;
1123 l_t_start_date DATE;
1124 l_temp_end_date DATE;
1125 l_temp_start_date DATE;
1126 l_tc_end_date DATE;
1127 l_tc_start_date DATE;
1128
1129 l_invalid_source_id EXCEPTION;
1130
1131 l_cur_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
1132 l_out_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
1133 l_temp_schedule_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
1134
1135 -- jmarques: 1786935: Modified cursor to include resource_type_code
1136 -- since resource_id is not unique. Also, added calendar_id > 0
1137 -- condition so that calendar_id, resource_id index would be used.
1138
1139 CURSOR C1 IS SELECT calendar_id,trunc(start_date_time) start_date,
1140 NVL(trunc(end_date_time),TO_DATE('01/01/2050','MM/DD/YYYY')) end_date
1141 FROM jtf_cal_resource_assign jtf_res
1142 WHERE jtf_res.resource_id = l_t_resource_id
1143 AND jtf_res.primary_calendar_flag = 'Y'
1144 AND jtf_res.calendar_id > 0
1145 AND jtf_res.resource_type_code = 'RS_EMPLOYEE'
1146 AND ( ( l_tc_start_date BETWEEN trunc(jtf_res.start_date_time) AND
1147 nvl(trunc(jtf_res.end_date_time),l_tc_end_date))
1148 OR ( l_tc_end_date BETWEEN jtf_res.start_date_time AND
1149 nvl(trunc(jtf_res.end_date_time),l_tc_end_date))
1150 OR ( l_tc_start_date < jtf_res.start_date_time AND
1151 l_tc_end_date > nvl(trunc(jtf_res.end_date_time),l_tc_end_date)) )
1152 order by start_date;
1153
1154 /*Code Added for bug 2687043 */
1155
1156 Cursor cur_organization(x_prm_resource_id IN NUMBER) IS
1157 select resource_organization_id, min(resource_effective_start_date)
1158 from pa_resources_denorm
1159 where resource_id = x_prm_resource_id
1160 group by resource_organization_id;
1161
1162 /*Code ends for bug 2687043 */
1163
1164 -- jmarques: 1965289: local vars
1165 l_prm_resource_id NUMBER;
1166 l_resource_organization_id NUMBER;
1167 l_resource_ou_id NUMBER;
1168 l_calendar_id NUMBER;
1169
1170 -- jmarques: 2196924: local vars
1171 l_ResStartDateTab PA_FORECAST_GLOB.DateTabTyp;
1172 l_ResEndDateTab PA_FORECAST_GLOB.DateTabTyp;
1173 i NUMBER;
1174 l_Sch_Record_Tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
1175 l_cap_start_date DATE;
1176 l_cap_end DATE;
1177 l_cap_start_index NUMBER;
1178 l_cap_end_index NUMBER;
1179 l_res_start_date DATE;
1180 l_res_end DATE;
1181 l_res_start_index NUMBER;
1182 l_res_end_index NUMBER;
1183 l_cap_first_start_date DATE;
1184 l_cap_last_end_date DATE;
1185 l_prev_res_end_date DATE;
1186 l_last_processed_cap_index NUMBER;
1187 l_cap_tab_index NUMBER;
1188 l_res_first_start_date DATE;
1189 l_res_last_end_date DATE;
1190 l_hole_start_date DATE;
1191 l_hole_end_date DATE;
1192 l_reprocess_flag VARCHAR2(1);
1193 l_j_index NUMBER;
1194 l_temp_index NUMBER;
1195 l_resource_id NUMBER;
1196
1197 BEGIN
1198 l_st_dt_done := FALSE;
1199 l_end_dt_done := FALSE;
1200 l_x_sch_copy_done := FALSE;
1201 l_t_first_record := FALSE;
1202 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
1203 PA_SCHEDULE_UTILS.log_message(1,'first status ... '||l_x_return_status);
1204
1205
1206 IF ( p_source_type = 'PA_PROJECT_PARTY_ID') THEN
1207 BEGIN
1208 select distinct NVL(resource_id,-99)
1209 into l_resource_id
1210 from pa_project_parties
1211 where project_party_id = p_source_id;
1212 EXCEPTION WHEN NO_DATA_FOUND THEN
1213 l_resource_id := -99;
1214 END;
1215
1216 -- Calling resource API that will return the resource id
1217 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1218 PA_RESOURCE_UTILS.get_crm_res_id( p_project_player_id => p_source_id,
1219 p_resource_id => NULL,
1220 x_jtf_resource_id => l_t_resource_id,
1221 x_return_status => l_x_return_status,
1222 x_error_message_code => x_msg_data );
1223 PA_SCHEDULE_UTILS.log_message(1,'status ... '||l_x_return_status);
1224 PA_SCHEDULE_UTILS.log_message(1,'get_crm_res_id');
1225
1226 END IF;
1227 ELSIF ( p_source_type = 'PA_RESOURCE_ID') THEN
1228 l_resource_id := p_source_id;
1229 -- Calling resource API That will return the resource id
1230 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1231 PA_RESOURCE_UTILS.get_crm_res_id( p_project_player_id => NULL,
1232 p_resource_id => p_source_id,
1233 x_jtf_resource_id => l_t_resource_id,
1234 x_return_status => l_x_return_status,
1235 x_error_message_code => x_msg_data );
1236 PA_SCHEDULE_UTILS.log_message(1,'status ... '||l_x_return_status);
1237 PA_SCHEDULE_UTILS.log_message(1,'get_crm_res_id2');
1238 END IF;
1239 PA_SCHEDULE_UTILS.log_message(1,'second status ... '||l_x_return_status);
1240 END IF;
1241
1242 PA_SCHEDULE_UTILS.log_message(1,'second status ... '||l_x_return_status);
1243 IF ( l_x_return_status <> fnd_api.g_ret_sts_success ) THEN
1244 RAISE l_invalid_source_id;
1245 END IF;
1246 PA_SCHEDULE_UTILS.log_message(1,'status ... '||l_x_return_status);
1247
1248 -- 1965289: Work around for CRM bug (cannot create future dated resources).
1249 -- If the jtf_resource_id is null, then we need to use the default
1250 -- calendar instead of going to the jtf_cal_resource_assign table.
1251
1252 -- Start 1965289 bugfix.
1253 IF (l_t_resource_id is null) THEN
1254 -- Find the start date for the first HR assignment.
1255 IF ( p_source_type = 'PA_PROJECT_PARTY_ID') THEN
1256 select resource_id
1257 into l_prm_resource_id
1258 from pa_project_parties
1259 where project_party_id = p_source_id;
1260 ELSIF ( p_source_type = 'PA_RESOURCE_ID') THEN
1261 l_prm_resource_id := p_source_id;
1262 END IF;
1263
1264 -- Get resource's organization on their
1265 -- min(resource_effective_start_date)
1266
1267 /* Code added for bug 2687043 */
1268 OPEN cur_organization(l_prm_resource_id);
1269 FETCH cur_organization INTO l_resource_organization_id,l_temp_start_date;
1270 CLOSE cur_organization;
1271
1272 /*The below code is commented for bug 2687043
1273
1274 select resource_organization_id, resource_effective_start_date
1275 into l_resource_organization_id, l_temp_start_date
1276 from pa_resources_denorm
1277 where resource_effective_start_date =
1278 (select min(res1.resource_effective_start_date)
1279 from pa_resources_denorm res1
1280 where res1.resource_id = l_prm_resource_id
1281 and res1.resource_effective_start_date >= trunc(sysdate))
1282 and resource_id = l_prm_resource_id;
1283
1284 */
1285
1286 -- Get default calendar using organization id.
1287 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1288 pa_resource_utils.get_org_defaults(
1289 p_organization_id => l_resource_organization_id,
1290 x_default_ou => l_resource_ou_id,
1291 x_default_cal_id => l_calendar_id,
1292 x_return_status => l_x_return_status);
1293 PA_SCHEDULE_UTILS.log_message(1,'l_resource_organization_id: '||l_resource_organization_id);
1294 PA_SCHEDULE_UTILS.log_message(1,'status ... '||l_x_return_status);
1295 PA_SCHEDULE_UTILS.log_message(1,'get_org_defaults');
1296 END IF;
1297
1298 if (l_calendar_id is null) then
1299 l_calendar_id := fnd_profile.value_specific('PA_PRM_DEFAULT_CALENDAR');
1300 end if;
1301
1302 -- Fix dates.
1303
1304 -- l_temp_start_date found above.
1305 l_temp_end_date := to_date('31/12/4712', 'DD/MM/YYYY');
1306
1307 IF (p_start_date IS NULL OR p_start_date < l_temp_start_date) THEN
1308 l_tc_start_date := l_temp_start_date;
1309 ELSE
1310 l_tc_start_date := p_start_date;
1311 END IF;
1312
1313 IF (p_end_date IS NULL) THEN
1314 l_tc_end_date := l_temp_end_date;
1315 ELSE
1316 l_tc_end_date := p_end_date;
1317 END IF;
1318
1319 -- Calling the get calendar schedule procedure which will bring
1320 -- the schedule for the specified calendar id
1321 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1322 get_calendar_schedule(l_calendar_id,
1323 l_tc_start_date,
1324 l_tc_end_date,
1325 l_cur_schedule_rec,
1326 l_x_return_status,
1327 x_msg_count,
1328 x_msg_data);
1329 PA_SCHEDULE_UTILS.log_message(1,'status ... '||l_x_return_status);
1330 PA_SCHEDULE_UTILS.log_message(1,'get_calendar_schedule');
1331 END IF;
1332
1333 IF (p_start_date is not null) then
1334 l_tc_start_date := p_start_date;
1335 END IF;
1336
1337 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1338 PA_SCHEDULE_UTILS.add_schedule_rec_tab(
1339 l_cur_schedule_rec,
1340 l_cur_schedule_rec.first,
1341 l_cur_schedule_rec.last,
1342 l_out_schedule_rec,
1343 l_x_return_status,
1344 x_msg_count,
1345 x_msg_data);
1346 PA_SCHEDULE_UTILS.log_message(1,'status ... '||l_x_return_status);
1347 PA_SCHEDULE_UTILS.log_message(1,'add_schedule_rec_tab');
1348 END IF;
1349
1350 ---- Start: Copied from below (same processing for work around)
1351 IF ( l_out_schedule_rec.count > 0 ) THEN
1352 l_I := l_out_schedule_rec.first;
1353 l_J := l_out_schedule_rec.Last;
1354
1355 IF (l_tc_start_date < l_out_schedule_rec(l_I).start_date) THEN
1356
1357 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1358 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,1,1,l_temp_schedule_rec,l_x_return_status,x_msg_count,
1359 x_msg_data);
1360 END IF;
1361
1362 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1363 PA_SCHEDULE_UTILS.update_sch_rec_tab(px_sch_record_tab => l_temp_schedule_rec,p_start_date =>l_tc_start_date,
1364 p_end_date =>l_out_schedule_rec(l_I).start_date -1 ,p_monday_hours =>0.00,p_tuesday_hours =>0.00,
1365 p_wednesday_hours =>0.00,p_thursday_hours =>0.00,p_friday_hours =>0.00,p_saturday_hours =>0.00,
1366 p_sunday_hours =>0.00,x_return_status => l_x_return_status,x_msg_count => x_msg_count,x_msg_data =>x_msg_data);
1367 END IF;
1368
1369 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1370 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_temp_schedule_rec,1,1,x_sch_record_tab,l_x_return_status,x_msg_count,
1371 x_msg_data);
1372 END IF;
1373
1374 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1375 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_out_schedule_rec,l_out_schedule_rec.first,l_out_schedule_rec.last,
1376 x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
1377 END IF;
1378
1379 l_x_sch_copy_done := TRUE;
1380 --PA_SCHEDULE_UTILS.log_message(2,'X1 :',x_sch_record_tab);
1381 END IF;
1382
1383 IF (l_tc_end_date > l_out_schedule_rec(l_J).end_date) THEN
1384
1385 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1386 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,1,1,l_temp_schedule_rec,l_x_return_status,x_msg_count,
1387 x_msg_data);
1388 END IF;
1389
1390 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1391 PA_SCHEDULE_UTILS.update_sch_rec_tab(px_sch_record_tab => l_temp_schedule_rec,
1392 p_start_date =>l_out_schedule_rec(l_J).end_date + 1 , p_end_date => l_tc_end_date,p_monday_hours =>0.00,
1393 p_tuesday_hours =>0.00, p_wednesday_hours =>0.00,p_thursday_hours =>0.00,p_friday_hours =>0.00,
1394 p_saturday_hours =>0.00,p_sunday_hours =>0.00,
1395 x_return_status => l_x_return_status,x_msg_count => x_msg_count,x_msg_data =>x_msg_data);
1396 END IF;
1397
1398 IF ( l_x_sch_copy_done = FALSE ) THEN
1399 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1400 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_out_schedule_rec,l_out_schedule_rec.first,l_out_schedule_rec.last,
1401 x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
1402 END IF;
1403
1404 END IF;
1405
1406 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1407 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_temp_schedule_rec,1,1,x_sch_record_tab,l_x_return_status,x_msg_count,
1408 x_msg_data);
1409 END IF;
1410
1411 l_x_sch_copy_done := TRUE;
1412 --PA_SCHEDULE_UTILS.log_message(2,'X2 :',x_sch_record_tab);
1413 END IF;
1414
1415 IF l_x_sch_copy_done = FALSE THEN
1416
1417 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1418 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,l_out_schedule_rec.first,l_out_schedule_rec.last,
1419 x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
1420 END IF;
1421 END IF;
1422 ELSE
1423 x_sch_record_tab(1).start_date := l_tc_start_date;
1424 x_sch_record_tab(1).end_date := l_tc_end_date ;
1425 x_sch_record_tab(1).monday_hours := 0.00;
1426 x_sch_record_tab(1).tuesday_hours := 0.00;
1427 x_sch_record_tab(1).wednesday_hours := 0.00;
1428 x_sch_record_tab(1).thursday_hours := 0.00;
1429 x_sch_record_tab(1).friday_hours := 0.00;
1430 x_sch_record_tab(1).saturday_hours := 0.00;
1431 x_sch_record_tab(1).sunday_hours := 0.00;
1432 END IF;
1433 -- End: Copied from below (same processing for work around)
1434 -- End 1965289 bug fix.
1435
1436 ELSE
1437
1438 -- Taking care if the passing start or end date is null if the dates are null take the value from table
1439 IF (p_start_date IS NULL OR p_end_date IS NULL) THEN
1440 -- jmarques: 1786935: Modified cursor to include resource_type_code
1441 -- since resource_id is not unique. Also, added calendar_id > 0
1442 -- condition so that calendar_id, resource_id index would be used.
1443
1444 SELECT MIN(start_date_time),MAX(NVL(end_date_time,TO_DATE('01/01/2050','MM/DD/YYYY')))
1445 INTO l_temp_start_date,l_temp_end_date
1446 FROM jtf_cal_resource_assign
1447 WHERE jtf_cal_resource_assign.resource_id = l_t_resource_id
1448 AND jtf_cal_resource_assign.calendar_id > 0
1449 AND jtf_cal_resource_assign.resource_type_code = 'RS_EMPLOYEE'
1450 AND jtf_cal_resource_assign.primary_calendar_flag = 'Y';
1451 END IF;
1452
1453 PA_SCHEDULE_UTILS.log_message(1,'Start date ... '||to_char(l_temp_start_date)||to_char(p_start_date));
1454 PA_SCHEDULE_UTILS.log_message(1,'end date ... '||to_char(l_temp_end_date)||to_char(p_end_date));
1455 IF (p_start_date IS NULL ) THEN
1456 l_tc_start_date := l_temp_start_date;
1457 ELSE
1458 l_tc_start_date := p_start_date;
1459 END IF;
1460
1461 IF (p_end_date IS NULL ) THEN
1462 l_tc_end_date := l_temp_end_date;
1463 ELSE
1464 l_tc_end_date := p_end_date;
1465 END IF;
1466
1467
1468 PA_SCHEDULE_UTILS.log_message(1,'Start of the get_resource_schedule API ... ');
1469
1470
1471 FOR v_c1 IN C1 LOOP
1472
1473 PA_SCHEDULE_UTILS.log_message(1,'inside cursor ... ');
1474
1475 PA_SCHEDULE_UTILS.log_message(2,'REC : '||to_char(v_c1.calendar_id)|| ' '||
1476 to_char(v_c1.start_date)||' '||
1477 to_char(v_c1.end_date));
1478
1479
1480 IF( l_t_first_record) THEN
1481 l_t_first_record := FALSE;
1482 ELSIF( v_c1.start_date <> (l_last_end_date + 1) ) THEN
1483 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1484 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_cur_schedule_rec,1,1,
1485 l_temp_schedule_rec,l_x_return_status,x_msg_count,x_msg_data);
1486 END IF;
1487
1488 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1489 PA_SCHEDULE_UTILS.update_sch_rec_tab(px_sch_record_tab => l_temp_schedule_rec,
1490 p_start_date =>l_last_end_date + 1, p_end_date =>v_c1.start_date -1 ,
1491 p_monday_hours =>0.00,p_tuesday_hours =>0.00,p_wednesday_hours =>0.00,
1492 p_thursday_hours =>0.00,p_friday_hours =>0.00,p_saturday_hours =>0.00,
1493 p_sunday_hours =>0.00,
1494 x_return_status => l_x_return_status,x_msg_count =>
1495 x_msg_count,x_msg_data =>x_msg_data);
1496 END IF;
1497 --PA_SCHEDULE_UTILS.log_message(2,'TEMP :',l_temp_schedule_rec);
1498
1499 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1500 -- Appending the records
1501 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_temp_schedule_rec,1,1,
1502 l_out_schedule_rec,l_x_return_status,x_msg_count,x_msg_data);
1503 END IF;
1504 END IF;
1505
1506 l_cur_schedule_rec.delete;
1507
1508 PA_SCHEDULE_UTILS.log_message(2,'in deleting CUR '||l_x_return_status);
1509 IF ( v_c1.end_date > l_tc_end_date ) THEN
1510 l_t_end_date := l_tc_end_date;
1511 ELSE
1512 l_t_end_date := v_c1.end_date;
1513 END IF;
1514
1515 IF ( v_c1.start_date < l_tc_start_date ) THEN
1516 l_t_start_date := l_tc_start_date;
1517 ELSE
1518 l_t_start_date := v_c1.start_date;
1519 PA_SCHEDULE_UTILS.log_message(2,'before get resource '||to_char(l_t_start_date,'dd-mon-yyyy'));
1520 END IF;
1521
1522 PA_SCHEDULE_UTILS.log_message(2,'before get resource '||l_x_return_status);
1523 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1524 -- Calling the get calendar schedule procedure which will bring the schedule for the specified calendar id
1525 get_calendar_schedule( v_c1.calendar_id,
1526 l_t_start_date,
1527 l_t_end_date,
1528 l_cur_schedule_rec,
1529 l_x_return_status,
1530 x_msg_count,
1531 x_msg_data);
1532 PA_SCHEDULE_UTILS.log_message(2,'inside get calendar CUR :',l_cur_schedule_rec);
1533 END IF;
1534 PA_SCHEDULE_UTILS.log_message(2,'after get resource CUR :',l_cur_schedule_rec);
1535
1536 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1537 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_cur_schedule_rec,l_cur_schedule_rec.first,
1538 l_cur_schedule_rec.last,l_out_schedule_rec,l_x_return_status,x_msg_count,
1539 x_msg_data);
1540 END IF;
1541
1542 l_last_end_date := v_c1.end_date;
1543
1544 PA_SCHEDULE_UTILS.log_message(2,'OUT :',l_out_schedule_rec);
1545
1546 END LOOP;
1547
1548 PA_SCHEDULE_UTILS.log_message(2,'OUTSIDE loop :');
1549
1550 IF ( l_out_schedule_rec.count > 0 ) THEN
1551 l_I := l_out_schedule_rec.first;
1552 l_J := l_out_schedule_rec.Last;
1553
1554 IF (l_tc_start_date < l_out_schedule_rec(l_I).start_date) THEN
1555
1556 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1557 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,1,1,l_temp_schedule_rec,l_x_return_status,x_msg_count,
1558 x_msg_data);
1559 END IF;
1560
1561 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1562 PA_SCHEDULE_UTILS.update_sch_rec_tab(px_sch_record_tab => l_temp_schedule_rec,p_start_date =>l_tc_start_date,
1563 p_end_date =>l_out_schedule_rec(l_I).start_date -1 ,p_monday_hours =>0.00,p_tuesday_hours =>0.00,
1564 p_wednesday_hours =>0.00,p_thursday_hours =>0.00,p_friday_hours =>0.00,p_saturday_hours =>0.00,
1565 p_sunday_hours =>0.00,x_return_status => l_x_return_status,x_msg_count => x_msg_count,x_msg_data =>x_msg_data);
1566 END IF;
1567
1568 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1569 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_temp_schedule_rec,1,1,x_sch_record_tab,l_x_return_status,x_msg_count,
1570 x_msg_data);
1571 END IF;
1572
1573 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1574 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_out_schedule_rec,l_out_schedule_rec.first,l_out_schedule_rec.last,
1575 x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
1576 END IF;
1577
1578 l_x_sch_copy_done := TRUE;
1579 --PA_SCHEDULE_UTILS.log_message(2,'X1 :',x_sch_record_tab);
1580 END IF;
1581
1582 IF (l_tc_end_date > l_out_schedule_rec(l_J).end_date) THEN
1583
1584 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1585 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,1,1,l_temp_schedule_rec,l_x_return_status,x_msg_count,
1586 x_msg_data);
1587 END IF;
1588
1589 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1590 PA_SCHEDULE_UTILS.update_sch_rec_tab(px_sch_record_tab => l_temp_schedule_rec,
1591 p_start_date =>l_out_schedule_rec(l_J).end_date + 1 , p_end_date => l_tc_end_date,p_monday_hours =>0.00,
1592 p_tuesday_hours =>0.00, p_wednesday_hours =>0.00,p_thursday_hours =>0.00,p_friday_hours =>0.00,
1593 p_saturday_hours =>0.00,p_sunday_hours =>0.00,
1594 x_return_status => l_x_return_status,x_msg_count => x_msg_count,x_msg_data =>x_msg_data);
1595 END IF;
1596
1597 IF ( l_x_sch_copy_done = FALSE ) THEN
1598 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1599 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_out_schedule_rec,l_out_schedule_rec.first,l_out_schedule_rec.last,
1600 x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
1601 END IF;
1602
1603 END IF;
1604
1605 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1606 PA_SCHEDULE_UTILS.add_schedule_rec_tab(l_temp_schedule_rec,1,1,x_sch_record_tab,l_x_return_status,x_msg_count,
1607 x_msg_data);
1608 END IF;
1609
1610 l_x_sch_copy_done := TRUE;
1611 --PA_SCHEDULE_UTILS.log_message(2,'X2 :',x_sch_record_tab);
1612 END IF;
1613
1614 IF l_x_sch_copy_done = FALSE THEN
1615
1616 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1617 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(l_out_schedule_rec,l_out_schedule_rec.first,l_out_schedule_rec.last,
1618 x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
1619 END IF;
1620 END IF;
1621 ELSE
1622 x_sch_record_tab(1).start_date := l_tc_start_date;
1623 x_sch_record_tab(1).end_date := l_tc_end_date ;
1624 x_sch_record_tab(1).monday_hours := 0.00;
1625 x_sch_record_tab(1).tuesday_hours := 0.00;
1626 x_sch_record_tab(1).wednesday_hours := 0.00;
1627 x_sch_record_tab(1).thursday_hours := 0.00;
1628 x_sch_record_tab(1).friday_hours := 0.00;
1629 x_sch_record_tab(1).saturday_hours := 0.00;
1630 x_sch_record_tab(1).sunday_hours := 0.00;
1631 END IF;
1632 END IF;
1633
1634 -- 2196924: Fix table by setting 0 for all dates with no HR assignment.
1635 IF (NVL(x_sch_record_tab.count,0) <> 0) THEN
1636 PA_SCHEDULE_UTILS.log_message(1,'x_sch_record_tab.count<>0');
1637 for i in x_sch_record_tab.first .. x_sch_record_tab.last loop
1638 PA_SCHEDULE_UTILS.log_message(1, i || ' ' || x_sch_record_tab(i).start_date || ' ' || x_sch_record_tab(i).end_date || ' ' || x_sch_record_tab(i).monday_hours);
1639 end loop;
1640
1641 l_cap_first_start_date := x_sch_record_tab(x_sch_record_tab.first).start_date;
1642 l_cap_last_end_date := x_sch_record_tab(x_sch_record_tab.last).end_date;
1643
1644 PA_SCHEDULE_UTILS.log_message(1,'l_cap_first_start_date: ' || l_cap_first_start_date);
1645 PA_SCHEDULE_UTILS.log_message(1,'l_cap_last_end_date: ' || l_cap_last_end_date);
1646
1647 SELECT rou.resource_effective_start_date,
1648 NVL(rou.resource_effective_end_date,SYSDATE)
1649 BULK COLLECT INTO
1650 l_ResStartDateTab,l_ResEndDateTab
1651 FROM pa_resources_denorm rou
1652 WHERE rou.resource_id= l_resource_id
1653 AND NVL(rou.resource_effective_end_date,SYSDATE) >=
1654 l_cap_first_start_date
1655 AND rou.resource_effective_start_date <= l_cap_last_end_date
1656 ORDER BY rou.resource_effective_start_date;
1657
1658 if (NVL(l_ResStartDateTab.count,0) = 0) THEN
1659 PA_SCHEDULE_UTILS.log_message(1,'Set all hours to 0 in l_sch_record_tab since no res denorm records exist. ');
1660 -- Set all hours to 0 in l_sch_record_tab since no res denorm records
1661 -- exist.
1662 l_sch_record_tab := x_sch_record_tab;
1663
1664 FOR i in l_sch_record_tab.first .. l_sch_record_tab.last loop
1665 l_sch_record_tab(i).monday_hours := 0;
1666 l_sch_record_tab(i).tuesday_hours := 0;
1667 l_sch_record_tab(i).wednesday_hours := 0;
1668 l_sch_record_tab(i).thursday_hours := 0;
1669 l_sch_record_tab(i).friday_hours := 0;
1670 l_sch_record_tab(i).saturday_hours := 0;
1671 l_sch_record_tab(i).sunday_hours := 0;
1672 END LOOP;
1673 else
1674 l_res_first_start_date := l_resstartdatetab(l_resstartdatetab.first);
1675 l_res_last_end_date := l_resenddatetab(l_resenddatetab.last);
1676
1677 PA_SCHEDULE_UTILS.log_message(1,'l_res_first_start_date: ' || l_res_first_start_date);
1678 PA_SCHEDULE_UTILS.log_message(1,'l_res_last_end_date: ' || l_res_last_end_date);
1679
1680 PA_SCHEDULE_UTILS.log_message(1,'Resource denorm records do exist.');
1681
1682 -- Check if there are any holes in resource denorm records.
1683 -- If so, then adjust x_sch_record_tab with that change.
1684
1685 -- If the start of the resource records is after the start of
1686 -- cap records, then insert a record in the beginning to indicate
1687 -- this hole.
1688 IF (l_cap_first_start_date < l_res_first_start_date) THEN
1689 l_resstartdatetab(l_resstartdatetab.first-1) := l_cap_first_start_date-10;
1690 l_resenddatetab(l_resenddatetab.first-1) := l_cap_first_start_date - 1;
1691 END IF;
1692
1693 -- If the end of the resource records is after the end of
1694 -- cap records, then insert a record in the end to indicate
1695 -- this hole.
1696 IF (l_cap_last_end_date > l_res_last_end_date) THEN
1697 l_resstartdatetab(l_resstartdatetab.last+1) := l_cap_last_end_date+1;
1698 l_resenddatetab(l_resenddatetab.last+1) := l_cap_last_end_date +10;
1699 END IF;
1700
1701 PA_SCHEDULE_UTILS.log_message(1,'l_prev_res_end_date: ' || l_prev_res_end_date);
1702
1703 l_last_processed_cap_index := 0;
1704 l_cap_tab_index := 1;
1705
1706 PA_SCHEDULE_UTILS.log_message(1,'l_res_last_end_date: ' || l_res_last_end_date);
1707 PA_schedule_utils.log_message(1,'l_cap_last_end_date: ' || l_cap_last_end_date);
1708
1709 l_last_processed_cap_index := x_sch_record_tab.first-1;
1710 PA_SCHEDULE_UTILS.log_message(1,'l_last_processed_cap_index: ' || l_last_processed_cap_index);
1711
1712 -- Find holes in l_ResStartDateTab, l_ResEndDateTab
1713 FOR i in l_ResStartDateTab.first .. l_ResStartDateTab.last LOOP
1714 pa_schedule_utils.log_message(1,'i: ' || i);
1715 PA_SCHEDULE_UTILS.log_message(1,'l_ResStartDateTab(i): ' || l_ResStartDateTab(i));
1716 PA_SCHEDULE_UTILS.log_message(1,'l_prev_res_end_date: ' || l_prev_res_end_date);
1717 if (l_ResStartDateTab(i) > l_prev_res_end_date+1) then
1718 l_hole_start_date := l_prev_res_end_date+1;
1719 l_hole_end_date := l_ResStartDateTab(i)-1;
1720 PA_SCHEDULE_UTILS.log_message(1,'Hole found: ' || l_hole_start_date || ' ' || l_hole_end_date);
1721
1722 -- Adjust x_sch_record_tab with decrease in availability.
1723 -- This is done by copying / modifying records up to hole end date.
1724 PA_SCHEDULE_UTILS.log_message(1,'l_last_processed_cap_index: ' || l_last_processed_cap_index);
1725 PA_SCHEDULE_UTILS.log_message(1,'Start loop through capacity records.');
1726
1727 <<l_cap_record_loop>>
1728 for j in (l_last_processed_cap_index + 1) .. x_sch_record_tab.last LOOP
1729
1730 l_j_index := j;
1731 PA_SCHEDULE_UTILS.log_message(1,'j: ' || j);
1732 PA_SCHEDULE_UTILS.log_message(1,'x_sch_record_tab(j).start_date: ' || x_sch_record_tab(j).start_date);
1733 PA_SCHEDULE_UTILS.log_message(1,'x_sch_record_tab(j).end_date: ' || x_sch_record_tab(j).end_date);
1734 PA_SCHEDULE_UTILS.log_message(1,'l_hole_end_date: ' || l_hole_end_date);
1735 l_reprocess_flag := 'N';
1736
1737
1738 IF (x_sch_record_tab(j).start_date = l_hole_end_date + 1) then
1739 PA_SCHEDULE_UTILS.log_message(1,'Finished looping through all capacity records for current hole. Find next hole.');
1740 l_reprocess_flag := 'Y'; -- Added after the fact
1741 EXIT l_cap_record_loop;
1742 -- Reprocess if the capacity record starts after the hole
1743 -- end date because it may overlap the next hole.
1744 ELSIF (x_sch_record_tab(j).start_date > l_hole_end_date + 1) then
1745 PA_SCHEDULE_UTILS.log_message(1,'Finished looping through all capacity records for current hole. Find next hole.');
1746 l_reprocess_flag := 'Y';
1747 EXIT l_cap_record_loop;
1748 end if;
1749
1750 -- If Capacity record is before hole.
1751 if (x_sch_record_tab(j).end_date < l_hole_start_date) then
1752
1753 PA_SCHEDULE_UTILS.log_message(1,'Capacity record before hole');
1754 -- Keep record as is.
1755 l_sch_record_tab(l_cap_tab_index) := x_sch_record_tab(j);
1756 l_cap_tab_index := l_cap_tab_index + 1;
1757 PA_SCHEDULE_UTILS.log_message(1,'j: ' || j);
1758 PA_SCHEDULE_UTILS.log_message(1,'x_sch_record_tab(j).start_date: ' || x_sch_record_tab(j).start_date);
1759 PA_SCHEDULE_UTILS.log_message(1,'x_sch_record_tab(j).end_date: ' || x_sch_record_tab(j).end_date);
1760 PA_SCHEDULE_UTILS.log_message(1,'j: ' || j);
1761
1762 -- If capacity record overlaps start date of hole.
1763 elsif (x_sch_record_tab(j).start_date < l_hole_start_date AND
1764 x_sch_record_tab(j).end_date <= l_hole_end_date) then
1765
1766 PA_SCHEDULE_UTILS.log_message(1,'capacity record overlaps start date of hole.');
1767 -- Keep record as is but end date it
1768 l_sch_record_tab(l_cap_tab_index) := x_sch_record_tab(j);
1769 l_sch_record_tab(l_cap_tab_index).end_date :=
1770 l_hole_start_date - 1;
1771 l_cap_tab_index := l_cap_tab_index + 1;
1772
1773 -- Create record for hole.
1774 l_sch_record_tab(l_cap_tab_index).start_date :=
1775 l_hole_start_date;
1776 l_sch_record_tab(l_cap_tab_index).end_date :=
1777 x_sch_record_tab(j).end_date;
1778 l_sch_record_tab(l_cap_tab_index).monday_hours := 0;
1779 l_sch_record_tab(l_cap_tab_index).tuesday_hours := 0;
1780 l_sch_record_tab(l_cap_tab_index).wednesday_hours := 0;
1781 l_sch_record_tab(l_cap_tab_index).thursday_hours := 0;
1782 l_sch_record_tab(l_cap_tab_index).friday_hours := 0;
1783 l_sch_record_tab(l_cap_tab_index).saturday_hours := 0;
1784 l_sch_record_tab(l_cap_tab_index).sunday_hours := 0;
1785 l_cap_tab_index := l_cap_tab_index + 1;
1786
1787 -- If capacity record overlaps start date and end date of hole.
1788 elsif (x_sch_record_tab(j).start_date < l_hole_start_date AND
1789 x_sch_record_tab(j).end_date > l_hole_end_date) then
1790
1791 PA_SCHEDULE_UTILS.log_message(1,'capacity record overlaps start date and end date of hole.');
1792
1793 -- Copy record over and end date it
1794 l_sch_record_tab(l_cap_tab_index) := x_sch_record_tab(j);
1795 l_sch_record_tab(l_cap_tab_index).end_date :=
1796 l_hole_start_date - 1;
1797 l_cap_tab_index := l_cap_tab_index + 1;
1798
1799 -- Create record for hole.
1800 l_sch_record_tab(l_cap_tab_index).start_date :=
1801 l_hole_start_date;
1802 l_sch_record_tab(l_cap_tab_index).end_date := l_hole_end_date;
1803 l_sch_record_tab(l_cap_tab_index).monday_hours := 0;
1804 l_sch_record_tab(l_cap_tab_index).tuesday_hours := 0;
1805 l_sch_record_tab(l_cap_tab_index).wednesday_hours := 0;
1806 l_sch_record_tab(l_cap_tab_index).thursday_hours := 0;
1807 l_sch_record_tab(l_cap_tab_index).friday_hours := 0;
1808 l_sch_record_tab(l_cap_tab_index).saturday_hours := 0;
1809 l_sch_record_tab(l_cap_tab_index).sunday_hours := 0;
1810 l_cap_tab_index := l_cap_tab_index + 1;
1811
1812 -- Modify x_sch_record_tab(j) so that the record will
1813 -- be reprocessed.
1814 PA_SCHEDULE_UTILS.log_message(1,'x_sch_record_tab(j).start_date: ' || x_sch_record_tab(j).start_date);
1815 PA_SCHEDULE_UTILS.log_message(1,'x_sch_record_tab(j).end_date: ' || x_sch_record_tab(j).end_date);
1816 PA_SCHEDULE_UTILS.log_message(1,'j: ' || j);
1817
1818 x_sch_record_tab(j).start_date := l_hole_end_date + 1;
1819 PA_SCHEDULE_UTILS.log_message(1,'Mark for reprocessing.');
1820 l_reprocess_flag := 'Y'; -- Mark for reprocessing.
1821
1822 EXIT l_cap_record_loop;
1823
1824 -- If capacity record within hole.
1825 elsif (x_sch_record_tab(j).start_date <= l_hole_end_date AND
1826 x_sch_record_tab(j).end_date <= l_hole_end_date) THEN
1827
1828 PA_SCHEDULE_UTILS.log_message(1,'capacity record within hole.');
1829
1830 -- Create record for hole.
1831 l_sch_record_tab(l_cap_tab_index) := x_sch_record_tab(j);
1832 l_sch_record_tab(l_cap_tab_index).monday_hours := 0;
1833 l_sch_record_tab(l_cap_tab_index).tuesday_hours := 0;
1834 l_sch_record_tab(l_cap_tab_index).wednesday_hours := 0;
1835 l_sch_record_tab(l_cap_tab_index).thursday_hours := 0;
1836 l_sch_record_tab(l_cap_tab_index).friday_hours := 0;
1837 l_sch_record_tab(l_cap_tab_index).saturday_hours := 0;
1838 l_sch_record_tab(l_cap_tab_index).sunday_hours := 0;
1839 l_cap_tab_index := l_cap_tab_index + 1;
1840
1841 -- If capacity record overlaps end date of hole.
1842 elsif (x_sch_record_tab(j).start_date <= l_hole_end_date AND
1843 x_sch_record_tab(j).end_date > l_hole_end_date) THEN
1844
1845 PA_SCHEDULE_UTILS.log_message(1,'capacity record overlaps end date of hole.');
1846
1847 -- Create record for hole.
1848 PA_SCHEDULE_UTILS.log_message(1,'l_cap_tab_index: ' || l_cap_tab_index);
1849 l_sch_record_tab(l_cap_tab_index) := x_sch_record_tab(j);
1850 l_sch_record_tab(l_cap_tab_index).end_date := l_hole_end_date;
1851 l_sch_record_tab(l_cap_tab_index).monday_hours := 0;
1852 l_sch_record_tab(l_cap_tab_index).tuesday_hours := 0;
1853 l_sch_record_tab(l_cap_tab_index).wednesday_hours := 0;
1854 l_sch_record_tab(l_cap_tab_index).thursday_hours := 0;
1855 l_sch_record_tab(l_cap_tab_index).friday_hours := 0;
1856 l_sch_record_tab(l_cap_tab_index).saturday_hours := 0;
1857 l_sch_record_tab(l_cap_tab_index).sunday_hours := 0;
1858 l_cap_tab_index := l_cap_tab_index + 1;
1859
1860 -- Modify x_sch_record_tab(j) so that the record will
1861 -- be reprocessed.
1862 PA_SCHEDULE_UTILS.log_message(1,'j: ' || j);
1863 PA_SCHEDULE_UTILS.log_message(1,'x_sch_record_tab(j).start_date: ' || x_sch_record_tab(j).start_date);
1864 PA_SCHEDULE_UTILS.log_message(1,'x_sch_record_tab(j).end_date: ' || x_sch_record_tab(j).end_date);
1865 x_sch_record_tab(j).start_date := l_hole_end_date + 1;
1866
1867 PA_SCHEDULE_UTILS.log_message(1,'Mark for reprocessing.');
1868 l_reprocess_flag := 'Y'; -- Mark for reprocessing.
1869 EXIT l_cap_record_loop;
1870 END IF;
1871 -- Type of hole if statement
1872 END LOOP;
1873 -- for j in l_last_processed_cap_index + 1 ..
1874 -- modifying l_sch_record_tab with hole info.
1875
1876 PA_SCHEDULE_UTILS.log_message(1,'JM: 1');
1877 PA_SCHEDULE_UTILS.log_message(1,'l_j_index: ' || l_j_index);
1878 IF (l_reprocess_flag = 'Y') THEN
1879 l_last_processed_cap_index := l_j_index-1;
1880 ELSE
1881 l_last_processed_cap_index := l_j_index;
1882 END IF;
1883
1884 END IF;
1885 -- l_ResStartDateTab(i) > l_prev_res_end_date+1
1886 -- When there is a hole
1887
1888 l_prev_res_end_date := l_ResEndDateTab(i);
1889 PA_SCHEDULE_UTILS.log_message(1,'JM: 2');
1890
1891 END LOOP;
1892 -- FOR i in l_ResStartDateTab.first .. l_ResStartDateTab.last
1893 -- Finding holes
1894
1895 -- Copy rest of schedule records to local table.
1896 for j in l_last_processed_cap_index + 1 .. x_sch_record_tab.last loop
1897 l_sch_record_tab(l_cap_tab_index) := x_sch_record_tab(j);
1898 l_cap_tab_index := l_cap_tab_index + 1;
1899 END LOOP;
1900
1901 END IF;
1902 -- if (NVL(l_ResStartDateTab.count,0) = 0) THEN
1903 -- If there are any records in resource denorm.
1904 PA_SCHEDULE_UTILS.log_message(1,'JM: 3');
1905 END IF;
1906 -- IF (NVL(x_sch_record_tab.count,0) <> 0) THEN
1907 -- If there are any capacity records.
1908
1909 x_sch_record_tab := l_sch_record_tab;
1910 -- End 2196924: Fix table by setting 0 for all dates with no HR assignment.
1911
1912 x_return_status := l_x_return_status;
1913 PA_SCHEDULE_UTILS.log_message(1,'last status ... '||l_x_return_status);
1914 PA_SCHEDULE_UTILS.log_message(1,'leaving get_resource_schedule');
1915 EXCEPTION
1916 WHEN l_invalid_source_id THEN
1917 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1918 x_msg_count := 1;
1919 x_msg_data := 'l_invalid_source_id';
1920 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
1921 p_procedure_name => 'get_resource_schedule');
1922 raise;
1923 WHEN OTHERS THEN
1924 x_msg_count := 1;
1925 x_msg_data := SQLERRM;
1926 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1927 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
1928 p_procedure_name => 'get_resource_schedule');
1929 raise;
1930
1931 END get_resource_schedule;
1932
1933
1934 -- This procedure is called from change_schedule procedure. This procedure applys
1935 -- the resultant schedule details ( after applying exceptions ) on the schedule related tables
1936 -- Input parameters
1937 -- Parameters Type Required Description
1938 -- P_Chg_Sch_Record_Tab SCHEDULETABTYP YES It has the schedule record which are marked for changed
1939 -- e.g I , U
1940 -- P_Del_Sch_Record_Tab SCHEDULETABTYP YES It has the schedule record which are marked for deletion
1941 --
1942
1943 PROCEDURE apply_schedule_change( p_chg_sch_record_tab IN PA_SCHEDULE_GLOB.ScheduleTabTyp,
1944 p_del_sch_record_tab IN PA_SCHEDULE_GLOB.ScheduleTabTyp,
1945 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
1946 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
1947 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
1948 IS
1949 l_I NUMBER;
1950 l_upd_sch_record_tab PA_SCHEDULE_GLOB.ScheduleTabTyp; -- variable used for storing the records kept for updation
1951 l_ins_sch_record_tab PA_SCHEDULE_GLOB.ScheduleTabTyp; -- variable used for storing the records kept for insertion
1952 BEGIN
1953 -- storing status for tracking the error
1954 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
1955 -- checking if the passing records is empty or not
1956 IF (p_chg_sch_record_tab.count = 0 ) THEN
1957 RAISE l_empty_tab_record;
1958 ELSE
1959 l_I := p_chg_sch_record_tab.first;
1960 END IF;
1961
1962 PA_SCHEDULE_UTILS.log_message(1,'Start of apply_schedule_change .... ');
1963 LOOP
1964
1965 IF (p_chg_sch_record_tab(l_I).change_type_code = 'U') THEN
1966 PA_SCHEDULE_UTILS.log_message(1,'U .... ');
1967 -- Calling the SCHEDULE UTILS api which will append the record if it marked for updation
1968 PA_SCHEDULE_UTILS.Add_Schedule_Rec_Tab(p_chg_sch_record_tab,l_I,l_I,l_upd_sch_record_tab,
1969 l_x_return_status,x_msg_count,x_msg_data);
1970 ELSIF (p_chg_sch_record_tab(l_I).change_type_code = 'I') THEN
1971 PA_SCHEDULE_UTILS.log_message(1,'I .... ');
1972
1973 -- Calling the SCHEDULE UTILS api which will append the record if it marked for insertion
1974 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1975 PA_SCHEDULE_UTILS.Add_Schedule_Rec_Tab(p_chg_sch_record_tab,l_I,l_I,l_ins_sch_record_tab,
1976 l_x_return_status,x_msg_count,x_msg_data);
1977 END IF;
1978
1979 END IF;
1980
1981 IF (l_I = p_chg_sch_record_tab.last ) THEN
1982 EXIT;
1983 ELSE
1984 l_I := p_chg_sch_record_tab.next(l_I);
1985 END IF;
1986 END LOOP;
1987
1988
1989
1990 -- Applying the changes according to their status i.e. insert,update or delete
1991 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1992 PA_SCHEDULE_PKG.Insert_Rows(l_ins_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
1993 END IF;
1994
1995 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
1996 PA_SCHEDULE_PKG.Update_Rows(l_upd_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
1997 END IF;
1998
1999 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2000 PA_SCHEDULE_PKG.Delete_Rows(p_del_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
2001 END IF;
2002
2003 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2004 PA_SCHEDULE_PVT.merge_work_pattern(p_chg_sch_record_tab(1).project_id,p_chg_sch_record_tab(1).assignment_id,l_x_return_status,x_msg_count,x_msg_data);
2005 END IF;
2006
2007 PA_SCHEDULE_UTILS.log_message(1,'end of apply_schedule_change .... ');
2008 x_return_status := l_x_return_status;
2009 EXCEPTION
2010 WHEN l_empty_tab_record THEN
2011 x_return_status := FND_API.G_RET_STS_SUCCESS;
2012 NULL;
2013 WHEN OTHERS THEN
2014 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2015 x_msg_count := 1;
2016 x_msg_data := SQLERRM;
2017 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
2018 p_procedure_name => 'apply_schedule_change');
2019 raise;
2020
2021 END apply_schedule_change;
2022
2023 -- This procedure will create the new schedule on the basis of passed criteria i.e change duration
2024 -- ,Change hours and so on
2025 -- Input parameters
2026 -- Parameters Type Required Description
2027 -- P_Sch_Except_Record_Tab SCHEXCEPTRECORD YES It has the exception record
2028 -- P_Sch_Record SCHEDULERECORD YES It has the schedule record
2029 -- In Out parameters
2030 -- X_Sch_Record_Tab SCHEDULETABTYP YES It store the new schedule
2031 --
2032
2033 PROCEDURE create_new_schedule(
2034 p_sch_except_record IN pa_schedule_glob.SchExceptRecord,
2035 p_sch_record IN pa_schedule_glob.ScheduleRecord,
2036 x_sch_record_tab IN OUT NOCOPY pa_schedule_glob.ScheduleTabTyp,
2037 x_difference_days IN NUMBER, -- Added for bug 7663765
2038 x_shift_unit_code IN VARCHAR2, -- Added for bug 7663765
2039 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
2040 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
2041 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
2042 IS
2043 l_t_team_player_id NUMBER;
2044 l_t_res_cal_percent NUMBER;
2045 l_t_calendar_id NUMBER;
2046 l_t_calendar_type VARCHAR2(30);
2047
2048 BEGIN
2049 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
2050
2051 PA_SCHEDULE_UTILS.log_message(1,'Start of create_new_schedule API ..... ');
2052 PA_SCHEDULE_UTILS.log_message(1,'exception_type_code '||p_sch_except_record.exception_type_code);
2053
2054 -- This procedure will create the new schedule for the given change duration exception it will create by changing
2055 -- the duration
2056 IF (p_sch_except_record.exception_type_code = 'CHANGE_DURATION' OR
2057 p_sch_except_record.exception_type_code = 'SHIFT_DURATION' OR
2058 p_sch_except_record.exception_type_code = 'DURATION_PATTERN_SHIFT') THEN
2059 -- Calling the procedure create_new_duration
2060 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2061 PA_SCHEDULE_PVT.create_new_duration(p_sch_except_record,
2062 p_sch_record,
2063 x_sch_record_tab,
2064 x_difference_days, -- Added for bug 7663765
2065 x_shift_unit_code, -- Added for bug 7663765
2066 l_x_return_status,
2067 x_msg_count,
2068 x_msg_data);
2069 END IF;
2070 ELSIF (p_sch_except_record.exception_type_code = 'CHANGE_HOURS') THEN
2071 -- This procedure will create the new schedule for the given change hours exception it will create by
2072 -- changing the hours for the given period
2073 -- Calling the procedure create_new_hours
2074 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2075 PA_SCHEDULE_PVT.create_new_hours(p_sch_except_record,
2076 p_sch_record,
2077 x_sch_record_tab,
2078 l_x_return_status,
2079 x_msg_count,
2080 x_msg_data);
2081 END IF;
2082 ELSIF (p_sch_except_record.exception_type_code = 'CHANGE_WORK_PATTERN') THEN
2083 -- This procedure will create the new schedule for the given change work pattern exception it will create
2084 -- by just changing the work patern for the given period
2085 -- Calling the procedure create_new_pattern
2086 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2087 PA_SCHEDULE_PVT.create_new_pattern(p_sch_except_record,
2088 p_sch_record,
2089 x_sch_record_tab,
2090 l_x_return_status,
2091 x_msg_count,
2092 x_msg_data);
2093 END IF;
2094 ELSIF (p_sch_except_record.exception_type_code = 'CHANGE_STATUS') THEN
2095 -- This procedure will create the new schedule for the given change status exception it will create
2096 -- by changing the status for that period only
2097 -- Calling the procedure create_new_status
2098 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2099 PA_SCHEDULE_PVT.create_new_status(p_sch_except_record,
2100 p_sch_record,
2101 x_sch_record_tab,
2102 l_x_return_status,
2103 x_msg_count,
2104 x_msg_data);
2105 END IF;
2106 ELSIF (p_sch_except_record.exception_type_code = 'CHANGE_CALENDAR') THEN
2107 -- This procedure will create the new schedule for the given change calendar exception it will create
2108 -- by changing the calendar for that period only
2109 -- Calling the procedure create_new_calendar
2110 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2111 PA_SCHEDULE_PVT.create_new_calendar(p_sch_except_record,
2112 p_sch_record,
2113 x_sch_record_tab,
2114 l_x_return_status,
2115 x_msg_count,
2116 x_msg_data);
2117 END IF;
2118 END IF;
2119
2120 PA_SCHEDULE_UTILS.log_message(1,'after calling respective APIs return x_sch_record_tab.coun '||to_char
2121 (x_sch_record_tab.count)||' Status '||l_x_return_status);
2122 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2123 PA_SCHEDULE_UTILS.update_sch_rec_tab(x_sch_record_tab,
2124 p_change_type_code => 'I',
2125 x_return_status => l_x_return_status,
2126 x_msg_count => x_msg_count,
2127 x_msg_data => x_msg_data
2128 );
2129 END IF;
2130 x_return_status := l_x_return_status;
2131
2132 EXCEPTION
2133 WHEN OTHERS THEN
2134 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2135 x_msg_count := 1;
2136 x_msg_data := SQLERRM;
2137 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
2138 p_procedure_name => 'create_new_schedule');
2139 raise;
2140
2141 END create_new_schedule;
2142
2143 -- This procedure will create the new calendar with the passed exception
2144 -- Input parameters
2145 -- Parameters Type Required Description
2146 -- In Out parameters
2147 -- P_Sch_Except_Record_Tab SCHEXCEPTRECORD YES It has the exception record
2148 -- P_Sch_Record SCHEDULERECORD YES It has the schedule record
2149 -- X_Sch_Record_Tab SCHEDULETABTYP YES It store the new schedule
2150 --
2151
2152 PROCEDURE create_new_calendar(
2153 p_sch_except_record IN pa_schedule_glob.SchExceptRecord,
2154 p_sch_record IN pa_schedule_glob.ScheduleRecord,
2155 x_sch_record_tab IN OUT NOCOPY pa_schedule_glob.ScheduleTabTyp,
2156 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
2157 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
2158 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
2159 )
2160 IS
2161 BEGIN
2162 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
2163
2164 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2165 PA_SCHEDULE_UTILS.check_calendar(
2166 p_calendar_id => p_sch_except_record.calendar_id,
2167 p_start_date => p_sch_except_record.start_date,
2168 p_end_date => p_sch_except_record.end_date,
2169 x_return_status => l_x_return_status,
2170 x_msg_count => x_msg_count,
2171 x_msg_data => x_msg_data);
2172 END IF;
2173
2174 -- Calling the procedure get_calendar_schedule that will bring the new schedule of the passed calendar
2175 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2176 PA_SCHEDULE_PVT.get_calendar_schedule(p_sch_except_record.calendar_id,
2177 p_sch_except_record.start_date,
2178 p_sch_except_record.end_date,
2179 x_sch_record_tab,
2180 l_x_return_status,
2181 x_msg_count,
2182 x_msg_data
2183 );
2184 END IF;
2185 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2186 PA_SCHEDULE_UTILS.update_sch_rec_tab(x_sch_record_tab,
2187 p_project_id => p_sch_except_record.project_id,
2188 p_schedule_type_code => p_sch_except_record.schedule_type_code,
2189 p_assignment_id => p_sch_except_record.assignment_id,
2190 p_assignment_status_code => p_sch_record.assignment_status_code,
2191 x_return_status => l_x_return_status,
2192 x_msg_count => x_msg_count,
2193 x_msg_data => x_msg_data
2194 );
2195 END IF;
2196 x_return_status := l_x_return_status;
2197 EXCEPTION
2198 WHEN OTHERS THEN
2199 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2200 x_msg_count := 1;
2201 x_msg_data := SQLERRM;
2202 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
2203 p_procedure_name => 'create_new_calendar');
2204
2205 PA_SCHEDULE_UTILS.log_message(1,'ERROR in create_new_schedule procedure ');
2206 raise;
2207
2208 END create_new_calendar;
2209
2210 -- This procedure will create the new schedule by createing the new hours on the basis of change hours
2211 -- code i.e PERCENTAGE or HOURS
2212 -- Input parameters
2213 -- Parameters Type Required Description
2214 -- P_Sch_Except_Record_Tab SCHEXCEPTRECORD YES It has the exception record
2215 -- P_Sch_Record SCHEDULERECORD YES It has the schedule record
2216 -- In Out parameters
2217 -- X_Sch_Record_Tab SCHEDULETABTYP YES It store the new schedule
2218 --
2219
2220 PROCEDURE create_new_hours(
2221 p_sch_except_record IN pa_schedule_glob.SchExceptRecord,
2222 p_sch_record IN pa_schedule_glob.ScheduleRecord,
2223 x_sch_record_tab IN OUT NOCOPY pa_schedule_glob.ScheduleTabTyp,
2224 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
2225 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
2226 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
2227 IS
2228 l_t_calendar_id pa_project_assignments.calendar_id%TYPE; -- to store the value for new creating hours
2229 l_t_calendar_type pa_project_assignments.calendar_type%TYPE; -- to store the value for new creating hours
2230 l_t_team_player_id NUMBER; -- to store the value for new creating hours
2231
2232 l_t_resource_id NUMBER; -- to sto
2233 l_t_asgn_type pa_project_assignments.assignment_type%TYPE; /*Bug 5682726*/
2234 BEGIN
2235 PA_SCHEDULE_UTILS.log_message(1,'start of create new hours ... ');
2236 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
2237 PA_SCHEDULE_UTILS.log_message(1,'start of create new hours ...change_hours_type ...'||
2238 p_sch_except_record.change_hours_type_code);
2239
2240 -- For this hours code we will changed the previous schedule 's hours with the new passed
2241 -- values and create new hours for a given period only
2242 IF (p_sch_except_record.change_hours_type_code = 'HOURS') THEN
2243 x_sch_record_tab(1).start_date := p_sch_except_record.start_date;
2244 x_sch_record_tab(1).end_date := p_sch_except_record.end_date;
2245
2246 IF (p_sch_except_record.non_working_day_flag = 'Y') THEN
2247 x_sch_record_tab(1).Monday_hours := p_sch_except_record.Monday_hours;
2248 x_sch_record_tab(1).Tuesday_hours := p_sch_except_record.Tuesday_hours;
2249 x_sch_record_tab(1).Wednesday_hours := p_sch_except_record.Wednesday_hours;
2250 x_sch_record_tab(1).Thursday_hours := p_sch_except_record.Thursday_hours;
2251 x_sch_record_tab(1).Friday_hours := p_sch_except_record.Friday_hours;
2252 x_sch_record_tab(1).Saturday_hours := p_sch_except_record.Saturday_hours;
2253 x_sch_record_tab(1).Sunday_hours := p_sch_except_record.Sunday_hours;
2254 ELSE
2255 x_sch_record_tab(1).Monday_hours := 0;
2256 x_sch_record_tab(1).Tuesday_hours := 0;
2257 x_sch_record_tab(1).Wednesday_hours := 0;
2258 x_sch_record_tab(1).Thursday_hours := 0;
2259 x_sch_record_tab(1).Friday_hours := 0;
2260 x_sch_record_tab(1).Saturday_hours := 0;
2261 x_sch_record_tab(1).Sunday_hours := 0;
2262
2263 /* Bug 5682726 - Start Changes */
2264
2265 SELECT assignment_type
2266 INTO l_t_asgn_type
2267 FROM pa_project_assignments
2268 where assignment_id = p_sch_except_record.assignment_id;
2269
2270 IF ( l_t_asgn_type = 'STAFFED_ASSIGNMENT' OR l_t_asgn_type =
2271 'STAFFED_ADMIN_ASSIGNMENT' ) THEN
2272
2273 IF (p_sch_except_record.change_calendar_type_code = 'RESOURCE') THEN /*start bug#10141855*/
2274
2275 SELECT project_party_id
2276 INTO l_t_team_player_id
2277 FROM pa_project_assignments
2278 WHERE assignment_id = p_sch_except_record.assignment_id;
2279
2280 SELECT resource_id
2281 INTO l_t_resource_id
2282 FROM pa_project_assignments
2283 WHERE assignment_id = p_sch_except_record.assignment_id;
2284
2285 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2286 PA_SCHEDULE_UTILS.check_calendar(p_resource_id => l_t_resource_id,
2287 p_start_date => p_sch_except_record.start_date,
2288 p_end_date => p_sch_except_record.end_date,
2289 x_return_status => l_x_return_status,
2290 x_msg_count => x_msg_count,
2291 x_msg_data => x_msg_data);
2292 END IF;
2293
2294 -- Calling the procedure get_resource_schedule that will bring the schedule associated with the resource
2295 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2296 PA_SCHEDULE_PVT.get_resource_schedule(l_t_team_player_id,
2297 'PA_PROJECT_PARTY_ID',
2298 p_sch_except_record.start_date,
2299 p_sch_except_record.end_date,
2300 x_sch_record_tab,
2301 l_x_return_status,
2302 x_msg_count,
2303 x_msg_data);
2304 END IF;
2305 ELSE
2306
2307 SELECT calendar_id
2308 INTO l_t_calendar_id
2309 FROM pa_project_assignments
2310 where assignment_id = p_sch_except_record.assignment_id;
2311
2312 PA_SCHEDULE_PVT.get_calendar_schedule( l_t_calendar_id,
2313 p_sch_except_record.start_date,
2314 p_sch_except_record.end_date,
2315 x_sch_record_tab,
2316 l_x_return_status,
2317 x_msg_count,
2318 x_msg_data);
2319
2320 END IF ; /*End bug#10141855*/
2321
2322 ELSE
2323 IF ( l_t_asgn_type = 'OPEN_ASSIGNMENT' ) THEN
2324 SELECT calendar_id
2325 INTO l_t_calendar_id
2326 FROM pa_project_assignments
2327 where assignment_id = p_sch_except_record.assignment_id;
2328
2329 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2330 PA_SCHEDULE_UTILS.check_calendar(p_calendar_id => l_t_calendar_id,
2331 p_start_date => p_sch_except_record.start_date,
2332 p_end_date => p_sch_except_record.end_date,
2333 x_return_status => l_x_return_status,
2334 x_msg_count => x_msg_count,
2335 x_msg_data => x_msg_data);
2336 END IF;
2337
2338
2339 -- Calling the procedure get_calendar_schedule that will bring the schedule associated with the
2340 -- assignment on the basis of passed calendar id
2341 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2342 PA_SCHEDULE_PVT.get_calendar_schedule(l_t_calendar_id,
2343 p_sch_except_record.start_date,
2344 p_sch_except_record.end_date,
2345 x_sch_record_tab,
2346 l_x_return_status,
2347 x_msg_count,
2348 x_msg_data);
2349 END IF;
2350
2351 END IF; /* IF ( l_t_asgn_type = 'OPEN_ASSIGNMENT' ) */
2352 END IF; /* IF ( l_t_asgn_type = 'STAFFED_ASSIGNMENT' ) */
2353
2354 IF (x_sch_record_tab(1).Monday_hours <> 0) THEN
2355 x_sch_record_tab(1).Monday_hours := p_sch_except_record.Monday_hours;
2356 END IF;
2357
2358 IF (x_sch_record_tab(1).Tuesday_hours <> 0) THEN
2359 x_sch_record_tab(1).Tuesday_hours := p_sch_except_record.Tuesday_hours;
2360 END IF;
2361
2362 IF (x_sch_record_tab(1).Wednesday_hours <> 0) THEN
2363 x_sch_record_tab(1).Wednesday_hours := p_sch_except_record.Wednesday_hours;
2364 END IF;
2365
2366 IF (x_sch_record_tab(1).Thursday_hours <> 0) THEN
2367 x_sch_record_tab(1).Thursday_hours := p_sch_except_record.Thursday_hours;
2368 END IF;
2369
2370 IF (x_sch_record_tab(1).Friday_hours <> 0) THEN
2371 x_sch_record_tab(1).Friday_hours := p_sch_except_record.Friday_hours;
2372 END IF;
2373
2374 IF (x_sch_record_tab(1).Saturday_hours <> 0) THEN
2375 x_sch_record_tab(1).Saturday_hours := p_sch_except_record.Saturday_hours;
2376 END IF;
2377
2378 IF (x_sch_record_tab(1).Sunday_hours <> 0) THEN
2379 x_sch_record_tab(1).Sunday_hours := p_sch_except_record.Sunday_hours;
2380 END IF;
2381 /* Bug 5682726 - End Changes */
2382 END IF;
2383
2384 END IF;
2385
2386 -- In this case we take the calendar which is asociated with the resource and apply the percentage change
2387 -- on the existing one or the created one
2388 IF (p_sch_except_record.change_hours_type_code = 'PERCENTAGE') THEN
2389
2390 -- If the calendar type is resource, then we 'll pick the value for calendar from
2391 -- resource i.e. CRM else from calendar
2392 IF (p_sch_except_record.change_calendar_type_code = 'RESOURCE') THEN
2393
2394 -- get project_party_id to pass api 'get_resource_schedule'
2395 SELECT project_party_id
2396 INTO l_t_team_player_id
2397 FROM pa_project_assignments
2398 WHERE assignment_id = p_sch_except_record.assignment_id;
2399
2400 SELECT resource_id
2401 INTO l_t_resource_id
2402 FROM pa_project_assignments
2403 WHERE assignment_id = p_sch_except_record.assignment_id;
2404
2405 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2406 PA_SCHEDULE_UTILS.check_calendar(p_resource_id => l_t_resource_id,
2407 p_start_date => p_sch_except_record.start_date,
2408 p_end_date => p_sch_except_record.end_date,
2409 x_return_status => l_x_return_status,
2410 x_msg_count => x_msg_count,
2411 x_msg_data => x_msg_data);
2412 END IF;
2413
2414 -- Calling the procedure get_resource_schedule that will bring the schedule associated with the resource
2415 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2416 PA_SCHEDULE_PVT.get_resource_schedule(l_t_team_player_id,
2417 'PA_PROJECT_PARTY_ID',
2418 p_sch_except_record.start_date,
2419 p_sch_except_record.end_date,
2420 x_sch_record_tab,
2421 l_x_return_status,
2422 x_msg_count,
2423 x_msg_data);
2424 -- if calendar_type is either 'PROJECT' or 'OTHER'
2425 END IF;
2426 ELSE
2427
2428 IF (p_sch_except_record.change_calendar_type_code = 'PROJECT') THEN
2429 SELECT calendar_id
2430 INTO l_t_calendar_id
2431 FROM pa_projects_all
2432 WHERE project_id = p_sch_except_record.project_id;
2433
2434 -- Use change_calendar_id passed from calendar LOV for the calendar_id to be updated
2435 ELSIF (p_sch_except_record.change_calendar_type_code = 'OTHER') THEN
2436 l_t_calendar_id := p_sch_except_record.change_calendar_id;
2437 END IF;
2438
2439 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2440 PA_SCHEDULE_UTILS.check_calendar(
2441 p_calendar_id => l_t_calendar_id,
2442 p_start_date => p_sch_except_record.start_date,
2443 p_end_date => p_sch_except_record.end_date,
2444 x_return_status => l_x_return_status,
2445 x_msg_count => x_msg_count,
2446 x_msg_data => x_msg_data);
2447 END IF;
2448
2449
2450 -- Calling the procedure get_calendar_schedule that will bring the schedule associated with the
2451 -- assignment on the basis of passed calendar id
2452 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2453 PA_SCHEDULE_PVT.get_calendar_schedule(l_t_calendar_id,
2454 p_sch_except_record.start_date,
2455 p_sch_except_record.end_date,
2456 x_sch_record_tab,
2457 l_x_return_status,
2458 x_msg_count,
2459 x_msg_data);
2460 END IF;
2461 END IF;
2462
2463 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2464 -- Calling the schedule API
2465 PA_SCHEDULE_UTILS.apply_percentage(x_sch_record_tab,
2466 p_sch_except_record.resource_calendar_percent,
2467 l_x_return_status,
2468 x_msg_count,
2469 x_msg_data );
2470 END IF;
2471
2472 END IF; --IF (p_sch_except_record.change_hours_type_code = 'PERCENTAGE')
2473
2474
2475 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2476 -- Updating the pa schedules table
2477 PA_SCHEDULE_UTILS.update_sch_rec_tab(x_sch_record_tab,
2478 p_project_id => p_sch_except_record.project_id,
2479 p_schedule_type_code => p_sch_except_record.schedule_type_code,
2480 p_assignment_id => p_sch_except_record.assignment_id,
2481 p_calendar_id => p_sch_except_record.calendar_id,
2482 p_assignment_status_code => p_sch_record.assignment_status_code,
2483 x_return_status => l_x_return_status,
2484 x_msg_count => x_msg_count,
2485 x_msg_data => x_msg_data
2486 );
2487 END IF;
2488
2489 x_return_status := l_x_return_status;
2490 EXCEPTION
2491 WHEN OTHERS THEN
2492 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2493 x_msg_count := 1;
2494 x_msg_data := SQLERRM;
2495 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
2496 p_procedure_name => 'create_new_hours');
2497 raise;
2498
2499 END create_new_hours;
2500
2501 -- This procedure will create new duration on the basis of passed exception and schedule
2502 -- Input parameters
2503 -- Parameters Type Required Description
2504 -- P_Sch_Except_Record_Tab SCHEXCEPTRECORD YES It has the exception record
2505 -- P_Sch_Record SCHEDULERECORD YES It has the schedule record
2506 -- In Out parameters
2507 -- X_Sch_Record_Tab SCHEDULETABTYP YES It store the new schedule
2508 --
2509
2510 PROCEDURE create_new_duration(
2511 p_sch_except_record IN pa_schedule_glob.SchExceptRecord,
2512 p_sch_record IN pa_schedule_glob.ScheduleRecord,
2513 x_sch_record_tab IN OUT NOCOPY pa_schedule_glob.ScheduleTabTyp,
2514 x_difference_days IN NUMBER, -- Added for bug 7663765
2515 x_shift_unit_code IN VARCHAR2, -- Added for bug 7663765
2516 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
2517 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
2518 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
2519 )
2520 IS
2521 l_t_team_player_id NUMBER;
2522 l_t_res_cal_percent NUMBER;
2523 l_t_calendar_id NUMBER;
2524 l_t_calendar_type VARCHAR2(30);
2525 BEGIN
2526 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
2527
2528 PA_SCHEDULE_UTILS.log_message(1,'Start of create_new_duration API .........');
2529 PA_SCHEDULE_UTILS.log_message(1,'schedule_type_code '||p_sch_except_record.schedule_type_code);
2530 -- Bug 1580455: added STAFFED_ADMIN_ASSIGNMENT case.
2531 /* Added the below if for 7663765 */
2532 IF (p_sch_except_record.exception_type_code = 'DURATION_PATTERN_SHIFT') then
2533
2534 PA_SCHEDULE_PVT.get_existing_schedule(l_t_calendar_id,
2535 p_sch_except_record.assignment_id,
2536 p_sch_except_record.start_date,
2537 p_sch_except_record.end_date,
2538 x_sch_record_tab,
2539 x_difference_days,
2540 x_shift_unit_code,
2541 l_x_return_status,
2542 x_msg_count,
2543 x_msg_data );
2544 else
2545 IF (p_sch_except_record.schedule_type_code = 'STAFFED_ASSIGNMENT') OR
2546 (p_sch_except_record.schedule_type_code = 'STAFFED_ADMIN_ASSIGNMENT') THEN
2547
2548 SELECT project_party_id , resource_calendar_percent,calendar_id,calendar_type
2549 INTO l_t_team_player_id,l_t_res_cal_percent,l_t_calendar_id,l_t_calendar_type
2550 FROM pa_project_assignments
2551 WHERE assignment_id = p_sch_except_record.assignment_id;
2552
2553 IF ( l_t_calendar_type = 'RESOURCE' ) THEN
2554 -- Calling the procedure get_resource_schedule which is assigned to the assignment
2555 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2556 PA_SCHEDULE_PVT.get_resource_schedule(l_t_team_player_id,
2557 'PA_PROJECT_PARTY_ID',
2558 p_sch_except_record.start_date,
2559 p_sch_except_record.end_date,
2560 x_sch_record_tab,
2561 l_x_return_status,
2562 x_msg_count,
2563 x_msg_data
2564 );
2565 END IF;
2566
2567 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2568 -- Calling the schedule API which will apply the percentage on the schedule
2569 PA_SCHEDULE_UTILS.apply_percentage(x_sch_record_tab,
2570 l_t_res_cal_percent,
2571 l_x_return_status,
2572 x_msg_count,
2573 x_msg_data
2574 );
2575 END IF;
2576
2577 ELSE
2578 -- Calling the procedure get_calendar_schedule for the calendar assigned to that resource
2579 PA_SCHEDULE_PVT.get_calendar_schedule(l_t_calendar_id,
2580 p_sch_except_record.start_date,
2581 p_sch_except_record.end_date,
2582 x_sch_record_tab,
2583 l_x_return_status,
2584 x_msg_count,
2585 x_msg_data
2586 );
2587 END IF;
2588
2589 ELSE
2590
2591 PA_SCHEDULE_UTILS.log_message(2,'cal_id '||p_sch_except_record.calendar_id||' st_dt '||
2592 p_sch_except_record.start_date||' en_dt '||p_sch_except_record.end_date);
2593
2594 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2595 -- Calling the procedure get_calendar_schedule on the basis of passed calendar id and for
2596 -- calendar type like assignment,project or others
2597 PA_SCHEDULE_PVT.get_calendar_schedule(p_sch_except_record.calendar_id,
2598 p_sch_except_record.start_date,
2599 p_sch_except_record.end_date,
2600 x_sch_record_tab,
2601 l_x_return_status,
2602 x_msg_count,
2603 x_msg_data
2604 );
2605 END IF;
2606
2607 PA_SCHEDULE_UTILS.log_message(2,'x_sch ',x_sch_record_tab);
2608 END IF;
2609 end if; -- 7663765
2610
2611 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2612 PA_SCHEDULE_UTILS.update_sch_rec_tab(x_sch_record_tab,
2613 p_project_id => p_sch_except_record.project_id,
2614 p_schedule_type_code => p_sch_except_record.schedule_type_code,
2615 p_assignment_id => p_sch_except_record.assignment_id,
2616 p_calendar_id => p_sch_except_record.calendar_id,
2617 p_assignment_status_code => p_sch_except_record.assignment_status_code,
2618 x_return_status => l_x_return_status,
2619 x_msg_count => x_msg_count,
2620 x_msg_data => x_msg_data
2621 );
2622 END IF;
2623
2624 x_return_status := l_x_return_status;
2625 EXCEPTION
2626 WHEN OTHERS THEN
2627 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2628 x_msg_count := 1;
2629 x_msg_data := SQLERRM;
2630 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
2631 p_procedure_name => 'create_new_duration');
2632
2633 PA_SCHEDULE_UTILS.log_message(1,'ERROR in create_new_duration procedure ');
2634 raise;
2635
2636 END create_new_duration;
2637
2638
2639
2640 --*******************************************************************************
2641 -- This procedure will merge the work pattern
2642 -- Input parameters
2643 -- Parameters Type Required Description
2644 -- p_project_id NUMBER YES It has the project_id
2645 -- p_assignment_id NUMBER YES It has the assignment_id
2646
2647 PROCEDURE merge_work_pattern(
2648 p_project_id IN NUMBER,
2649 p_assignment_id IN NUMBER,
2650 x_return_status OUT NOCOPY VARCHAR2,
2651 x_msg_count OUT NOCOPY NUMBER,
2652 x_msg_data OUT NOCOPY VARCHAR2 )
2653 IS
2654 CURSOR csr_get_sch IS
2655 select
2656 rowid,
2657 calendar_id,
2658 schedule_id,
2659 schedule_type_code,
2660 status_code,
2661 start_date,
2662 end_date,
2663 monday_hours,
2664 tuesday_hours,
2665 wednesday_hours,
2666 thursday_hours,
2667 friday_hours,
2668 saturday_hours,
2669 sunday_hours
2670 from pa_schedules
2671 where project_id = p_project_id and
2672 assignment_id = p_assignment_id
2673 order by start_date;
2674
2675 l_temp_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
2676 l_del_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
2677 l_final_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
2678
2679 l_I NUMBER;
2680 l_J NUMBER;
2681 l_K NUMBER;
2682 l_Flag VARCHAR2(1) := 'Y';
2683 l_Merge_Flag VARCHAR2(1) := 'N';
2684 l_schrowid rowid;
2685 l_schedule_id number;
2686 l_calendar_id number;
2687 l_schedule_type_code varchar2(30);
2688 l_assignment_status_code varchar2(30);
2689 l_start_date DATE;
2690 l_end_date DATE;
2691 l_monday_hours number;
2692 l_tuesday_hours number;
2693 l_wednesday_hours number;
2694 l_thursday_hours number;
2695 l_friday_hours number;
2696 l_saturday_hours number;
2697 l_sunday_hours number;
2698
2699 /*Added status variable for bug 6921728*/
2700 l_x_return_status varchar2(1) ;
2701
2702
2703 BEGIN
2704 /*Added initialization for bug 6921728*/
2705 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
2706
2707 l_I := 1;
2708
2709 FOR rec_sch IN csr_get_sch LOOP
2710 l_temp_sch_rec_tab(l_i).schrowid := rec_sch.rowid;
2711 l_temp_sch_rec_tab(l_i).schedule_id := rec_sch.schedule_id;
2712 l_temp_sch_rec_tab(l_i).calendar_id := rec_sch.calendar_id;
2713 l_temp_sch_rec_tab(l_i).schedule_type_code := rec_sch.schedule_type_code;
2714 l_temp_sch_rec_tab(l_i).assignment_status_code := rec_sch.status_code;
2715 l_temp_sch_rec_tab(l_i).start_date := rec_sch.start_date;
2716 l_temp_sch_rec_tab(l_i).end_date := rec_sch.end_date;
2717 l_temp_sch_rec_tab(l_i).Monday_hours := rec_sch.Monday_hours;
2718 l_temp_sch_rec_tab(l_i).Tuesday_hours := rec_sch.Tuesday_hours;
2719 l_temp_sch_rec_tab(l_i).Wednesday_hours := rec_sch.Wednesday_hours;
2720 l_temp_sch_rec_tab(l_i).Thursday_hours := rec_sch.Thursday_hours;
2721 l_temp_sch_rec_tab(l_i).Friday_hours := rec_sch.Friday_hours;
2722 l_temp_sch_rec_tab(l_i).saturday_hours := rec_sch.saturday_hours;
2723 l_temp_sch_rec_tab(l_i).Sunday_hours := rec_sch.sunday_hours;
2724 l_I := l_I + 1;
2725 END LOOP;
2726
2727 l_schrowid := l_temp_sch_rec_tab(1).schrowid ;
2728 l_schedule_id := l_temp_sch_rec_tab(1).schedule_id ;
2729 l_calendar_id := l_temp_sch_rec_tab(1).calendar_id ;
2730 l_schedule_type_code := l_temp_sch_rec_tab(1).schedule_type_code ;
2731 l_assignment_status_code := l_temp_sch_rec_tab(1).assignment_status_code ;
2732 l_start_date := l_temp_sch_rec_tab(1).start_date ;
2733 l_end_date := l_temp_sch_rec_tab(1).end_date ;
2734 l_monday_hours := l_temp_sch_rec_tab(1).Monday_hours ;
2735 l_tuesday_hours := l_temp_sch_rec_tab(1).Tuesday_hours ;
2736 l_wednesday_hours := l_temp_sch_rec_tab(1).Wednesday_hours ;
2737 l_thursday_hours := l_temp_sch_rec_tab(1).Thursday_hours ;
2738 l_friday_hours := l_temp_sch_rec_tab(1).Friday_hours ;
2739 l_saturday_hours := l_temp_sch_rec_tab(1).saturday_hours;
2740 l_sunday_hours := l_temp_sch_rec_tab(1).Sunday_hours ;
2741
2742 l_J := 2;
2743 l_K := 1;
2744 l_I := 1;
2745
2746
2747 FOR i IN 1 .. (l_temp_sch_rec_tab.count - 1) LOOP
2748 l_Flag := 'Y';
2749
2750 IF ((l_temp_sch_rec_tab(l_J).assignment_status_code = l_assignment_status_code) AND
2751 (l_temp_sch_rec_tab(l_J).Monday_hours = l_monday_hours ) AND
2752 (l_temp_sch_rec_tab(l_J).Tuesday_hours = l_tuesday_hours ) AND
2753 (l_temp_sch_rec_tab(l_J).Wednesday_hours = l_wednesday_hours ) AND
2754 (l_temp_sch_rec_tab(l_J).Thursday_hours = l_thursday_hours ) AND
2755 (l_temp_sch_rec_tab(l_J).Friday_hours = l_friday_hours ) AND
2756 (l_temp_sch_rec_tab(l_J).saturday_hours = l_saturday_hours ) AND
2757 (l_temp_sch_rec_tab(l_J).Sunday_hours = l_sunday_hours )) THEN
2758 l_Flag := 'N';
2759 l_Merge_Flag := 'Y';
2760 END IF;
2761
2762 IF (l_Flag = 'Y') THEN
2763
2764 l_final_sch_rec_tab(l_K).schrowid := l_schrowid;
2765 l_final_sch_rec_tab(l_K).schedule_id := l_schedule_id;
2766 l_final_sch_rec_tab(l_K).calendar_id := l_calendar_id;
2767 l_final_sch_rec_tab(l_K).assignment_id := p_assignment_id;
2768 l_final_sch_rec_tab(l_K).project_id := p_project_id;
2769 l_final_sch_rec_tab(l_K).schedule_type_code := l_schedule_type_code;
2770 l_final_sch_rec_tab(l_K).assignment_status_code := l_assignment_status_code;
2771 l_final_sch_rec_tab(l_K).start_date := l_start_date;
2772 l_final_sch_rec_tab(l_K).end_date := l_end_date;
2773 l_final_sch_rec_tab(l_K).Monday_hours := l_monday_hours;
2774 l_final_sch_rec_tab(l_K).Tuesday_hours := l_tuesday_hours;
2775 l_final_sch_rec_tab(l_K).Wednesday_hours := l_wednesday_hours;
2776 l_final_sch_rec_tab(l_K).Thursday_hours := l_thursday_hours;
2777 l_final_sch_rec_tab(l_K).Friday_hours := l_friday_hours;
2778 l_final_sch_rec_tab(l_K).saturday_hours := l_saturday_hours;
2779 l_final_sch_rec_tab(l_K).Sunday_hours := l_sunday_hours;
2780
2781 l_K := l_K + 1;
2782
2783 l_schrowid := l_temp_sch_rec_tab(l_J).schrowid;
2784 l_schedule_id := l_temp_sch_rec_tab(l_J).schedule_id ;
2785 l_calendar_id := l_temp_sch_rec_tab(l_J).calendar_id ;
2786 l_schedule_type_code := l_temp_sch_rec_tab(l_J).schedule_type_code ;
2787 l_assignment_status_code := l_temp_sch_rec_tab(l_J).assignment_status_code;
2788 l_start_date := l_temp_sch_rec_tab(l_J).start_date ;
2789 l_end_date := l_temp_sch_rec_tab(l_J).end_date;
2790 l_monday_hours := l_temp_sch_rec_tab(l_J).Monday_hours ;
2791 l_tuesday_hours := l_temp_sch_rec_tab(l_J).Tuesday_hours ;
2792 l_wednesday_hours := l_temp_sch_rec_tab(l_J).Wednesday_hours;
2793 l_thursday_hours := l_temp_sch_rec_tab(l_J).Thursday_hours;
2794 l_friday_hours := l_temp_sch_rec_tab(l_J).Friday_hours;
2795 l_saturday_hours := l_temp_sch_rec_tab(l_J).saturday_hours ;
2796 l_sunday_hours := l_temp_sch_rec_tab(l_J).Sunday_hours;
2797
2798 END IF;
2799
2800 IF (l_Flag = 'N') THEN
2801 l_end_date := l_temp_sch_rec_tab(l_J).end_date;
2802 l_del_sch_rec_tab(l_I).schedule_id := l_temp_sch_rec_tab(l_J).schedule_id;
2803 l_I := l_I + 1;
2804 END IF;
2805
2806 l_J := l_J + 1;
2807
2808 END LOOP;
2809
2810 l_final_sch_rec_tab(l_K).schrowid := l_schrowid;
2811 l_final_sch_rec_tab(l_K).schedule_id := l_schedule_id;
2812 l_final_sch_rec_tab(l_K).calendar_id := l_calendar_id;
2813 l_final_sch_rec_tab(l_K).assignment_id := p_assignment_id;
2814 l_final_sch_rec_tab(l_K).project_id := p_project_id;
2815 l_final_sch_rec_tab(l_K).schedule_type_code := l_schedule_type_code;
2816 l_final_sch_rec_tab(l_K).assignment_status_code := l_assignment_status_code;
2817 l_final_sch_rec_tab(l_K).start_date := l_start_date;
2818 l_final_sch_rec_tab(l_K).end_date := l_end_date;
2819 l_final_sch_rec_tab(l_K).Monday_hours := l_monday_hours;
2820 l_final_sch_rec_tab(l_K).Tuesday_hours := l_tuesday_hours;
2821 l_final_sch_rec_tab(l_K).Wednesday_hours := l_wednesday_hours;
2822 l_final_sch_rec_tab(l_K).Thursday_hours := l_thursday_hours;
2823 l_final_sch_rec_tab(l_K).Friday_hours := l_friday_hours;
2824 l_final_sch_rec_tab(l_K).saturday_hours := l_saturday_hours;
2825 l_final_sch_rec_tab(l_K).Sunday_hours := l_sunday_hours;
2826
2827
2828 IF (l_Merge_Flag = 'Y') THEN
2829 PA_SCHEDULE_PKG.Update_Rows(l_final_sch_rec_tab,l_x_return_status,x_msg_count,x_msg_data);
2830 PA_SCHEDULE_PKG.Delete_Rows(l_del_sch_rec_tab,l_x_return_status,x_msg_count,x_msg_data);
2831 ELSE
2832 PA_SCHEDULE_UTILS.log_message(1,'INFO: No Merging required.... ');
2833
2834 END IF;
2835
2836 /*Added for bug 6921728*/
2837 x_return_status := l_x_return_status ;
2838
2839 EXCEPTION
2840 WHEN OTHERS THEN
2841 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2842 x_msg_count := 1;
2843 x_msg_data := SQLERRM;
2844 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
2845 p_procedure_name => 'merge_work_pattern');
2846
2847 PA_SCHEDULE_UTILS.log_message(1,'ERROR in merge_work_pattern procedure ');
2848 raise;
2849 END merge_work_pattern;
2850
2851 --*******************************************************************************
2852
2853
2854 -- This procedure will create the new schedule with the new pattern
2855 -- Input parameters
2856 -- Parameters Type Required Description
2857 -- P_Sch_Except_Record_Tab SCHEXCEPTRECORD YES It has the exception record
2858 -- P_Sch_Record SCHEDULERECORD YES It has the schedule record
2859 -- In Out parameters
2860 -- X_Sch_Record_Tab SCHEDULETABTYP YES It store the new schedule
2861 --
2862
2863 PROCEDURE create_new_pattern(
2864 p_sch_except_record IN pa_schedule_glob.SchExceptRecord,
2865 p_sch_record IN pa_schedule_glob.ScheduleRecord,
2866 x_sch_record_tab IN OUT NOCOPY pa_schedule_glob.ScheduleTabTyp,
2867 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
2868 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
2869 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
2870 )
2871 IS
2872
2873 BEGIN
2874 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
2875
2876 x_sch_record_tab(1).start_date := p_sch_except_record.start_date;
2877 x_sch_record_tab(1).end_date := p_sch_except_record.end_date;
2878 x_sch_record_tab(1).Monday_hours := nvl(p_sch_except_record.Monday_hours, p_sch_record.Monday_hours);
2879 x_sch_record_tab(1).Tuesday_hours := nvl(p_sch_except_record.Tuesday_hours, p_sch_record.Tuesday_hours);
2880 x_sch_record_tab(1).Wednesday_hours := nvl(p_sch_except_record.Wednesday_hours, p_sch_record.Wednesday_hours);
2881 x_sch_record_tab(1).Thursday_hours := nvl(p_sch_except_record.Thursday_hours, p_sch_record.Thursday_hours);
2882 x_sch_record_tab(1).Friday_hours := nvl(p_sch_except_record.Friday_hours, p_sch_record.Friday_hours);
2883 x_sch_record_tab(1).Saturday_hours := nvl(p_sch_except_record.Saturday_hours, p_sch_record.Saturday_hours);
2884 x_sch_record_tab(1).Sunday_hours := nvl(p_sch_except_record.Sunday_hours, p_sch_record.Sunday_hours);
2885
2886 -- Updating the records with the new work pattern
2887
2888 PA_SCHEDULE_UTILS.update_sch_rec_tab(x_sch_record_tab,
2889 p_project_id => p_sch_except_record.project_id,
2890 p_schedule_type_code => p_sch_except_record.schedule_type_code,
2891 p_assignment_id => p_sch_except_record.assignment_id,
2892 p_calendar_id => p_sch_except_record.calendar_id,
2893 p_assignment_status_code => p_sch_record.assignment_status_code,
2894 x_return_status => l_x_return_status,
2895 x_msg_count => x_msg_count,
2896 x_msg_data => x_msg_data
2897 );
2898
2899
2900 x_return_status := l_x_return_status;
2901 EXCEPTION
2902 WHEN OTHERS THEN
2903 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2904 x_msg_count := 1;
2905 x_msg_data := SQLERRM;
2906 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
2907 p_procedure_name => 'create_new_pattern');
2908 raise;
2909
2910
2911 END create_new_pattern;
2912
2913 -- This procedure will create the new schedule the with passed status for the given period
2914 -- Input parameters
2915 -- Parameters Type Required Description
2916 -- P_Sch_Except_Record_Tab SCHEXCEPTRECORD YES It has the exception record
2917 -- P_Sch_Record SCHEDULERECORD YES It has the schedule record
2918 -- In Out parameters
2919 -- X_Sch_Record_Tab SCHEDULETABTYP YES It store the new schedule
2920 --
2921
2922 PROCEDURE create_new_status(
2923 p_sch_except_record IN pa_schedule_glob.SchExceptRecord,
2924 p_sch_record IN pa_schedule_glob.ScheduleRecord,
2925 x_sch_record_tab IN OUT NOCOPY pa_schedule_glob.ScheduleTabTyp,
2926 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
2927 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
2928 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
2929 )
2930 IS
2931 Status_change_not_allowed EXCEPTION;
2932 BEGIN
2933 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
2934 x_sch_record_tab(1).start_date := p_sch_except_record.start_date;
2935 x_sch_record_tab(1).end_date := p_sch_except_record.end_date;
2936 x_sch_record_tab(1).assignment_status_code := p_sch_except_record.assignment_status_code;
2937
2938 -- Check if the user is allowed to change the status.
2939
2940 IF ( ( p_sch_except_record.assignment_status_code <> p_sch_record.assignment_status_code) AND
2941 (PA_PROJECT_STUS_UTILS.Allow_Status_Change(
2942 o_status_code => p_sch_record.assignment_status_code ,
2943 n_status_code => p_sch_except_record.assignment_status_code) <> 'Y' ) ) THEN
2944 Raise Status_change_not_allowed;
2945 END IF;
2946
2947 -- Updating the records with the given status
2948 PA_SCHEDULE_UTILS.update_sch_rec_tab(x_sch_record_tab,
2949 p_project_id => p_sch_except_record.project_id,
2950 p_schedule_type_code => p_sch_except_record.schedule_type_code,
2951 p_assignment_id => p_sch_except_record.assignment_id,
2952 p_calendar_id => p_sch_except_record.calendar_id,
2953 P_monday_hours => p_sch_record.Monday_hours,
2954 P_Tuesday_hours => p_sch_record.Tuesday_hours,
2955 P_Wednesday_hours => p_sch_record.Wednesday_hours,
2956 P_Thursday_hours => p_sch_record.Thursday_hours,
2957 P_Friday_hours => p_sch_record.Friday_hours,
2958 P_Saturday_hours => p_sch_record.Saturday_hours,
2959 P_Sunday_hours => p_sch_record.Sunday_hours,
2960 x_return_status => l_x_return_status,
2961 x_msg_count => x_msg_count,
2962 x_msg_data => x_msg_data
2963 );
2964
2965 x_return_status := l_x_return_status;
2966 EXCEPTION
2967 WHEN Status_change_not_allowed THEN
2968 PA_UTILS.add_message('PA','PA_STATUS_CANT_CHANGE');
2969 x_return_status := FND_API.G_RET_STS_ERROR;
2970 x_msg_count := 1;
2971 x_msg_data := 'PA_STATUS_CANT_CHANGE';
2972
2973 WHEN OTHERS THEN
2974 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2975 x_msg_count := 1;
2976 x_msg_data := SQLERRM;
2977 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
2978 p_procedure_name => 'create_new_status');
2979 raise;
2980
2981 END create_new_status;
2982
2983 -- This procedure is called from change_schedule procedure. This procedure will apply 'CHANGE DURATION'
2984 -- exception on the schedule details. Output of this procedure is the resultant schedule records.
2985 -- Input parameters
2986 -- Parameters Type Required Description
2987 -- P_Sch_Except_Record_Tab SCHEXCEPTRECORD YES It has the exception record
2988 -- P_Sch_Record SCHEDULERECORD YES It has the schedule record
2989 -- In Out parameters
2990 -- X_Sch_Record_Tab SCHEDULETABTYP YES It store the new schedule
2991 --
2992
2993 PROCEDURE apply_change_duration
2994 ( p_sch_record_tab IN pa_schedule_glob.ScheduleTabTyp,
2995 p_sch_except_record IN pa_schedule_glob.SchExceptRecord,
2996 x_sch_record_tab IN OUT NOCOPY pa_schedule_glob.ScheduleTabTyp,
2997 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
2998 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
2999 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
3000 IS
3001 l_temp_p_sch_record_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3002 l_out_tr_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3003 l_temp_tr_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3004 l_temp_except_rec PA_SCHEDULE_GLOB.SchExceptRecord;
3005 l_I NUMBER;
3006 l_temp_first NUMBER;
3007 l_temp_last NUMBER;
3008 l_stat_date_done BOOLEAN;
3009 l_end_date_done BOOLEAN;
3010 l_copy_cur_sch BOOLEAN;
3011 l_cur_exp_start_date DATE;
3012 l_cur_exp_end_date DATE;
3013 l_chg_exp_start_date DATE;
3014 l_chg_exp_end_date DATE;
3015 /* Added the below parameters for 7663765 */
3016 l_shifted_days NUMBER := 0;
3017 l_difference_days NUMBER := 0;
3018 l_shift_unit_code VARCHAR2(20) := NULL;
3019
3020 BEGIN
3021 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
3022 PA_SCHEDULE_UTILS.log_message(1,'start of the apply_change_duration API ....... ');
3023
3024 l_stat_date_done := false;
3025 l_end_date_done := false;
3026
3027 l_cur_exp_start_date := p_sch_except_record.start_date;
3028 l_cur_exp_end_date := p_sch_except_record.end_date;
3029
3030 l_chg_exp_start_date := p_sch_except_record.start_date;
3031 l_chg_exp_end_date := p_sch_except_record.end_date;
3032
3033 -- Copying this schedule record for the further calculation
3034 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(p_sch_record_tab,
3035 p_sch_record_tab.first,
3036 p_sch_record_tab.last,
3037 l_temp_p_sch_record_tab,
3038 l_x_return_status,
3039 x_msg_count,
3040 x_msg_data );
3041
3042 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3043 -- Copying exception record for the further calculation
3044 PA_SCHEDULE_UTILS.copy_except_record(p_sch_except_record,
3045 l_temp_except_rec,
3046 l_x_return_status,
3047 x_msg_count,
3048 x_msg_data );
3049 END IF;
3050
3051 l_temp_first := l_temp_p_sch_record_tab.first;
3052 l_temp_last := l_temp_p_sch_record_tab.last;
3053
3054 /* Uncommented below for bug 7663765 */
3055 ----------------------------------------------------------------------------------------------
3056 --
3057 -- Logic For Duration Shift
3058 --
3059 ----------------------------------------------------------------------------------------------
3060 IF (p_sch_except_record.exception_type_code = 'DURATION_PATTERN_SHIFT') THEN
3061
3062 -- If p_number_of_shift is not null, calculate the new start_date and end_date by adding
3063 -- or substracting p_number_of_shift from p_asgn_start_date and p_asgn_end_date
3064 IF (p_sch_except_record.number_of_shift is NOT NULL) THEN
3065
3066 -- compute shifted_days
3067 IF (p_sch_except_record.duration_shift_unit_code = 'DAYS') THEN
3068 l_shifted_days := p_sch_except_record.number_of_shift;
3069 ELSIF (p_sch_except_record.duration_shift_unit_code = 'WEEKS') THEN
3070 l_shifted_days := p_sch_except_record.number_of_shift*7;
3071 ELSIF (p_sch_except_record.duration_shift_unit_code = 'MONTHS') THEN
3072 l_shift_unit_code := 'MONTHS';
3073 l_shifted_days := p_sch_except_record.number_of_shift;
3074 END IF;
3075
3076 -- set start_Date, end_date according to shift_type_code and shifed_days
3077 IF (p_sch_except_record.duration_shift_type_code = 'FORWARD') THEN
3078 l_difference_days := l_shifted_days;
3079 ELSIF (p_sch_except_record.duration_shift_type_code = 'BACKWARD') THEN
3080 l_difference_days := -1 * l_shifted_days;
3081 END IF;
3082
3083 END IF;
3084
3085 END IF; -- IF (exception_type_code = 'RETAIN_DURATION_PATTERN_SHIFT')
3086
3087 /* Ends uncommenting*/
3088
3089 PA_SCHEDULE_UTILS.log_message(1,'SCH_START ',l_temp_p_sch_record_tab);
3090
3091 PA_SCHEDULE_UTILS.log_message(1,'START EXCEPT START_DATE '||p_sch_except_record.start_date||' END_DATE '
3092 ||p_sch_except_record.end_date);
3093
3094 -- Exception date is falling outside the start date and end date of the schedule
3095 IF ( p_sch_except_record.start_date IS NOT NULL ) AND
3096 ( p_sch_except_record.end_date IS NOT NULL ) AND
3097 ( ( p_sch_except_record.end_date <
3098 l_temp_p_sch_record_tab(l_temp_first).start_date )
3099 OR
3100 ( p_sch_except_record.start_date >
3101 l_temp_p_sch_record_tab(l_temp_last).end_date ) ) THEN
3102
3103 PA_SCHEDULE_UTILS.log_message(1,'out side boundary condition ');
3104
3105 l_stat_date_done := true;
3106 l_end_date_done := true;
3107 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3108 -- Marking the schedule record for deletion
3109 PA_SCHEDULE_UTILS.mark_del_sch_rec_tab ( l_temp_p_sch_record_tab.first,
3110 l_temp_p_sch_record_tab.last,
3111 l_temp_p_sch_record_tab,
3112 l_x_return_status,
3113 x_msg_count,
3114 x_msg_data);
3115 END IF;
3116
3117 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3118 -- Create the new schedule after applying the exception i.e after change the duration
3119 create_new_schedule( p_sch_except_record,
3120 l_temp_p_sch_record_tab(l_temp_first),
3121 l_out_tr_sch_rec_tab,
3122 l_difference_days, -- 7663765
3123 l_shift_unit_code, -- 7663765
3124 l_x_return_status,
3125 x_msg_count,
3126 x_msg_data );
3127 END IF;
3128
3129 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3130 -- Adding the previous record into the new record
3131 --7663765
3132 /* if (p_sch_except_record.exception_type_code = 'DURATION_PATTERN_SHIFT') then
3133 PA_SCHEDULE_UTILS.copy_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3134 l_temp_p_sch_record_tab.first,
3135 l_temp_p_sch_record_tab.last,
3136 l_out_tr_sch_rec_tab,
3137 l_x_return_status,
3138 x_msg_count,
3139 x_msg_data );
3140 else */
3141 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3142 l_temp_p_sch_record_tab.first,
3143 l_temp_p_sch_record_tab.last,
3144 l_out_tr_sch_rec_tab,
3145 l_x_return_status,
3146 x_msg_count,
3147 x_msg_data );
3148 /* end if; */ /* commented for bug 9229210 */
3149 END IF;
3150 END IF;
3151
3152 PA_SCHEDULE_UTILS.log_message(2,'BEFORE LOOP');
3153
3154 l_I := l_temp_p_sch_record_tab.first ;
3155
3156 IF ( p_sch_except_record.start_date IS NULL ) THEN
3157 l_stat_date_done := true;
3158 END IF;
3159 IF ( p_sch_except_record.end_date IS NULL ) THEN
3160 l_end_date_done := true;
3161 END IF;
3162
3163 LOOP
3164 PA_SCHEDULE_UTILS.log_message(2,'LOOP START (l_I='||to_char(l_I)||') s: '||
3165 l_temp_p_sch_record_tab(l_I).start_date||' e: '||
3166 l_temp_p_sch_record_tab(l_I).end_date );
3167
3168 l_copy_cur_sch := false;
3169
3170 -- If the exception start date is falling under the end date of the schedule and outside the start date
3171 -- of the schedule then we will create a record which will be having start date as exception date and
3172 -- end date will be one day minus from the start date of the scheule for the first record
3173 IF ( l_stat_date_done = false) THEN
3174 IF (( p_sch_except_record.start_date <= l_temp_p_sch_record_tab(l_I).end_date )) THEN
3175
3176 PA_SCHEDULE_UTILS.log_message(2,'inside exp_start_date <= sch_start_date ');
3177
3178 l_stat_date_done := true;
3179 IF ( ( l_I = l_temp_first ) AND
3180 ( p_sch_except_record.start_date
3181 < l_temp_p_sch_record_tab(l_I).start_date )) THEN
3182
3183 PA_SCHEDULE_UTILS.log_message(2,'inside exp_start_date < sch_start_date AND First shift ');
3184
3185 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3186 PA_SCHEDULE_UTILS.update_except_record(px_except_record => l_temp_except_rec,
3187 p_start_date => p_sch_except_record.start_date,
3188 p_end_date => l_temp_p_sch_record_tab( l_temp_first).start_date -1,
3189 x_return_status => l_x_return_status,
3190 x_msg_count => x_msg_count,
3191 x_msg_data => x_msg_data );
3192 END IF;
3193
3194 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3195 create_new_schedule( l_temp_except_rec,
3196 l_temp_p_sch_record_tab(l_temp_first),
3197 l_out_tr_sch_rec_tab,
3198 l_difference_days, -- 7663765
3199 l_shift_unit_code, -- 7663765
3200 l_x_return_status,
3201 x_msg_count,
3202 x_msg_data );
3203 END IF;
3204 ELSE
3205
3206 PA_SCHEDULE_UTILS.log_message(2,'inside exp_start_date <= sch_start_date AND NOT Last shift ');
3207
3208 l_temp_p_sch_record_tab(l_I).start_date := p_sch_except_record.start_date;
3209
3210 -- Bug#9952027 - Ensure that the existing schedules are marked for deletion in case of 'Shift Duration & Pattern'
3211 if (p_sch_except_record.exception_type_code = 'DURATION_PATTERN_SHIFT') THEN
3212 l_temp_p_sch_record_tab(l_I).change_type_code := 'D';
3213 else
3214 l_temp_p_sch_record_tab(l_I).change_type_code := 'U';
3215 end if;
3216 END IF;
3217
3218 IF ( l_end_date_done ) THEN
3219 l_copy_cur_sch := true;
3220 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3221 -- 7663765
3222 /* if (p_sch_except_record.exception_type_code = 'DURATION_PATTERN_SHIFT') then
3223 PA_SCHEDULE_UTILS.copy_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3224 l_I,
3225 l_temp_p_sch_record_tab.last,
3226 l_out_tr_sch_rec_tab,
3227 l_x_return_status,
3228 x_msg_count,
3229 x_msg_data );
3230 else */
3231 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3232 l_I,
3233 l_temp_p_sch_record_tab.last,
3234 l_out_tr_sch_rec_tab,
3235 l_x_return_status,
3236 x_msg_count,
3237 x_msg_data );
3238 /* end if; */ /* commented for bug 9229210 */
3239 END IF;
3240
3241 END IF;
3242 ELSE
3243 PA_SCHEDULE_UTILS.log_message(2,'inside exp_start_date > sch_start_date AND MARKING SHIFT as DELETE');
3244 l_temp_p_sch_record_tab(l_I).change_type_code := 'D';
3245 END IF; -- start_date cond if */
3246 END IF; -- l_stat_date_done if */
3247
3248 IF ( l_end_date_done = false) THEN
3249 IF (( p_sch_except_record.end_date <= l_temp_p_sch_record_tab(l_I).end_date )) THEN
3250 l_end_date_done := true;
3251
3252 PA_SCHEDULE_UTILS.log_message(2,'inside exp_end_date <= sch_end_date ');
3253
3254 l_temp_p_sch_record_tab(l_I).end_date := p_sch_except_record.end_date;
3255
3256 -- Bug#9952027 - Ensure that the existing schedules are marked for deletion in case of 'Shift Duration & Pattern'
3257 if (p_sch_except_record.exception_type_code = 'DURATION_PATTERN_SHIFT') THEN
3258 l_temp_p_sch_record_tab(l_I).change_type_code := 'D';
3259 else
3260 l_temp_p_sch_record_tab(l_I).change_type_code := 'U';
3261 end if;
3262
3263 IF ( l_I < l_temp_last ) THEN
3264
3265 PA_SCHEDULE_UTILS.log_message(2,'inside exp_end_date <= sch_end_date AND MARKING DELETE ');
3266 -- Mark remaining shifts as delete. */
3267 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3268 PA_SCHEDULE_UTILS.mark_del_sch_rec_tab ( l_temp_p_sch_record_tab.next(l_I),
3269 l_temp_p_sch_record_tab.last,
3270 l_temp_p_sch_record_tab,
3271 l_x_return_status,
3272 x_msg_count,
3273 x_msg_data );
3274 END IF;
3275 END IF;
3276 l_copy_cur_sch := true;
3277 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3278 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3279 l_I,
3280 l_temp_p_sch_record_tab.last,
3281 l_out_tr_sch_rec_tab,
3282 l_x_return_status,
3283 x_msg_count,
3284 x_msg_data );
3285 END IF;
3286 ELSIF ( ( p_sch_except_record.end_date > l_temp_p_sch_record_tab(l_I).end_date ) AND
3287 ( l_I = l_temp_last ) ) THEN
3288
3289 PA_SCHEDULE_UTILS.log_message(2,'inside exp_end_date > sch_end_date AND LAST SHIFT ');
3290
3291 l_copy_cur_sch := true;
3292 l_end_date_done := true;
3293 -- Copy this shift into l_out_tr_sch_rec_tab; */
3294 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3295 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3296 l_I,
3297 l_I,
3298 l_out_tr_sch_rec_tab,
3299 l_x_return_status,
3300 x_msg_count,
3301 x_msg_data );
3302 END IF;
3303
3304 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3305 PA_SCHEDULE_UTILS.update_except_record(px_except_record => l_temp_except_rec,
3306 p_start_date => l_temp_p_sch_record_tab(l_I).end_date +1 ,
3307 p_end_date => p_sch_except_record.end_date,
3308 x_return_status => l_x_return_status,
3309 x_msg_count => x_msg_count,
3310 x_msg_data => x_msg_data );
3311
3312 END IF;
3313
3314 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3315 create_new_schedule( l_temp_except_rec,
3316 l_temp_p_sch_record_tab(l_temp_first),
3317 l_temp_tr_sch_rec_tab,
3318 l_difference_days, -- 7663765
3319 l_shift_unit_code, -- 7663765
3320 l_x_return_status,
3321 x_msg_count,
3322 x_msg_data );
3323 END IF;
3324
3325 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3326 -- 7663765
3327 /* if (p_sch_except_record.exception_type_code = 'DURATION_PATTERN_SHIFT') then
3328 PA_SCHEDULE_UTILS.copy_schedule_rec_tab ( l_temp_tr_sch_rec_tab ,
3329 l_temp_tr_sch_rec_tab.first,
3330 l_temp_tr_sch_rec_tab.last,
3331 l_out_tr_sch_rec_tab,
3332 l_x_return_status,
3333 x_msg_count,
3334 x_msg_data );
3335 else */
3336 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_tr_sch_rec_tab ,
3337 l_temp_tr_sch_rec_tab.first,
3338 l_temp_tr_sch_rec_tab.last,
3339 l_out_tr_sch_rec_tab,
3340 l_x_return_status,
3341 x_msg_count,
3342 x_msg_data );
3343 /* end if; */ /* commented for bug 9229210 */
3344 END IF;
3345 ELSE
3346 -- Bug#9952027 - Ensure that the existing schedules are marked for deletion in case of 'Shift Duration & Pattern'
3347 if (p_sch_except_record.exception_type_code = 'DURATION_PATTERN_SHIFT') THEN
3348 l_temp_p_sch_record_tab(l_I).change_type_code := 'D';
3349 end if;
3350 END IF; -- end_date cond if */
3351 END IF; -- l_end_date_done if */
3352
3353 IF ( l_copy_cur_sch = false ) THEN
3354 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3355 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3356 l_I,
3357 l_I,
3358 l_out_tr_sch_rec_tab,
3359 l_x_return_status,
3360 x_msg_count,
3361 x_msg_data );
3362 END IF;
3363 END IF;
3364
3365 IF ( ( ( l_stat_date_done ) AND (l_end_date_done) )
3366 OR
3367 ( l_I = l_temp_last ) ) THEN
3368 EXIT;
3369 ELSE
3370 l_I := l_temp_p_sch_record_tab.next(l_I);
3371 END IF;
3372
3373 END LOOP;
3374
3375 PA_SCHEDULE_UTILS.log_message(2,'DONE_CHANGE_DURATION : out_tr.count : '||l_out_tr_sch_rec_tab.count);
3376
3377 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3378 PA_SCHEDULE_UTILS.copy_schedule_rec_tab ( l_out_tr_sch_rec_tab ,
3379 l_out_tr_sch_rec_tab.first,
3380 l_out_tr_sch_rec_tab.last,
3381 x_sch_record_tab,
3382 l_x_return_status,
3383 x_msg_count,
3384 x_msg_data );
3385 END IF;
3386
3387 x_return_status := l_x_return_status;
3388 EXCEPTION
3389 WHEN OTHERS THEN
3390 x_return_status := FND_API.G_RET_STS_ERROR;
3391 x_msg_count := 1;
3392 x_msg_data := SQLERRM;
3393 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
3394 p_procedure_name => 'apply_change_duration');
3395
3396 PA_SCHEDULE_UTILS.log_message(1,'ERROR while running apply...');
3397 raise;
3398 END apply_change_duration;
3399
3400 -- This procedure is caled from change_schedule procedure .This procedure will apply changes on schedule
3401 -- other than 'CHANGE DURATION' exception on the schedule details. Out put of this procedure is the resultant
3402 -- schedule record
3403 -- Input parameters
3404 -- Parameters Type Required Description
3405 -- P_Sch_Except_Record_Tab SCHEXCEPTRECORD YES It has the exception record
3406 -- P_Sch_Record SCHEDULERECORD YES It has the schedule record
3407 -- In Out parameters
3408 -- X_Sch_Record_Tab SCHEDULETABTYP YES It store the new schedule
3409 --
3410
3411
3412 PROCEDURE apply_other_changes
3413 ( p_sch_record_tab IN pa_schedule_glob.ScheduleTabTyp,
3414 p_sch_except_record IN pa_schedule_glob.SchExceptRecord,
3415 x_sch_record_tab IN OUT NOCOPY pa_schedule_glob.ScheduleTabTyp,
3416 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
3417 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
3418 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
3419 IS
3420
3421 l_temp_p_sch_record_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3422 l_out_tr_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3423 l_temp_tr_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3424 l_temp_except_rec PA_SCHEDULE_GLOB.SchExceptRecord;
3425 l_I NUMBER;
3426 l_sch_first NUMBER;
3427 l_sch_last NUMBER;
3428 l_chg_exp_start_date DATE;
3429 l_chg_exp_end_date DATE;
3430 l_curr_exp_start_date DATE;
3431 l_curr_exp_end_date DATE;
3432 l_curr_sch_start_date DATE;
3433 l_curr_sch_end_date DATE;
3434 l_change_done BOOLEAN;
3435 l_copy_cur_sch BOOLEAN;
3436 l_create_new_sch BOOLEAN;
3437 l_create_third_sch BOOLEAN;
3438
3439 BEGIN
3440 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
3441 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(p_sch_record_tab,
3442 p_sch_record_tab.first,
3443 p_sch_record_tab.last,
3444 l_temp_p_sch_record_tab,
3445 l_x_return_status,
3446 x_msg_count,
3447 x_msg_data );
3448
3449 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3450 PA_SCHEDULE_UTILS.copy_except_record(p_sch_except_record,
3451 l_temp_except_rec,
3452 l_x_return_status,
3453 x_msg_count,
3454 x_msg_data );
3455 END IF;
3456
3457 l_sch_first := l_temp_p_sch_record_tab.first;
3458 l_sch_last := l_temp_p_sch_record_tab.last;
3459
3460 l_curr_exp_start_date := p_sch_except_record.start_date;
3461 l_curr_exp_end_date := p_sch_except_record.end_date;
3462
3463 PA_SCHEDULE_UTILS.log_message(1,'SCH_START ',l_temp_p_sch_record_tab);
3464 PA_SCHEDULE_UTILS.log_message(1,'START EXCEPT START_DATE '||l_curr_exp_start_date||' END_DATE '||l_curr_exp_end_date);
3465
3466 l_I := l_temp_p_sch_record_tab.first ;
3467
3468 LOOP
3469 l_copy_cur_sch := false;
3470 l_create_new_sch := false;
3471 l_create_third_sch := false;
3472
3473 l_curr_sch_start_date := l_temp_p_sch_record_tab(l_I).start_date;
3474 l_curr_sch_end_date := l_temp_p_sch_record_tab(l_I).end_date;
3475
3476 PA_SCHEDULE_UTILS.log_message(2,'SHIFT('||l_I||') '||l_curr_sch_start_date||' '||l_curr_sch_end_date);
3477 IF ( l_curr_exp_start_date <= l_curr_sch_end_date ) THEN
3478
3479 PA_SCHEDULE_UTILS.log_message(2,'inside l_curr_exp_start_date <= l_curr_sch_end_date if .... ');
3480 IF ( l_curr_exp_start_date <= l_curr_sch_start_date ) THEN
3481
3482 PA_SCHEDULE_UTILS.log_message(2,'inside l_curr_exp_start_date <= l_curr_sch_start_date if .... ');
3483 l_chg_exp_start_date := l_curr_sch_start_date;
3484
3485 IF ( l_curr_exp_end_date < l_curr_sch_end_date ) THEN
3486
3487 PA_SCHEDULE_UTILS.log_message(2,'inside l_curr_exp_end_date < l_curr_sch_end_date if ...... ');
3488 l_chg_exp_end_date := l_curr_exp_end_date;
3489 l_temp_p_sch_record_tab(l_I).start_date := l_curr_exp_end_date + 1;
3490 IF (nvl(l_temp_p_sch_record_tab(l_I).change_type_code,'U') <> 'I') THEN -- Added If condition for 4349232
3491 l_temp_p_sch_record_tab(l_I).change_type_code := 'U';
3492 END IF;
3493
3494 ELSIF ( l_curr_exp_end_date >= l_curr_sch_end_date ) THEN
3495
3496 PA_SCHEDULE_UTILS.log_message(2,'inside l_curr_exp_end_date >= l_curr_sch_end_date if ...... ');
3497 l_chg_exp_end_date := l_curr_sch_end_date;
3498 l_temp_p_sch_record_tab(l_I).change_type_code := 'D';
3499
3500 END IF;
3501 l_create_new_sch := true;
3502
3503 IF ( l_curr_exp_end_date <= l_curr_sch_end_date ) THEN
3504 PA_SCHEDULE_UTILS.log_message(2,'inside l_curr_exp_end_date <= l_curr_sch_end_date if ........... ');
3505 l_change_done := true;
3506 END IF;
3507
3508 ELSIF ( l_curr_exp_start_date > l_curr_sch_start_date ) THEN
3509
3510 PA_SCHEDULE_UTILS.log_message(2,'inside l_curr_exp_start_date > l_curr_sch_start_date if ...... ');
3511
3512 l_temp_p_sch_record_tab(l_I).end_date := l_curr_exp_start_date - 1;
3513
3514 IF (nvl(l_temp_p_sch_record_tab(l_I).change_type_code,'U') <> 'I') THEN -- Added If condition for 4287560
3515 l_temp_p_sch_record_tab(l_I).change_type_code := 'U';
3516 END IF;
3517
3518 l_copy_cur_sch := true;
3519 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3520 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3521 l_I,
3522 l_I,
3523 l_out_tr_sch_rec_tab,
3524 l_x_return_status,
3525 x_msg_count,
3526 x_msg_data );
3527 END IF;
3528
3529 PA_SCHEDULE_UTILS.log_message(2,'l_out_tr_sch_rec_tab.count '||to_char(l_out_tr_sch_rec_tab.count));
3530 l_chg_exp_start_date := l_curr_exp_start_date;
3531 IF ( l_curr_exp_end_date > l_curr_sch_end_date ) THEN
3532 PA_SCHEDULE_UTILS.log_message(2,'inside l_curr_exp_end_date > l_curr_sch_end_date if ....... ');
3533 l_chg_exp_end_date := l_curr_sch_end_date;
3534 ELSE
3535 PA_SCHEDULE_UTILS.log_message(2,'inside l_curr_exp_end_date <= l_curr_sch_end_date if ....... ');
3536 l_chg_exp_end_date := l_curr_exp_end_date;
3537 l_change_done := true;
3538 END IF;
3539 l_create_new_sch := true;
3540
3541 IF ( l_curr_exp_end_date < l_curr_sch_end_date ) THEN
3542 PA_SCHEDULE_UTILS.log_message(2,'inside l_curr_exp_end_date < l_curr_sch_end_date if .... ');
3543 l_create_third_sch := true;
3544 l_change_done := true;
3545 END IF;
3546
3547 END IF; -- end of level 2 if */
3548 END IF; -- end of level 1 if */
3549
3550 IF ( l_create_new_sch ) THEN
3551 PA_SCHEDULE_UTILS.log_message(2,'inside l_create_new_sch if ........'||'status '||l_x_return_status);
3552 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3553 PA_SCHEDULE_UTILS.update_except_record(px_except_record => l_temp_except_rec,
3554 p_start_date => l_chg_exp_start_date,
3555 p_end_date => l_chg_exp_end_date,
3556 x_return_status => l_x_return_status,
3557 x_msg_count => x_msg_count,
3558 x_msg_data => x_msg_data );
3559 END IF;
3560
3561 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3562 create_new_schedule( l_temp_except_rec,
3563 l_temp_p_sch_record_tab(l_I),
3564 l_temp_tr_sch_rec_tab,
3565 0, -- 7663765
3566 NULL, --7663765
3567 l_x_return_status,
3568 x_msg_count,
3569 x_msg_data );
3570 END IF;
3571 PA_SCHEDULE_UTILS.log_message(2,'l_temp_tr_sch_rec_tab.count '||to_char(l_temp_tr_sch_rec_tab.count)||
3572 l_x_return_status);
3573
3574 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3575 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_tr_sch_rec_tab ,
3576 l_temp_tr_sch_rec_tab.first,
3577 l_temp_tr_sch_rec_tab.last,
3578 l_out_tr_sch_rec_tab,
3579 l_x_return_status,
3580 x_msg_count,
3581 x_msg_data );
3582 END IF;
3583 PA_SCHEDULE_UTILS.log_message(2,'l_out_tr_sch_rec_tab.count '||to_char(l_out_tr_sch_rec_tab.count));
3584 END IF;
3585
3586 IF ( l_create_third_sch = true ) THEN
3587
3588 PA_SCHEDULE_UTILS.log_message(2,'inside l_create_third_sch if ........');
3589 l_temp_p_sch_record_tab(l_I).start_date := l_curr_exp_end_date + 1;
3590 l_temp_p_sch_record_tab(l_I).end_date := l_curr_sch_end_date;
3591 l_temp_p_sch_record_tab(l_I).change_type_code := 'I';
3592 l_temp_p_sch_record_tab(l_I).schedule_id := -1; -- Included for Bug 4616327
3593 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3594 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3595 l_I,
3596 l_I,
3597 l_out_tr_sch_rec_tab,
3598 l_x_return_status,
3599 x_msg_count,
3600 x_msg_data );
3601 END IF;
3602
3603 PA_SCHEDULE_UTILS.log_message(2,'l_out_tr_sch_rec_tab.count '||to_char(l_out_tr_sch_rec_tab.count));
3604 END IF;
3605
3606 IF ( l_copy_cur_sch = false ) THEN
3607 PA_SCHEDULE_UTILS.log_message(2,'inside l_copy_cur_sch if ........');
3608 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3609 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3610 l_I,
3611 l_I,
3612 l_out_tr_sch_rec_tab,
3613 l_x_return_status,
3614 x_msg_count,
3615 x_msg_data );
3616 END IF;
3617 PA_SCHEDULE_UTILS.log_message(2,'l_out_tr_sch_rec_tab.count '||to_char(l_out_tr_sch_rec_tab.count));
3618 END IF;
3619
3620 IF ( l_change_done ) OR ( l_I = l_sch_last ) THEN
3621
3622 PA_SCHEDULE_UTILS.log_message(2,'inside l_change_done if ........');
3623 IF ( l_I < l_sch_last ) THEN
3624 PA_SCHEDULE_UTILS.log_message(2,'inside l_I < l_sch_last if ....... ');
3625 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3626 PA_SCHEDULE_UTILS.add_schedule_rec_tab ( l_temp_p_sch_record_tab ,
3627 l_temp_p_sch_record_tab.next(l_I),
3628 l_sch_last,
3629 l_out_tr_sch_rec_tab,
3630 l_x_return_status,
3631 x_msg_count,
3632 x_msg_data );
3633 END IF;
3634 PA_SCHEDULE_UTILS.log_message(2,'l_out_tr_sch_rec_tab.count '||to_char(l_out_tr_sch_rec_tab.count));
3635 END IF;
3636 EXIT;
3637 ELSE
3638 PA_SCHEDULE_UTILS.log_message(2,'go to next shift ..... ');
3639 l_I := l_temp_p_sch_record_tab.next(l_I);
3640 END IF;
3641
3642 END LOOP;
3643
3644 PA_SCHEDULE_UTILS.log_message(2,'end of the loop l_out_tr_sch_rec_tab.count '||
3645 to_char(l_out_tr_sch_rec_tab.count)||'status '||l_x_return_status);
3646 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3647 PA_SCHEDULE_UTILS.copy_schedule_rec_tab ( l_out_tr_sch_rec_tab ,
3648 l_out_tr_sch_rec_tab.first,
3649 l_out_tr_sch_rec_tab.last,
3650 x_sch_record_tab,
3651 l_x_return_status,
3652 x_msg_count,
3653 x_msg_data );
3654 END IF;
3655
3656 PA_SCHEDULE_UTILS.log_message(2,'end of the loop x_sch_record_tab.count '||to_char(x_sch_record_tab.count));
3657 x_return_status := l_x_return_status;
3658 EXCEPTION
3659 WHEN OTHERS THEN
3660 x_return_status := FND_API.G_RET_STS_ERROR;
3661 x_msg_count := 1;
3662 x_msg_data := SQLERRM;
3663 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
3664 p_procedure_name => 'apply_other_change');
3665
3666 PA_SCHEDULE_UTILS.log_message(2,'ERROR in apply_other_changes ....');
3667 PA_SCHEDULE_UTILS.log_message(2,sqlerrm);
3668 raise;
3669 END apply_other_changes;
3670
3671
3672 -- This procedure will apply the assignment change for duration change
3673 -- Input parameters
3674 -- Parameters Type Required Description
3675 -- Sch_Except_Record_Tab SCHEXCEPTTABTYP YES It has the exception record
3676 -- Chg_Tr_Sch_Rec_Tab SCHEDULETABTYP YES It has the schedule record
3677 --
3678
3679 PROCEDURE apply_assignment_change (
3680 p_record_version_number IN NUMBER,
3681 chg_tr_sch_rec_tab IN PA_SCHEDULE_GLOB.ScheduleTabTyp,
3682 sch_except_record_tab IN PA_SCHEDULE_GLOB.SchExceptTabTyp,
3683 p_called_by_proj_party IN VARCHAR2 := 'N', -- Added for Bug 6631033
3684 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
3685 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
3686 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
3687 IS
3688 l_t_start_date DATE := NULL; -- To store exception start date
3689 l_t_end_date DATE := NULL; -- To store exception end date
3690 l_t_multi_flag VARCHAR2(1); -- To stote value Y or N for multiple status
3691 l_t_assignment_id NUMBER; -- To store the assignment Id for the records to be procesed
3692 -- added for Bug fix: 4537865
3693 l_new_t_assignment_id NUMBER;
3694 -- added for Bug fix: 4537865
3695 l_change_flag BOOLEAN; -- To store the value TRUE or FALSE if the status is changed from previous record
3696 l_prev_status VARCHAR2(30); -- To store the status of the previous record for
3697 -- compareing with the current record
3698 l_curr_status VARCHAR2(30); -- To store the current status of the assignment.
3699 -- This will be used to update the assignments table
3700 -- if there is only one status .
3701 l_J NUMBER; -- To store the first record of the chg_tr_sch_rec_tab
3702
3703 l_t_project_id NUMBER;
3704 l_t_project_role_id NUMBER ; -- To Store project role id
3705 l_t_resource_source_id NUMBER ; -- To Store resource source id
3706 l_t_resource_id NUMBER ;
3707 l_t_project_party_id NUMBER ; -- To Store project party id
3708 l_t_record_version_number NUMBER;
3709 l_t_asgn_start_date DATE ; -- To Store Assignment Start Date
3710 l_t_asgn_end_date DATE ; -- To Store Assignment End Date
3711 l_wf_type VARCHAR2(80);
3712 l_wf_item_type VARCHAR2(2000);
3713 l_wf_process VARCHAR2(2000);
3714 -- Bug#9114277 l_new_calendar_id pa_project_assignments.calendar_id%TYPE; ---- bug#9071974
3715 -- Bug#9114277 l_RESOURCE_CALENDAR_PERCENT pa_project_assignments.RESOURCE_CALENDAR_PERCENT%TYPE; ---- bug#9071974
3716 BEGIN
3717 -- Intilizing the variable */
3718 l_t_multi_flag := 'N';
3719 l_change_flag := FALSE;
3720 l_t_assignment_id := chg_tr_sch_rec_tab(1).assignment_id;
3721 l_t_project_id := chg_tr_sch_rec_tab(1).project_id;
3722 l_x_return_status := FND_API.G_RET_STS_SUCCESS; -- Storing the status for tracking the error
3723
3724 --Bug#9114277 l_new_calendar_id := Nvl (sch_except_record_tab(1).change_calendar_id,FND_API.G_MISS_NUM); ---- bug#9071974
3725 --Bug#9114277 l_RESOURCE_CALENDAR_PERCENT := Nvl (sch_except_record_tab(1).RESOURCE_CALENDAR_PERCENT,FND_API.G_MISS_NUM); ---- bug#9071974
3726
3727 -- Loop for processing the exception records from exception table type variable for change duration */
3728 IF (sch_except_record_tab.count > 0 ) THEN
3729 FOR I IN sch_except_record_tab.first..sch_except_record_tab.last LOOP
3730 --7663765
3731 IF ( (sch_except_record_tab(I).exception_type_code = 'CHANGE_DURATION') OR
3732 (sch_except_record_tab(I).exception_type_code = 'SHIFT_DURATION')
3733 OR (sch_except_record_tab(I).exception_type_code = 'DURATION_PATTERN_SHIFT') ) THEN
3734 l_t_start_date := sch_except_record_tab(I).start_date;
3735 l_t_end_date := sch_except_record_tab(I).end_date;
3736 l_change_flag := TRUE;
3737
3738 END IF;
3739
3740 IF (sch_except_record_tab(I).exception_type_code = 'CHANGE_STATUS') THEN
3741 l_change_flag := TRUE;
3742 END IF;
3743
3744 END LOOP;
3745 ELSE
3746 Raise l_empty_tab_record;
3747 END IF;
3748
3749 -- if the tab type does not contain any data */
3750 IF (chg_tr_sch_rec_tab.count = 0 ) THEN
3751 Raise l_empty_tab_record;
3752 ELSE
3753 l_J := chg_tr_sch_rec_tab.FIRST;
3754 END IF;
3755
3756 -- Loop for processing schedule records from schedule tab type variable if the status is changed from revious one */
3757 l_prev_status := chg_tr_sch_rec_tab(l_J).assignment_status_code;
3758 l_curr_status := chg_tr_sch_rec_tab(l_J).assignment_status_code;
3759
3760 FOR K IN chg_tr_sch_rec_tab.FIRST..chg_tr_sch_rec_tab.LAST LOOP
3761
3762 IF ( l_prev_status <> chg_tr_sch_rec_tab(K).assignment_status_code) THEN
3763 l_t_multi_flag := 'Y';
3764 l_change_flag := TRUE;
3765 l_curr_status := null;
3766 EXIT;
3767 END IF;
3768
3769 END LOOP;
3770
3771 PA_SCHEDULE_UTILS.log_message(1,'20: ' || l_x_return_status ||
3772 ' ' || x_msg_count ||
3773 ' ' || x_msg_data);
3774
3775 -- if the records is having more than one status then updating the table for it column multi flag */
3776 IF (l_change_flag) THEN
3777 -- bug#9071974
3778 PA_PROJECT_ASSIGNMENTS_PKG.Update_Row(
3779 p_record_version_number => p_record_version_number,
3780 p_assignment_id => l_t_assignment_id,
3781 p_start_date => nvl(l_t_start_date,FND_API.G_MISS_DATE),
3782 p_end_date => nvl(l_t_end_date,FND_API.G_MISS_DATE),
3783 p_multiple_status_flag => l_t_multi_flag,
3784 p_status_code => l_curr_status,
3785 p_assignment_effort =>
3786 pa_schedule_utils.get_num_hours(l_t_project_id, l_t_assignment_id),
3787 x_return_status => l_x_return_status );
3788 ELSE
3789 -- bug#9071974
3790 PA_PROJECT_ASSIGNMENTS_PKG.Update_Row(
3791 p_record_version_number => p_record_version_number,
3792 p_assignment_id => l_t_assignment_id,
3793 p_assignment_effort =>
3794 pa_schedule_utils.get_num_hours(l_t_project_id, l_t_assignment_id),
3795 x_return_status => l_x_return_status );
3796 END IF;
3797
3798 PA_SCHEDULE_UTILS.log_message(1,'20: ' || l_x_return_status ||
3799 ' ' || x_msg_count ||
3800 ' ' || x_msg_data);
3801
3802 -- If assignment record is successfully updated then call procedure to update pa project parties.
3803 --
3804 -- jmarques (1590046): Added STAFFED_ADMIN_ASSIGNMENT check to if statement.
3805 IF ( ( l_x_return_status = FND_API.G_RET_STS_SUCCESS ) AND
3806 ( (chg_tr_sch_rec_tab(l_J).schedule_type_code = 'STAFFED_ASSIGNMENT') OR
3807 (chg_tr_sch_rec_tab(l_J).schedule_type_code = 'STAFFED_ADMIN_ASSIGNMENT') )
3808 ) THEN
3809
3810 SELECT
3811 proj_part.PROJECT_ROLE_ID,
3812 proj_part.RESOURCE_SOURCE_ID,
3813 proj_part.PROJECT_PARTY_ID,
3814 proj_part.RESOURCE_ID,
3815 proj_part.RECORD_VERSION_NUMBER,
3816 proj_asgn.START_DATE,
3817 proj_asgn.END_DATE
3818 INTO
3819 l_t_project_role_id,
3820 l_t_resource_source_id,
3821 l_t_project_party_id,
3822 l_t_resource_id,
3823 l_t_record_version_number,
3824 l_t_asgn_start_date,
3825 l_t_asgn_end_date
3826 FROM pa_project_parties proj_part,
3827 pa_project_assignments proj_asgn
3828 WHERE proj_asgn.PROJECT_PARTY_ID = proj_part.PROJECT_PARTY_ID
3829 AND proj_asgn.ASSIGNMENT_ID = l_t_assignment_id;
3830
3831 IF ( l_t_start_date is NULL ) THEN
3832 l_t_start_date := l_t_asgn_start_date;
3833 END IF;
3834
3835 IF ( l_t_end_date is NULL ) THEN
3836 l_t_end_date := l_t_asgn_end_date;
3837 END IF;
3838
3839 PA_SCHEDULE_UTILS.log_message(1,'21: ' || l_x_return_status ||
3840 ' ' || x_msg_count ||
3841 ' ' || x_msg_data);
3842
3843 IF p_called_by_proj_party = 'N' then -- Bug 6631033
3844
3845 pa_project_parties_pvt.UPDATE_PROJECT_PARTY(
3846 P_VALIDATE_ONLY => 'F',
3847 P_OBJECT_ID => chg_tr_sch_rec_tab(l_J).project_id,
3848 P_OBJECT_TYPE => 'PA_PROJECTS',
3849 P_PROJECT_ROLE_ID => l_t_project_role_id,
3850 P_RESOURCE_TYPE_ID => 101,
3851 P_RESOURCE_SOURCE_ID => l_t_resource_source_id,
3852 P_RESOURCE_ID => l_t_resource_id,
3853 P_START_DATE_ACTIVE => l_t_start_date ,
3854 P_END_DATE_ACTIVE => l_t_end_date ,
3855 P_SCHEDULED_FLAG => 'Y',
3856 P_RECORD_VERSION_NUMBER => l_t_record_version_number,
3857 P_CALLING_MODULE => 'ASSIGNMENT',
3858 P_PROJECT_END_DATE => NULL,
3859 P_PROJECT_ID => chg_tr_sch_rec_tab(l_J).project_id,
3860 P_PROJECT_PARTY_ID => l_t_project_party_id,
3861 P_ASSIGNMENT_ID => l_t_assignment_id,
3862 P_ASSIGN_RECORD_VERSION_NUMBER => p_record_version_number,
3863 --X_ASSIGNMENT_ID => l_t_assignment_id, * Commented for Bug Fix: 4537865
3864 X_ASSIGNMENT_ID => l_new_t_assignment_id, -- Added for bug fix: 4537865
3865 X_WF_TYPE => l_wf_type,
3866 X_WF_ITEM_TYPE => l_wf_item_type,
3867 X_WF_PROCESS => l_wf_process,
3868 X_RETURN_STATUS => l_x_return_status,
3869 X_MSG_COUNT => x_msg_count,
3870 X_MSG_DATA => x_msg_data );
3871
3872 END IF; -- Bug 6631033
3873
3874 -- added for Bug fix: 4537865
3875
3876 IF l_x_return_status = FND_API.G_RET_STS_SUCCESS THEN
3877 l_t_assignment_id := l_new_t_assignment_id;
3878 END IF;
3879 -- added for Bug fix: 4537865
3880
3881 END IF;
3882
3883 x_return_status := l_x_return_status;
3884 EXCEPTION
3885 WHEN l_empty_tab_record THEN
3886 x_return_status := FND_API.G_RET_STS_SUCCESS;
3887 NULL;
3888 WHEN OTHERS THEN
3889 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3890 x_msg_count := 1;
3891 x_msg_data := SQLERRM;
3892 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
3893 p_procedure_name => 'apply_assignment_change');
3894 raise;
3895 END apply_assignment_change;
3896
3897
3898 -- Procedure : get_periodic_start_end
3899 -- Purpose : Get min start date and max end date for working days in the schedule...
3900 -- Input parameters
3901 -- Parameters Type Required Description
3902 -- P_Start_Date DATE YES starting date of the open assignment
3903 -- P_End_Date DATE YES ending date of the open assignment
3904 -- p_task_assignment_id_tbl SYSTEM.PA_NUM_TBL_TYPE YES Table of resource_assignment_id's
3905
3906
3907 -- Procedure : get_periodic_start_end
3908 -- Purpose : Get min start date and max end date for working days in the schedule...
3909 -- Input parameters
3910 -- Parameters Type Required Description
3911 -- P_Start_Date DATE YES starting date of the open assignment
3912 -- P_End_Date DATE YES ending date of the open assignment
3913 -- p_task_assignment_id_tbl SYSTEM.PA_NUM_TBL_TYPE YES Table of resource_assignment_id's
3914
3915 PROCEDURE get_periodic_start_end(
3916 p_start_date IN DATE,
3917 p_end_date IN DATE,
3918 p_project_assignment_id IN NUMBER,
3919 p_task_assignment_id_tbl IN SYSTEM.PA_NUM_TBL_TYPE,
3920 x_min_start_date OUT NOCOPY DATE, --File.Sql.39 bug 4440895
3921 x_max_end_date OUT NOCOPY DATE, --File.Sql.39 bug 4440895
3922 p_project_id IN NUMBER,
3923 p_budget_version_id IN NUMBER,
3924 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
3925 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
3926 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
3927 )
3928 IS
3929
3930 Cursor C_Periodic_dates1 IS
3931 select least(min(start_date), p_start_date), greatest(max(end_date), p_end_date)
3932 from pa_budget_lines a, pa_resource_assignments b
3933 where a.resource_assignment_id = b.resource_assignment_id
3934 and b.project_assignment_id = p_project_assignment_id
3935 and b.project_id = p_project_id
3936 and b.budget_version_id = p_budget_version_id
3937 and ((a.start_date between p_start_date and p_end_date) OR
3938 (a.end_date between p_start_date and p_end_date) OR
3939 (p_start_date between a.start_date and a.end_date) OR
3940 (p_end_date between a.start_date and a.end_date))
3941 and b.ta_display_flag = 'Y';
3942
3943 /**
3944 -- II phase selective Id's and using Global Temp. Table if necessary.
3945 --Cursor to obtain earliest periodic start date and latest periodic end date
3946 --(intermediate/overlapped periods only)
3947 --Cursor to be confirmed
3948
3949 Cursor C_task_assignment_date(p_proj_start_date IN DATE, p_proj_end_date IN DATE) IS
3950 --Use commented if considering when project assgt. start date is lesser and end date greater than periods.
3951 select least(min(start_date), p_proj_start_date), greatest(max(end_date), p_proj_end_date) from
3952 --select min(start_date, p_proj_start_date), max(end_date, p_proj_end_date) from
3953 pa_budget_lines a, pa_tmp_task_assign_ids b where
3954 (a.start_date between (p_proj_start_date) and (p_proj_end_date)) OR
3955 (a.end_date between (p_proj_start_date) and (p_proj_end_date)) OR
3956 ((p_proj_start_date) between a.start_date and a.end_date) OR
3957 ((p_proj_end_date) between a.start_date and a.end_date)
3958 AND a.resource_assignment_id = b.resource_assignment_id;
3959
3960
3961 Cursor C_Project_Assgt_Check is
3962 Select project_assignment_id from
3963 PA_TMP_TASK_ASSIGN_IDS where project_assignment_id = p_project_assignment_id;
3964 ***/
3965
3966 BEGIN
3967
3968 x_return_status := FND_API.G_RET_STS_SUCCESS ;
3969
3970
3971 OPEN C_Periodic_dates1;
3972 FETCH C_Periodic_dates1 into x_min_start_date, x_max_end_date;
3973 CLOSE C_Periodic_dates1;
3974
3975 /*Added for 4996210: If dates are null then return error status */
3976
3977 IF x_min_start_date IS NULL OR x_max_end_date IS NULL THEN
3978 x_return_status := FND_API.G_RET_STS_ERROR;
3979 x_msg_count := 1;
3980 x_msg_data := 'Error while calling get_periodic_start_end';
3981 END IF;
3982
3983 /* End 4996210 */
3984
3985
3986
3987 EXCEPTION
3988 WHEN OTHERS THEN
3989 PA_SCHEDULE_UTILS.log_message(1, 'Error in get_periodic_start_end.....'||sqlerrm);
3990 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3991 x_msg_count := 1;
3992 x_msg_data := SQLERRM;
3993 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
3994 p_procedure_name => 'get_periodic_start_end');
3995 raise;
3996 END get_periodic_start_end;
3997
3998
3999
4000
4001
4002
4003 -- Procedure : create_opn_asg_schedule
4004 -- Purpose : Create schedule for open assignments. it get the schedule for the calendar associated
4005 -- with the calendar id of the open asignment and create schedules from them
4006 -- Input parameters
4007 -- Parameters Type Required Description
4008 -- P_Project_Id NUMBER YES project id of the associated calendar
4009 -- P_Calendar_Id NUMBER NO Id for that calendar which is associated to this
4010 -- assignment
4011 -- P_Assignment_Id NUMBER YES Id of that assignment which being used
4012 -- for creation of open assignment
4013 -- P_Start_Date DATE YES starting date of the open assignment
4014 -- P_End_Date DATE YES ending date of the open assignment
4015 -- P_Assignment_Status_Code VARCHAR2 YES Status of the assignment e.g OPEN/CONFIRM/PROVISIONAL
4016 -- P_Work_Type_Id NUMBER NO Id for the work type.
4017 -- P_Task_Id NUMBER NO Id for the tasa.
4018 -- P_Task_Percentage NUMBER NO Percentage of the corresponding task.
4019 -- p_sum_tasks_flag VARCHAR2 YES Indicates whether to sum task assignment periodic dates
4020 -- p_task_assignment_id_tbl SYSTEM.PA_NUM_TBL_TYPE REQUIRED Indicates the task assignments to choose.
4021
4022
4023
4024 PROCEDURE create_opn_asg_schedule(p_project_id IN NUMBER,
4025 p_calendar_id IN NUMBER,
4026 p_assignment_id IN NUMBER,
4027 p_start_date IN DATE,
4028 p_end_date IN DATE,
4029 p_assignment_status_code IN VARCHAR2,
4030 p_work_type_id IN NUMBER:=NULL,
4031 p_task_id IN NUMBER:=NULL,
4032 p_task_percentage IN NUMBER:=NULL,
4033 p_sum_tasks_flag IN VARCHAR2,
4034 p_task_assignment_id_tbl IN SYSTEM.PA_NUM_TBL_TYPE:=SYSTEM.PA_NUM_TBL_TYPE(),
4035 p_budget_version_id IN NUMBER:= NULL,
4036 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
4037 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
4038 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
4039 )
4040 IS
4041
4042 l_x_schedule_tab_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
4043 l_new_schedule_tab_rec PA_SCHEDULE_GLOB.ScheduleTabTyp;
4044
4045 l_start_date DATE;
4046 l_end_date DATE;
4047
4048 l_alias_name PA_RESOURCE_LIST_MEMBERS.ALIAS%TYPE; /*Added for 4996210 */
4049 l_total_hours NUMBER; -- Bug 5126919
4050 BEGIN
4051 l_x_return_status := FND_API.G_RET_STS_SUCCESS ;
4052 PA_SCHEDULE_UTILS.log_message(1, 'Start of the create_oasgn_schedule API ....');
4053
4054 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API get_calendar_schedule ....');
4055
4056 -- New code to process task assignment summation jraj 12/19/03
4057 -- Based on if p_sum_tasks_flag = Y
4058
4059 l_start_date := p_start_date;
4060 l_end_date := p_end_date;
4061
4062 IF p_sum_tasks_flag = 'Y' then
4063
4064 get_periodic_start_end( p_start_date,
4065 p_end_date,
4066 p_assignment_id,
4067 p_task_assignment_id_tbl,
4068 l_start_date,
4069 l_end_date,
4070 p_project_id,
4071 p_budget_version_id,
4072 x_return_status,
4073 x_msg_count,
4074 x_msg_data
4075 );
4076
4077 END IF;
4078
4079 /*Bug 4996210 : If get_periodic_start_end returns error then raise error for all the resourcelist members for which the planned work quantity is null or zero*/
4080
4081 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4082
4083 BEGIN
4084 IF p_task_assignment_id_tbl.COUNT > 0 THEN
4085 SELECT ALIAS INTO l_alias_name FROM
4086 pa_resource_list_members WHERE RESOURCE_LIST_MEMBER_ID = (SELECT RESOURCE_LIST_MEMBER_ID
4087 FROM pa_resource_assignments WHERE resource_assignment_id = p_task_assignment_id_tbl(1));
4088 ELSE
4089 l_alias_name := NULL;
4090 END IF;
4091
4092
4093 EXCEPTION
4094 WHEN OTHERS THEN
4095 NULL;
4096
4097 END;
4098
4099 FND_MESSAGE.SET_NAME('PA','PA_PLAN_QTY_NULL');
4100 FND_MESSAGE.SET_TOKEN('TASK_ASSIG',l_alias_name);
4101 FND_MSG_PUB.add;
4102 RAISE FND_API.G_EXC_ERROR;
4103 END IF;
4104
4105 /*End for 4996210 */
4106
4107
4108 -- Calling the PA_SCHEDULE_PVT API to get the calendar schedule
4109 PA_SCHEDULE_PVT.get_calendar_schedule(p_calendar_id,
4110 l_start_date,
4111 l_end_date,
4112 l_x_schedule_tab_rec,
4113 l_x_return_status,
4114 x_msg_count,
4115 x_msg_data
4116 );
4117
4118
4119 IF p_sum_tasks_flag = 'Y' then
4120
4121
4122 -- Call task summation API.
4123 -- and obtain new l_new_schedule_tab_rec
4124 sum_task_assignments(
4125 p_task_assignment_id_tbl,
4126 l_x_schedule_tab_rec,
4127 p_start_date,
4128 p_end_date,
4129 l_total_hours, -- Bug 5126919
4130 l_new_schedule_tab_rec,
4131 l_x_return_status,
4132 x_msg_count,
4133 x_msg_data
4134 );
4135
4136 ELSE
4137
4138 l_new_schedule_tab_rec := l_x_schedule_tab_rec;
4139
4140
4141 END IF;
4142
4143 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API get_calendar_schedule ....');
4144
4145 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API update_sch_rec_tab ....');
4146 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API update_sch_rec_tab ....'||l_x_return_status);
4147
4148 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
4149 -- updating the passed schedule table of record for creating the schedule for open assignment
4150 PA_SCHEDULE_UTILS.update_sch_rec_tab(l_new_schedule_tab_rec,
4151 p_project_id => p_project_id,
4152 p_calendar_id => p_calendar_id,
4153 p_schedule_type_code => 'OPEN_ASSIGNMENT',
4154 p_assignment_id => p_assignment_id,
4155 p_assignment_status_code => p_assignment_status_code,
4156 x_return_status => l_x_return_status,
4157 x_msg_count => x_msg_count,
4158 x_msg_data => x_msg_data
4159 );
4160 END IF;
4161
4162 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API update_sch_rec_tab .....');
4163 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API insert_rows ....');
4164 PA_SCHEDULE_UTILS.log_message(1,'SCH_REC',l_x_schedule_tab_rec);
4165
4166 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
4167 -- Inserting the schedule in the PA_SCHEDULE table
4168 PA_SCHEDULE_PKG.insert_rows(l_new_schedule_tab_rec,
4169 l_x_return_status,
4170 x_msg_count,
4171 x_msg_data,
4172 l_total_hours -- Bug 5126919
4173 );
4174 END IF;
4175
4176 -- Calling the Timeline api to build the timeline records for the assignment
4177 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
4178 PA_TIMELINE_PVT.CREATE_TIMELINE (p_assignment_id =>p_assignment_id ,
4179 x_return_status =>l_x_return_status ,
4180 x_msg_count =>x_msg_count ,
4181 x_msg_data =>x_msg_data );
4182
4183 END IF;
4184
4185
4186 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API insert_rows ....');
4187 PA_SCHEDULE_UTILS.log_message(1, 'End of the create_oasgn_schedule API ....');
4188 x_return_status := l_x_return_status;
4189 EXCEPTION
4190
4191 /*Added for 4996210 */
4192 WHEN FND_API.G_EXC_ERROR THEN
4193 x_return_status := FND_API.G_RET_STS_ERROR;
4194 /*End 4996210 */
4195
4196 WHEN OTHERS THEN
4197 PA_SCHEDULE_UTILS.log_message(1, 'Error in create_oasgn_schedule API .....'||sqlerrm);
4198 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4199 x_msg_count := 1;
4200 x_msg_data := SQLERRM;
4201 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
4202 p_procedure_name => 'create_opn_asg_schedule');
4203 raise;
4204
4205 END create_opn_asg_schedule;
4206
4207 -- Procedure : create_opn_asg_schedule
4208 -- Purpose : Add multiple open assignment schedules. Copy
4209 -- assignment schedules from an open or staffed
4210 -- assignment.
4211 -- Input parameters
4212 -- Parameters Type Required Description
4213 -- P_Project_Id NUMBER NO project id of the associated calendar
4214 -- P_Calendar_Id NUMBER NO Id for that calendar which is associated to this
4215 -- assignment
4216 -- P_Assignment_Id_Tbl PL/SQL TABLE YES Ids of the assignmentswhose schedules need to be created.
4217 -- P_Source_Assignment_Id NUMBER NO Id of the source assignment
4218 -- P_Start_Date DATE NO starting date of the open assignment
4219 -- P_End_Date DATE NO ending date of the open assignment
4220 -- P_Assignment_Status_Code VARCHAR2 NO Status of the assignment e.g OPEN/CONFIRM/PROVISIONAL
4221 -- p_sum_tasks_flag VARCHAR2 NO Indicates whether to sum task assignment periodic dates
4222 -- p_task_assignment_id_tbl SYSTEM.PA_NUM_TBL_TYPE NO Indicates the task assignments to choose.
4223
4224
4225 PROCEDURE create_opn_asg_schedule(p_project_id IN NUMBER :=NULL,
4226 p_asgn_creation_mode IN VARCHAR2 := NULL, /* Added for Bug 6145532 */
4227 p_calendar_id IN NUMBER :=NULL,
4228 p_assignment_id_tbl IN PA_ASSIGNMENTS_PUB.assignment_id_tbl_type,
4229 p_assignment_source_id IN NUMBER :=NULL,
4230 p_start_date IN DATE:=NULL,
4231 p_end_date IN DATE := NULL,
4232 p_assignment_status_code IN VARCHAR2:= NULL,
4233 p_sum_tasks_flag IN VARCHAR2 default null,
4234 p_task_assignment_id_tbl IN SYSTEM.PA_NUM_TBL_TYPE:=SYSTEM.PA_NUM_TBL_TYPE(),
4235 p_budget_version_id IN NUMBER:= NULL,
4236 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
4237 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
4238 x_msg_data OUT NOCOPY VARCHAR2) IS --File.Sql.39 bug 4440895
4239
4240 l_assignment_id PA_PROJECT_ASSIGNMENTS.assignment_id%TYPE;
4241 l_assignment_id_tbl PA_ASSIGNMENTS_PUB.assignment_id_tbl_type;
4242 l_x_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
4243 l_current_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
4244 l_temp_number NUMBER;
4245 BEGIN
4246 l_assignment_id_tbl := p_assignment_id_tbl;
4247 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
4248 PA_SCHEDULE_UTILS.log_message(1, 'Start of the create_asgn_schedule API ....');
4249
4250
4251 -- Case I: add multiple open assignments. When p_assignment_source_id IS
4252 -- NULL, a new open assignment schedule needs to be generated based on the -- calendar id passed in, then copy the schedule to the rest of assignments.
4253 -- Case II: Copy schedule from an existing assignment with calendar change.
4254 -- The two cases share the same implementation because they both need to
4255 -- generate new schedule based on the calendar id passed in.
4256
4257 IF p_assignment_source_id IS NULL OR
4258 (p_assignment_source_id IS NOT NULL AND p_calendar_id IS NOT NULL) THEN
4259 -- Create an open assignment schedule for the first assignment in
4260 -- table l_assignment_id_tbl.
4261
4262
4263
4264 PA_SCHEDULE_PVT.create_opn_asg_schedule (
4265 p_project_id => p_project_id,
4266 p_calendar_id => p_calendar_id,
4267 p_assignment_id => l_assignment_id_tbl(l_assignment_id_tbl.FIRST).assignment_id,
4268 p_start_date => p_start_date,
4269 p_end_date => p_end_date,
4270 p_assignment_status_code => p_assignment_status_code,
4271 p_sum_tasks_flag => p_sum_tasks_flag,
4272 p_task_assignment_id_tbl => p_task_assignment_id_tbl,
4273 p_budget_version_id => p_budget_version_id,
4274 p_work_type_id => l_temp_number,
4275 x_return_status => l_x_return_status,
4276 x_msg_count => x_msg_count,
4277 x_msg_data => x_msg_data
4278 );
4279
4280 -- When more than one assignment ids are passed in, the newly created
4281 -- schedule will be copied to the rest of the assignments
4282 IF l_assignment_id_tbl.COUNT >1 THEN
4283 -- Delete the first assignment_id from l_assignment_id_tbl and store it
4284 -- in l_assignment_id.
4285 l_assignment_id := l_assignment_id_tbl(l_assignment_id_tbl.FIRST).assignment_id;
4286 l_assignment_id_tbl.DELETE(l_assignment_id_tbl.FIRST);
4287
4288 -- Calling the PA_SCHEDULE_PVT API to get the schedule of the first
4289 -- assignment.
4290 PA_SCHEDULE_PVT.get_assignment_schedule(l_assignment_id,
4291 l_current_sch_rec_tab,
4292 l_x_return_status,
4293 x_msg_count,
4294 x_msg_data
4295 );
4296
4297 -- Copy schedules for the rest of the assignments in the table
4298 -- l_assignment_id_tbl.
4299 FOR l_counter IN l_assignment_id_tbl.FIRST .. l_assignment_id_tbl.LAST LOOP
4300 -- Update the passed schedule table of record for creating the schedule for open assignment
4301 PA_SCHEDULE_UTILS.update_sch_rec_tab(
4302 px_sch_record_tab => l_current_sch_rec_tab,
4303 p_assignment_id => l_assignment_id_tbl(l_counter).assignment_id,
4304 x_return_status => l_x_return_status,
4305 x_msg_count => x_msg_count,
4306 x_msg_data => x_msg_data
4307 );
4308 -- Add the schedule record to l_x_sch_rec_tab.
4309 PA_SCHEDULE_UTILS.add_schedule_rec_tab(
4310 p_sch_record_tab => l_current_sch_rec_tab,
4311 p_start_id => l_current_sch_rec_tab.first,
4312 p_end_id => l_current_sch_rec_tab.last,
4313 px_sch_record_tab => l_x_sch_rec_tab,
4314 x_return_status => l_x_return_status,
4315 x_msg_count => x_msg_count,
4316 x_msg_data => x_msg_data
4317 );
4318 END LOOP;
4319
4320 -- Bulk insert all the schedule records stored in l_x_sch_rec_tab.
4321 -- Inserting the schedule in the PA_SCHEDULE table
4322 PA_SCHEDULE_PKG.insert_rows(
4323 p_sch_record_tab => l_x_sch_rec_tab,
4324 x_return_status => l_x_return_status,
4325 x_msg_count => x_msg_count,
4326 x_msg_data => x_msg_data
4327 );
4328
4329 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API insert_rows ....');
4330
4331 -- Copy timeline data.
4332 PA_TIMELINE_PVT.copy_open_asgn_timeline (
4333 p_assignment_id_tbl => l_assignment_id_tbl,
4334 p_assignment_source_id => l_assignment_id,
4335 x_return_status => l_x_return_status,
4336 x_msg_count => x_msg_count,
4337 x_msg_data => x_msg_data
4338 );
4339 END IF;
4340
4341 -- Case III: Copy schedule from an existing open/staffed assignment with
4342 -- status change only.
4343 ELSIF p_assignment_source_id IS NOT NULL AND p_assignment_status_code IS NOT NULL and p_calendar_id IS NULL THEN
4344 -- Get source assignment schedule.
4345
4346
4347 --Commenting below for Bug 6145532
4348 /*
4349 PA_SCHEDULE_PVT.get_assignment_schedule(p_assignment_source_id,
4350 l_current_sch_rec_tab,
4351 l_x_return_status,
4352 x_msg_count,
4353 x_msg_data
4354 );
4355 */
4356 /* Added for Bug 6145532*/
4357 IF ( NVL(p_asgn_creation_mode,'DEFAULT') = 'PARTIAL' ) THEN
4358
4359 --New call of PA_SCHEDULE_PVT.get_assignment_schedule with
4360
4361 --dates range, to get partial schedule of assignment for the
4362
4363 --leftover requirement to be made.
4364
4365 PA_SCHEDULE_PVT.get_assignment_schedule(p_assignment_source_id,
4366 p_start_date,
4367 p_end_date,
4368 l_current_sch_rec_tab,
4369 l_x_return_status,
4370 x_msg_count,
4371 x_msg_data
4372 );
4373 ELSE
4374 -- Bug 6145532 : this is the old code that was being called always
4375 PA_SCHEDULE_PVT.get_assignment_schedule(p_assignment_source_id,
4376 l_current_sch_rec_tab,
4377 l_x_return_status,
4378 x_msg_count,
4379 x_msg_data
4380 );
4381 END IF ;
4382 /* changes end for Bug 6145532*/
4383 FOR l_counter IN l_assignment_id_tbl.FIRST .. l_assignment_id_tbl.LAST LOOP
4384 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API update_sch_rec_tab ....');
4385 -- Update the passed schedule record with p_assignment_status_code
4386 PA_SCHEDULE_UTILS.update_sch_rec_tab(
4387 px_sch_record_tab => l_current_sch_rec_tab,
4388 p_schedule_type_code => 'OPEN_ASSIGNMENT',
4389 p_assignment_id => l_assignment_id_tbl(l_counter).assignment_id,
4390 p_assignment_status_code => p_assignment_status_code,
4391 x_return_status => l_x_return_status,
4392 x_msg_count => x_msg_count,
4393 x_msg_data => x_msg_data
4394 );
4395 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API update_sch_rec_tab .....');
4396 -- Add the shedule record to l_x_sch_rec_tab.
4397 PA_SCHEDULE_UTILS.add_schedule_rec_tab(
4398 p_sch_record_tab => l_current_sch_rec_tab,
4399 p_start_id => l_current_sch_rec_tab.FIRST,
4400 p_end_id => l_current_sch_rec_tab.LAST,
4401 px_sch_record_tab => l_x_sch_rec_tab,
4402 x_return_status => l_x_return_status,
4403 x_msg_count => x_msg_count,
4404 x_msg_data => x_msg_data
4405 );
4406 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API add_schedule_rec_tab .....');
4407 END LOOP;
4408
4409 -- Bulk insert all the schedule records stored in l_x_sch_rec_tab.
4410 PA_SCHEDULE_PKG.insert_rows(
4411 p_sch_record_tab => l_x_sch_rec_tab,
4412 x_return_status => l_x_return_status,
4413 x_msg_count => x_msg_count,
4414 x_msg_data => x_msg_data
4415 );
4416 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API insert_rows ....');
4417
4418 -- Calling the Timeline API to build timeline records for the first
4419 -- assignment in the table l_assignment_id_tbl.
4420 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
4421 PA_TIMELINE_PVT.CREATE_TIMELINE (
4422 p_assignment_id =>l_assignment_id_tbl(l_assignment_id_tbl.FIRST).assignment_id,
4423 x_return_status =>l_x_return_status ,
4424 x_msg_count =>x_msg_count ,
4425 x_msg_data =>x_msg_data
4426 );
4427 END IF;
4428 -- Copy timeline records for the rest of the assignments in the
4429 -- table l_assignment_id_tbl.
4430 IF l_assignment_id_tbl.COUNT > 1 THEN
4431 l_assignment_id := l_assignment_id_tbl(l_assignment_id_tbl.FIRST).assignment_id;
4432 l_assignment_id_tbl.DELETE(l_assignment_id_tbl.FIRST);
4433 PA_TIMELINE_PVT.copy_open_asgn_timeline (
4434 p_assignment_id_tbl => l_assignment_id_tbl,
4435 p_assignment_source_id => l_assignment_id,
4436 x_return_status => l_x_return_status,
4437 x_msg_count => x_msg_count,
4438 x_msg_data => x_msg_data
4439 );
4440 END IF;
4441
4442 -- Case IV: Copy schedule from an existing open assignment without any
4443 -- changes except for assignment id.
4444 ELSIF p_assignment_source_id IS NOT NULL AND p_assignment_status_code IS NULL AND p_calendar_id IS NULL THEN
4445 -- Get source assignment schedule.
4446 PA_SCHEDULE_PVT.get_assignment_schedule(p_assignment_source_id,
4447 l_current_sch_rec_tab,
4448 l_x_return_status,
4449 x_msg_count,
4450 x_msg_data
4451 );
4452
4453 FOR l_counter IN l_assignment_id_tbl.FIRST .. l_assignment_id_tbl.LAST LOOP
4454 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API update_sch_rec_tab ....');
4455 -- Update the passed schedule record with assignment_id.
4456 PA_SCHEDULE_UTILS.update_sch_rec_tab(
4457 px_sch_record_tab => l_current_sch_rec_tab,
4458 p_assignment_id => l_assignment_id_tbl(l_counter).assignment_id,
4459 x_return_status => l_x_return_status,
4460 x_msg_count => x_msg_count,
4461 x_msg_data => x_msg_data
4462 );
4463 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API update_sch_rec_tab .....');
4464 -- Add the shedule record to l_x_sch_rec_tab.
4465 PA_SCHEDULE_UTILS.add_schedule_rec_tab(
4466 p_sch_record_tab => l_current_sch_rec_tab,
4467 p_start_id => l_current_sch_rec_tab.first,
4468 p_end_id => l_current_sch_rec_tab.last,
4469 px_sch_record_tab => l_x_sch_rec_tab,
4470 x_return_status => l_x_return_status,
4471 x_msg_count => x_msg_count,
4472 x_msg_data => x_msg_data
4473 );
4474 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API add_schedule_rec_tab .....');
4475 END LOOP;
4476
4477 -- Bulk insert all the schedule records stored in l_x_sch_rec_tab.
4478 PA_SCHEDULE_PKG.insert_rows(
4479 p_sch_record_tab => l_x_sch_rec_tab,
4480 x_return_status => l_x_return_status,
4481 x_msg_count => x_msg_count,
4482 x_msg_data => x_msg_data
4483 );
4484 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API insert_rows ....');
4485
4486 -- Copy timeline data.
4487 PA_TIMELINE_PVT.copy_open_asgn_timeline (
4488 p_assignment_id_tbl => l_assignment_id_tbl,
4489 p_assignment_source_id => p_assignment_source_id,
4490 x_return_status => l_x_return_status,
4491 x_msg_count => x_msg_count,
4492 x_msg_data => x_msg_data
4493 );
4494
4495 END IF;
4496
4497 x_return_status := l_x_return_status;
4498
4499 EXCEPTION
4500 WHEN OTHERS THEN
4501 PA_SCHEDULE_UTILS.log_message(1, 'Error in create_opn_asgn_schedule API .....'||sqlerrm);
4502 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4503 x_msg_count := 1;
4504 x_msg_data := SQLERRM;
4505 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
4506 p_procedure_name => 'create_opn_asg_schedule');
4507 raise;
4508
4509 END create_opn_asg_schedule;
4510
4511
4512 -- Procedure : create_stf_asg_schedule
4513 -- Purpose : Create schedule for staffed assignments.
4514 -- Input parameters
4515 -- Parameters Type Required Description
4516 -- P_Project_Id NUMBER YES project id of the associated calendar
4517 -- P_Schedule_Basis_Flag VARCHAR2 YES It is schedule basis flag.
4518 -- P_Calendar_Id NUMBER NO Id for that calendar which is associated to this
4519 -- assignment
4520 -- P_Assignment_Id NUMBER YES New id of staffed assignment
4521 -- P_Open_Assignment_Id NUMBER YES Id of that assignment which is beging used
4522 -- for creation of staffed assignment
4523 -- P_Resource_Calendar_Percent NUMBER YES It is percentage of the resource correponding to the calendar
4524 -- P_Start_Date DATE YES starting date of the open assignment
4525 -- P_End_Date DATE YES ending date of the open assignment
4526 -- P_Assignment_Status_Code VARCHAR2 YES Status of the assignment e.g OPEN/CONFIRM/PROVISIONAL
4527 -- P_Work_Type_Id NUMBER NO Id for the work type.
4528 -- P_Task_Id NUMBER NO Id for the tasa.
4529 -- P_Task_Percentage NUMBER NO Percentage of the corresponding task.
4530 -- p_sum_tasks_flag VARCHAR2 NO Indicates whether to sum task assignment periodic dates
4531 -- p_task_assignment_id_tbl SYSTEM.PA_NUM_TBL_TYPE NO Indicates the task assignments to choose.
4532
4533
4534 PROCEDURE create_stf_asg_schedule(p_project_id IN NUMBER,
4535 p_schedule_basis_flag IN VARCHAR2,
4536 p_project_party_id IN NUMBER,
4537 p_calendar_id IN NUMBER,
4538 p_assignment_id IN NUMBER,
4539 p_open_assignment_id IN NUMBER,
4540 p_resource_calendar_percent IN NUMBER,
4541 p_start_date IN DATE,
4542 p_end_date IN DATE,
4543 p_assignment_status_code IN VARCHAR2,
4544 p_work_type_id IN NUMBER,
4545 p_task_id IN NUMBER,
4546 p_task_percentage IN NUMBER,
4547 p_sum_tasks_flag IN VARCHAR2 default null,
4548 p_task_assignment_id_tbl IN SYSTEM.PA_NUM_TBL_TYPE:=SYSTEM.PA_NUM_TBL_TYPE(),
4549 p_budget_version_id IN NUMBER:= NULL,
4550 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
4551 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
4552 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
4553 )
4554 IS
4555
4556 l_x_sch_record_tab PA_SCHEDULE_GLOB.ScheduleTabTyp; -- Temporary variable to store the
4557 -- schedule type table of records
4558
4559 l_req_start_date PA_PROJECT_ASSIGNMENTS.start_date%TYPE;
4560 l_req_end_date pa_project_assignments.end_date%TYPE;
4561 l_calendar_id pa_project_assignments.calendar_id%TYPE;
4562
4563 l_new_schedule_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
4564
4565 l_start_date DATE;
4566 l_end_date DATE;
4567 l_total_hours NUMBER; -- Bug 5126919
4568
4569 BEGIN
4570 --jm_profiler.set_time('Create Schedule');
4571
4572 -- Assigning status successs for tracking the error
4573 l_x_return_status := FND_API.G_RET_STS_SUCCESS ;
4574 PA_SCHEDULE_UTILS.log_message(1,'Start of the create_sasgn_schedule API ... ');
4575
4576 -- =================================================
4577 -- New code to process task assignment summation jraj 12/19/03
4578
4579 l_start_date := p_start_date;
4580 l_end_date := p_end_date;
4581
4582
4583 IF p_sum_tasks_flag = 'Y' then
4584
4585 get_periodic_start_end( p_start_date,
4586 p_end_date,
4587 p_assignment_id,
4588 p_task_assignment_id_tbl,
4589 l_start_date,
4590 l_end_date,
4591 p_project_id,
4592 p_budget_version_id,
4593 x_return_status,
4594 x_msg_count,
4595 x_msg_data
4596 );
4597
4598 END IF;
4599
4600
4601 --===================================================
4602
4603 -- If the calendar type is resource then it will generate the schedule on the basis of
4604 -- the calendar asign to the resource
4605 IF (p_schedule_basis_flag = 'R') then
4606 PA_SCHEDULE_UTILS.log_message(1, 'Schedule Basis Flag - R');
4607 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API get_resource_schedule ....');
4608
4609 -- Calling tthe PVT API which will get the schedule for staffed asignment and calendar type is resource
4610 PA_SCHEDULE_PVT.get_resource_schedule(p_project_party_id,
4611 'PA_PROJECT_PARTY_ID',
4612 l_start_date,
4613 l_end_date,
4614 l_x_sch_record_tab,
4615 l_x_return_status,
4616 x_msg_count,
4617 x_msg_data
4618 );
4619 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API get_resource_schedule ....');
4620 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API apply_percentage ....');
4621
4622 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
4623 -- Calling the PA_SCHEDULE_UTILS API whice will apply the percentage of the resource can be used
4624 PA_SCHEDULE_UTILS.apply_percentage(l_x_sch_record_tab,
4625 p_resource_calendar_percent,
4626 l_x_return_status,
4627 x_msg_count,
4628 x_msg_data
4629 );
4630 END IF;
4631 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API apply_percentage ....');
4632
4633 -- If the calendar type is other then resource then it will generate
4634 -- the schedule on the basis of the assignment asign to the calendar type
4635 ELSIF (p_schedule_basis_flag = 'A') THEN
4636 PA_SCHEDULE_UTILS.log_message(1, 'Schedule basis flag = A ....');
4637 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API get_assignment_schedule ....');
4638
4639 -- code fix starts for bug 2335580
4640 SELECT start_date, end_date,calendar_id
4641 into l_req_start_date, l_req_end_date, l_calendar_id
4642 from pa_project_assignments
4643 where assignment_id=p_open_assignment_id;
4644
4645
4646 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
4647 -- Calling the PVT API which will get the schedule on the basis of passed assignment id
4648 --Added for 2335580
4649 -- To check for this date clause jraj 12/19/03..
4650
4651 IF (p_start_date >l_req_end_date and p_end_date >l_req_end_date) OR
4652 (p_start_date <l_req_start_date AND p_end_date <l_req_start_date) THEN
4653 PA_SCHEDULE_PVT.get_calendar_schedule(l_calendar_id,
4654 l_start_date,
4655 l_end_date,
4656 l_x_sch_record_tab,
4657 l_x_return_status,
4658 x_msg_count,
4659 x_msg_data
4660
4661 );
4662 ELSE
4663
4664
4665 PA_SCHEDULE_PVT.get_assignment_schedule(p_open_assignment_id,
4666 l_start_date,
4667 l_end_date,
4668 l_x_sch_record_tab,
4669 l_x_return_status,
4670 x_msg_count,
4671 x_msg_data
4672 );
4673 END IF;
4674 END IF;
4675 PA_SCHEDULE_UTILS.log_message(1, 'After get_assignment_schedule .',l_x_sch_record_tab);
4676 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API get_assignment_schedule ....');
4677
4678 -- if the calendar type is other then resource then it will generate
4679 -- the schedule on the basis of the assignment asign to the calendar type
4680 ELSIF (p_schedule_basis_flag IN ('P','O')) THEN
4681 PA_SCHEDULE_UTILS.log_message(1, 'Schedule Basis Flag P or O');
4682 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API get_calendar_schedule ....');
4683
4684 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
4685 -- Calling the PVT API which will get the schedule on the basis of passed calendar id
4686 PA_SCHEDULE_PVT.get_calendar_schedule(p_calendar_id,
4687 l_start_date,
4688 l_end_date,
4689 l_x_sch_record_tab,
4690 l_x_return_status,
4691 x_msg_count,
4692 x_msg_data
4693 );
4694 END IF;
4695
4696 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API get_calendar_schedule ....');
4697 END IF;
4698
4699
4700 IF p_sum_tasks_flag = 'Y' then
4701
4702 null;
4703 -- Call task summation API.
4704 -- and obtain new l_new_schedule_tab_rec
4705 sum_task_assignments(
4706 p_task_assignment_id_tbl,
4707 l_x_sch_record_tab,
4708 p_start_date,
4709 p_end_date,
4710 l_total_hours, --Bug 5126919
4711 l_new_schedule_tab,
4712 l_x_return_status,
4713 x_msg_count,
4714 x_msg_data
4715 );
4716 ELSE
4717 l_new_schedule_tab := l_x_sch_record_tab;
4718
4719 END IF;
4720
4721
4722
4723 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API update_sch_rec_tab ....');
4724 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
4725 -- updating the passed schedule table of record for creating the schedule for staffed assignment
4726 PA_SCHEDULE_UTILS.update_sch_rec_tab(l_new_schedule_tab,
4727 P_project_id => p_project_id,
4728 p_schedule_type_code => 'STAFFED_ASSIGNMENT',
4729 p_calendar_id => p_calendar_id,
4730 p_assignment_id => p_assignment_id,
4731 p_assignment_status_code => p_assignment_status_code,
4732 x_return_status => l_x_return_status,
4733 x_msg_count => x_msg_count,
4734 x_msg_data => x_msg_data
4735 );
4736 END IF;
4737
4738 PA_SCHEDULE_UTILS.log_message(1, 'SCH_REC',l_new_schedule_tab);
4739 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API update_sch_rec_tab ....');
4740 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API insert_rows ....');
4741
4742 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
4743 -- Inserting the record in PA_SCHEDULES table
4744 PA_SCHEDULE_PKG.insert_rows(
4745 l_new_schedule_tab,
4746 l_x_return_status,
4747 x_msg_count,
4748 x_msg_data,
4749 l_total_hours -- Bug 5126919
4750 );
4751 END IF;
4752
4753 --jm_profiler.set_time('Create Schedule');
4754
4755 -- Calling the Timeline api to build the timeline records for the assignment
4756 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
4757 PA_TIMELINE_PVT.CREATE_TIMELINE (p_assignment_id =>p_assignment_id ,
4758 x_return_status =>l_x_return_status ,
4759 x_msg_count =>x_msg_count ,
4760 x_msg_data =>x_msg_data );
4761 END IF;
4762
4763 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API insert_rows ....');
4764 PA_SCHEDULE_UTILS.log_message(1,'End of the create_sasgn_schedule API ... ');
4765 x_return_status := l_x_return_status;
4766 EXCEPTION
4767 WHEN OTHERS THEN
4768 PA_SCHEDULE_UTILS.log_message(1,'ERROR in create_sasgn_schedule API ..'||sqlerrm);
4769 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4770 x_msg_count := 1;
4771 x_msg_data := SQLERRM;
4772 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
4773 p_procedure_name => 'create_stf_asg_schedule');
4774 raise;
4775
4776 END create_stf_asg_schedule;
4777
4778
4779 -- This procedure will delete the schedule,exception records corresponding to the passed assignment id
4780 -- Input parameters
4781 -- Parameters Type Required Description
4782 -- P_Assignment_Id NUMBER YES it is assignment id used for deletion
4783 --
4784 PROCEDURE delete_asgn_schedules ( p_assignment_id IN NUMBER,
4785 p_perm_delete IN VARCHAR2 := FND_API.G_TRUE,
4786 p_change_id IN NUMBER := null,
4787 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
4788 x_msg_count OUT NOCOPY NUMBER , --File.Sql.39 bug 4440895
4789 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
4790 IS
4791 BEGIN
4792
4793 -- Storing the value for error tracking
4794 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
4795
4796 -- deleting the records from pa_schedules,pa_schedule_exceptions and pa_schedule_except_history */
4797
4798 DELETE pa_schedules
4799 WHERE assignment_id = p_assignment_id;
4800
4801 DELETE pa_schedule_exceptions
4802 WHERE assignment_id = p_assignment_id;
4803
4804 -- Delete entire exception history if p_perm_delete
4805 -- Otherwise, just delete exceptions with change_id >= p_change_id
4806 if FND_API.TO_BOOLEAN(p_perm_delete) then
4807 DELETE pa_schedule_except_history
4808 WHERE assignment_id = p_assignment_id;
4809 else
4810 DELETE pa_schedule_except_history
4811 WHERE assignment_id = p_assignment_id
4812 and change_id >= p_change_id;
4813 end if;
4814
4815 -- Delete entire schedules history if p_perm_delete.
4816 if FND_API.TO_BOOLEAN(p_perm_delete) then
4817 DELETE pa_schedules_history
4818 WHERE assignment_id = p_assignment_id;
4819 end if;
4820
4821 -- Calling the Timeline api to delete the timeline records
4822 -- for the assignment
4823 PA_TIMELINE_PVT.DELETE_TIMELINE (p_assignment_id =>p_assignment_id ,
4824 x_return_status =>l_x_return_status ,
4825 x_msg_count =>x_msg_count ,
4826 x_msg_data =>x_msg_data );
4827
4828 x_return_status := l_x_return_status;
4829
4830 EXCEPTION
4831 WHEN OTHERS THEN
4832 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4833 x_msg_count := 1;
4834 x_msg_data := SQLERRM;
4835 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_UTILS',
4836 p_procedure_name => 'delete_asgn_schedules');
4837 raise;
4838
4839 END delete_asgn_schedules;
4840
4841
4842 -- Effects: Changes the schedule statuses of the assignment to the
4843 -- appropriate success status.
4844 -- Impl Notes: Call API to retrieve next status. Do nothing if the status is
4845 -- the same.
4846
4847 PROCEDURE update_sch_wf_success(
4848 p_assignment_id IN NUMBER,
4849 p_record_version_number IN NUMBER,
4850 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
4851 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
4852 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
4853 )
4854 IS
4855
4856 l_next_status_code pa_project_assignments.status_code%type;
4857 l_temp_status_code pa_project_assignments.status_code%type;
4858 l_project_id pa_project_assignments.project_id%type;
4859 l_calendar_id pa_project_assignments.calendar_id%type;
4860 l_assignment_type pa_project_assignments.assignment_type%type;
4861 l_asgn_start_date pa_project_assignments.start_date%type;
4862 l_asgn_end_date pa_project_assignments.end_date%type;
4863 l_status_type VARCHAR2(30);
4864 l_temp_index_out NUMBER;
4865 l_record_version_number NUMBER;
4866 -- added for Bug fix: 4537865
4867 l_new_msg_data VARCHAR2(2000);
4868 -- added for Bug fix: 4537865
4869
4870
4871 /*Added for bug 2279209 */
4872
4873 l_schedule_id pa_schedules.schedule_id%TYPE;
4874 l_first_status pa_schedules.status_code%TYPE;
4875 l_start_date pa_schedules.start_date%TYPE;
4876 l_end_date pa_schedules.end_date%TYPE;
4877 l_loop_thru_record varchar2(1) :='Y';
4878 l_status_code pa_schedules.status_code%TYPE;
4879
4880 /* Added for bug 2329948 */
4881 l_first_start_date pa_schedules.start_date%TYPE;
4882 l_last_end_date pa_schedules.end_date%TYPE;
4883 l_count NUMBER;
4884
4885
4886 CURSOR C1 IS
4887 SELECT schedule_id, status_code, start_date, end_date
4888 FROM pa_schedules
4889 WHERE assignment_id = p_assignment_id
4890 ORDER BY start_date;
4891
4892 CURSOR C2 IS
4893 SELECT project_id, calendar_id,
4894 assignment_type, start_date, end_date
4895 FROM pa_project_assignments
4896 WHERE assignment_id = p_assignment_id;
4897
4898 BEGIN
4899 PA_SCHEDULE_UTILS.log_message(1,'Start of the update_sch_wf_success API');
4900 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
4901
4902 l_record_version_number := p_record_version_number;
4903
4904 open c2;
4905 fetch c2 into l_project_id, l_calendar_id,
4906 l_assignment_type, l_asgn_start_date, l_asgn_end_date;
4907 close c2;
4908
4909 -- Derive status type.
4910 if ( l_assignment_type = 'OPEN_ASSIGNMENT' ) then
4911 l_status_type := 'OPEN_ASGMT';
4912 else
4913 l_status_type := 'STAFFED_ASGMT';
4914 end if;
4915
4916 /* Commented for bug 2329948 */
4917
4918 /*
4919 --Added for bug 2279209
4920
4921 OPEN C1;
4922 LOOP
4923 FETCH C1 INTO l_schedule_id, l_status_code, l_start_date, l_end_date;
4924
4925 IF SQL%ROWCOUNT > 0 THEN
4926 IF l_first_status IS NULL AND l_status_code IS NOT NULL THEN
4927 l_first_status :=l_status_code;
4928 END IF;
4929
4930 IF l_first_status <> l_status_code THEN
4931 l_loop_thru_record :='Y';
4932 CLOSE C1;
4933 EXIT ;
4934 ELSE
4935 l_first_status :=l_status_code;
4936 IF C1%NOTFOUND THEN
4937 l_loop_thru_record :='N';
4938 EXIT ;
4939 END IF;
4940 END IF;
4941 END IF;
4942 END LOOP;
4943 CLOSE C1;
4944
4945 IF l_loop_thru_record ='N' THEN
4946 PA_SCHEDULE_UTILS.log_message(1,'Change status API called once');
4947
4948 SELECT min(start_date), max(end_date)
4949 INTO l_start_date, l_end_date
4950 FROM pa_schedules
4951 where assignment_id= p_assignment_id;
4952
4953 PA_SCHEDULE_UTILS.log_message(1,'Call API to get next status');
4954 PA_PROJECT_STUS_UTILS.get_wf_success_failure_status (
4955 p_status_code => l_first_status,
4956 p_status_type => l_status_type,
4957 x_wf_success_status_code => l_next_status_code,
4958 x_wf_failure_status_code => l_temp_status_code,
4959 x_return_status => l_x_return_status,
4960 x_error_message_code => x_msg_data) ;
4961 if (l_next_status_code <> l_first_status) then
4962 PA_SCHEDULE_UTILS.log_message(1, 'Calling change_status');
4963
4964 PA_SCHEDULE_PUB.change_status(
4965 p_record_version_number => l_record_version_number,
4966 p_project_id => l_project_id,
4967 p_calendar_id => l_calendar_id,
4968 p_assignment_id => p_assignment_id,
4969 p_assignment_type => l_assignment_type,
4970 p_status_type => null,
4971 p_start_date => l_start_date,
4972 p_end_date => l_end_date,
4973 p_assignment_status_code => l_next_status_code,
4974 p_asgn_start_date => l_asgn_start_date,
4975 p_asgn_end_date => l_asgn_end_date,
4976 p_init_msg_list => FND_API.G_FALSE,
4977 p_save_to_hist => FND_API.G_FALSE,
4978 x_return_status => l_x_return_status,
4979 x_msg_count => x_msg_count,
4980 x_msg_data => x_msg_data);
4981 end if;
4982 l_record_version_number := NULL;
4983
4984 ELSE
4985 --Code change ends for bug 2279209
4986
4987 FOR rec IN C1 LOOP
4988 PA_SCHEDULE_UTILS.log_message(1, 'In loop: ' || rec.start_date ||
4989 ' ' || rec.end_date);
4990 -- Call Ramesh's API to get next success status.
4991 -- For now, make them the same.
4992 PA_PROJECT_STUS_UTILS.get_wf_success_failure_status (
4993 p_status_code => rec.status_code,
4994 p_status_type => l_status_type,
4995 x_wf_success_status_code => l_next_status_code,
4996 x_wf_failure_status_code => l_temp_status_code,
4997 x_return_status => l_x_return_status,
4998 x_error_message_code => x_msg_data) ;
4999
5000 if (l_next_status_code <> rec.status_code) then
5001 PA_SCHEDULE_UTILS.log_message(1, 'Calling change_status');
5002 PA_SCHEDULE_PUB.change_status(
5003 p_record_version_number => l_record_version_number,
5004 p_project_id => l_project_id,
5005 p_calendar_id => l_calendar_id,
5006 p_assignment_id => p_assignment_id,
5007 p_assignment_type => l_assignment_type,
5008 p_status_type => null,
5009 p_start_date => rec.start_date,
5010 p_end_date => rec.end_date,
5011 p_assignment_status_code => l_next_status_code,
5012 p_asgn_start_date => l_asgn_start_date,
5013 p_asgn_end_date => l_asgn_end_date,
5014 p_init_msg_list => FND_API.G_FALSE,
5015 p_save_to_hist => FND_API.G_FALSE,
5016 x_return_status => l_x_return_status,
5017 x_msg_count => x_msg_count,
5018 x_msg_data => x_msg_data);
5019
5020 -- jmarques 1797355: Modifying l_record_version_number to be null
5021 -- since the record_version_number has already been checked in the
5022 -- first call to change_status. We cannot pass
5023 -- p_record_version_number to subsequent calls of change_status
5024 -- since the record_version_number has changed between calls.
5025 -- We must pass null instead.
5026
5027 l_record_version_number := NULL;
5028 END IF;
5029 end loop;
5030
5031 END IF; -- bug 2279209
5032
5033 */
5034 /* Commented till here for bug 2329948 */
5035
5036 /* Added for bug#2329948 */
5037 SELECT COUNT(*)
5038 INTO l_count
5039 FROM pa_schedules
5040 WHERE assignment_id = p_assignment_id;
5041
5042 OPEN C1;
5043 LOOP
5044 FETCH C1 INTO l_schedule_id, l_status_code, l_start_date, l_end_date;
5045
5046 IF C1%FOUND THEN
5047 IF l_first_status IS NULL THEN
5048 l_first_status := l_status_code;
5049 END IF;
5050
5051 IF l_first_start_date IS NULL THEN
5052 l_first_start_date := l_start_date;
5053 END IF;
5054
5055 IF l_first_status <> l_status_code THEN
5056 PA_SCHEDULE_UTILS.log_message(1,'Call API to get next status');
5057 PA_PROJECT_STUS_UTILS.get_wf_success_failure_status (
5058 p_status_code => l_first_status,
5059 p_status_type => l_status_type,
5060 x_wf_success_status_code => l_next_status_code,
5061 x_wf_failure_status_code => l_temp_status_code,
5062 x_return_status => l_x_return_status,
5063 x_error_message_code => x_msg_data);
5064
5065 IF (l_next_status_code <> l_first_status) THEN
5066 PA_SCHEDULE_UTILS.log_message(1, 'Calling change_status');
5067
5068 PA_SCHEDULE_PUB.change_status(
5069 p_record_version_number => l_record_version_number,
5070 p_project_id => l_project_id,
5071 p_calendar_id => l_calendar_id,
5072 p_assignment_id => p_assignment_id,
5073 p_assignment_type => l_assignment_type,
5074 p_status_type => null,
5075 p_start_date => l_first_start_date,
5076 p_end_date => l_last_end_date,
5077 p_assignment_status_code => l_next_status_code,
5078 p_asgn_start_date => l_asgn_start_date,
5079 p_asgn_end_date => l_asgn_end_date,
5080 p_init_msg_list => FND_API.G_FALSE,
5081 p_save_to_hist => FND_API.G_FALSE,
5082 x_return_status => l_x_return_status,
5083 x_msg_count => x_msg_count,
5084 x_msg_data => x_msg_data);
5085 END IF;
5086 l_record_version_number := NULL;
5087 l_first_status := l_status_code;
5088 l_first_start_date := l_start_date;
5089 END IF;
5090 l_last_end_date := l_end_date;
5091
5092 IF C1%ROWCOUNT = l_count THEN
5093 PA_SCHEDULE_UTILS.log_message(1,'Call API to get next status for last record');
5094 PA_PROJECT_STUS_UTILS.get_wf_success_failure_status (
5095 p_status_code => l_first_status,
5096 p_status_type => l_status_type,
5097 x_wf_success_status_code => l_next_status_code,
5098 x_wf_failure_status_code => l_temp_status_code,
5099 x_return_status => l_x_return_status,
5100 x_error_message_code => x_msg_data);
5101
5102 IF (l_next_status_code <> l_first_status) THEN
5103 PA_SCHEDULE_UTILS.log_message(1, 'Calling change_status last record');
5104
5105 PA_SCHEDULE_PUB.change_status(
5106 p_record_version_number => l_record_version_number,
5107 p_project_id => l_project_id,
5108 p_calendar_id => l_calendar_id,
5109 p_assignment_id => p_assignment_id,
5110 p_assignment_type => l_assignment_type,
5111 p_status_type => null,
5112 p_start_date => l_first_start_date,
5113 p_end_date => l_last_end_date,
5114 p_assignment_status_code => l_next_status_code,
5115 p_asgn_start_date => l_asgn_start_date,
5116 p_asgn_end_date => l_asgn_end_date,
5117 p_init_msg_list => FND_API.G_FALSE,
5118 p_save_to_hist => FND_API.G_FALSE,
5119 x_return_status => l_x_return_status,
5120 x_msg_count => x_msg_count,
5121 x_msg_data => x_msg_data);
5122 END IF;
5123 END IF;
5124 ELSE
5125 EXIT;
5126 END IF;
5127 END LOOP;
5128 CLOSE C1;
5129 /* End of code added for bug 2329948 */
5130
5131
5132 -- If records exist in pa_schedules_history with last_approved_flag
5133 -- set the flag to 'N'
5134 PA_SCHEDULE_UTILS.log_message(1, 'Setting last approved flag to N');
5135 update pa_schedules_history
5136 set last_approved_flag = 'N'
5137 where assignment_id = p_assignment_id
5138 and last_approved_flag = 'Y';
5139
5140 PA_SCHEDULE_UTILS.log_message(1,'End of the update_sch_wf_success API ... '
5141 || l_x_return_status);
5142
5143 x_return_status := l_x_return_status;
5144 x_msg_count := FND_MSG_PUB.Count_Msg;
5145 If x_msg_count = 1 THEN
5146 pa_interface_utils_pub.get_messages
5147 (p_encoded => FND_API.G_TRUE ,
5148 p_msg_index => 1,
5149 p_msg_count => x_msg_count ,
5150 p_msg_data => x_msg_data ,
5151 --p_data => x_msg_data, * Commented for Bug: 4537865
5152 p_data => l_new_msg_data, -- added for Bug fix: 4537865
5153 p_msg_index_out => l_temp_index_out );
5154 -- added for Bug fix: 4537865
5155 x_msg_data := l_new_msg_data;
5156 -- added for Bug fix: 4537865
5157 End If;
5158
5159
5160 EXCEPTION
5161 WHEN OTHERS THEN
5162 PA_SCHEDULE_UTILS.log_message(1,'ERROR in update_sch_wf_success API ..'||sqlerrm);
5163 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5164 x_msg_count := 1;
5165 x_msg_data := SQLERRM;
5166 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
5167 p_procedure_name => 'update_sch_wf_success');
5168 END update_sch_wf_success;
5169
5170 -- Effects: Changes the schedule statuses of the assignment to the
5171 -- appropriate failure status.
5172 -- Impl Notes: Call API to retrieve next status. Do nothing if the status is
5173 -- the same.
5174
5175 PROCEDURE update_sch_wf_failure(
5176 p_assignment_id IN NUMBER,
5177 p_record_version_number IN NUMBER,
5178 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
5179 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
5180 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5181 )
5182 IS
5183 L_next_status_code pa_project_assignments.status_code%type;
5184 l_temp_status_code pa_project_assignments.status_code%type;
5185 l_project_id pa_project_assignments.project_id%type;
5186 l_calendar_id pa_project_assignments.calendar_id%type;
5187 l_assignment_type pa_project_assignments.assignment_type%type;
5188 l_asgn_start_date pa_project_assignments.start_date%type;
5189 l_asgn_end_date pa_project_assignments.end_date%type;
5190 l_status_type VARCHAR2(30);
5191 l_temp_index_out NUMBER;
5192 l_record_version_number NUMBER;
5193 -- added for Bug Fix: 4537865
5194 l_new_msg_data VARCHAR2(2000);
5195 -- added for Bug Fix: 4537865
5196
5197
5198 /* Added for bug 2329948 */
5199 l_schedule_id pa_schedules.schedule_id%TYPE;
5200 l_start_date pa_schedules.start_date%TYPE;
5201 l_end_date pa_schedules.end_date%TYPE;
5202 l_status_code pa_schedules.status_code%TYPE;
5203 l_first_status pa_schedules.status_code%TYPE;
5204 l_first_start_date pa_schedules.start_date%TYPE;
5205 l_last_end_date pa_schedules.end_date%TYPE;
5206 l_count NUMBER;
5207
5208 CURSOR C1 IS
5209 SELECT schedule_id, status_code, start_date, end_date
5210 FROM pa_schedules
5211 WHERE assignment_id = p_assignment_id
5212 ORDER BY start_date;
5213
5214 CURSOR C2 IS
5215 SELECT project_id, calendar_id,
5216 assignment_type, start_date, end_date
5217 FROM pa_project_assignments
5218 WHERE assignment_id = p_assignment_id;
5219
5220 BEGIN
5221 PA_SCHEDULE_UTILS.log_message(1,'Start of the update_sch_wf_failure API');
5222 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
5223
5224 l_record_version_number := p_record_version_number;
5225
5226 -- Get assignment information
5227 open c2;
5228 fetch c2 into l_project_id, l_calendar_id,
5229 l_assignment_type, l_asgn_start_date, l_asgn_end_date;
5230 close c2;
5231
5232 -- Derive status type.
5233 if ( l_assignment_type = 'OPEN_ASSIGNMENT' ) then
5234 l_status_type := 'OPEN_ASGMT';
5235 else
5236 l_status_type := 'STAFFED_ASGMT';
5237 end if;
5238
5239 /* Commented for bug 2329948 */
5240
5241 /* FOR rec IN C1 LOOP
5242 -- Call Ramesh's API to get next success status.
5243 -- For now, make them the same.
5244 PA_PROJECT_STUS_UTILS.get_wf_success_failure_status (
5245 p_status_code => rec.status_code,
5246 p_status_type => l_status_type,
5247 x_wf_success_status_code => l_temp_status_code,
5248 x_wf_failure_status_code => l_next_status_code,
5249 x_return_status => l_x_return_status,
5250 x_error_message_code => x_msg_data) ;
5251
5252 if (l_next_status_code <> rec.status_code) then
5253 PA_SCHEDULE_PUB.change_status(
5254 p_record_version_number => l_record_version_number,
5255 p_project_id => l_project_id,
5256 p_calendar_id => l_calendar_id,
5257 p_assignment_id => p_assignment_id,
5258 p_assignment_type => l_assignment_type,
5259 p_status_type => null,
5260 p_start_date => rec.start_date,
5261 p_end_date => rec.end_date,
5262 p_assignment_status_code => l_next_status_code,
5263 p_asgn_start_date => l_asgn_start_date,
5264 p_asgn_end_date => l_asgn_end_date,
5265 p_init_msg_list => FND_API.G_FALSE,
5266 p_save_to_hist => FND_API.G_FALSE,
5267 x_return_status => l_x_return_status,
5268 x_msg_count => x_msg_count,
5269 x_msg_data => x_msg_data);
5270
5271 -- jmarques 1797355: Modifying l_record_version_number to be null
5272 -- since the record_version_number has already been checked in the
5273 -- first call to change_status. We cannot pass
5274 -- p_record_version_number to subsequent calls of change_status
5275 -- since the record_version_number has changed between calls.
5276 -- We must pass null instead.
5277
5278 l_record_version_number := NULL;
5279 end if;
5280 end loop;
5281 */
5282
5283 /* Commented till here for bug 2329948 */
5284
5285 /* Added for bug#2329948 */
5286 SELECT COUNT(*)
5287 INTO l_count
5288 FROM pa_schedules
5289 WHERE assignment_id = p_assignment_id;
5290
5291 OPEN C1;
5292 LOOP
5293 FETCH C1 INTO l_schedule_id, l_status_code, l_start_date, l_end_date;
5294
5295 IF C1%FOUND THEN
5296 IF l_first_status IS NULL THEN
5297 l_first_status := l_status_code;
5298 END IF;
5299
5300 IF l_first_start_date IS NULL THEN
5301 l_first_start_date := l_start_date;
5302 END IF;
5303
5304 IF l_first_status <> l_status_code THEN
5305 PA_SCHEDULE_UTILS.log_message(1,'Call API to get next status');
5306 PA_PROJECT_STUS_UTILS.get_wf_success_failure_status (
5307 p_status_code => l_first_status,
5308 p_status_type => l_status_type,
5309 x_wf_success_status_code => l_temp_status_code,
5310 x_wf_failure_status_code => l_next_status_code,
5311 x_return_status => l_x_return_status,
5312 x_error_message_code => x_msg_data);
5313
5314 IF (l_next_status_code <> l_first_status) THEN
5315 PA_SCHEDULE_UTILS.log_message(1, 'Calling change_status');
5316
5317 PA_SCHEDULE_PUB.change_status(
5318 p_record_version_number => l_record_version_number,
5319 p_project_id => l_project_id,
5320 p_calendar_id => l_calendar_id,
5321 p_assignment_id => p_assignment_id,
5322 p_assignment_type => l_assignment_type,
5323 p_status_type => null,
5324 p_start_date => l_first_start_date,
5325 p_end_date => l_last_end_date,
5326 p_assignment_status_code => l_next_status_code,
5327 p_asgn_start_date => l_asgn_start_date,
5328 p_asgn_end_date => l_asgn_end_date,
5329 p_init_msg_list => FND_API.G_FALSE,
5330 p_save_to_hist => FND_API.G_FALSE,
5331 x_return_status => l_x_return_status,
5332 x_msg_count => x_msg_count,
5333 x_msg_data => x_msg_data);
5334 END IF;
5335 l_record_version_number := NULL;
5336 l_first_status := l_status_code;
5337 l_first_start_date := l_start_date;
5338 END IF;
5339 l_last_end_date := l_end_date;
5340
5341 IF C1%ROWCOUNT = l_count THEN
5342 PA_SCHEDULE_UTILS.log_message(1,'Call API to get next status for last record');
5343 PA_PROJECT_STUS_UTILS.get_wf_success_failure_status (
5344 p_status_code => l_first_status,
5345 p_status_type => l_status_type,
5346 x_wf_success_status_code => l_temp_status_code,
5347 x_wf_failure_status_code => l_next_status_code,
5348 x_return_status => l_x_return_status,
5349 x_error_message_code => x_msg_data);
5350
5351 IF (l_next_status_code <> l_first_status) THEN
5352 PA_SCHEDULE_UTILS.log_message(1, 'Calling change_status last record');
5353
5354 PA_SCHEDULE_PUB.change_status(
5355 p_record_version_number => l_record_version_number,
5356 p_project_id => l_project_id,
5357 p_calendar_id => l_calendar_id,
5358 p_assignment_id => p_assignment_id,
5359 p_assignment_type => l_assignment_type,
5360 p_status_type => null,
5361 p_start_date => l_first_start_date,
5362 p_end_date => l_last_end_date,
5363 p_assignment_status_code => l_next_status_code,
5364 p_asgn_start_date => l_asgn_start_date,
5365 p_asgn_end_date => l_asgn_end_date,
5366 p_init_msg_list => FND_API.G_FALSE,
5367 p_save_to_hist => FND_API.G_FALSE,
5368 x_return_status => l_x_return_status,
5369 x_msg_count => x_msg_count,
5370 x_msg_data => x_msg_data);
5371 END IF;
5372 END IF;
5373 ELSE
5374 EXIT;
5375 END IF;
5376 END LOOP;
5377 CLOSE C1;
5378 /* End of code added for bug 2329948 */
5379
5380
5381 x_msg_count := FND_MSG_PUB.Count_Msg;
5382 If x_msg_count = 1 THEN
5383 pa_interface_utils_pub.get_messages
5384 (p_encoded => FND_API.G_TRUE ,
5385 p_msg_index => 1,
5386 p_msg_count => x_msg_count ,
5387 p_msg_data => x_msg_data ,
5388 --p_data => x_msg_data, * Commented for Bug fix: 4537865
5389 p_data => l_new_msg_data, -- added for Bug Fix: 4537865
5390 p_msg_index_out => l_temp_index_out );
5391 -- added for Bug Fix: 4537865
5392 x_msg_data := l_new_msg_data;
5393 -- added for Bug Fix: 4537865
5394 End If;
5395
5396 x_return_status := l_x_return_status;
5397 PA_SCHEDULE_UTILS.log_message(1,'End of the update_sch_wf_failure API ... ');
5398
5399 EXCEPTION
5400 WHEN OTHERS THEN
5401 PA_SCHEDULE_UTILS.log_message(1,'ERROR in update_sch_wf_failure API ..'||sqlerrm);
5402 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5403 x_msg_count := 1;
5404 x_msg_data := SQLERRM;
5405 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
5406 p_procedure_name => 'update_sch_wf_failure');
5407 END update_sch_wf_failure;
5408
5409 -- Effects: Reverts the schedule back to the last approved schedule.
5410 -- Impl Notes: Copies schedule records with p_assignment_id, from schedules
5411 -- history to schedules table. Do not update if there are
5412 -- no records with last_approved_flag = 'Y'. Delete those records from
5413 -- pa_schedule_history. Be sure to use delete schedule API to remove old
5414 -- schedules. Also, call create_timeline.
5415
5416 PROCEDURE revert_to_last_approved(
5417 p_assignment_id IN NUMBER,
5418 p_change_id IN NUMBER,
5419 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
5420 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
5421 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5422 )
5423 IS
5424 l_index NUMBER;
5425 l_temp_index_out NUMBER;
5426 -- added for Bug fix: 4537865
5427 l_new_msg_data VARCHAR2(2000);
5428 -- added for Bug fix: 4537865
5429
5430 CURSOR C1 IS
5431 select schedule_id, calendar_id, assignment_id, project_id,
5432 schedule_type_code, status_code, start_date, end_date, monday_hours,
5433 tuesday_hours, wednesday_hours, thursday_hours, friday_hours,
5434 saturday_hours, sunday_hours, change_id, last_approved_flag, request_id,
5435 program_application_id, program_id, program_update_date, creation_date,
5436 created_by, last_update_date, last_update_by, last_update_login
5437 from pa_schedules_history
5438 where assignment_id = p_assignment_id
5439 and last_approved_flag = 'Y';
5440
5441 BEGIN
5442 PA_SCHEDULE_UTILS.log_message(1,'Start of the revert_to_last_approved API');
5443 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
5444
5445 l_index := 0;
5446 for rec in c1 loop
5447 l_index := l_index + 1;
5448
5449 if l_index = 1 then
5450 -- Delete schedules for the assignment in order to insert new assignment
5451 -- records.
5452 delete_asgn_schedules(
5453 p_assignment_id => p_assignment_id,
5454 p_perm_delete => FND_API.G_FALSE,
5455 p_change_id => p_change_id,
5456 x_return_status => l_x_return_status,
5457 x_msg_count => x_msg_count,
5458 x_msg_data => x_msg_data);
5459 end if;
5460 -- Insert row into PA_SCHEDULES
5461 pa_schedule_pkg.insert_rows (
5462 p_calendar_id => rec.calendar_id,
5463 p_assignment_id => rec.assignment_id ,
5464 p_project_id => rec.project_id ,
5465 p_schedule_type_code => rec.schedule_type_code,
5466 p_assignment_status_code => rec.status_code ,
5467 p_start_date => rec.start_date ,
5468 p_end_date => rec.end_date ,
5469 p_monday_hours => rec.monday_hours ,
5470 p_tuesday_hours => rec.tuesday_hours ,
5471 p_wednesday_hours => rec.wednesday_hours ,
5472 p_thursday_hours => rec.thursday_hours,
5473 p_friday_hours => rec.friday_hours ,
5474 p_saturday_hours => rec.saturday_hours,
5475 p_sunday_hours => rec.sunday_hours ,
5476 x_return_status => l_x_return_status ,
5477 x_msg_count => x_msg_count ,
5478 x_msg_data => x_msg_data);
5479 end loop;
5480
5481 -- Call create_timeline and delete records from schedule history
5482 -- if we inserted any rows.
5483 if l_index <> 0 then
5484 delete pa_schedules_history
5485 where assignment_id = p_assignment_id
5486 and last_approved_flag = 'Y';
5487
5488 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
5489 PA_TIMELINE_PVT.CREATE_TIMELINE (
5490 p_assignment_id => p_assignment_id,
5491 x_return_status => l_x_return_status,
5492 x_msg_count => x_msg_count,
5493 x_msg_data => x_msg_data);
5494 END IF;
5495
5496 end if;
5497
5498 x_msg_count := FND_MSG_PUB.Count_Msg;
5499 If x_msg_count = 1 THEN
5500 pa_interface_utils_pub.get_messages
5501 (p_encoded => FND_API.G_TRUE ,
5502 p_msg_index => 1,
5503 p_msg_count => x_msg_count ,
5504 p_msg_data => x_msg_data ,
5505 --p_data => x_msg_data, * Commented for Bug fix: 4537865
5506 p_data => l_new_msg_data, -- added for Bug fix: 4537865
5507 p_msg_index_out => l_temp_index_out );
5508 -- added for Bug fix: 4537865
5509 x_msg_data := l_new_msg_data;
5510 -- added for Bug fix: 4537865
5511 End If;
5512
5513 x_return_status := l_x_return_status;
5514 PA_SCHEDULE_UTILS.log_message(1,'End of the revert_to_last_approved API ... ');
5515
5516 EXCEPTION
5517 WHEN OTHERS THEN
5518 PA_SCHEDULE_UTILS.log_message(1,'ERROR in revert_to_last_approved API ..'||sqlerrm);
5519 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5520 x_msg_count := 1;
5521 x_msg_data := SQLERRM;
5522 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
5523 p_procedure_name => 'revert_to_last_approved');
5524 END revert_to_last_approved;
5525
5526 -- Effects: Adds schedule records for p_assignment_id to pa_schedules_history
5527 -- if they do not already exist.
5528 -- Impl Notes: If records already exist in pa_schedule_history with change_id,
5529 -- then do nothing. Otherwise, uncheck any records with last_approved_flag
5530 -- and copy schedule records there with correct change_id with
5531 -- last_approved_flag checked.
5532
5533 PROCEDURE update_history_table(
5534 p_assignment_id IN NUMBER,
5535 p_change_id IN NUMBER,
5536 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
5537 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
5538 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5539 )
5540 IS
5541
5542 l_index NUMBER;
5543 l_assignment_id NUMBER;
5544 l_change_id NUMBER;
5545 l_temp_index_out NUMBER;
5546 -- added for bug fix: 4537865
5547 l_new_msg_data VARCHAR2(2000);
5548 -- added for bug fix: 4537865
5549
5550 -- Contains all the records with p_change_id.
5551 CURSOR C1 IS
5552 select assignment_id
5553 from pa_schedules_history
5554 where assignment_id = p_assignment_id
5555 and change_id = p_change_id;
5556
5557 -- Contains the schedule records for assignment_id.
5558 CURSOR C2 IS
5559 select schedule_id, calendar_id, assignment_id, project_id,
5560 schedule_type_code, status_code, start_date, end_date, monday_hours,
5561 tuesday_hours, wednesday_hours, thursday_hours, friday_hours,
5562 saturday_hours, sunday_hours, creation_date, created_by, last_update_date,
5563 last_update_by, last_update_login, request_id, program_application_id,
5564 program_id, program_update_date
5565 from pa_schedules
5566 where assignment_id = p_assignment_id;
5567
5568 BEGIN
5569 PA_SCHEDULE_UTILS.log_message(1,'Start of the update_history_table API');
5570 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
5571
5572 -- If there are no records in pa_schedules_history with change_id
5573 -- then update table.
5574 open c1;
5575 fetch c1 into l_assignment_id;
5576 if c1%NOTFOUND then
5577 close c1;
5578
5579 -- Copy records in pa_schedules to pa_schedules_history
5580 for rec in c2 loop
5581 insert into pa_schedules_history
5582 ( schedule_id, calendar_id, assignment_id, project_id,
5583 schedule_type_code, status_code, start_date, end_date, monday_hours,
5584 tuesday_hours, wednesday_hours, thursday_hours, friday_hours,
5585 saturday_hours, sunday_hours, change_id, last_approved_flag,
5586 creation_date, created_by, last_update_date, last_update_by,
5587 last_update_login, request_id, program_application_id, program_id,
5588 program_update_date)
5589 values
5590 ( rec.schedule_id, rec.calendar_id, rec.assignment_id, rec.project_id,
5591 rec.schedule_type_code, rec.status_code, rec.start_date, rec.end_date,
5592 rec.monday_hours, rec.tuesday_hours, rec.wednesday_hours,
5593 rec.thursday_hours, rec.friday_hours, rec.saturday_hours,
5594 rec.sunday_hours, p_change_id, 'Y', rec.creation_date, rec.created_by,
5595 rec.last_update_date, rec.last_update_by, rec.last_update_login,
5596 rec.request_id, rec.program_application_id, rec.program_id,
5597 rec.program_update_date);
5598 end loop;
5599
5600 -- If there are records in pa_schedules_history with change_id
5601 -- then do nothing.
5602 else
5603 close c1;
5604 end if;
5605
5606 x_msg_count := FND_MSG_PUB.Count_Msg;
5607 If x_msg_count = 1 THEN
5608 pa_interface_utils_pub.get_messages
5609 (p_encoded => FND_API.G_TRUE ,
5610 p_msg_index => 1,
5611 p_msg_count => x_msg_count ,
5612 p_msg_data => x_msg_data ,
5613 --p_data => x_msg_data, * Commented for Bgu: 4537865
5614 p_data => l_new_msg_data, -- added for bug fix: 4537865
5615 p_msg_index_out => l_temp_index_out );
5616 -- added for bug fix: 4537865
5617 x_msg_data := l_new_msg_data;
5618 -- added for bug fix: 4537865
5619 End If;
5620
5621 x_return_status := l_x_return_status;
5622 PA_SCHEDULE_UTILS.log_message(1,'End of the update_history_table API ... ');
5623
5624 EXCEPTION
5625 WHEN OTHERS THEN
5626 PA_SCHEDULE_UTILS.log_message(1,'ERROR in update_history_table API ..'||sqlerrm);
5627 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5628 x_msg_count := 1;
5629 x_msg_data := SQLERRM;
5630 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
5631 p_procedure_name => 'update_history_table');
5632 END update_history_table;
5633
5634
5635 --
5636 -- Procedure : Update_asgmt_changed_items_tab
5637 -- Purpose : Poplulates new and old values for schedule changes to pa_asgmt_changed_items
5638 -- table which stores the assignment_changes that are pending approval.
5639 -- Parameter
5640 -- p_populate_mode : SAVED/ASSIGNMENT_UPDATED/SCHEDULE_UPDATED
5641 --
5642 PROCEDURE update_asgmt_changed_items_tab
5643 ( p_assignment_id IN NUMBER
5644 ,p_populate_mode IN VARCHAR2 := 'SAVED'
5645 ,p_change_id IN NUMBER
5646 ,p_exception_type_code IN VARCHAR2 := NULL
5647 ,p_start_date IN DATE := NULL
5648 ,p_end_date IN DATE := NULL
5649 ,p_requirement_status_code IN VARCHAR2 := NULL
5650 ,p_assignment_status_code IN VARCHAR2 := NULL
5651 ,p_start_date_tbl IN SYSTEM.PA_DATE_TBL_TYPE := NULL
5652 ,p_end_date_tbl IN SYSTEM.PA_DATE_TBL_TYPE := NULL
5653 ,p_monday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
5654 ,p_tuesday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
5655 ,p_wednesday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
5656 ,p_thursday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
5657 ,p_friday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
5658 ,p_saturday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
5659 ,p_sunday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
5660 ,p_non_working_day_flag IN VARCHAR2 := 'N'
5661 ,p_change_hours_type_code IN VARCHAR2 := NULL
5662 ,p_hrs_per_day IN NUMBER := NULL
5663 ,p_calendar_percent IN NUMBER := NULL
5664 ,p_change_calendar_type_code IN VARCHAR2 := NULL
5665 ,p_change_calendar_name IN VARCHAR2 := NULL
5666 ,p_change_calendar_id IN NUMBER := NULL
5667 ,p_duration_shift_type_code IN VARCHAR2 := NULL
5668 ,p_duration_shift_unit_code IN VARCHAR2 := NULL
5669 ,p_number_of_shift IN NUMBER := NULL
5670 ,x_return_status OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
5671 IS
5672 l_changed_item_name pa_asgmt_changed_items.changed_item_name%TYPE;
5673 l_date_range pa_asgmt_changed_items.date_range%TYPE;
5674 l_old_value pa_asgmt_changed_items.old_value%TYPE;
5675 l_new_value pa_asgmt_changed_items.new_value%TYPE;
5676 /* Added for bug 1635170*/
5677 temp_start_date DATE;
5678 temp_end_date DATE;
5679 l_insert_schedule_change BOOLEAN :=TRUE;
5680 /* End for bug 1635170*/
5681 l_start_date DATE;
5682 l_end_date DATE;
5683 l_project_calendar_id NUMBER;
5684 l_assignment_type pa_project_assignments.assignment_type%TYPE;
5685 l_status_code pa_schedules.status_code%TYPE;
5686 l_apprvl_status_code pa_project_assignments.apprvl_status_code%TYPE;
5687 l_shifted_days NUMBER;
5688 l_calendar_id NUMBER;
5689
5690
5691 -- Bug 8856611 ,changed cursor to substitute 0 for null for all hour values
5692 CURSOR C1 IS
5693 SELECT exception_type_code, start_date, end_date, calendar_id,
5694 status_code, resource_calendar_percent, non_working_day_flag,
5695 change_hours_type_code, nvl(monday_hours,0) monday_hours , nvl(tuesday_hours,0) tuesday_hours,
5696 nvl(wednesday_hours,0) wednesday_hours, nvl(thursday_hours,0) thursday_hours, nvl(friday_hours,0) friday_hours, nvl(saturday_hours,0) saturday_hours,
5697 nvl(sunday_hours,0) sunday_hours, change_calendar_type_code, change_calendar_id
5698 FROM pa_schedule_except_history
5699 WHERE assignment_id = p_assignment_id
5700 AND change_id = p_change_id;
5701
5702 CURSOR get_start_end_date IS
5703 Select start_date, end_date
5704 from pa_project_assignments
5705 where assignment_id = p_assignment_id;
5706
5707 CURSOR get_apprvl_status_code IS
5708 SELECT apprvl_status_code
5709 FROM pa_project_assignments
5710 WHERE assignment_id = p_assignment_id;
5711
5712 CURSOR get_project_calendar_id IS
5713 SELECT prj.calendar_id
5714 FROM pa_projects_all prj,
5715 pa_project_assignments asmt
5716 WHERE asmt.assignment_id = p_assignment_id
5717 AND prj.project_id = asmt.project_id;
5718
5719 BEGIN
5720 x_return_status := FND_API.G_RET_STS_SUCCESS;
5721
5722 -- get approval status
5723 OPEN get_apprvl_status_code;
5724 FETCH get_apprvl_status_code INTO l_apprvl_status_code;
5725 CLOSE get_apprvl_status_code;
5726
5727 ------------------------------------------------------------------------
5728 -- Populate the temp table from pa_schedule_except_history
5729 ------------------------------------------------------------------------
5730 -- If there is last approved data in history table and approval status is not 'approve',
5731 -- populate temp table from history table first. Because we need to consider mass update submit case.
5732 IF (p_change_id <> -1 AND l_apprvl_status_code <> PA_ASSIGNMENT_APPROVAL_PUB.g_approved) THEN
5733 FOR v_c1 IN C1 LOOP
5734 -- If exception_type is either 'CHANGE_DURATION' or 'SHIFT_DURATION', we want to add only one row
5735 -- to the temp table for both.
5736 IF ( (v_c1.exception_type_code = 'CHANGE_DURATION' OR v_c1.exception_type_code = 'SHIFT_DURATION' OR v_c1.exception_type_code = 'DURATION_PATTERN_SHIFT') AND
5737 l_insert_schedule_change = FALSE) THEN
5738 NULL;
5739 ELSE
5740 l_changed_item_name := PA_SCHEDULE_PVT.get_changed_item_name_text(v_c1.exception_type_code);
5741
5742 IF (v_c1.exception_type_code='CHANGE_DURATION' OR v_c1.exception_type_code='SHIFT_DURATION' OR v_c1.exception_type_code = 'DURATION_PATTERN_SHIFT') THEN
5743 l_date_range := ' ';
5744 ELSE
5745 l_date_range := PA_SCHEDULE_PVT.get_date_range_text(v_c1.start_date, v_c1.end_date);
5746 END IF;
5747
5748 -- v_c1.start_date,v_c1.end_date are not used for exception_type 'CHANGE_DURATION' or 'SHIFT_DURATION'
5749 l_old_value := get_old_value_text(v_c1.exception_type_code,
5750 p_assignment_id,
5751 v_c1.start_date,
5752 v_c1.end_date);
5753 /*Added for bug 1635170 */
5754 IF (v_c1.exception_type_code = 'CHANGE_DURATION' OR v_c1.exception_type_code = 'SHIFT_DURATION' OR v_c1.exception_type_code = 'DURATION_PATTERN_SHIFT' )THEN
5755 OPEN get_start_end_date;
5756 FETCH get_start_end_date into temp_start_date, temp_end_date;
5757 CLOSE get_start_end_date;
5758
5759 IF (p_populate_mode = 'ASSIGNMENT_UPDATED' AND (p_exception_type_code='CHANGE_DURATION'
5760 OR p_exception_type_code='SHIFT_DURATION' OR p_exception_type_code = 'DURATION_PATTERN_SHIFT') ) THEN
5761 SELECT DECODE(p_start_date, null, temp_start_date, p_start_date),
5762 DECODE(p_end_date, null, temp_end_date, p_end_date)
5763 INTO l_start_date,
5764 l_end_date
5765 FROM DUAL;
5766 ELSE
5767 l_start_date := temp_start_date;
5768 l_end_date := temp_end_date;
5769 END IF;
5770
5771 l_insert_schedule_change := FALSE;
5772 END IF;
5773 /*End of bug 1635170 */
5774
5775 IF (v_c1.exception_type_code = 'CHANGE_HOURS' AND v_c1.change_hours_type_code='PERCENTAGE'
5776 AND v_c1.change_calendar_type_code='PROJECT') THEN
5777 OPEN get_project_calendar_id;
5778 FETCH get_project_calendar_id into l_calendar_id;
5779 CLOSE get_project_calendar_id;
5780 ELSE
5781 l_calendar_id := v_c1.calendar_id;
5782 END IF;
5783
5784 -- l_start_date, l_end_date are used only for exception_type 'CHANGE_DURATION' or 'SHIFT_DURATION'
5785 l_new_value := get_new_value_text(v_c1.exception_type_code,
5786 l_calendar_id, --v_c1.calendar_id,
5787 l_start_date,
5788 l_end_date,
5789 v_c1.status_code,
5790 v_c1.change_calendar_id,
5791 v_c1.monday_hours,
5792 v_c1.tuesday_hours,
5793 v_c1.wednesday_hours,
5794 v_c1.thursday_hours,
5795 v_c1.friday_hours,
5796 v_c1.saturday_hours,
5797 v_c1.sunday_hours,
5798 v_c1.change_hours_type_code,
5799 v_c1.non_working_day_flag,
5800 v_c1.monday_hours,
5801 v_c1.resource_calendar_percent,
5802 v_c1.change_calendar_type_code,
5803 null);
5804
5805 INSERT INTO pa_asgmt_changed_items (assignment_id, changed_item_name, date_range, old_value, new_value)
5806 VALUES (p_assignment_id, l_changed_item_name, l_date_range, l_old_value, l_new_value);
5807 END IF; /* Added for bug 1635170*/
5808 END LOOP;
5809 END IF;
5810
5811 ---------------------------------------------------------------------------------
5812 -- Populate the temp table for the passed parameters (updated but not saved yet)
5813 ---------------------------------------------------------------------------------
5814 IF (p_populate_mode = 'SCHEDULE_UPDATED') THEN
5815
5816 IF ((p_exception_type_code='CHANGE_DURATION' OR p_exception_type_code='SHIFT_DURATION' OR p_exception_type_code = 'DURATION_PATTERN_SHIFT') AND
5817 l_insert_schedule_change = FALSE ) THEN
5818 null;
5819
5820 -----------------------------------------------
5821 -- For work pattern changes (passed parameters)
5822 -----------------------------------------------
5823 ELSIF (p_exception_type_code = 'CHANGE_WORK_PATTERN') THEN
5824
5825 IF p_start_date_tbl.COUNT > 0 THEN
5826 FOR j IN p_start_date_tbl.FIRST .. p_start_date_tbl.LAST LOOP
5827
5828 l_changed_item_name := PA_SCHEDULE_PVT.get_changed_item_name_text(p_exception_type_code);
5829
5830 l_date_range := PA_SCHEDULE_PVT.get_date_range_text(p_start_date_tbl(j), p_end_date_tbl(j));
5831
5832 l_old_value := get_old_value_text(p_exception_type_code,
5833 p_assignment_id,
5834 p_start_date_tbl(j),
5835 p_end_date_tbl(j));
5836
5837 l_new_value := get_new_value_text(p_exception_type_code,
5838 null,
5839 p_start_date_tbl(j),
5840 p_end_date_tbl(j),
5841 null,
5842 null,
5843 p_monday_hours_tbl(j),
5844 p_tuesday_hours_tbl(j),
5845 p_wednesday_hours_tbl(j),
5846 p_thursday_hours_tbl(j),
5847 p_friday_hours_tbl(j),
5848 p_saturday_hours_tbl(j),
5849 p_sunday_hours_tbl(j),
5850 null,
5851 null,
5852 null,
5853 null,
5854 null,
5855 null);
5856
5857 INSERT INTO pa_asgmt_changed_items (assignment_id, changed_item_name, date_range, old_value, new_value)
5858 VALUES (p_assignment_id, l_changed_item_name, l_date_range, l_old_value, l_new_value);
5859 END LOOP;
5860
5861 END IF;
5862
5863 -----------------------------------------------
5864 -- For other changes (passed parameters)
5865 -----------------------------------------------
5866 ELSE
5867 l_changed_item_name := PA_SCHEDULE_PVT.get_changed_item_name_text(p_exception_type_code);
5868
5869 IF (p_exception_type_code='CHANGE_DURATION' OR p_exception_type_code='SHIFT_DURATION' OR p_exception_type_code = 'DURATION_PATTERN_SHIFT') THEN
5870 l_date_range := ' ';
5871 ELSE
5872 l_date_range := PA_SCHEDULE_PVT.get_date_range_text(p_start_date, p_end_date);
5873 END IF;
5874
5875 l_old_value := get_old_value_text(p_exception_type_code,
5876 p_assignment_id,
5877 p_start_date,
5878 p_end_date);
5879
5880 IF (p_exception_type_code = 'CHANGE_DURATION' OR p_exception_type_code = 'SHIFT_DURATION' OR p_exception_type_code = 'DURATION_PATTERN_SHIFT') THEN
5881 OPEN get_start_end_date;
5882 FETCH get_start_end_date into temp_start_date, temp_end_date;
5883 CLOSE get_start_end_date;
5884
5885 IF p_exception_type_code = 'CHANGE_DURATION' THEN
5886 SELECT DECODE(p_start_date, null, temp_start_date, p_start_date),
5887 DECODE(p_end_date, null, temp_end_date, p_end_date)
5888 INTO l_start_date,
5889 l_end_date
5890 FROM DUAL;
5891 ELSE
5892 IF (p_number_of_shift is NOT NULL) THEN
5893 -- compute shifted_days
5894 IF (p_duration_shift_unit_code = 'DAYS') THEN
5895 l_shifted_days := p_number_of_shift;
5896 ELSIF (p_duration_shift_unit_code = 'WEEKS') THEN
5897 l_shifted_days := p_number_of_shift*7;
5898 END IF;
5899
5900 -- set start_Date, end_date according to shift_type_code and shifed_days
5901 IF (p_duration_shift_type_code = 'FORWARD') THEN
5902 IF (p_duration_shift_unit_code = 'MONTHS') THEN
5903 l_start_date := add_months(temp_start_date, p_number_of_shift) ;
5904 l_end_date := add_months(temp_end_date, p_number_of_shift) ;
5905 ELSE
5906 l_start_date := temp_start_date + l_shifted_days;
5907 l_end_date := temp_end_date + l_shifted_days;
5908 END IF;
5909 ELSIF (p_duration_shift_type_code = 'BACKWARD') THEN
5910 IF (p_duration_shift_unit_code = 'MONTHS') THEN
5911 l_start_date := add_months(temp_start_date, p_number_of_shift * -1) ;
5912 l_end_date := add_months(temp_end_date, p_number_of_shift * -1) ;
5913 ELSE
5914 l_start_date := temp_start_date - l_shifted_days;
5915 l_end_date := temp_end_date - l_shifted_days;
5916 END IF;
5917 END IF;
5918 END IF;
5919 END IF; -- end of duration shift
5920
5921 -- if project calendar has been selected, pass project_calendar_id
5922 ELSIF (p_exception_type_code = 'CHANGE_HOURS' AND p_change_hours_type_code='PERCENTAGE' AND
5923 p_change_calendar_type_code='PROEJCT') THEN
5924 SELECT calendar_id
5925 INTO l_project_calendar_id
5926 FROM pa_project_assignments
5927 WHERE assignment_id = p_assignment_id;
5928
5929 -- If Status has been updated, pass appropriate status_code
5930 ELSIF (p_exception_type_code = 'CHANGE_STATUS') THEN
5931 SELECT assignment_type
5932 INTO l_assignment_type
5933 FROM pa_project_assignments
5934 WHERE assignment_id = p_assignment_id;
5935
5936 IF (l_assignment_type = 'OPEN_ASSIGNMENT') THEN
5937 l_status_code := p_requirement_status_code;
5938 ELSE
5939 l_status_code := p_assignment_status_code;
5940 END IF;
5941 END IF;
5942
5943 l_new_value := get_new_value_text (p_exception_type_code,
5944 l_project_calendar_id,
5945 l_start_date,
5946 l_end_date,
5947 l_status_code,
5948 p_change_calendar_id,
5949 null,
5950 null,
5951 null,
5952 null,
5953 null,
5954 null,
5955 null,
5956 p_change_hours_type_code,
5957 p_non_working_day_flag,
5958 p_hrs_per_day,
5959 p_calendar_percent,
5960 p_change_calendar_type_code,
5961 p_change_calendar_name);
5962
5963 INSERT INTO pa_asgmt_changed_items (assignment_id, changed_item_name, date_range, old_value, new_value)
5964 VALUES (p_assignment_id, l_changed_item_name, l_date_range, l_old_value, l_new_value);
5965 END IF;
5966 END IF; -- IF (p_populate_mode = 'SCHEDULE_UPDATED')
5967
5968 EXCEPTION
5969 WHEN OTHERS THEN
5970 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5971
5972 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
5973 p_procedure_name => 'update_asgmt_changed_items_tab');
5974 RAISE;
5975
5976 END update_asgmt_changed_items_tab;
5977
5978
5979
5980 -- Procedure : check_overcommitment_single
5981 -- Purpose : First checks if this assignment alone causes resource
5982 -- overcommitment. If Yes, then stores self-conflict and user
5983 -- action in PA_ASSIGNMENT_CONFLICT_HIST.
5984 PROCEDURE check_overcommitment_single( p_assignment_id IN NUMBER,
5985 p_resolve_conflict_action_code IN VARCHAR2,
5986 p_conflict_group_id IN NUMBER := NULL,
5987 x_overcommitment_flag OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
5988 x_conflict_group_id OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
5989 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
5990 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
5991 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
5992 IS
5993
5994 G_AVAILABILITY_CAL_PERIOD VARCHAR2(15) := FND_PROFILE.VALUE('PA_AVAILABILITY_CAL_PERIOD');
5995 G_OVERCOMMITMENT_PERCENTAGE NUMBER := FND_NUMBER.CANONICAL_TO_NUMBER(FND_PROFILE.VALUE('PA_OVERCOMMITMENT_PERCENTAGE'))/100;
5996
5997 CURSOR c1 IS
5998 SELECT resource_id, start_date, end_date
5999 FROM pa_project_assignments
6000 WHERE assignment_id = p_assignment_id;
6001
6002 l_assignment_id_tbl PA_PLSQL_DATATYPES.NumTabTyp;
6003 l_resource_id NUMBER;
6004 l_start_date DATE;
6005 l_end_date DATE;
6006 l_self_conflict_flag VARCHAR2(1) := 'N';
6007
6008 BEGIN
6009 x_return_status := FND_API.G_RET_STS_SUCCESS;
6010
6011 OPEN c1;
6012 FETCH c1 INTO l_resource_id, l_start_date, l_end_date;
6013 CLOSE c1;
6014
6015 IF l_resource_id IS NOT NULL THEN
6016
6017 IF G_AVAILABILITY_CAL_PERIOD = 'DAILY' THEN
6018
6019 select distinct fi.assignment_id
6020 BULK COLLECT INTO l_assignment_id_tbl
6021 from pa_forecast_items fi,
6022 (select resource_id,
6023 sum(item_quantity) total_assigned_quantity,
6024 item_date,
6025 delete_flag,
6026 forecast_item_type
6027 from pa_forecast_items fi1, pa_schedules sch, pa_project_statuses a, pa_project_statuses b
6028 where (fi1.assignment_id = p_assignment_id or asgmt_sys_status_code = 'STAFFED_ASGMT_CONF' )
6029 and fi1.assignment_id = sch.assignment_id
6030 and fi1.item_date between sch.start_date and sch.end_date
6031 and sch.status_code = a.project_status_code
6032 and a.wf_success_status_code = b.project_status_code
6033 and b.project_system_status_code = 'STAFFED_ASGMT_CONF'
6034 -- Added for bug 9039642
6035 and fi1.delete_flag = 'N'
6036 and fi1.forecast_item_type = 'A'
6037 and fi1.resource_id = l_resource_id
6038 and fi1.item_date between l_start_date AND l_end_date
6039 group by resource_id, item_date, delete_flag, forecast_item_type
6040 )fi_assigned,
6041 (select resource_id,
6042 capacity_quantity,
6043 item_date,
6044 delete_flag
6045 from pa_forecast_items
6046 where forecast_item_type = 'U'
6047 )fi_capacity
6048 where fi.assignment_id <> p_assignment_id
6049 and fi.resource_id = l_resource_id
6050 and fi.resource_id = fi_capacity.resource_id
6051 and fi_capacity.resource_id = fi_assigned.resource_id
6052 and fi_capacity.resource_id = l_resource_id -- Bug 4918687 SQL ID 14905966
6053 and fi.item_date BETWEEN l_start_date AND l_end_date
6054 and fi.item_date = fi_capacity.item_date
6055 and fi_capacity.item_date = fi_assigned.item_date
6056 and ((fi_capacity.capacity_quantity*(1+G_OVERCOMMITMENT_PERCENTAGE) - fi_assigned.total_assigned_quantity <= 0 and G_OVERCOMMITMENT_PERCENTAGE > 0)
6057 or (fi_capacity.capacity_quantity - fi_assigned.total_assigned_quantity < 0 and G_OVERCOMMITMENT_PERCENTAGE = 0))
6058 and fi.delete_flag = 'N'
6059 and fi.delete_flag = fi_capacity.delete_flag
6060 and fi_capacity.delete_flag = fi_assigned.delete_flag
6061 and fi.forecast_item_type = 'A'
6062 and fi.forecast_item_type = fi_assigned.forecast_item_type
6063 and fi.asgmt_sys_status_code = 'STAFFED_ASGMT_CONF';
6064
6065 -- Check self conflict.
6066 check_self_conflict(p_assignment_id => p_assignment_id,
6067 p_resource_id => l_resource_id,
6068 p_start_date => l_start_date,
6069 p_end_date => l_end_date,
6070 x_self_conflict_flag => l_self_conflict_flag,
6071 x_return_status => x_return_status,
6072 x_msg_count => x_msg_count,
6073 x_msg_data => x_msg_data);
6074
6075
6076 ELSIF G_AVAILABILITY_CAL_PERIOD = 'WEEKLY' THEN
6077
6078 select distinct fi.assignment_id
6079 BULK COLLECT INTO l_assignment_id_tbl
6080 from pa_forecast_items fi,
6081 (select resource_id,
6082 sum(item_quantity) total_assigned_quantity,
6083 GLOBAL_EXP_PERIOD_END_DATE week_end_date,
6084 delete_flag,
6085 forecast_item_type
6086 from pa_forecast_items fi1, pa_schedules sch, pa_project_statuses a, pa_project_statuses b
6087 where (fi1.assignment_id = p_assignment_id or asgmt_sys_status_code = 'STAFFED_ASGMT_CONF' )
6088 and fi1.item_date between l_start_date and l_end_date
6089 and fi1.assignment_id = sch.assignment_id
6090 and fi1.item_date between sch.start_date and sch.end_date
6091 and sch.status_code = a.project_status_code
6092 and a.wf_success_status_code = b.project_status_code
6093 and b.project_system_status_code = 'STAFFED_ASGMT_CONF'
6094 group by resource_id, GLOBAL_EXP_PERIOD_END_DATE, delete_flag, forecast_item_type
6095 )fi_assigned,
6096 (select resource_id,
6097 sum(capacity_quantity) capacity_quantity,
6098 GLOBAL_EXP_PERIOD_END_DATE week_end_date,
6099 delete_flag
6100 from pa_forecast_items
6101 where forecast_item_type = 'U'
6102 group by resource_id, GLOBAL_EXP_PERIOD_END_DATE, delete_flag
6103 )fi_capacity
6104 where fi.assignment_id <> p_assignment_id
6105 and fi.resource_id = l_resource_id
6106 and fi.resource_id = fi_capacity.resource_id
6107 and fi_capacity.resource_id = fi_assigned.resource_id
6108 and fi.item_date between l_start_date and l_end_date
6109 and fi.GLOBAL_EXP_PERIOD_END_DATE = fi_capacity.week_end_date
6110 and fi_capacity.week_end_date = fi_assigned.week_end_date
6111 and ((fi_capacity.capacity_quantity*(1+G_OVERCOMMITMENT_PERCENTAGE) - fi_assigned.total_assigned_quantity <= 0 and G_OVERCOMMITMENT_PERCENTAGE > 0)
6112 or (fi_capacity.capacity_quantity - fi_assigned.total_assigned_quantity < 0 and G_OVERCOMMITMENT_PERCENTAGE = 0))
6113 and fi.delete_flag = 'N'
6114 and fi.delete_flag = fi_capacity.delete_flag
6115 and fi_capacity.delete_flag = fi_assigned.delete_flag
6116 and fi.forecast_item_type = 'A'
6117 and fi.forecast_item_type = fi_assigned.forecast_item_type
6118 and fi.asgmt_sys_status_code = 'STAFFED_ASGMT_CONF';
6119
6120 -- Check self conflict.
6121 check_self_conflict(p_assignment_id => p_assignment_id,
6122 p_resource_id => l_resource_id,
6123 p_start_date => l_start_date,
6124 p_end_date => l_end_date,
6125 x_self_conflict_flag => l_self_conflict_flag,
6126 x_return_status => x_return_status,
6127 x_msg_count => x_msg_count,
6128 x_msg_data => x_msg_data);
6129
6130
6131 END IF;
6132 END IF;
6133
6134 -- Insert the self conflicting assignment_id if applicable.
6135 IF l_self_conflict_flag = 'Y' THEN
6136 IF l_assignment_id_tbl.COUNT > 0 THEN
6137 l_assignment_id_tbl(l_assignment_id_tbl.LAST+1) := p_assignment_id;
6138 ELSE
6139 l_assignment_id_tbl(1) := p_assignment_id;
6140 END IF;
6141 END IF;
6142
6143
6144 IF l_assignment_id_tbl.COUNT > 0 THEN
6145 x_overcommitment_flag := 'Y';
6146 PA_ASGN_CONFLICT_HIST_PKG.insert_rows(p_conflict_group_id => p_conflict_group_id,
6147 p_assignment_id => p_assignment_id,
6148 p_conflict_assignment_id_tbl => l_assignment_id_tbl,
6149 p_resolve_conflict_action_code => p_resolve_conflict_action_code,
6150 p_processed_flag => 'N',
6151 x_conflict_group_id => x_conflict_group_id,
6152 x_return_status => x_return_status,
6153 x_msg_count => x_msg_count,
6154 x_msg_data => x_msg_data);
6155
6156 ELSE
6157 x_overcommitment_flag := 'N';
6158 x_conflict_group_id := p_conflict_group_id;
6159 END IF;
6160
6161
6162 EXCEPTION
6163 WHEN OTHERS THEN
6164 x_overcommitment_flag := NULL ; -- 4537865
6165 x_conflict_group_id := NULL ;-- 4537865
6166
6167 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
6168 x_msg_count := 1;
6169 x_msg_data := SQLERRM;
6170 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
6171 p_procedure_name => 'check_overcommitment_single');
6172 RAISE;
6173 END check_overcommitment_single;
6174
6175
6176 -- Procedure : check_overcommitment_mult
6177 -- Purpose : First checks if this assignment alone causes resource
6178 -- overcommitment. If Yes, then stores self-conflict and user
6179 -- action in PA_ASSIGNMENT_CONFLICT_HIST.
6180 PROCEDURE check_overcommitment_mult(p_item_type IN PA_WF_PROCESSES.item_type%TYPE,
6181 p_item_key IN PA_WF_PROCESSES.item_key%TYPE,
6182 p_conflict_group_id IN NUMBER := NULL,
6183 p_resolve_conflict_action_code IN VARCHAR2,
6184 x_overcommitment_flag OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
6185 x_conflict_group_id OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
6186 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
6187 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
6188 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
6189 IS
6190
6191 G_AVAILABILITY_CAL_PERIOD VARCHAR2(15) := FND_PROFILE.VALUE('PA_AVAILABILITY_CAL_PERIOD');
6192 G_OVERCOMMITMENT_PERCENTAGE NUMBER := FND_NUMBER.CANONICAL_TO_NUMBER(FND_PROFILE.VALUE('PA_OVERCOMMITMENT_PERCENTAGE'))/100;
6193
6194 l_assignment_id_tbl PA_PLSQL_DATATYPES.NumTabTyp;
6195 l_conflict_group_id NUMBER := p_conflict_group_id;
6196 -- added for bug fix: 4537865
6197 l_new_conflict_group_id NUMBER;
6198 -- added for bug fix: 4537865
6199 l_intra_txn_conflict_flag_tbl SYSTEM.PA_VARCHAR2_1_TBL_TYPE;
6200 l_resource_id NUMBER;
6201 l_start_date DATE;
6202 l_end_date DATE;
6203 l_self_conflict_flag VARCHAR2(1) := 'N';
6204
6205 CURSOR c1 IS
6206 SELECT assignment_id
6207 FROM pa_mass_txn_asgmt_success_v
6208 WHERE item_type = p_item_type
6209 AND item_key = p_item_key;
6210
6211 BEGIN
6212 PA_SCHEDULE_UTILS.debug('Entering check_overcommitment_mult');
6213 x_return_status := FND_API.G_RET_STS_SUCCESS;
6214
6215 FOR v_c1 IN c1 LOOP
6216 IF v_c1.assignment_id IS NOT NULL THEN
6217 PA_SCHEDULE_UTILS.debug('v_c1.assignment_id = '|| v_c1.assignment_id);
6218 SELECT resource_id, start_date, end_date
6219 INTO l_resource_id, l_start_date, l_end_date
6220 FROM pa_project_assignments
6221 WHERE assignment_id = v_c1.assignment_id;
6222 PA_SCHEDULE_UTILS.debug('l_resource_id = '|| l_resource_id);
6223
6224 IF G_AVAILABILITY_CAL_PERIOD = 'DAILY' THEN
6225 select distinct fi.assignment_id,
6226 decode (mass.assignment_id, null, 'N', 'Y') intra_txn_conflict_flag
6227 BULK COLLECT INTO l_assignment_id_tbl, l_intra_txn_conflict_flag_tbl
6228 from pa_forecast_items fi, pa_mass_txn_asgmt_success_v mass, pa_schedules sch, pa_project_statuses a, pa_project_statuses b,
6229 (select resource_id,
6230 sum(item_quantity) total_assigned_quantity,
6231 item_date,
6232 delete_flag,
6233 forecast_item_type
6234 from
6235 (select resource_id,
6236 item_quantity,
6237 item_date,
6238 delete_flag,
6239 forecast_item_type
6240 from pa_forecast_items fi1, pa_schedules sch, pa_project_statuses a, pa_project_statuses b
6241 where (fi1.assignment_id in (select assignment_id from pa_mass_txn_asgmt_success_v where item_type = p_item_type and item_key = p_item_key) or asgmt_sys_status_code = 'STAFFED_ASGMT_CONF' )
6242 and fi1.assignment_id = sch.assignment_id
6243 and fi1.item_date between sch.start_date and sch.end_date
6244 and sch.status_code = a.project_status_code
6245 and a.wf_success_status_code = b.project_status_code
6246 and b.project_system_status_code = 'STAFFED_ASGMT_CONF'
6247 UNION ALL
6248 select resource_id,
6249 item_quantity,
6250 item_date,
6251 delete_flag,
6252 forecast_item_type
6253 from pa_forecast_items
6254 where asgmt_sys_status_code = 'STAFFED_ASGMT_CONF'
6255 and assignment_id not in (select assignment_id from pa_mass_txn_asgmt_success_v where item_type = p_item_type and item_key = p_item_key))
6256 group by resource_id, item_date, delete_flag, forecast_item_type
6257 )FI_ASSIGNED,
6258 (select resource_id,
6259 capacity_quantity,
6260 item_date,
6261 delete_flag
6262 from pa_forecast_items
6263 where forecast_item_type = 'U'
6264 )fi_capacity
6265 where fi.assignment_id <> v_c1.assignment_id
6266 and fi.resource_id = l_resource_id
6267 and fi.resource_id = fi_capacity.resource_id
6268 and fi_capacity.resource_id = fi_assigned.resource_id
6269 and fi.item_date BETWEEN l_start_date AND l_end_date
6270 and fi.item_date = fi_capacity.item_date
6271 and fi_capacity.item_date = fi_assigned.item_date
6272 and ((fi_capacity.capacity_quantity*(1+G_OVERCOMMITMENT_PERCENTAGE) - fi_assigned.total_assigned_quantity <= 0 and G_OVERCOMMITMENT_PERCENTAGE > 0)
6273 or (fi_capacity.capacity_quantity - fi_assigned.total_assigned_quantity < 0 and G_OVERCOMMITMENT_PERCENTAGE = 0))
6274 and fi.delete_flag = 'N'
6275 and fi.delete_flag = fi_capacity.delete_flag
6276 and fi_capacity.delete_flag = fi_assigned.delete_flag
6277 and fi.forecast_item_type = 'A'
6278 and fi.forecast_item_type = fi_assigned.forecast_item_type
6279 and fi.assignment_id = mass.assignment_id(+)
6280 and mass.item_type(+) = p_item_type
6281 and mass.item_key(+) = p_item_key
6282 and (fi.assignment_id in (select assignment_id from pa_mass_txn_asgmt_success_v where item_type = p_item_type and item_key = p_item_key) or fi.asgmt_sys_status_code = 'STAFFED_ASGMT_CONF')
6283 and fi.assignment_id = sch.assignment_id
6284 and fi.item_date between sch.start_date and sch.end_date
6285 and sch.status_code = a.project_status_code
6286 and a.wf_success_status_code = b.project_status_code
6287 and b.project_system_status_code = 'STAFFED_ASGMT_CONF';
6288
6289
6290 -- Check self conflict.
6291 check_self_conflict(p_assignment_id => v_c1.assignment_id,
6292 p_resource_id => l_resource_id,
6293 p_start_date => l_start_date,
6294 p_end_date => l_end_date,
6295 x_self_conflict_flag => l_self_conflict_flag,
6296 x_return_status => x_return_status,
6297 x_msg_count => x_msg_count,
6298 x_msg_data => x_msg_data);
6299
6300
6301 ELSIF G_AVAILABILITY_CAL_PERIOD = 'WEEKLY' THEN
6302 PA_SCHEDULE_UTILS.debug('Entering check_overcommitment_mult: WEEKLY');
6303
6304 select distinct fi.assignment_id,
6305 decode (mass.assignment_id, null, 'N', 'Y') intra_txn_flag
6306 BULK COLLECT INTO l_assignment_id_tbl, l_intra_txn_conflict_flag_tbl
6307 from pa_forecast_items fi, pa_mass_txn_asgmt_success_v mass, pa_schedules sch, pa_project_statuses a, pa_project_statuses b,
6308 (select resource_id,
6309 sum(item_quantity) total_assigned_quantity,
6310 GLOBAL_EXP_PERIOD_END_DATE,
6311 delete_flag,
6312 forecast_item_type
6313 from
6314 (select resource_id,
6315 item_quantity,
6316 GLOBAL_EXP_PERIOD_END_DATE,
6317 delete_flag,
6318 forecast_item_type
6319 from pa_forecast_items fi1, pa_schedules sch, pa_project_statuses a, pa_project_statuses b
6320 where (fi1.assignment_id in (select assignment_id from pa_mass_txn_asgmt_success_v where item_type = p_item_type and item_key = p_item_key) or asgmt_sys_status_code = 'STAFFED_ASGMT_CONF' )
6321 and fi1.item_date between l_start_date and l_end_date
6322 and fi1.assignment_id = sch.assignment_id
6323 and fi1.item_date between sch.start_date and sch.end_date
6324 and sch.status_code = a.project_status_code
6325 and a.wf_success_status_code = b.project_status_code
6326 and b.project_system_status_code = 'STAFFED_ASGMT_CONF'
6327 UNION ALL
6328 select resource_id,
6329 item_quantity,
6330 GLOBAL_EXP_PERIOD_END_DATE,
6331 delete_flag,
6332 forecast_item_type
6333 from pa_forecast_items
6334 where asgmt_sys_status_code = 'STAFFED_ASGMT_CONF'
6335 and item_date between l_start_date and l_end_date
6336 and assignment_id not in (select assignment_id from pa_mass_txn_asgmt_success_v where item_type = p_item_type and item_key = p_item_key))
6337 group by resource_id, GLOBAL_EXP_PERIOD_END_DATE, delete_flag, forecast_item_type
6338 )FI_ASSIGNED,
6339 (select resource_id,
6340 sum(capacity_quantity) capacity_quantity,
6341 GLOBAL_EXP_PERIOD_END_DATE,
6342 delete_flag
6343 from pa_forecast_items
6344 where forecast_item_type = 'U'
6345 group by resource_id, GLOBAL_EXP_PERIOD_END_DATE, delete_flag
6346 )fi_capacity
6347 where fi.assignment_id <> v_c1.assignment_id
6348 and fi.resource_id = l_resource_id
6349 and fi.resource_id = fi_capacity.resource_id
6350 and fi_capacity.resource_id = fi_assigned.resource_id
6351 and fi.item_date BETWEEN l_start_date AND l_end_date
6352 and fi.GLOBAL_EXP_PERIOD_END_DATE = fi_capacity.GLOBAL_EXP_PERIOD_END_DATE
6353 and fi_capacity.GLOBAL_EXP_PERIOD_END_DATE = fi_assigned.GLOBAL_EXP_PERIOD_END_DATE
6354 and ((fi_capacity.capacity_quantity*(1+G_OVERCOMMITMENT_PERCENTAGE) - fi_assigned.total_assigned_quantity <= 0 and G_OVERCOMMITMENT_PERCENTAGE > 0)
6355 or (fi_capacity.capacity_quantity - fi_assigned.total_assigned_quantity < 0 and G_OVERCOMMITMENT_PERCENTAGE = 0))
6356 and fi.delete_flag = 'N'
6357 and fi.delete_flag = fi_capacity.delete_flag
6358 and fi_capacity.delete_flag = fi_assigned.delete_flag
6359 and fi.forecast_item_type = 'A'
6360 and fi.forecast_item_type = fi_assigned.forecast_item_type
6361 and fi.assignment_id = mass.assignment_id(+)
6362 and mass.item_type(+) = p_item_type
6363 and mass.item_key(+) = p_item_key
6364 and (fi.assignment_id in (select assignment_id from pa_mass_txn_asgmt_success_v where item_type = p_item_type and item_key = p_item_key) or fi.asgmt_sys_status_code = 'STAFFED_ASGMT_CONF')
6365 and fi.assignment_id = sch.assignment_id
6366 and fi.item_date between sch.start_date and sch.end_date
6367 and sch.status_code = a.project_status_code
6368 and a.wf_success_status_code = b.project_status_code
6369 and b.project_system_status_code = 'STAFFED_ASGMT_CONF';
6370
6371
6372 PA_SCHEDULE_UTILS.debug('Before check_self_conflict');
6373
6374 -- Check self conflict.
6375 check_self_conflict(p_assignment_id => v_c1.assignment_id,
6376 p_resource_id => l_resource_id,
6377 p_start_date => l_start_date,
6378 p_end_date => l_end_date,
6379 x_self_conflict_flag => l_self_conflict_flag,
6380 x_return_status => x_return_status,
6381 x_msg_count => x_msg_count,
6382 x_msg_data => x_msg_data);
6383
6384 PA_SCHEDULE_UTILS.debug('After check_self_conflict');
6385
6386 END IF;
6387
6388 -- Insert the self conflicting assignment_id if applicable.
6389 IF l_self_conflict_flag = 'Y' THEN
6390 IF l_assignment_id_tbl.COUNT > 0 THEN
6391 l_assignment_id_tbl(l_assignment_id_tbl.LAST+1) := v_c1.assignment_id;
6392 l_intra_txn_conflict_flag_tbl.EXTEND;
6393 l_intra_txn_conflict_flag_tbl(l_intra_txn_conflict_flag_tbl.LAST) := 'N';
6394 ELSE
6395 select v_c1.assignment_id, 'N'
6396 bulk collect into l_assignment_id_tbl, l_intra_txn_conflict_flag_tbl
6397 from dual;
6398 -- l_assignment_id_tbl(1) := v_c1.assignment_id;
6399 -- l_intra_txn_conflict_flag_tbl(1) := 'N';
6400 END IF;
6401 END IF;
6402
6403 PA_SCHEDULE_UTILS.debug('Before insert_rows into conflict history');
6404 IF l_assignment_id_tbl.COUNT > 0 THEN
6405 PA_ASGN_CONFLICT_HIST_PKG.insert_rows(p_conflict_group_id => l_conflict_group_id,
6406 p_assignment_id => v_c1.assignment_id,
6407 p_conflict_assignment_id_tbl => l_assignment_id_tbl,
6408 p_resolve_conflict_action_code => p_resolve_conflict_action_code,
6409 p_intra_txn_conflict_flag_tbl => l_intra_txn_conflict_flag_tbl,
6410 p_processed_flag => 'N',
6411 --x_conflict_group_id => l_conflict_group_id, * commented for bug: 4537865
6412 x_conflict_group_id => l_new_conflict_group_id, -- added for bug fix: 4537865
6413 x_return_status => x_return_status,
6414 x_msg_count => x_msg_count,
6415 x_msg_data => x_msg_data);
6416
6417 -- added for bug fix: 4537865
6418 IF x_return_status = FND_API.G_RET_STS_SUCCESS THEN
6419 l_conflict_group_id := l_new_conflict_group_id;
6420 END IF;
6421 -- added for bug fix: 4537865
6422
6423 END IF;
6424 PA_SCHEDULE_UTILS.debug('After insert_rows into conflict history');
6425
6426 END IF;
6427 END LOOP;
6428
6429 IF l_conflict_group_id IS NOT NULL THEN
6430 x_overcommitment_flag := 'Y';
6431 x_conflict_group_id := l_conflict_group_id;
6432 ELSE
6433 x_overcommitment_flag := 'N';
6434 x_conflict_group_id := NULL;
6435 END IF;
6436
6437
6438 EXCEPTION
6439 WHEN OTHERS THEN
6440 x_overcommitment_flag := NULL ; -- 4537865
6441 x_conflict_group_id := NULL ;-- 4537865
6442 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
6443 x_msg_count := 1;
6444 x_msg_data := SQLERRM;
6445 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
6446 p_procedure_name => 'check_overcommitment_mult');
6447 RAISE;
6448 END check_overcommitment_mult;
6449
6450
6451 -- Procedure : check_self_conflict
6452 -- Purpose : Check if the assignment is causing self conflict.
6453 --
6454 PROCEDURE check_self_conflict(p_assignment_id IN NUMBER,
6455 p_resource_id IN NUMBER,
6456 p_start_date IN DATE,
6457 p_end_date IN DATE,
6458 x_self_conflict_flag OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
6459 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
6460 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
6461 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
6462 IS
6463
6464 G_AVAILABILITY_CAL_PERIOD VARCHAR2(15) := FND_PROFILE.VALUE('PA_AVAILABILITY_CAL_PERIOD');
6465 G_OVERCOMMITMENT_PERCENTAGE NUMBER := FND_NUMBER.CANONICAL_TO_NUMBER(FND_PROFILE.VALUE('PA_OVERCOMMITMENT_PERCENTAGE'))/100;
6466
6467 l_week_start_date DATE;
6468 l_week_end_date DATE;
6469
6470 -- Cursor for Daily.
6471 CURSOR c1 IS
6472 SELECT fi_assigned.item_quantity, fi_assigned.item_date from
6473 (select
6474 resource_id,
6475 item_quantity,
6476 item_date,
6477 asgmt_sys_status_code,
6478 delete_flag
6479 from pa_forecast_items fi, pa_schedules sch, pa_project_statuses a, pa_project_statuses b
6480 where fi.assignment_id = p_assignment_id
6481 and fi.assignment_id = sch.assignment_id
6482 and fi.item_date between sch.start_date and sch.end_date
6483 and forecast_item_type = 'A'
6484 and sch.status_code = a.project_status_code
6485 and a.wf_success_status_code = b.project_status_code
6486 and b.project_system_status_code = 'STAFFED_ASGMT_CONF'
6487 )fi_assigned,
6488 (select resource_id,
6489 capacity_quantity capacity_quantity,
6490 item_date,
6491 delete_flag
6492 from pa_forecast_items
6493 where forecast_item_type = 'U'
6494 )fi_capacity
6495 where fi_assigned.resource_id = p_resource_id
6496 and fi_assigned.resource_id = fi_capacity.resource_id
6497 and fi_assigned.item_date between p_start_date and p_end_date
6498 and fi_assigned.item_date = fi_capacity.item_date
6499 and ((fi_capacity.capacity_quantity*(1+G_OVERCOMMITMENT_PERCENTAGE) - fi_assigned.item_quantity <= 0 and G_OVERCOMMITMENT_PERCENTAGE > 0)
6500 or (fi_capacity.capacity_quantity - fi_assigned.item_quantity < 0 and G_OVERCOMMITMENT_PERCENTAGE = 0))
6501 and fi_assigned.delete_flag = 'N'
6502 and fi_assigned.delete_flag = fi_capacity.delete_flag;
6503
6504 -- Cursor for Weekly.
6505 CURSOR c2 IS
6506 SELECT fi_assigned.weekly_quantity, fi_assigned.week_end_date
6507 from
6508 (select resource_id,
6509 sum(item_quantity) weekly_quantity,
6510 GLOBAL_EXP_PERIOD_END_DATE week_end_date,
6511 delete_flag
6512 from pa_forecast_items fi, pa_schedules sch, pa_project_statuses a, pa_project_statuses b
6513 where fi.assignment_id = p_assignment_id
6514 and fi.assignment_id = sch.assignment_id
6515 and item_date between l_week_start_date and l_week_end_date
6516 and item_date between sch.start_date and sch.end_date
6517 and forecast_item_type = 'A'
6518 and sch.status_code = a.project_status_code
6519 and a.wf_success_status_code = b.project_status_code
6520 and b.project_system_status_code = 'STAFFED_ASGMT_CONF'
6521 group by resource_id, GLOBAL_EXP_PERIOD_END_DATE, delete_flag
6522 )fi_assigned,
6523 (select resource_id,
6524 sum(capacity_quantity) capacity_quantity,
6525 GLOBAL_EXP_PERIOD_END_DATE week_end_date,
6526 delete_flag
6527 from pa_forecast_items
6528 where forecast_item_type = 'U'
6529 and item_date between l_week_start_date and l_week_end_date
6530 group by resource_id, GLOBAL_EXP_PERIOD_END_DATE, delete_flag
6531 )fi_capacity
6532 where fi_assigned.resource_id = p_resource_id
6533 and fi_assigned.resource_id = fi_capacity.resource_id
6534 and fi_assigned.week_end_date = fi_capacity.week_end_date
6535 and ((fi_capacity.capacity_quantity*(1+G_OVERCOMMITMENT_PERCENTAGE) - fi_assigned.weekly_quantity <= 0 and G_OVERCOMMITMENT_PERCENTAGE > 0)
6536 or (fi_capacity.capacity_quantity - fi_assigned.weekly_quantity < 0 and G_OVERCOMMITMENT_PERCENTAGE = 0))
6537 and fi_assigned.delete_flag = 'N'
6538 and fi_assigned.delete_flag = fi_capacity.delete_flag;
6539
6540 v_c1 c1%ROWTYPE;
6541 v_c2 c2%ROWTYPE;
6542
6543 BEGIN
6544 x_return_status := FND_API.G_RET_STS_SUCCESS;
6545
6546 IF G_AVAILABILITY_CAL_PERIOD = 'DAILY' THEN
6547 OPEN c1;
6548 FETCH c1 INTO v_c1;
6549 IF c1%NOTFOUND THEN
6550 x_self_conflict_flag := 'N';
6551 ELSE
6552 x_self_conflict_flag := 'Y';
6553 END IF;
6554 CLOSE c1;
6555 PA_SCHEDULE_UTILS.debug('daily: x_self_conflict_flag = ' || x_self_conflict_flag);
6556 ELSIF G_AVAILABILITY_CAL_PERIOD = 'WEEKLY' THEN
6557 -- Bug 2288823: check_self_conflict for the period from the week start date of
6558 -- p_start_date and the week end date of p_end_date for WEEKLY profile.
6559 l_week_start_date := PA_TIMELINE_UTIL.get_week_end_date(p_org_id => NULL,
6560 p_given_date => p_start_date) - 6;
6561 l_week_end_date := PA_TIMELINE_UTIL.get_week_end_date(p_org_id => NULL,
6562 p_given_date => p_end_date);
6563 OPEN c2;
6564 FETCH c2 INTO v_c2;
6565 IF c2%NOTFOUND THEN
6566 x_self_conflict_flag := 'N';
6567 ELSE
6568 x_self_conflict_flag := 'Y';
6569 END IF;
6570 CLOSE c2;
6571 PA_SCHEDULE_UTILS.debug('weekly: x_self_conflict_flag = ' || x_self_conflict_flag);
6572 END IF;
6573
6574
6575 EXCEPTION
6576 WHEN OTHERS THEN
6577 x_self_conflict_flag := NULL ; -- 4537865
6578 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
6579 x_msg_count := 1;
6580 x_msg_data := SQLERRM;
6581 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
6582 p_procedure_name => 'check_self_conflict');
6583 RAISE;
6584 END check_self_conflict;
6585
6586
6587 -- Procedure : resolve_conflicts
6588 -- Purpose : Resolves remaining conflicts by taking action chosen to user
6589 -- detailed in PA_ASSIGNMENT_CONFLICT_HIST. Updates
6590 -- processed_flag in the table once complete.
6591 PROCEDURE resolve_conflicts( p_conflict_group_id IN NUMBER,
6592 p_assignment_id IN NUMBER,
6593 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
6594 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
6595 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
6596 IS
6597
6598 G_AVAILABILITY_CAL_PERIOD VARCHAR2(15) := FND_PROFILE.VALUE('PA_AVAILABILITY_CAL_PERIOD');
6599 G_OVERCOMMITMENT_PERCENTAGE NUMBER := FND_NUMBER.CANONICAL_TO_NUMBER(FND_PROFILE.VALUE('PA_OVERCOMMITMENT_PERCENTAGE'))/100;
6600
6601 -- Cursor c1 is used to resolve_conflicts_action_code.
6602 CURSOR c1 IS
6603 SELECT DISTINCT resolve_conflicts_action_code
6604 FROM pa_assignment_conflict_hist
6605 WHERE conflict_group_id = p_conflict_group_id
6606 AND assignment_id = p_assignment_id
6607 AND processed_flag = 'N';
6608
6609 v_c1 c1%ROWTYPE;
6610
6611 -- Cursor c3 is used to retrieve all the conflicting assignments and also
6612 -- check if they are locked in another mass wf process.
6613 CURSOR c3 IS
6614 SELECT conflict_assignment_id,
6615 decode(asgn.MASS_WF_IN_PROGRESS_FLAG,
6616 'Y', decode(hist.intra_txn_conflict_flag, 'N', 'Y', 'N'),
6617 decode(asgn.apprvl_status_code, 'ASGMT_APPRVL_SUBMITTED', 'Y', 'N')) locking_flag
6618 FROM pa_assignment_conflict_hist hist, pa_project_assignments asgn
6619 WHERE hist.conflict_assignment_id = asgn.assignment_id
6620 AND hist.conflict_group_id = p_conflict_group_id
6621 AND hist.assignment_id = p_assignment_id
6622 AND hist.processed_flag = 'N'
6623 AND hist.resolve_conflicts_action_code = 'REMOVE_CONFLICTS'
6624 AND hist.self_conflict_flag = 'N';
6625
6626 -- Parameters for the causing assignment.
6627 l_resource_id NUMBER;
6628 l_asn_start_date DATE;
6629 l_asn_end_date DATE;
6630 l_resolve_conflict_action_code VARCHAR2(30);
6631
6632 -- Parameters for the conflicting assignment used to call
6633 -- PA_SCHEDULE_PUB.change_work_pattern.
6634 l_record_version_number NUMBER;
6635 l_project_id NUMBER;
6636 l_calendar_id NUMBER;
6637 l_assignment_type pa_project_assignments.assignment_type%TYPE;
6638 l_start_date DATE;
6639 l_end_date DATE;
6640 l_asgn_start_date DATE;
6641 l_asgn_end_date DATE;
6642
6643 -- The start date and end date of an assignment causing conflicts.
6644 l_conflict_start_date DATE;
6645 l_conflict_end_date DATE;
6646
6647 -- Parameters used to contruct the work pattern record table.
6648 l_count NUMBER;
6649 l_flag VARCHAR2(1);
6650 l_cur_assignment_id NUMBER;
6651 l_cur_item_date DATE;
6652 l_cur_week_end_date DATE;
6653 l_cur_overcom_quantity NUMBER;
6654 l_assignment_id_tbl PA_PLSQL_DATATYPES.IdTabTyp;
6655 l_item_date_tbl PA_PLSQL_DATATYPES.DateTabTyp;
6656 l_week_end_date_tbl PA_PLSQL_DATATYPES.DateTabTyp;
6657 l_item_quantity_tbl PA_PLSQL_DATATYPES.NumTabTyp;
6658 l_overcom_quantity_tbl PA_PLSQL_DATATYPES.NumTabTyp;
6659 l_work_pattern_tbl WorkPatternTabTyp;
6660 l_cur_work_pattern_tbl WorkPatternTabTyp;
6661
6662 l_msg_index_out NUMBER;
6663 -- added for Bug fix: 4537865
6664 l_new_msg_data VARCHAR2(2000);
6665 -- added for Bug fix: 4537865
6666
6667 BEGIN
6668 x_return_status := FND_API.G_RET_STS_SUCCESS;
6669
6670 PA_SCHEDULE_UTILS.debug('p_conflict_group_id = ' || p_conflict_group_id);
6671
6672 OPEN c1;
6673 FETCH c1 INTO v_c1;
6674 IF c1%NOTFOUND THEN
6675 l_resolve_conflict_action_code := 'NO_DATA_FOUND';
6676 ELSE
6677 l_resolve_conflict_action_code := v_c1.resolve_conflicts_action_code;
6678 END IF;
6679 CLOSE c1;
6680
6681 PA_SCHEDULE_UTILS.debug('l_resolve_conflict_action_code = ' || l_resolve_conflict_action_code);
6682
6683 -- Processing for action code 'KEEP_CONFLICTS'
6684 IF l_resolve_conflict_action_code = 'KEEP_CONFLICTS' THEN
6685 PA_ASGN_CONFLICT_HIST_PKG.update_rows(p_conflict_group_id => p_conflict_group_id,
6686 p_assignment_id => p_assignment_id,
6687 p_processed_flag => 'Y',
6688 x_return_status => x_return_status,
6689 x_msg_count => x_msg_count,
6690 x_msg_data => x_msg_data);
6691
6692 ELSIF l_resolve_conflict_action_code = 'REMOVE_CONFLICTS' THEN
6693 -- Check if any conflicting assignments are locked in another mass wf
6694 -- process. If yes, return status 'E', populate the error stack with the
6695 -- error message.
6696 FOR v_c3 IN c3 LOOP
6697 IF v_c3.locking_flag = 'Y' THEN
6698 pa_schedule_utils.log_message(1, 'Remove conflicts failed due to assignments locking');
6699 RAISE l_remove_conflicts_failed;
6700 END IF;
6701 END LOOP;
6702
6703 SELECT resource_id, start_date, end_date
6704 INTO l_resource_id, l_asn_start_date, l_asn_end_date
6705 FROM pa_project_assignments
6706 WHERE assignment_id = p_assignment_id;
6707
6708 IF G_AVAILABILITY_CAL_PERIOD = 'DAILY' THEN
6709 l_conflict_start_date := l_asn_start_date;
6710 l_conflict_end_date := l_asn_end_date;
6711
6712 SELECT DISTINCT conf.conflict_assignment_id,
6713 fi.item_date,
6714 fi.GLOBAL_EXP_PERIOD_END_DATE,
6715 fi.item_quantity,
6716 fi_overcom.overcommitment_quantity
6717 BULK COLLECT INTO l_assignment_id_tbl, l_item_date_tbl, l_week_end_date_tbl, l_item_quantity_tbl, l_overcom_quantity_tbl
6718 FROM pa_forecast_items fi,
6719 pa_assignment_conflict_hist conf,
6720 (SELECT
6721 resource_id,
6722 item_date,
6723 DECODE(sign(capacity_quantity*G_OVERCOMMITMENT_PERCENTAGE-overcommitment_quantity), 1, 0, overcommitment_quantity) overcommitment_quantity,
6724 delete_flag
6725 FROM pa_forecast_items
6726 WHERE forecast_item_type = 'U'
6727 ) fi_overcom
6728 WHERE fi.resource_id = l_resource_id
6729 AND fi.resource_id = fi_overcom.resource_id
6730 AND fi.item_date between l_conflict_start_date AND l_conflict_end_date
6731 AND fi.item_date = fi_overcom.item_date
6732 AND fi.delete_flag = 'N'
6733 AND fi.delete_flag = fi_overcom.delete_flag
6734 AND fi.forecast_item_type = 'A'
6735 AND fi.assignment_id = conf.conflict_assignment_id
6736 AND conf.assignment_id = p_assignment_id
6737 AND conf.conflict_group_id = p_conflict_group_id
6738 AND conf.resolve_conflicts_action_code = 'REMOVE_CONFLICTS'
6739 AND conf.self_conflict_flag = 'N'
6740 AND fi_overcom.overcommitment_quantity > 0
6741 ORDER BY fi.item_date, fi.item_quantity asc;
6742
6743 ELSIF G_AVAILABILITY_CAL_PERIOD = 'WEEKLY' THEN
6744 l_conflict_start_date := l_asn_start_date;
6745 l_conflict_end_date := l_asn_end_date;
6746 SELECT DISTINCT fi.assignment_id,
6747 fi.item_date,
6748 fi.GLOBAL_EXP_PERIOD_END_DATE,
6749 fi.item_quantity,
6750 fi_overcom.overcommitment_quantity
6751 BULK COLLECT INTO l_assignment_id_tbl, l_item_date_tbl, l_week_end_date_tbl, l_item_quantity_tbl, l_overcom_quantity_tbl
6752 FROM pa_forecast_items fi, pa_assignment_conflict_hist conf,
6753 (SELECT
6754 resource_id,
6755 overcommitment_quantity,
6756 item_date,
6757 delete_flag
6758 from pa_forecast_items
6759 where forecast_item_type = 'U'
6760 )fi_overcom,
6761 (SELECT
6762 resource_id,
6763 GLOBAL_EXP_PERIOD_END_DATE week_end_date,
6764 decode(sign(sum(capacity_quantity)*G_OVERCOMMITMENT_PERCENTAGE-sum(overcommitment_quantity)), 1, 0, sum(overcommitment_quantity)) overcommitment_quantity,
6765 delete_flag
6766 FROM pa_forecast_items
6767 WHERE forecast_item_type = 'U'
6768 AND item_date BETWEEN l_conflict_start_date AND l_conflict_end_date
6769 GROUP BY resource_id, GLOBAL_EXP_PERIOD_END_DATE, delete_flag
6770 ) fi_week
6771 WHERE fi.resource_id = l_resource_id
6772 AND fi.resource_id = fi_overcom.resource_id
6773 AND fi_overcom.resource_id = fi_week.resource_id
6774 AND fi.item_date BETWEEN l_conflict_start_date AND l_conflict_end_date
6775 AND fi.item_date = fi_overcom.item_date
6776 AND fi.GLOBAL_EXP_PERIOD_END_DATE = fi_week.week_end_date
6777 AND fi.delete_flag = 'N'
6778 AND fi.delete_flag = fi_overcom.delete_flag
6779 AND fi_overcom.delete_flag = fi_week.delete_flag
6780 AND fi.forecast_item_type = 'A'
6781 AND fi.assignment_id = conf.conflict_assignment_id
6782 AND conf.assignment_id = p_assignment_id
6783 AND conf.conflict_group_id = p_conflict_group_id
6784 AND conf.resolve_conflicts_action_code = 'REMOVE_CONFLICTS'
6785 AND conf.self_conflict_flag = 'N'
6786 AND fi_week.overcommitment_quantity > 0
6787 ORDER BY fi.item_date, fi.item_quantity asc;
6788
6789
6790 END IF;
6791
6792 IF l_assignment_id_tbl.COUNT > 0 THEN
6793 l_count := 0;
6794 l_cur_item_date := l_item_date_tbl(l_item_date_tbl.FIRST)-1;
6795 --PA_SCHEDULE_UTILS.debug ('l_cur_item_date = '|| l_cur_item_date);
6796 l_cur_week_end_date := l_week_end_date_tbl(l_week_end_date_tbl.FIRST);
6797 --PA_SCHEDULE_UTILS.debug ('l_cur_week_end_date = '|| l_cur_week_end_date);
6798
6799 FOR j IN l_assignment_id_tbl.FIRST .. l_assignment_id_tbl.LAST LOOP
6800 --PA_SCHEDULE_UTILS.debug ('Entering l_assignment_id_tbl LOOP');
6801 --PA_SCHEDULE_UTILS.debug ('j = ' || j);
6802
6803 -- When starting a new week.
6804 IF l_week_end_date_tbl(j) <> l_cur_week_end_date AND l_cur_work_pattern_tbl.COUNT > 0 THEN
6805 --PA_SCHEDULE_UTILS.debug('New week: l_week_end_date_tbl(j) = '||l_week_end_date_tbl(j));
6806 l_cur_week_end_date := l_week_end_date_tbl(j);
6807 -- Insert l_cur_work_pattern_tbl into l_work_pattern_tbl
6808 insert_work_pattern_tab(p_cur_work_pattern_tbl => l_cur_work_pattern_tbl,
6809 x_work_pattern_tbl => l_work_pattern_tbl,
6810 x_return_status => x_return_status,
6811 x_msg_count => x_msg_count,
6812 x_msg_data => x_msg_data);
6813 --empty l_cur_work_pattern_tbl
6814 l_cur_work_pattern_tbl.DELETE;
6815
6816 END IF;
6817
6818 -- When starting a new item_date.
6819 IF l_item_date_tbl(j) <> l_cur_item_date THEN
6820 --PA_SCHEDULE_UTILS.debug('New item date: l_item_date_tbl(j) = '||l_item_date_tbl(j));
6821 -- Remove the overcommitment quantity for all the assignments
6822 -- on the current item date.
6823 IF l_count > 0 THEN
6824 update_work_pattern_record(p_overcom_quantity => l_cur_overcom_quantity,
6825 p_count => l_count,
6826 p_item_date => l_cur_item_date,
6827 x_work_pattern_tbl => l_cur_work_pattern_tbl,
6828 x_return_status => x_return_status,
6829 x_msg_count => x_msg_count,
6830 x_msg_data => x_msg_data);
6831 END IF;
6832
6833 -- Start counting for a new item date.
6834 l_count := 1;
6835 l_cur_item_date := l_item_date_tbl(j);
6836 l_cur_assignment_id := l_assignment_id_tbl(j);
6837 l_cur_overcom_quantity := l_overcom_quantity_tbl(j);
6838
6839 insert_work_pattern_record(p_assignment_id => l_assignment_id_tbl(j),
6840 p_item_quantity => l_item_quantity_tbl(j),
6841 p_item_date => l_item_date_tbl(j),
6842 p_week_end_date => l_week_end_date_tbl(j),
6843 x_work_pattern_tbl => l_cur_work_pattern_tbl,
6844 x_return_status => x_return_status,
6845 x_msg_count => x_msg_count,
6846 x_msg_data => x_msg_data);
6847
6848 -- When starting a new assignment on the same item_date.
6849 ELSIF l_item_date_tbl(j) = l_cur_item_date AND l_assignment_id_tbl(j) <> l_cur_assignment_id THEN
6850 --PA_SCHEDULE_UTILS.debug('New assignment: l_assignment_id_tbl(j) = '||l_assignment_id_tbl(j));
6851 l_count := l_count +1;
6852 insert_work_pattern_record(p_assignment_id => l_assignment_id_tbl(j),
6853 p_item_quantity => l_item_quantity_tbl(j),
6854 p_item_date => l_item_date_tbl(j),
6855 p_week_end_date => l_week_end_date_tbl(j),
6856 x_work_pattern_tbl => l_cur_work_pattern_tbl,
6857 x_return_status => x_return_status,
6858 x_msg_count => x_msg_count,
6859 x_msg_data => x_msg_data);
6860
6861 END IF;
6862
6863 -- Update work pattern for the last day in the current week.
6864 IF (j <> l_assignment_id_tbl.LAST AND l_week_end_date_tbl(j+1) <> l_cur_week_end_date) OR j = l_assignment_id_tbl.LAST THEN
6865 update_work_pattern_record(p_overcom_quantity => l_cur_overcom_quantity,
6866 p_count => l_count,
6867 p_item_date => l_cur_item_date,
6868 x_work_pattern_tbl => l_cur_work_pattern_tbl,
6869 x_return_status => x_return_status,
6870 x_msg_count => x_msg_count,
6871 x_msg_data => x_msg_data);
6872 END IF;
6873
6874
6875 -- Insert the current work pattern record into l_work_pattern_tbl for the last
6876 -- week of the l_assignment_id_tbl loop.
6877 IF j = l_assignment_id_tbl.LAST THEN
6878 -- Insert l_cur_work_pattern_tbl into l_work_pattern_tbl
6879 insert_work_pattern_tab(p_cur_work_pattern_tbl => l_cur_work_pattern_tbl,
6880 x_work_pattern_tbl => l_work_pattern_tbl,
6881 x_return_status => x_return_status,
6882 x_msg_count => x_msg_count,
6883 x_msg_data => x_msg_data);
6884 --empty l_cur_work_pattern_tbl
6885 l_cur_work_pattern_tbl.DELETE;
6886 END IF;
6887
6888 END LOOP;
6889
6890
6891 -- Update schedules for those conflicting assignments based on the work
6892 -- pattern information stored in l_work_pattern_tbl.
6893 FOR v_c3 IN c3 LOOP
6894 PA_SCHEDULE_UTILS.debug ('Entering c3 loop');
6895 -- 2167889: null instead of record_version_number
6896 SELECT null, project_id, calendar_id, assignment_type,start_date, end_date
6897 INTO l_record_version_number, l_project_id, l_calendar_id, l_assignment_type, l_asgn_start_date, l_asgn_end_date
6898 FROM pa_project_assignments
6899 WHERE assignment_id = v_c3.conflict_assignment_id;
6900 PA_SCHEDULE_UTILS.debug ('l_work_pattern_tbl.COUNT = '|| l_work_pattern_tbl.COUNT);
6901 FOR i IN l_work_pattern_tbl.FIRST .. l_work_pattern_tbl.LAST LOOP
6902 IF l_work_pattern_tbl(i).assignment_id = v_c3.conflict_assignment_id THEN
6903
6904 -- Calculate the start_date and end_date for the updating period.
6905 -- Bug 2146377: Added start_date/end_date constraint so that the updating
6906 -- period is always within the conflict_start_date and conflict_end_date.
6907 -- Also, it is always within the asgn_start_date and asgn_end_date.
6908 l_start_date := l_work_pattern_tbl(i).start_date;
6909 l_end_date := l_work_pattern_tbl(i).end_date;
6910 IF trunc(l_start_date) < trunc(l_conflict_start_date)
6911 OR trunc(l_start_date) < trunc(l_asgn_start_date) THEN
6912 IF trunc(l_conflict_start_date) < trunc(l_asgn_start_date) THEN
6913 l_start_date := l_asgn_start_date;
6914 ELSE
6915 l_start_date := l_conflict_start_date;
6916 END IF;
6917 END IF;
6918 IF trunc(l_end_date) > trunc(l_conflict_end_date)
6919 OR trunc(l_end_date) > trunc(l_asgn_end_date) THEN
6920 IF trunc(l_conflict_end_date) > trunc(l_asgn_end_date) THEN
6921 l_end_date := l_asgn_end_date;
6922 ELSE
6923 l_end_date := l_conflict_end_date;
6924 END IF;
6925 END IF;
6926 PA_SCHEDULE_UTILS.debug('Before Change Work Pattern');
6927 PA_SCHEDULE_UTILS.debug('l_start_date = '|| l_start_date);
6928 PA_SCHEDULE_UTILS.debug('l_end_date = '|| l_end_date);
6929
6930 IF l_work_pattern_tbl(i).monday_hours = -99 THEN
6931 l_work_pattern_tbl(i).monday_hours := NULL;
6932 END IF;
6933 IF l_work_pattern_tbl(i).tuesday_hours = -99 THEN
6934 l_work_pattern_tbl(i).tuesday_hours := NULL;
6935 END IF;
6936 IF l_work_pattern_tbl(i).wednesday_hours = -99 THEN
6937 l_work_pattern_tbl(i).wednesday_hours := NULL;
6938 END IF;
6939 IF l_work_pattern_tbl(i).thursday_hours = -99 THEN
6940 l_work_pattern_tbl(i).thursday_hours := NULL;
6941 END IF;
6942 IF l_work_pattern_tbl(i).friday_hours = -99 THEN
6943 l_work_pattern_tbl(i).friday_hours := NULL;
6944 END IF;
6945 IF l_work_pattern_tbl(i).saturday_hours = -99 THEN
6946 l_work_pattern_tbl(i).saturday_hours := NULL;
6947 END IF;
6948 IF l_work_pattern_tbl(i).sunday_hours = -99 THEN
6949 l_work_pattern_tbl(i).sunday_hours := NULL;
6950 END IF;
6951
6952 PA_SCHEDULE_UTILS.debug('work_pattern = '||
6953 l_work_pattern_tbl(i).monday_hours||';'||
6954 l_work_pattern_tbl(i).tuesday_hours||';'||
6955 l_work_pattern_tbl(i).wednesday_hours||';'||
6956 l_work_pattern_tbl(i).thursday_hours||';'||
6957 l_work_pattern_tbl(i).friday_hours||';'||
6958 l_work_pattern_tbl(i).saturday_hours||';'||
6959 l_work_pattern_tbl(i).sunday_hours);
6960
6961 PA_SCHEDULE_PUB.change_work_pattern(
6962 p_record_version_number => l_record_version_number,
6963 p_project_id => l_project_id,
6964 p_calendar_id => l_calendar_id,
6965 p_assignment_id => v_c3.conflict_assignment_id,
6966 p_assignment_type => l_assignment_type,
6967 p_start_date => l_start_date,
6968 p_end_date => l_end_date,
6969 p_monday_hours => l_work_pattern_tbl(i).monday_hours,
6970 p_tuesday_hours => l_work_pattern_tbl(i).tuesday_hours,
6971 p_wednesday_hours => l_work_pattern_tbl(i).wednesday_hours,
6972 p_thursday_hours => l_work_pattern_tbl(i).thursday_hours,
6973 p_friday_hours => l_work_pattern_tbl(i).friday_hours,
6974 p_saturday_hours => l_work_pattern_tbl(i).saturday_hours,
6975 p_sunday_hours => l_work_pattern_tbl(i).sunday_hours,
6976 p_asgn_start_date => l_asgn_start_date,
6977 p_asgn_end_date => l_asgn_end_date,
6978 p_remove_conflict_flag => 'Y',
6979 x_return_status => x_return_status,
6980 x_msg_count => x_msg_count,
6981 x_msg_data => x_msg_data );
6982
6983 PA_SCHEDULE_UTILS.debug('After Change Work Pattern');
6984 END IF;
6985 END LOOP;
6986
6987 -- Update pa_assignment_conflict_hist table.
6988 IF x_return_status = FND_API.G_RET_STS_SUCCESS THEN
6989 PA_ASGN_CONFLICT_HIST_PKG.update_rows(p_conflict_group_id => p_conflict_group_id,
6990 p_assignment_id => p_assignment_id,
6991 p_processed_flag => 'Y',
6992 x_return_status => x_return_status,
6993 x_msg_count => x_msg_count,
6994 x_msg_data => x_msg_data);
6995 END IF;
6996
6997 END LOOP;
6998 END IF;
6999
7000 END IF;
7001
7002 EXCEPTION
7003 WHEN l_remove_conflicts_failed THEN
7004 PA_UTILS.add_message('PA','PA_REMOVE_CONFLICTS_FAILED');
7005 x_return_status := FND_API.G_RET_STS_ERROR;
7006 x_msg_data := 'PA_REMOVE_CONFLICTS_FAILED';
7007 x_msg_count := FND_MSG_PUB.Count_Msg;
7008 IF x_msg_count = 1 THEN
7009 pa_interface_utils_pub.get_messages
7010 (p_encoded => FND_API.G_TRUE,
7011 p_msg_index => 1,
7012 p_msg_count => x_msg_count,
7013 p_msg_data => x_msg_data,
7014 --p_data => x_msg_data, * Commented for Bug fix: 4537865
7015 p_data => l_new_msg_data, -- added for Bug fix: 4537865
7016 p_msg_index_out => l_msg_index_out );
7017 -- added for Bug fix: 4537865
7018 x_msg_data := l_new_msg_data;
7019 -- added for Bug fix: 4537865
7020 End IF;
7021 WHEN OTHERS THEN
7022 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7023 x_msg_count := 1;
7024 x_msg_data := SQLERRM;
7025 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7026 p_procedure_name => 'resolve_conflicts');
7027 RAISE;
7028 END resolve_conflicts;
7029
7030
7031 PROCEDURE insert_work_pattern_record( p_assignment_id IN NUMBER,
7032 p_item_quantity IN NUMBER,
7033 p_item_date IN DATE,
7034 p_week_end_date IN DATE,
7035 x_work_pattern_tbl IN OUT NOCOPY WorkPatternTabTyp,
7036 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7037 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7038 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7039
7040 IS
7041
7042 l_count NUMBER :=0;
7043 l_flag VARCHAR(2) := 'N';
7044 l_week_day VARCHAR2(15);
7045
7046 BEGIN
7047
7048 FOR j IN 1 .. x_work_pattern_tbl.COUNT LOOP
7049 IF x_work_pattern_tbl(j).assignment_id = p_assignment_id THEN
7050 l_count := j;
7051 l_flag := 'Y';
7052 EXIT;
7053 END IF;
7054 END LOOP;
7055
7056 IF l_flag = 'N' THEN
7057 l_count := x_work_pattern_tbl.COUNT +1;
7058 x_work_pattern_tbl(l_count).assignment_id := p_assignment_id;
7059 x_work_pattern_tbl(l_count).start_date := p_week_end_date -6;
7060 x_work_pattern_tbl(l_count).end_date := p_week_end_date;
7061 x_work_pattern_tbl(l_count).monday_hours := -99;
7062 x_work_pattern_tbl(l_count).tuesday_hours := -99;
7063 x_work_pattern_tbl(l_count).wednesday_hours :=-99;
7064 x_work_pattern_tbl(l_count).thursday_hours :=-99;
7065 x_work_pattern_tbl(l_count).friday_hours :=-99;
7066 x_work_pattern_tbl(l_count).saturday_hours := -99;
7067 x_work_pattern_tbl(l_count).sunday_hours :=-99;
7068 END IF;
7069
7070 l_week_day := TO_CHAR(p_item_date, 'DY', 'NLS_DATE_LANGUAGE=AMERICAN');
7071
7072 IF l_week_day = 'MON' THEN
7073 x_work_pattern_tbl(l_count).monday_hours := p_item_quantity;
7074 ELSIF l_week_day = 'TUE' THEN
7075 x_work_pattern_tbl(l_count).tuesday_hours := p_item_quantity;
7076 ELSIF l_week_day = 'WED' THEN
7077 x_work_pattern_tbl(l_count).wednesday_hours := p_item_quantity;
7078 ELSIF l_week_day = 'THU' THEN
7079 x_work_pattern_tbl(l_count).thursday_hours := p_item_quantity;
7080 ELSIF l_week_day = 'FRI' THEN
7081 x_work_pattern_tbl(l_count).friday_hours := p_item_quantity;
7082 ELSIF l_week_day = 'SAT' THEN
7083 x_work_pattern_tbl(l_count).saturday_hours := p_item_quantity;
7084 ELSIF l_week_day = 'SUN' THEN
7085 x_work_pattern_tbl(l_count).sunday_hours := p_item_quantity;
7086 END IF;
7087
7088 PA_SCHEDULE_UTILS.debug('After insert_work_pattern_record: work_pattern = '||
7089 x_work_pattern_tbl(l_count).monday_hours||';'||
7090 x_work_pattern_tbl(l_count).tuesday_hours||';'||
7091 x_work_pattern_tbl(l_count).wednesday_hours||';'||
7092 x_work_pattern_tbl(l_count).thursday_hours||';'||
7093 x_work_pattern_tbl(l_count).friday_hours||';'||
7094 x_work_pattern_tbl(l_count).saturday_hours||';'||
7095 x_work_pattern_tbl(l_count).sunday_hours);
7096
7097 x_return_status := FND_API.G_RET_STS_SUCCESS;
7098 EXCEPTION
7099 WHEN OTHERS THEN
7100 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7101 x_msg_count := 1;
7102 x_msg_data := SQLERRM;
7103 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7104 p_procedure_name => 'insert_work_pattern_record');
7105 RAISE;
7106
7107 END insert_work_pattern_record;
7108
7109
7110 PROCEDURE update_work_pattern_record(p_overcom_quantity IN NUMBER,
7111 p_count IN NUMBER,
7112 p_item_date IN DATE,
7113 x_work_pattern_tbl IN OUT NOCOPY WorkPatternTabTyp,
7114 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7115 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7116 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7117
7118 IS
7119 l_week_day VARCHAR2(15);
7120 l_remove_quantity NUMBER;
7121 l_overcom_quantity NUMBER;
7122 l_count NUMBER;
7123
7124 BEGIN
7125 x_return_status := FND_API.G_RET_STS_SUCCESS;
7126
7127 IF x_work_pattern_tbl.COUNT > 0 THEN
7128
7129 l_week_day := TO_CHAR(p_item_date, 'DY', 'NLS_DATE_LANGUAGE=AMERICAN');
7130 l_overcom_quantity := p_overcom_quantity;
7131 l_remove_quantity := ROUND(p_overcom_quantity / p_count, 2);
7132
7133 FOR j IN x_work_pattern_tbl.FIRST .. x_work_pattern_tbl.LAST LOOP
7134
7135 IF l_week_day = 'MON' THEN
7136 IF (x_work_pattern_tbl(j).monday_hours - l_remove_quantity)>=0 THEN
7137 x_work_pattern_tbl(j).monday_hours := x_work_pattern_tbl(j).monday_hours - l_remove_quantity;
7138 ELSIF x_work_pattern_tbl(j).monday_hours > 0 THEN
7139 l_overcom_quantity := l_overcom_quantity - x_work_pattern_tbl(j).monday_hours;
7140 l_count := l_count -1;
7141 l_remove_quantity := ROUND(l_overcom_quantity/l_count, 2);
7142 x_work_pattern_tbl(j).monday_hours := 0;
7143 END IF;
7144 ELSIF l_week_day = 'TUE' THEN
7145 IF (x_work_pattern_tbl(j).tuesday_hours - l_remove_quantity)>=0 THEN
7146 x_work_pattern_tbl(j).tuesday_hours := x_work_pattern_tbl(j).tuesday_hours - l_remove_quantity;
7147 ELSIF x_work_pattern_tbl(j).tuesday_hours > 0 THEN
7148 l_overcom_quantity := l_overcom_quantity - x_work_pattern_tbl(j).tuesday_hours;
7149 l_count := l_count -1;
7150 l_remove_quantity := ROUND(l_overcom_quantity/l_count, 2);
7151 x_work_pattern_tbl(j).tuesday_hours :=0;
7152 END IF;
7153 ELSIF l_week_day = 'WED' THEN
7154 IF (x_work_pattern_tbl(j).wednesday_hours - l_remove_quantity)>=0 THEN
7155 x_work_pattern_tbl(j).wednesday_hours:= x_work_pattern_tbl(j).wednesday_hours - l_remove_quantity;
7156 ELSIF x_work_pattern_tbl(j).wednesday_hours > 0 THEN
7157 l_overcom_quantity := l_overcom_quantity - x_work_pattern_tbl(j).wednesday_hours;
7158 l_count := l_count -1;
7159 l_remove_quantity := ROUND(l_overcom_quantity/l_count, 2);
7160 x_work_pattern_tbl(j).wednesday_hours :=0;
7161 END IF;
7162 ELSIF l_week_day = 'THU' THEN
7163 IF (x_work_pattern_tbl(j).thursday_hours - l_remove_quantity)>=0 THEN
7164 x_work_pattern_tbl(j).thursday_hours:= x_work_pattern_tbl(j).thursday_hours - l_remove_quantity;
7165 ELSIF x_work_pattern_tbl(j).thursday_hours > 0 THEN
7166 l_overcom_quantity := l_overcom_quantity - x_work_pattern_tbl(j).thursday_hours;
7167 l_count := l_count -1;
7168 l_remove_quantity := ROUND(l_overcom_quantity/l_count, 2);
7169 x_work_pattern_tbl(j).thursday_hours:=0;
7170 END IF;
7171 ELSIF l_week_day = 'FRI' THEN
7172 IF (x_work_pattern_tbl(j).friday_hours - l_remove_quantity)>=0 THEN
7173 x_work_pattern_tbl(j).friday_hours:= x_work_pattern_tbl(j).friday_hours - l_remove_quantity;
7174 ELSIF x_work_pattern_tbl(j).friday_hours > 0 THEN
7175 l_overcom_quantity := l_overcom_quantity - x_work_pattern_tbl(j).friday_hours;
7176 l_count := l_count -1;
7177 l_remove_quantity := ROUND(l_overcom_quantity/l_count, 2);
7178 x_work_pattern_tbl(j).friday_hours :=0;
7179 END IF;
7180 ELSIF l_week_day = 'SAT' THEN
7181 IF (x_work_pattern_tbl(j).saturday_hours - l_remove_quantity)>=0 THEN
7182 x_work_pattern_tbl(j).saturday_hours:= x_work_pattern_tbl(j).saturday_hours - l_remove_quantity;
7183 ELSIF x_work_pattern_tbl(j).saturday_hours > 0 THEN
7184 l_overcom_quantity := l_overcom_quantity - x_work_pattern_tbl(j).saturday_hours;
7185 l_count := l_count -1;
7186 l_remove_quantity := ROUND(l_overcom_quantity/l_count, 2);
7187 x_work_pattern_tbl(j).saturday_hours:=0;
7188 END IF;
7189 ELSIF l_week_day = 'SUN' THEN
7190 IF(x_work_pattern_tbl(j).sunday_hours - l_remove_quantity)>=0 THEN
7191 x_work_pattern_tbl(j).sunday_hours:= x_work_pattern_tbl(j).sunday_hours - l_remove_quantity;
7192 ELSIF x_work_pattern_tbl(j).sunday_hours > 0 THEN
7193 l_overcom_quantity := l_overcom_quantity - x_work_pattern_tbl(j).sunday_hours;
7194 l_count := l_count -1;
7195 l_remove_quantity := ROUND(l_overcom_quantity/l_count, 2);
7196 x_work_pattern_tbl(j).sunday_hours:=0;
7197 END IF;
7198 END IF;
7199
7200 PA_SCHEDULE_UTILS.debug('After update_work_pattern_record: work_pattern = '||
7201 x_work_pattern_tbl(j).monday_hours||';'||
7202 x_work_pattern_tbl(j).tuesday_hours||';'||
7203 x_work_pattern_tbl(j).wednesday_hours||';'||
7204 x_work_pattern_tbl(j).thursday_hours||';'||
7205 x_work_pattern_tbl(j).friday_hours||';'||
7206 x_work_pattern_tbl(j).saturday_hours||';'||
7207 x_work_pattern_tbl(j).sunday_hours);
7208
7209 END LOOP;
7210 END IF;
7211
7212 EXCEPTION
7213 WHEN OTHERS THEN
7214 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7215 x_msg_count := 1;
7216 x_msg_data := SQLERRM;
7217 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7218 p_procedure_name => 'insert_work_pattern_record');
7219 RAISE;
7220
7221 END update_work_pattern_record;
7222
7223
7224 PROCEDURE insert_work_pattern_tab(p_cur_work_pattern_tbl IN WorkPatternTabTyp,
7225 x_work_pattern_tbl IN OUT NOCOPY WorkPatternTabTyp,
7226 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7227 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7228 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7229 IS
7230 l_cur NUMBER;
7231 l_flag VARCHAR2(1);
7232
7233 BEGIN
7234 x_return_status := FND_API.G_RET_STS_SUCCESS;
7235
7236 --l_flag := 'N';
7237 FOR j IN p_cur_work_pattern_tbl.FIRST .. p_cur_work_pattern_tbl.LAST LOOP
7238
7239 l_flag := 'N';
7240 IF x_work_pattern_tbl.COUNT > 0 THEN
7241
7242 -- Loop through the table from the end because we only want to compare
7243 -- the new work pattern record with previous week's work pattern record
7244 -- of the same assignment and see whether they share the same work
7245 -- pattern. If yes, we simply update the old record with a new end date.
7246 -- Otherwise, insert a new record.
7247 FOR i IN x_work_pattern_tbl.FIRST .. x_work_pattern_tbl.LAST LOOP
7248 IF x_work_pattern_tbl(i).assignment_id = p_cur_work_pattern_tbl(j).assignment_id AND x_work_pattern_tbl(i).end_date = p_cur_work_pattern_tbl(j).end_date - 7 THEN
7249
7250 PA_SCHEDULE_UTILS.debug('Inside insert table: x_work_pattern_tbl(i).end_date = '|| x_work_pattern_tbl(i).end_date);
7251
7252 IF (x_work_pattern_tbl(i).monday_hours = p_cur_work_pattern_tbl(j).monday_hours
7253 AND x_work_pattern_tbl(i).tuesday_hours = p_cur_work_pattern_tbl(j).tuesday_hours
7254 AND x_work_pattern_tbl(i).wednesday_hours = p_cur_work_pattern_tbl(j).wednesday_hours
7255 AND x_work_pattern_tbl(i).thursday_hours = p_cur_work_pattern_tbl(j).thursday_hours
7256 AND x_work_pattern_tbl(i).friday_hours = p_cur_work_pattern_tbl(j).friday_hours
7257 AND x_work_pattern_tbl(i).saturday_hours = p_cur_work_pattern_tbl(j).saturday_hours
7258 AND x_work_pattern_tbl(i).sunday_hours = p_cur_work_pattern_tbl(j).sunday_hours)
7259 THEN
7260 l_cur := i;
7261 l_flag := 'Y';
7262 EXIT;
7263 ELSE
7264 l_flag := 'N';
7265 EXIT;
7266 END IF;
7267 END IF;
7268 END LOOP;
7269
7270 IF l_flag = 'Y' THEN
7271 x_work_pattern_tbl(l_cur).end_date := p_cur_work_pattern_tbl(j).end_date;
7272 ELSE
7273 l_cur := x_work_pattern_tbl.COUNT +1;
7274 x_work_pattern_tbl(l_cur).assignment_id := p_cur_work_pattern_tbl(j).assignment_id;
7275 x_work_pattern_tbl(l_cur).start_date := p_cur_work_pattern_tbl(j).start_date;
7276 x_work_pattern_tbl(l_cur).end_date := p_cur_work_pattern_tbl(j).end_date;
7277 x_work_pattern_tbl(l_cur).monday_hours := p_cur_work_pattern_tbl(j).monday_hours;
7278 x_work_pattern_tbl(l_cur).tuesday_hours := p_cur_work_pattern_tbl(j).tuesday_hours;
7279 x_work_pattern_tbl(l_cur).wednesday_hours := p_cur_work_pattern_tbl(j).wednesday_hours;
7280 x_work_pattern_tbl(l_cur).thursday_hours := p_cur_work_pattern_tbl(j).thursday_hours;
7281 x_work_pattern_tbl(l_cur).friday_hours := p_cur_work_pattern_tbl(j).friday_hours;
7282 x_work_pattern_tbl(l_cur).saturday_hours := p_cur_work_pattern_tbl(j).saturday_hours;
7283 x_work_pattern_tbl(l_cur).sunday_hours := p_cur_work_pattern_tbl(j).sunday_hours;
7284 END IF;
7285
7286 -- When x_work_pattern_tbl is empty,insert the work pattern record.
7287 ELSE
7288 l_cur := x_work_pattern_tbl.COUNT +1;
7289 x_work_pattern_tbl(l_cur).assignment_id := p_cur_work_pattern_tbl(j).assignment_id;
7290 x_work_pattern_tbl(l_cur).start_date := p_cur_work_pattern_tbl(j).start_date;
7291 x_work_pattern_tbl(l_cur).end_date := p_cur_work_pattern_tbl(j).end_date;
7292 x_work_pattern_tbl(l_cur).monday_hours := p_cur_work_pattern_tbl(j).monday_hours;
7293 x_work_pattern_tbl(l_cur).tuesday_hours := p_cur_work_pattern_tbl(j).tuesday_hours;
7294 x_work_pattern_tbl(l_cur).wednesday_hours := p_cur_work_pattern_tbl(j).wednesday_hours;
7295 x_work_pattern_tbl(l_cur).thursday_hours := p_cur_work_pattern_tbl(j).thursday_hours;
7296 x_work_pattern_tbl(l_cur).friday_hours := p_cur_work_pattern_tbl(j).friday_hours;
7297 x_work_pattern_tbl(l_cur).saturday_hours := p_cur_work_pattern_tbl(j).saturday_hours;
7298 x_work_pattern_tbl(l_cur).sunday_hours := p_cur_work_pattern_tbl(j).sunday_hours;
7299 END IF;
7300
7301 END LOOP;
7302
7303
7304 EXCEPTION
7305 WHEN OTHERS THEN
7306 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7307 x_msg_count := 1;
7308 x_msg_data := SQLERRM;
7309 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7310 p_procedure_name => 'insert_work_pattern_tab');
7311 RAISE;
7312
7313 END insert_work_pattern_tab;
7314
7315
7316 -- Procedure : overcom_post_aprvl_processing
7317 -- Purpose : Completes post-processing for overcommitment module after
7318 -- approval is complete.
7319 PROCEDURE overcom_post_aprvl_processing(p_conflict_group_id IN NUMBER,
7320 p_fnd_user_name IN VARCHAR2,
7321 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7322 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7323 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7324 IS
7325
7326 -- Retriev the source project info.
7327
7328 /* Commented this cursor for bug 3115273 and added new one below.
7329 Rremoved some columns and modified table from pa_projects_list_v to pa_projects_all,
7330 Also removed distinct and added rownum = 1
7331
7332 CURSOR c1 IS
7333 SELECT DISTINCT asgn.project_id, proj.name, proj.segment1, proj.person_name, proj.carrying_out_organization_name, proj.customer_name
7334 FROM pa_project_assignments asgn, pa_assignment_conflict_hist hist, pa_project_lists_v proj
7335 WHERE asgn.assignment_id = hist.assignment_id
7336 AND hist.conflict_group_id = p_conflict_group_id
7337 AND asgn.project_id = proj.project_id;
7338
7339 End of comment for bug 3115273 */
7340
7341 /* Cursor added for bug 3115273 */
7342
7343 CURSOR c1 IS
7344 SELECT asgn.project_id, proj.name, proj.segment1, proj.carrying_out_organization_id
7345 FROM pa_project_assignments asgn, pa_assignment_conflict_hist hist, pa_projects_all proj
7346 WHERE asgn.assignment_id = hist.assignment_id
7347 AND hist.conflict_group_id = p_conflict_group_id
7348 AND asgn.project_id = proj.project_id
7349 AND ROWNUM = 1;
7350
7351 v_c1 c1%ROWTYPE;
7352
7353 -- Retrieve conflict projects info.
7354 CURSOR c2 IS
7355 SELECT DISTINCT asgn.project_id, proj.name, proj.segment1
7356 FROM pa_project_assignments asgn, pa_assignment_conflict_hist hist, pa_projects_all proj
7357 WHERE asgn.assignment_id = hist.conflict_assignment_id
7358 AND hist.conflict_group_id = p_conflict_group_id
7359 AND asgn.project_id = proj.project_id
7360 AND hist.self_conflict_flag = 'N';
7361
7362 v_c2 c2%ROWTYPE;
7363
7364 -- Retrieve Self Conflicts info.
7365 CURSOR c3 IS
7366 SELECT assignment_id
7367 FROM pa_assignment_conflict_hist
7368 WHERE conflict_group_id = p_conflict_group_id
7369 AND self_conflict_flag = 'Y'
7370 AND resolve_conflicts_action_code = 'REMOVE_CONFLICTS';
7371
7372 v_c3 c3%ROWTYPE;
7373
7374 /* Added cursor get_organization_name for bug 3115273 */
7375
7376 CURSOR get_organization_name(c_organization_id number)is
7377 SELECT organ.name
7378 FROM
7379 hr_all_organization_units_tl organ
7380 WHERE
7381 organ.organization_id = c_organization_id AND
7382 organ.LANGUAGE = USERENV('LANG');
7383
7384 /* End of code added for bug 3115273 */
7385
7386 l_item_type pa_wf_processes.item_type%TYPE;
7387 l_item_key pa_wf_processes.item_key%TYPE;
7388 l_source_proj_id NUMBER;
7389 l_source_proj_name pa_projects_all.name%TYPE;
7390 l_source_proj_number pa_projects_all.segment1%TYPE;
7391 l_source_proj_mgr_name per_all_people_f.full_name%type; /* Bug 3115273 pa_project_lists_v.person_name%TYPE; */
7392 l_source_proj_organization hr_all_organization_units_tl.name%type; /* Bug 3115273 pa_project_lists_v.carrying_out_organization_name%TYPE; */
7393 l_source_proj_customer pa_customers_v.customer_name%type; /* Bug 3115273 pa_project_lists_v.customer_name%TYPE; */
7394 l_conflict_proj_id NUMBER;
7395 l_conflict_proj_mgr_id NUMBER;
7396 -- 3051479: Increased the size of the following two variables.
7397 l_conflict_mgr_user_name VARCHAR2(360);
7398 l_conflict_mgr_display_name VARCHAR2(360);
7399 -- End of 3051479
7400 l_view_conflicts_url VARCHAR2(600);
7401
7402 l_err_code NUMBER := 0;
7403 l_err_stage VARCHAR2(2000);
7404 l_err_stack VARCHAR2(2000);
7405
7406 BEGIN
7407 x_return_status := FND_API.G_RET_STS_SUCCESS;
7408
7409 OPEN c1;
7410 FETCH c1 INTO v_c1;
7411 CLOSE c1;
7412 l_source_proj_id := v_c1.project_id;
7413 l_source_proj_name := v_c1.name;
7414 l_source_proj_number := v_c1.segment1;
7415
7416 /* Commented for bug 3115273
7417 l_source_proj_mgr_name := v_c1.person_name;
7418 l_source_proj_organization := v_c1.carrying_out_organization_name;
7419 l_source_proj_customer := v_c1.customer_name;
7420 */
7421
7422 /* Added for bug 3115273 */
7423 l_source_proj_mgr_name := PA_PROJECT_PARTIES_UTILS.GET_PROJECT_MANAGER_NAME(v_c1.project_id);
7424
7425 OPEN get_organization_name(v_c1.carrying_out_organization_id);
7426 Fetch get_organization_name into l_source_proj_organization;
7427 CLOSE get_organization_name;
7428
7429 l_source_proj_customer := PA_PROJECTS_MAINT_UTILS.GET_PRIMARY_CUSTOMER_NAME(v_c1.project_id);
7430 /* End of code added for bug 3115273 */
7431
7432 l_item_type := 'PAROVCNT';
7433
7434 -- Loop through the conflicting projects and send notifications depending on
7435 -- whether the conflicting project manager is present.
7436 FOR v_c2 in c2 LOOP
7437
7438 SELECT PA_PRM_WF_ITEM_KEY_S.nextval
7439 INTO l_item_key
7440 FROM DUAL;
7441
7442 l_conflict_proj_id := v_c2.project_id;
7443 l_conflict_proj_mgr_id := PA_PROJECTS_MAINT_UTILS.get_project_manager(v_c2.project_id);
7444 PA_SCHEDULE_UTILS.debug('l_conflict_proj_mgr_id = '||l_conflict_proj_mgr_id);
7445 -- Send notifications to conflicting project managers.
7446 IF l_conflict_proj_mgr_id IS NOT NULL THEN
7447
7448 WF_DIRECTORY.getusername
7449 (p_orig_system => 'PER',
7450 p_orig_system_id => l_conflict_proj_mgr_id,
7451 p_name => l_conflict_mgr_user_name,
7452 p_display_name => l_conflict_mgr_display_name);
7453
7454 PA_SCHEDULE_UTILS.debug('l_conflict_mgr_user_name = '|| l_conflict_mgr_user_name);
7455
7456 -- Create the WF process
7457 wf_engine.CreateProcess ( ItemType => l_item_type,
7458 ItemKey => l_item_key,
7459 process => 'PRO_PROJ_MGR_WARN');
7460
7461 l_view_conflicts_url :=
7462 'JSP:/OA_HTML/OA.jsp?akRegionApplicationId=275&akRegionCode=PA_VIEW_CONFLICTS_LAYOUT&paCallingPage=ProjMgrNotif&addBreadCrumb=RP'
7463 ||'&paConflictGroupId='||p_conflict_group_id
7464 ||'&paProjectId='||l_source_proj_id
7465 ||'&paConflictProjectId='||l_conflict_proj_id;
7466
7467 wf_engine.SetItemAttrText
7468 ( itemtype => l_item_type,
7469 itemkey => l_item_key,
7470 aname => 'ATTR_VIEW_CONFLICTS_URL_INFO',
7471 avalue => l_view_conflicts_url
7472 );
7473
7474 wf_engine.SetItemAttrText
7475 ( itemtype => l_item_type,
7476 itemkey => l_item_key,
7477 aname => 'ATTR_NTF_RECEPIENT',
7478 avalue => l_conflict_mgr_user_name
7479 );
7480
7481 -- Now start the WF process
7482 wf_engine.StartProcess
7483 ( itemtype => l_item_type,
7484 itemkey => l_item_key );
7485
7486 -- Insert to PA tables wf process information.
7487 -- This is required for displaying notifications on PA pages.
7488 PA_WORKFLOW_UTILS.Insert_WF_Processes
7489 (p_wf_type_code => 'OVERCOMMITMENT'
7490 ,p_item_type => l_item_type
7491 ,p_item_key => l_item_key
7492 ,p_entity_key1 => to_char(l_source_proj_id)
7493 ,p_entity_key2 => to_char(l_conflict_proj_id)
7494 ,p_description => NULL
7495 ,p_err_code => l_err_code
7496 ,p_err_stage => l_err_stage
7497 ,p_err_stack => l_err_stack
7498 );
7499
7500 -- Send notifications to the submitter that conflicting project manager
7501 -- can not be informed.
7502 ELSE
7503
7504 -- Create the WF process
7505 wf_engine.CreateProcess ( ItemType => l_item_type,
7506 ItemKey => l_item_key,
7507 process => 'PRO_PROJ_MGR_MISSING');
7508
7509 wf_engine.SetItemAttrText
7510 ( itemtype => l_item_type,
7511 itemkey => l_item_key,
7512 aname => 'ATTR_PROJ_NAME',
7513 avalue => l_source_proj_name
7514 );
7515 wf_engine.SetItemAttrText
7516 ( itemtype => l_item_type,
7517 itemkey => l_item_key,
7518 aname => 'ATTR_PROJ_NUMBER',
7519 avalue => l_source_proj_number
7520 );
7521 wf_engine.SetItemAttrText
7522 ( itemtype => l_item_type,
7523 itemkey => l_item_key,
7524 aname => 'ATTR_PROJ_MANAGER',
7525 avalue => l_source_proj_mgr_name
7526 );
7527 wf_engine.SetItemAttrText
7528 ( itemtype => l_item_type,
7529 itemkey => l_item_key,
7530 aname => 'ATTR_PROJ_ORGANIZATION',
7531 avalue => l_source_proj_organization
7532 );
7533 wf_engine.SetItemAttrText
7534 ( itemtype => l_item_type,
7535 itemkey => l_item_key,
7536 aname => 'ATTR_PROJ_CUSTOMER',
7537 avalue => l_source_proj_customer
7538 );
7539 wf_engine.SetItemAttrText
7540 ( itemtype => l_item_type,
7541 itemkey => l_item_key,
7542 aname => 'ATTR_CONFLICT_PROJ_NAME',
7543 avalue => v_c2.name
7544 );
7545 wf_engine.SetItemAttrText
7546 ( itemtype => l_item_type,
7547 itemkey => l_item_key,
7548 aname => 'ATTR_CONFLICT_PROJ_NUMBER',
7549 avalue => v_c2.segment1
7550 );
7551
7552 l_view_conflicts_url :=
7553 'JSP:/OA_HTML/OA.jsp?akRegionApplicationId=275&akRegionCode=PA_VIEW_CONFLICTS_LAYOUT&paCallingPage=NoProjMgrNotif&addBreadCrumb=RP'
7554 ||'&paConflictGroupId='||p_conflict_group_id
7555 ||'&paProjectId='||l_source_proj_id
7556 ||'&paConflictProjectId='||l_conflict_proj_id;
7557
7558 wf_engine.SetItemAttrText
7559 ( itemtype => l_item_type,
7560 itemkey => l_item_key,
7561 aname => 'ATTR_VIEW_CONFLICTS_URL_INFO',
7562 avalue => l_view_conflicts_url
7563 );
7564
7565 wf_engine.SetItemAttrText
7566 ( itemtype => l_item_type,
7567 itemkey => l_item_key,
7568 aname => 'ATTR_NTF_RECEPIENT',
7569 avalue => p_fnd_user_name
7570 );
7571
7572 -- Now start the WF process
7573 wf_engine.StartProcess
7574 ( itemtype => l_item_type,
7575 itemkey => l_item_key );
7576
7577 -- Insert to PA tables wf process information.
7578 -- This is required for displaying notifications on PA pages.
7579 PA_WORKFLOW_UTILS.Insert_WF_Processes
7580 (p_wf_type_code => 'OVERCOMMITMENT'
7581 ,p_item_type => l_item_type
7582 ,p_item_key => l_item_key
7583 ,p_entity_key1 => to_char(l_source_proj_id)
7584 ,p_entity_key2 => to_char(l_conflict_proj_id)
7585 ,p_description => NULL
7586 ,p_err_code => l_err_code
7587 ,p_err_stage => l_err_stage
7588 ,p_err_stack => l_err_stack
7589 );
7590
7591 END IF;
7592 END LOOP;
7593
7594 -- Send Self Conflicts notifications.
7595 OPEN c3;
7596 FETCH c3 INTO v_c3;
7597 IF (c3%FOUND) THEN
7598 PA_SCHEDULE_UTILS.debug('Send self overcommitment notifications');
7599 -- Create the WF process
7600 SELECT PA_PRM_WF_ITEM_KEY_S.nextval
7601 INTO l_item_key
7602 FROM DUAL;
7603 wf_engine.CreateProcess ( ItemType => l_item_type,
7604 ItemKey => l_item_key,
7605 process => 'PRO_SELF_OVC_WARN');
7606
7607 wf_engine.SetItemAttrText
7608 ( itemtype => l_item_type,
7609 itemkey => l_item_key,
7610 aname => 'ATTR_PROJ_NAME',
7611 avalue => l_source_proj_name
7612 );
7613 wf_engine.SetItemAttrText
7614 ( itemtype => l_item_type,
7615 itemkey => l_item_key,
7616 aname => 'ATTR_PROJ_NUMBER',
7617 avalue => l_source_proj_number
7618 );
7619 wf_engine.SetItemAttrText
7620 ( itemtype => l_item_type,
7621 itemkey => l_item_key,
7622 aname => 'ATTR_PROJ_MANAGER',
7623 avalue => l_source_proj_mgr_name
7624 );
7625 wf_engine.SetItemAttrText
7626 ( itemtype => l_item_type,
7627 itemkey => l_item_key,
7628 aname => 'ATTR_PROJ_ORGANIZATION',
7629 avalue => l_source_proj_organization
7630 );
7631 wf_engine.SetItemAttrText
7632 ( itemtype => l_item_type,
7633 itemkey => l_item_key,
7634 aname => 'ATTR_PROJ_CUSTOMER',
7635 avalue => l_source_proj_customer
7636 );
7637
7638 l_view_conflicts_url :=
7639 'JSP:/OA_HTML/OA.jsp?akRegionApplicationId=275&akRegionCode=PA_VIEW_CONFLICTS_LAYOUT&paCallingPage=SelfConflictNotif&addBreadCrumb=RP'
7640 ||'&paConflictGroupId='||p_conflict_group_id
7641 ||'&paProjectId='||l_source_proj_id;
7642
7643 wf_engine.SetItemAttrText
7644 ( itemtype => l_item_type,
7645 itemkey => l_item_key,
7646 aname => 'ATTR_SELF_CONFLICTS_URL_INFO',
7647 avalue => l_view_conflicts_url
7648 );
7649
7650 wf_engine.SetItemAttrText
7651 ( itemtype => l_item_type,
7652 itemkey => l_item_key,
7653 aname => 'ATTR_NTF_RECEPIENT',
7654 avalue => p_fnd_user_name
7655 );
7656
7657 -- Now start the WF process
7658 wf_engine.StartProcess
7659 ( itemtype => l_item_type,
7660 itemkey => l_item_key );
7661
7662 -- Insert to PA tables wf process information.
7663 -- This is required for displaying notifications on PA pages.
7664 PA_WORKFLOW_UTILS.Insert_WF_Processes
7665 (p_wf_type_code => 'OVERCOMMITMENT'
7666 ,p_item_type => l_item_type
7667 ,p_item_key => l_item_key
7668 ,p_entity_key1 => to_char(l_source_proj_id)
7669 ,p_entity_key2 => 'SELF_OVERCOMMITMENT'
7670 ,p_description => NULL
7671 ,p_err_code => l_err_code
7672 ,p_err_stage => l_err_stage
7673 ,p_err_stack => l_err_stack
7674 );
7675
7676 END IF;
7677 CLOSE c3;
7678
7679 EXCEPTION
7680 WHEN OTHERS THEN
7681 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7682 x_msg_count := 1;
7683 x_msg_data := SQLERRM;
7684 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7685 p_procedure_name => 'overcom_post_aprvl_processing');
7686 RAISE;
7687 END overcom_post_aprvl_processing;
7688
7689
7690 -- Procedure : will_resolve_conflicts_by_rmvl
7691 -- Purpose : Returns 'Y' if user has chosen to remove one or more
7692 -- conflicts.
7693 PROCEDURE will_resolve_conflicts_by_rmvl(p_conflict_group_id IN NUMBER,
7694 x_resolve_conflicts_by_rmvl OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7695 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7696 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7697 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7698 IS
7699
7700 CURSOR c1 IS
7701 SELECT assignment_id
7702 FROM pa_assignment_conflict_hist
7703 WHERE conflict_group_id = p_conflict_group_id
7704 AND resolve_conflicts_action_code = 'REMOVE_CONFLICTS'
7705 AND self_conflict_flag = 'N'
7706 AND processed_flag = 'N';
7707
7708 v_c1 c1%ROWTYPE;
7709
7710 BEGIN
7711
7712 OPEN c1;
7713 FETCH c1 INTO v_c1;
7714 IF c1%NOTFOUND THEN
7715 x_resolve_conflicts_by_rmvl := 'N';
7716 ELSE
7717 x_resolve_conflicts_by_rmvl := 'Y';
7718 END IF;
7719 CLOSE c1;
7720
7721 x_return_status := FND_API.G_RET_STS_SUCCESS;
7722 EXCEPTION
7723 WHEN OTHERS THEN
7724 -- 4537865
7725 x_resolve_conflicts_by_rmvl := NULL ;
7726
7727 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7728 x_msg_count := 1;
7729 x_msg_data := SQLERRM;
7730 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7731 p_procedure_name => 'will_resolve_conflicts_by_rmvl');
7732 RAISE;
7733 END will_resolve_conflicts_by_rmvl;
7734
7735
7736 -- Procedure : has_resolved_conflicts_by_rmvl
7737 -- Purpose : Returns 'Y' if remove conflicts has been sucessful.
7738 PROCEDURE has_resolved_conflicts_by_rmvl(p_conflict_group_id IN NUMBER,
7739 p_assignment_id IN NUMBER,
7740 x_resolve_conflicts_by_rmvl OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7741 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7742 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7743 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7744 IS
7745 CURSOR c1 IS
7746 SELECT processed_flag
7747 FROM pa_assignment_conflict_hist
7748 WHERE conflict_group_id = p_conflict_group_id
7749 AND assignment_id = p_assignment_id
7750 AND resolve_conflicts_action_code = 'REMOVE_CONFLICTS'
7751 AND self_conflict_flag = 'N'
7752 AND processed_flag = 'Y';
7753
7754 v_c1 c1%ROWTYPE;
7755 BEGIN
7756
7757 OPEN c1;
7758 FETCH c1 INTO v_c1;
7759 IF c1%NOTFOUND THEN
7760 x_resolve_conflicts_by_rmvl := 'N';
7761 ELSE
7762 x_resolve_conflicts_by_rmvl := 'Y';
7763 END IF;
7764 CLOSE c1;
7765
7766 x_return_status := FND_API.G_RET_STS_SUCCESS;
7767 EXCEPTION
7768 WHEN OTHERS THEN
7769 -- 4537865
7770 x_resolve_conflicts_by_rmvl := NULL ;
7771 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7772 x_msg_count := 1;
7773 x_msg_data := SQLERRM;
7774 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7775 p_procedure_name => 'has_resolved_conflicts_by_rmvl');
7776 RAISE;
7777 END has_resolved_conflicts_by_rmvl;
7778
7779
7780 -- Procedure : cancel_overcom_txn_items
7781 -- Purpose : Cancels transaction items marked with CANCEL_TXN_ITEM.
7782 -- Updates processed_flag in the table once complete.
7783 PROCEDURE cancel_overcom_txn_items (p_conflict_group_id IN NUMBER,
7784 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7785 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7786 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7787 IS
7788
7789 -- 2167889: null instead of record_version_number
7790 CURSOR c1 IS
7791 SELECT DISTINCT conf.assignment_id, null record_version_number, asgn.assignment_type, asgn.start_date, asgn.end_date
7792 FROM pa_assignment_conflict_hist conf, pa_project_assignments asgn
7793 WHERE conf.conflict_group_id = p_conflict_group_id
7794 AND conf.assignment_id = asgn.assignment_id
7795 AND conf.resolve_conflicts_action_code = 'CANCEL_TXN_ITEM'
7796 AND conf.processed_flag = 'N';
7797
7798 BEGIN
7799 x_return_status := FND_API.G_RET_STS_SUCCESS;
7800
7801 For v_c1 in c1 LOOP
7802 PA_ASSIGNMENT_APPROVAL_PUB.cancel_assignment(p_record_version_number =>v_c1.record_version_number,
7803 p_assignment_id => v_c1.assignment_id,
7804 p_assignment_type => v_c1.assignment_type,
7805 p_start_date => v_c1.start_date,
7806 p_end_date => v_c1.end_date,
7807 x_return_status => x_return_status,
7808 x_msg_count => x_msg_count,
7809 x_msg_data => x_msg_data);
7810
7811 IF x_return_status = FND_API.G_RET_STS_SUCCESS THEN
7812 PA_ASGN_CONFLICT_HIST_PKG.update_rows(p_conflict_group_id => p_conflict_group_id,
7813 p_assignment_id => v_c1.assignment_id,
7814 p_processed_flag => 'Y',
7815 x_return_status => x_return_status,
7816 x_msg_count => x_msg_count,
7817 x_msg_data => x_msg_data);
7818 END IF;
7819 END LOOP;
7820
7821 EXCEPTION
7822 WHEN OTHERS THEN
7823 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7824 x_msg_count := 1;
7825 x_msg_data := SQLERRM;
7826 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7827 p_procedure_name => 'cancel_overcom_txn_items');
7828 RAISE;
7829 END cancel_overcom_txn_items;
7830
7831
7832 -- Procedure : revert_overcom_txn_items
7833 -- Purpose : Reverts transaction items marked with REVERT_TXN_ITEM.
7834 -- Updates processed_flag in the table once complete.
7835 PROCEDURE revert_overcom_txn_items (p_conflict_group_id IN NUMBER,
7836 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7837 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7838 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7839 IS
7840
7841 CURSOR c1 IS
7842 SELECT DISTINCT assignment_id
7843 FROM pa_assignment_conflict_hist
7844 WHERE conflict_group_id = p_conflict_group_id
7845 AND resolve_conflicts_action_code = 'REVERT_TXN_ITEM'
7846 AND processed_flag = 'N';
7847
7848 BEGIN
7849 x_return_status := FND_API.G_RET_STS_SUCCESS;
7850
7851 FOR v_c1 IN c1 LOOP
7852 PA_SCHEDULE_UTILS.debug('Revert_Overcom_Txn_Items: v_c1.assignment_id = ' || v_c1.assignment_id);
7853 PA_ASSIGNMENT_APPROVAL_PUB.revert_to_last_approved(p_assignment_id => v_c1.assignment_id,
7854 x_return_status => x_return_status,
7855 x_msg_count => x_msg_count,
7856 x_msg_data => x_msg_data);
7857 PA_SCHEDULE_UTILS.debug('Revert_Overcom_Txn_Items: After revert_to_last_approved');
7858 IF x_return_status = FND_API.G_RET_STS_SUCCESS THEN
7859 PA_ASGN_CONFLICT_HIST_PKG.update_rows(p_conflict_group_id => p_conflict_group_id,
7860 p_assignment_id => v_c1.assignment_id,
7861 p_processed_flag => 'Y',
7862 x_return_status => x_return_status,
7863 x_msg_count => x_msg_count,
7864 x_msg_data => x_msg_data);
7865 END IF;
7866 END LOOP;
7867
7868 EXCEPTION
7869 WHEN OTHERS THEN
7870 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7871 x_msg_count := 1;
7872 x_msg_data := SQLERRM;
7873 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7874 p_procedure_name => 'revert_overcom_txn_items');
7875 RAISE;
7876 END revert_overcom_txn_items;
7877
7878
7879 -- Procedure : get_conflicting_asgmt_count
7880 -- Purpose : Returns number of assignments causing conflict including
7881 -- self conflict.
7882 PROCEDURE get_conflicting_asgmt_count (p_conflict_group_id IN NUMBER,
7883 x_assignment_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7884 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7885 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7886 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7887 IS
7888
7889 BEGIN
7890
7891 SELECT COUNT(DISTINCT assignment_id)
7892 INTO x_assignment_count
7893 FROM pa_assignment_conflict_hist
7894 WHERE conflict_group_id = p_conflict_group_id;
7895
7896 x_return_status := FND_API.G_RET_STS_SUCCESS;
7897 EXCEPTION
7898 WHEN OTHERS THEN
7899 -- 4537865
7900 x_assignment_count := NULL ;
7901
7902 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7903 x_msg_count := 1;
7904 x_msg_data := SQLERRM;
7905 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7906 p_procedure_name => 'get_conflicting_asgmt_count');
7907 RAISE;
7908 END get_conflicting_asgmt_count;
7909
7910
7911 -- Procedure : has_action_taken_on_conflicts
7912 -- Purpose : This is called from View Conflicts page when the notification
7913 -- is sent to a mass txn submitter to choose action on assignment
7914 -- conflicts. This must return 'Y' before the user can continue
7915 -- the mass approval workflow.
7916 PROCEDURE has_action_taken_on_conflicts (p_conflict_group_id IN
7917 NUMBER,
7918 x_action_taken OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7919 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7920 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7921 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7922 IS
7923
7924 -- Cursor which retrieves the assignments on which action is not taken.
7925 CURSOR c1 IS
7926 SELECT assignment_id
7927 FROM pa_assignment_conflict_hist
7928 WHERE conflict_group_id = p_conflict_group_id
7929 AND resolve_conflicts_action_code = 'NOTIFY_IF_CONFLICT';
7930
7931 v_c1 c1%ROWTYPE;
7932
7933 BEGIN
7934 x_return_status := FND_API.G_RET_STS_SUCCESS;
7935 OPEN c1;
7936 FETCH c1 INTO v_c1;
7937 IF c1%NOTFOUND THEN
7938 x_action_taken := 'Y';
7939 ELSE
7940 x_action_taken := 'N';
7941 END IF;
7942 CLOSE c1;
7943
7944 EXCEPTION
7945 WHEN OTHERS THEN
7946 -- 4537865
7947 x_action_taken := NULL ;
7948
7949 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7950 x_msg_count := 1;
7951 x_msg_data := SQLERRM;
7952 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7953 p_procedure_name => 'has_action_taken_on_conflicts');
7954 RAISE;
7955 END has_action_taken_on_conflicts;
7956
7957
7958 -- Procedure : check_asgmt_apprvl_working
7959 -- Purpose : Return 'Y' if the conflict group contains an assignment whose
7960 -- apprvl_status_code is 'ASGMT_APPRVL_WORKING'. Otherwise, 'N'.
7961 PROCEDURE check_asgmt_apprvl_working (p_conflict_group_id IN
7962 NUMBER,
7963 x_result OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7964 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
7965 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
7966 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
7967 IS
7968
7969 CURSOR c1 IS
7970 SELECT hist.assignment_id
7971 FROM pa_assignment_conflict_hist hist, pa_project_assignments asgn
7972 WHERE hist.assignment_id = asgn.assignment_id
7973 AND hist.conflict_group_id = p_conflict_group_id
7974 AND asgn.apprvl_status_code = 'ASGMT_APPRVL_WORKING';
7975
7976 v_c1 c1%ROWTYPE;
7977 BEGIN
7978 x_return_status := FND_API.G_RET_STS_SUCCESS;
7979
7980 OPEN c1;
7981 FETCH c1 INTO v_c1;
7982 IF c1%NOTFOUND THEN
7983 x_result := 'N';
7984 ELSE
7985 x_result := 'Y';
7986 END IF;
7987 CLOSE c1;
7988
7989 EXCEPTION
7990 WHEN OTHERS THEN
7991 -- 4537865
7992 x_result := NULL ;
7993
7994 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7995 x_msg_count := 1;
7996 x_msg_data := SQLERRM;
7997 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
7998 p_procedure_name => 'check_asgmt_apprvl_working');
7999 RAISE;
8000 END check_asgmt_apprvl_working;
8001
8002 -- This procedure will sum the task assignments given a schedule of working days and output a
8003 -- new project schedule spanning from p_start_date to p_end_date
8004 -- NOTE: The time span of the schedule of working days must include the time span of all of
8005 -- the tasks falling into the p_start_date to p_end_date
8006 -- Input parameters
8007 -- Parameters Type Required Description
8008 -- P_Task_Assignments_Tbl TASKASSIGNMENTTABTYPE YES Table of Task Assignment IDs to be summed
8009 -- P_Schedule_Tbl SCHEDULETABTYP YES Working Days Schedule
8010 -- P_Start_Date DATE YES Starting date of the schedule for that calendar
8011 -- P_End_Date DATE YES Ending date of the schedule for that calendar
8012 --
8013 -- Out parameters
8014 -- X_Schedule_Tbl SCHEDULETABTYP YES Schedule representing the summation of all the tasks
8015 --
8016 --Bug 5126919: Added parameter x_total_hours which will contain the total hours for which the x_schedule_tbl
8017 --will be prepared.
8018 PROCEDURE sum_task_assignments (
8019 p_task_assignments_tbl IN SYSTEM.PA_NUM_TBL_TYPE ,
8020 p_schedule_tbl IN PA_SCHEDULE_GLOB.ScheduleTabTyp ,
8021 p_start_date IN DATE ,
8022 p_end_date IN DATE ,
8023 x_total_hours OUT NOCOPY NUMBER , -- Bug 5126919
8024 x_schedule_tbl OUT NOCOPY PA_SCHEDULE_GLOB.ScheduleTabTyp , --File.Sql.39 bug 4440895
8025 x_return_status OUT NOCOPY VARCHAR2 , --File.Sql.39 bug 4440895
8026 x_msg_count OUT NOCOPY NUMBER , --File.Sql.39 bug 4440895
8027 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
8028 )
8029
8030 IS
8031 TYPE SummationRecord IS RECORD (
8032 schedule_date DATE ,
8033 working_day NUMBER ,
8034 hours NUMBER ,
8035 day_of_week PA_SCHEDULE_PVT.DayOfWeekType ,
8036 calendar_id NUMBER ,
8037 assignment_id NUMBER ,
8038 project_id NUMBER ,
8039 schedule_type_code VARCHAR2(30) ,
8040 assignment_status_code VARCHAR2(30) ,
8041 system_status_code VARCHAR2(30) ,
8042 change_type_code VARCHAR2(30) );
8043
8044 TYPE SummationTableType IS TABLE OF SummationRecord INDEX BY BINARY_INTEGER;
8045
8046 l_summation_tbl SummationTableType;
8047 l_schedule_index_first NUMBER;
8048 l_schedule_index_last NUMBER;
8049 l_schedule_start_date DATE;
8050 l_schedule_end_date DATE;
8051 l_schedule_row_start_date DATE;
8052 l_schedule_row_end_date DATE;
8053
8054 l_current_date DATE;
8055 l_working_day NUMBER;
8056 l_hours NUMBER;
8057 l_found BOOLEAN;
8058 l_day_of_week PA_SCHEDULE_PVT.DayOfWeekType;
8059
8060 l_summation_index_first NUMBER;
8061 l_summation_index_last NUMBER;
8062
8063 l_task_assignment_id NUMBER;
8064 l_task_index_first NUMBER;
8065 l_task_index_last NUMBER;
8066 l_period_start_date DATE;
8067 l_period_end_date DATE;
8068 l_ta_planning_start_date DATE;
8069 l_ta_planning_end_date DATE;
8070
8071 l_total_hours NUMBER;
8072 l_num_working_days NUMBER;
8073 l_hours_per_day NUMBER;
8074 l_next_day_schedule_hours NUMBER;
8075
8076 counter NUMBER;
8077 summation_counter NUMBER;
8078 schedule_counter NUMBER;
8079 task_counter NUMBER;
8080
8081 l_schedule_record PA_SCHEDULE_GLOB.ScheduleRecord;
8082 l_empty_schedule_record PA_SCHEDULE_GLOB.ScheduleRecord;
8083 l_debug_mode VARCHAR2(20) := 'N'; -- 4387388
8084
8085 CURSOR C1 IS
8086 SELECT a.start_date, a.end_date, NVL(a.quantity,0),
8087 c.planning_start_date, c.planning_end_date -- 4367912
8088 FROM pa_budget_lines a,
8089 -- pa_projects_all b, -- Bug 5086869
8090 pa_resource_assignments c
8091 WHERE a.resource_assignment_id = c.resource_assignment_id
8092 AND c.resource_assignment_id = l_task_assignment_id;
8093 -- Bug 5086869 - In WP, there is only one currency
8094 -- so no need for currency join.
8095 -- AND a.txn_currency_code = b.project_currency_code
8096 -- AND b.project_id = c.project_id
8097
8098 BEGIN
8099
8100 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
8101
8102 -- Start of Debugging Statements
8103 IF l_debug_mode = 'Y' THEN -- 4387388
8104 PA_SCHEDULE_UTILS.log_message(1, 'p_start_date: ' || p_start_date);
8105 PA_SCHEDULE_UTILS.log_message(1, 'p_end_date: ' || p_end_date);
8106 IF p_task_assignments_tbl IS NOT NULL THEN
8107 IF p_task_assignments_tbl.count > 0 THEN
8108 FOR i IN p_task_assignments_tbl.first .. p_task_assignments_tbl.last LOOP
8109 PA_SCHEDULE_UTILS.log_message(1, 'p_task_assignments_tbl('||i||'): ' || p_task_assignments_tbl(i));
8110 END LOOP;
8111 END IF;
8112 END IF;
8113 IF p_schedule_tbl IS NOT NULL THEN
8114 IF p_schedule_tbl.count > 0 THEN
8115 FOR schedule_counter IN p_schedule_tbl.first .. p_schedule_tbl.last LOOP
8116 PA_SCHEDULE_UTILS.log_message(1,
8117 p_schedule_tbl(schedule_counter).start_date || '|' ||
8118 p_schedule_tbl(schedule_counter).end_date || '|' ||
8119 round(p_schedule_tbl(schedule_counter).monday_hours,2) || '|' ||
8120 round(p_schedule_tbl(schedule_counter).tuesday_hours,2) || '|' ||
8121 round(p_schedule_tbl(schedule_counter).wednesday_hours,2) || '|' ||
8122 round(p_schedule_tbl(schedule_counter).thursday_hours,2) || '|' ||
8123 round(p_schedule_tbl(schedule_counter).friday_hours,2) || '|' ||
8124 round(p_schedule_tbl(schedule_counter).saturday_hours,2) || '|' ||
8125 round(p_schedule_tbl(schedule_counter).sunday_hours,2) || '|' ||
8126 p_schedule_tbl(schedule_counter).calendar_id || '|' ||
8127 p_schedule_tbl(schedule_counter).assignment_id || '|' ||
8128 p_schedule_tbl(schedule_counter).project_id || '|' ||
8129 p_schedule_tbl(schedule_counter).schedule_type_code || '|' ||
8130 p_schedule_tbl(schedule_counter).assignment_status_code || '|' ||
8131 p_schedule_tbl(schedule_counter).system_status_code || '|' ||
8132 p_schedule_tbl(schedule_counter).change_type_code || '|');
8133 END LOOP;
8134 END IF;
8135 END IF;
8136 END IF; -- 4387388
8137 -- End of Debugging Statements
8138
8139 x_return_status := FND_API.G_RET_STS_SUCCESS;
8140 -- Check for invalid dates in p_schedule_tbl
8141 IF p_schedule_tbl.first IS NULL OR p_schedule_tbl.last IS NULL THEN
8142 l_schedule_start_date := p_start_date - 1;
8143 l_schedule_end_date := p_start_date - 2;
8144 ELSE
8145 l_schedule_index_first := p_schedule_tbl.first;
8146 l_schedule_index_last := p_schedule_tbl.last;
8147
8148 l_schedule_start_date := p_schedule_tbl(l_schedule_index_first).start_date;
8149 l_schedule_end_date := p_schedule_tbl(l_schedule_index_last).end_date;
8150
8151 FOR schedule_counter IN l_schedule_index_first .. l_schedule_index_last LOOP
8152 IF p_schedule_tbl(schedule_counter).start_date IS NULL OR
8153 p_schedule_tbl(schedule_counter).end_date IS NULL THEN
8154 l_schedule_start_date := p_start_date - 1;
8155 l_schedule_end_date := p_start_date - 2;
8156 END IF;
8157 END LOOP;
8158 END IF;
8159
8160 -- Initialize l_summation_tbl
8161 summation_counter := 1;
8162 l_current_date := l_schedule_start_date;
8163 WHILE l_current_date <= l_schedule_end_date LOOP
8164
8165 l_day_of_week := get_day_of_week(p_date => l_current_date);
8166 l_working_day := 0;
8167 l_hours := 0;
8168 l_found := FALSE;
8169 FOR counter IN l_schedule_index_first .. l_schedule_index_last LOOP
8170 l_schedule_row_start_date := p_schedule_tbl(counter).start_date;
8171 l_schedule_row_end_date := p_schedule_tbl(counter).end_date;
8172 IF l_current_date BETWEEN l_schedule_row_start_date AND l_schedule_row_end_date THEN
8173 l_hours := get_hours_by_day_of_week( p_schedule_record => p_schedule_tbl(counter),
8174 p_day_of_week => l_day_of_week);
8175 IF l_hours > 0 THEN
8176 l_working_day := 1;
8177 END IF;
8178 l_found := TRUE;
8179 schedule_counter := counter;
8180 EXIT;
8181 END IF;
8182 END LOOP;
8183 IF l_found THEN
8184 l_summation_tbl(summation_counter).schedule_date := l_current_date;
8185 l_summation_tbl(summation_counter).working_day := l_working_day;
8186 l_summation_tbl(summation_counter).hours := 0;
8187 l_summation_tbl(summation_counter).day_of_week := l_day_of_week;
8188 l_summation_tbl(summation_counter).calendar_id := p_schedule_tbl(schedule_counter).calendar_id;
8189 l_summation_tbl(summation_counter).assignment_id := p_schedule_tbl(schedule_counter).assignment_id;
8190 l_summation_tbl(summation_counter).project_id := p_schedule_tbl(schedule_counter).project_id;
8191 l_summation_tbl(summation_counter).schedule_type_code := p_schedule_tbl(schedule_counter).schedule_type_code;
8192 l_summation_tbl(summation_counter).assignment_status_code := p_schedule_tbl(schedule_counter).assignment_status_code;
8193 l_summation_tbl(summation_counter).system_status_code := p_schedule_tbl(schedule_counter).system_status_code;
8194 l_summation_tbl(summation_counter).change_type_code := p_schedule_tbl(schedule_counter).change_type_code;
8195 ELSE
8196 l_summation_tbl(summation_counter).schedule_date := NULL;
8197 END IF;
8198 l_current_date := l_current_date + 1;
8199 summation_counter := summation_counter + 1;
8200 END LOOP;
8201
8202 -- Fill in hours data
8203 l_task_index_first := NVL(p_task_assignments_tbl.first,0);
8204 l_task_index_last := NVL(p_task_assignments_tbl.last,-1);
8205 l_summation_index_first := NVL(l_summation_tbl.first,0);
8206 l_summation_index_last := NVL(l_summation_tbl.last,-1);
8207
8208 x_total_hours :=0; -- Bug 5126919
8209
8210
8211 FOR task_counter IN l_task_index_first .. l_task_index_last LOOP
8212 l_task_assignment_id := p_task_assignments_tbl(task_counter);
8213 OPEN C1;
8214 LOOP
8215 FETCH C1 INTO l_period_start_date, l_period_end_date, l_total_hours,
8216 l_ta_planning_start_date, l_ta_planning_end_date; -- 4367912
8217 EXIT WHEN C1%NOTFOUND;
8218
8219 x_total_hours := x_total_hours + l_total_hours; -- Bug 5126919
8220
8221 -- 4367912: PJ.M:B15:P2:QA:STF:ASNMT THRU BOTOM UP APPROACH & TASK ASNMT SCH USES RES CALNDR
8222 -- Make sure the dates used to calculate the number of working
8223 -- dates should be within TA planning dates
8224
8225 -- Begin Bug:5872132:In order to calculate the number of working days acculately: we need to consider the
8226 -- number of working days between Team Role Start Date(p_start_date) & Team Role End date(p_end_date)
8227 -- instead of considering TA planning dates.
8228 IF l_period_start_date < p_start_date THEN
8229 l_period_start_date := p_start_date;
8230 END IF;
8231 IF l_period_end_date > p_end_date THEN
8232 l_period_end_date := p_end_date;
8233 END IF;
8234 -- End Bug:5872132:
8235
8236 -- END OF 4367912
8237
8238 -- Determine the number of working days in the period
8239 l_num_working_days := 0;
8240 FOR summation_counter IN l_summation_index_first .. l_summation_index_last LOOP
8241 IF l_summation_tbl(summation_counter).schedule_date BETWEEN l_period_start_date AND l_period_end_date THEN
8242 IF l_summation_tbl(summation_counter).working_day = 1 THEN
8243 l_num_working_days := l_num_working_days + 1;
8244 END IF;
8245 END IF;
8246 END LOOP;
8247
8248 IF l_num_working_days = 0 THEN
8249 l_hours_per_day := 0;
8250 ELSE
8251 l_hours_per_day := l_total_hours / l_num_working_days;
8252 END IF;
8253
8254
8255 /*
8256 DBMS_OUTPUT.put_line( l_period_start_date || ' ' || l_period_end_date || ' ' ||
8257 l_total_hours || ' ' || l_num_working_days || ' ' || round(l_hours_per_day,2));
8258 */
8259 -- Loop through l_summation_tbl to update hours column
8260 FOR summation_counter IN l_summation_index_first .. l_summation_index_last LOOP
8261 IF l_summation_tbl(summation_counter).schedule_date BETWEEN l_period_start_date AND l_period_end_date THEN
8262 IF l_summation_tbl(summation_counter).working_day = 1 THEN
8263 l_summation_tbl(summation_counter).hours := l_summation_tbl(summation_counter).hours + l_hours_per_day;
8264 END IF;
8265 END IF;
8266 END LOOP;
8267 END LOOP;
8268 CLOSE C1;
8269 END LOOP;
8270
8271 -- Create x_schedule_tbl
8272 IF (l_schedule_start_date <= p_start_date) AND (l_schedule_end_date >= p_end_date) THEN
8273 schedule_counter := 1;
8274 summation_counter := NVL(l_summation_tbl.first, 0);
8275
8276 -- Set summation_counter to point to p_start_date
8277 WHILE l_summation_tbl(summation_counter).schedule_date < p_start_date LOOP
8278 summation_counter := summation_counter + 1;
8279 END LOOP;
8280
8281 l_current_date := p_start_date;
8282 WHILE l_current_date <= p_end_date LOOP
8283 IF l_summation_tbl(summation_counter).schedule_date IS NOT NULL THEN
8284 set_hours_by_day_of_week( p_schedule_record => l_schedule_record,
8285 p_day_of_week => l_summation_tbl(summation_counter).day_of_week,
8286 p_hours => l_summation_tbl(summation_counter).hours );
8287 IF l_schedule_record.start_date IS NULL THEN
8288 -- Start New Record
8289 l_schedule_record.start_date := l_current_date;
8290 l_schedule_record.calendar_id := l_summation_tbl(summation_counter).calendar_id;
8291 l_schedule_record.assignment_id := l_summation_tbl(summation_counter).assignment_id;
8292 l_schedule_record.project_id := l_summation_tbl(summation_counter).project_id;
8293 l_schedule_record.schedule_type_code := l_summation_tbl(summation_counter).schedule_type_code;
8294 l_schedule_record.assignment_status_code := l_summation_tbl(summation_counter).assignment_status_code;
8295 l_schedule_record.system_status_code := l_summation_tbl(summation_counter).system_status_code;
8296 l_schedule_record.change_type_code := l_summation_tbl(summation_counter).change_type_code;
8297 END IF;
8298 IF (l_current_date = p_end_date) OR
8299 (l_summation_tbl(summation_counter+1).schedule_date IS NULL) OR
8300 (NVL(l_schedule_record.calendar_id,-100) <> NVL(l_summation_tbl(summation_counter+1).calendar_id,-100)) OR
8301 (NVL(l_schedule_record.assignment_id,-100) <> NVL(l_summation_tbl(summation_counter+1).assignment_id,-100)) OR
8302 (NVL(l_schedule_record.project_id,-100) <> NVL(l_summation_tbl(summation_counter+1).project_id,-100)) OR
8303 (NVL(l_schedule_record.schedule_type_code,'') <> NVL(l_summation_tbl(summation_counter+1).schedule_type_code,'')) OR
8304 (NVL(l_schedule_record.assignment_status_code,'') <> NVL(l_summation_tbl(summation_counter+1).assignment_status_code,'')) OR
8305 (NVL(l_schedule_record.system_status_code,'') <> NVL(l_summation_tbl(summation_counter+1).system_status_code,'')) OR
8306 (NVL(l_schedule_record.change_type_code,'') <> NVL(l_summation_tbl(summation_counter+1).change_type_code,'')) OR
8307 (NVL( get_hours_by_day_of_week(p_schedule_record => l_schedule_record,p_day_of_week => l_summation_tbl(summation_counter+1).day_of_week) <>
8308 l_summation_tbl(summation_counter+1).hours, FALSE)) THEN
8309 -- Add Record to Table and Create a New One
8310 l_schedule_record.end_date := l_current_date;
8311 IF l_schedule_record.monday_hours IS NULL THEN
8312 l_schedule_record.monday_hours := 0;
8313 END IF;
8314 IF l_schedule_record.tuesday_hours IS NULL THEN
8315 l_schedule_record.tuesday_hours := 0;
8316 END IF;
8317 IF l_schedule_record.wednesday_hours IS NULL THEN
8318 l_schedule_record.wednesday_hours := 0;
8319 END IF;
8320 IF l_schedule_record.thursday_hours IS NULL THEN
8321 l_schedule_record.thursday_hours := 0;
8322 END IF;
8323 IF l_schedule_record.friday_hours IS NULL THEN
8324 l_schedule_record.friday_hours := 0;
8325 END IF;
8326 IF l_schedule_record.saturday_hours IS NULL THEN
8327 l_schedule_record.saturday_hours := 0;
8328 END IF;
8329 IF l_schedule_record.sunday_hours IS NULL THEN
8330 l_schedule_record.sunday_hours := 0;
8331 END IF;
8332 x_schedule_tbl(schedule_counter) := l_schedule_record;
8333 schedule_counter := schedule_counter + 1;
8334 l_schedule_record := l_empty_schedule_record;
8335 END IF;
8336 END IF;
8337 l_current_date := l_current_date + 1;
8338 summation_counter := summation_counter + 1;
8339 END LOOP;
8340 END IF;
8341 /*
8342 l_schedule_index_first := NVL(x_schedule_tbl.first,0);
8343 l_schedule_index_last := NVL(x_schedule_tbl.last,-1);
8344
8345 DBMS_OUTPUT.put_line('COUNT: ' || x_schedule_tbl.count);
8346
8347 */
8348
8349 IF l_debug_mode = 'Y' THEN -- 4387388
8350 IF x_schedule_tbl IS NOT NULL THEN
8351 IF x_schedule_tbl.count > 0 THEN
8352 FOR schedule_counter IN x_schedule_tbl.first .. x_schedule_tbl.last LOOP
8353 PA_SCHEDULE_UTILS.log_message(1,
8354 x_schedule_tbl(schedule_counter).start_date || '|' ||
8355 x_schedule_tbl(schedule_counter).end_date || '|' ||
8356 round(x_schedule_tbl(schedule_counter).monday_hours,2) || '|' ||
8357 round(x_schedule_tbl(schedule_counter).tuesday_hours,2) || '|' ||
8358 round(x_schedule_tbl(schedule_counter).wednesday_hours,2) || '|' ||
8359 round(x_schedule_tbl(schedule_counter).thursday_hours,2) || '|' ||
8360 round(x_schedule_tbl(schedule_counter).friday_hours,2) || '|' ||
8361 round(x_schedule_tbl(schedule_counter).saturday_hours,2) || '|' ||
8362 round(x_schedule_tbl(schedule_counter).sunday_hours,2) || '|' ||
8363 x_schedule_tbl(schedule_counter).calendar_id || '|' ||
8364 x_schedule_tbl(schedule_counter).assignment_id || '|' ||
8365 x_schedule_tbl(schedule_counter).project_id || '|' ||
8366 x_schedule_tbl(schedule_counter).schedule_type_code || '|' ||
8367 x_schedule_tbl(schedule_counter).assignment_status_code || '|' ||
8368 x_schedule_tbl(schedule_counter).system_status_code || '|' ||
8369 x_schedule_tbl(schedule_counter).change_type_code || '|');
8370 END LOOP;
8371 END IF;
8372 END IF;
8373 END IF; -- 4387388
8374
8375 EXCEPTION
8376 WHEN OTHERS THEN
8377 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8378 x_msg_count := 1;
8379 x_msg_data := SQLERRM;
8380 x_total_hours := 0; -- Bug 5126919
8381 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
8382 p_procedure_name => 'sum_task_assignments');
8383 raise;
8384
8385 END sum_task_assignments;
8386
8387 -- This procedure sets the number of hours in a given schedule record for a particular day of the week
8388 -- Input parameters
8389 -- Parameters Type Required Description
8390 -- P_Schedule_Tbl PA_SCHEDULE_GLOB.ScheduleRecord YES Schedule Record
8391 -- P_Day_Of_Week PA_SCHEDULE_PVT.DayOfWeekType YES Day of the week
8392 -- P_Hours NUMBER YES Hours for that day
8393 --
8394 -- Out parameters
8395 --
8396 PROCEDURE set_hours_by_day_of_week (
8397 p_schedule_record IN OUT NOCOPY PA_SCHEDULE_GLOB.ScheduleRecord ,
8398 p_day_of_week IN PA_SCHEDULE_PVT.DayOfWeekType ,
8399 p_hours IN NUMBER) IS
8400 BEGIN
8401 IF p_day_of_week = 'MON' THEN
8402 p_schedule_record.monday_hours := p_hours;
8403 ELSIF p_day_of_week = 'TUE' THEN
8404 p_schedule_record.tuesday_hours := p_hours;
8405 ELSIF p_day_of_week = 'WED' THEN
8406 p_schedule_record.wednesday_hours := p_hours;
8407 ELSIF p_day_of_week = 'THU' THEN
8408 p_schedule_record.thursday_hours := p_hours;
8409 ELSIF p_day_of_week = 'FRI' THEN
8410 p_schedule_record.friday_hours := p_hours;
8411 ELSIF p_day_of_week = 'SAT' THEN
8412 p_schedule_record.saturday_hours := p_hours;
8413 ELSIF p_day_of_week = 'SUN' THEN
8414 p_schedule_record.sunday_hours := p_hours;
8415 END IF;
8416 -- 4537865
8417 EXCEPTION
8418 WHEN OTHERS THEN
8419 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
8420 p_procedure_name => 'set_hours_by_day_of_week',
8421 p_error_text => SUBSTRB(SQLERRM,1,240));
8422 RAISE;
8423 END set_hours_by_day_of_week;
8424
8425 -- Function : Get_changed_item_name_text
8426 -- Purpose : Returns the changed item name display text for
8427 -- p_exception_type_code.
8428 FUNCTION get_changed_item_name_text( p_exception_type_code IN VARCHAR2)
8429 RETURN VARCHAR2
8430
8431 IS
8432 BEGIN
8433 return PA_ASSIGNMENT_APPROVAL_PVT.get_lookup_meaning('PA_CHANGED_ITEMS', p_exception_type_code);
8434 END get_changed_item_name_text;
8435
8436 -- Function : Get_date_range_text
8437 -- Purpose : Returns the display text for the date range of the
8438 -- assignment.
8439
8440 FUNCTION Get_date_range_text ( p_start_date IN DATE,
8441 p_end_date IN DATE) RETURN VARCHAR2
8442 IS
8443 l_start_date VARCHAR2(80);
8444 l_end_date VARCHAR2(80);
8445 l_date_range_text VARCHAR2(240);
8446 l_date_format VARCHAR2(80);
8447
8448 BEGIN
8449 -- don't remove this, for some reason, icx_sec.getID doesn't work first time
8450 -- in the new session.
8451 l_date_format := icx_sec.getID(n_param =>icx_sec.PV_DATE_FORMAT);
8452 l_date_format := icx_sec.getID(n_param =>icx_sec.PV_DATE_FORMAT);
8453
8454 IF p_start_date IS NOT null THEN
8455 l_start_date := to_char(p_start_date, l_date_format);
8456 ELSE
8457 l_start_date := ' ';
8458 END IF;
8459
8460 IF p_end_date IS NOT NULL THEN
8461 l_end_date := to_char(p_end_date, l_date_format);
8462 ELSE
8463 l_end_date := ' ';
8464 END IF;
8465
8466 IF ((p_start_date IS NOT NULL) OR (p_end_date IS NOT NULL)) THEN
8467 l_date_range_text := l_start_date||' - '||l_end_date;
8468 ELSE
8469 l_date_range_text := ' ';
8470 END IF;
8471
8472 RETURN l_date_range_text;
8473
8474 END get_date_range_text;
8475
8476
8477 --
8478 -- Function : Get_old_value_text
8479 -- Purpose : Returns the display text for the old schedule value
8480 -- of the assignment.
8481 --
8482 FUNCTION get_old_value_text (p_exception_type_code IN VARCHAR2,
8483 p_assignment_id IN NUMBER,
8484 p_start_date IN DATE,
8485 p_end_date IN DATE) RETURN VARCHAR2
8486 IS
8487 l_resource_calendar VARCHAR2(80);
8488 l_old_value_text VARCHAR2(240);
8489 l_current_value VARCHAR2(240);
8490 l_previous_value VARCHAR2(240);
8491 l_count NUMBER;
8492 l_multiple VARCHAR2(1);
8493 l_history_exist VARCHAR2(1);
8494 l_apprvl_status_code pa_project_assignments.apprvl_status_code%TYPE;
8495
8496 CURSOR C1 IS
8497 SELECT calendar_id, calendar_type, start_date, end_date
8498 FROM pa_assignments_history
8499 WHERE assignment_id = p_assignment_id
8500 AND last_approved_flag = 'Y';
8501
8502 v_c1 C1%ROWTYPE;
8503
8504 CURSOR C1_CURRENT IS
8505 SELECT calendar_id, calendar_type, start_date, end_date
8506 FROM pa_project_assignments
8507 WHERE assignment_id = p_assignment_id;
8508
8509 v_c1_current C1_CURRENT%ROWTYPE;
8510
8511 CURSOR C2 IS
8512 SELECT to_char(trunc(monday_hours,2)) mon_hours,
8513 to_char(trunc(tuesday_hours,2)) tue_hours,
8514 to_char(trunc(wednesday_hours,2)) wed_hours,
8515 to_char(trunc(thursday_hours,2)) thu_hours,
8516 to_char(trunc(friday_hours,2)) fri_hours,
8517 to_char(trunc(saturday_hours,2)) sat_hours,
8518 to_char(trunc(sunday_hours,2)) sun_hours,
8519 status_code,
8520 start_date,
8521 end_date
8522 FROM pa_schedules_history
8523 WHERE assignment_id = p_assignment_id
8524 AND last_approved_flag = 'Y'
8525 AND ( (start_date <= p_start_date AND end_date >= p_end_date)
8526 OR (start_date >= p_start_date AND end_date <= p_end_date)
8527 OR (start_date <= p_start_date AND p_start_date <= end_date)
8528 OR (start_date <= p_end_date AND p_end_date <= end_date));
8529
8530 v_c2 C2%ROWTYPE;
8531
8532 CURSOR C2_CURRENT IS
8533 SELECT to_char(trunc(monday_hours,2)) mon_hours,
8534 to_char(trunc(tuesday_hours,2)) tue_hours,
8535 to_char(trunc(wednesday_hours,2)) wed_hours,
8536 to_char(trunc(thursday_hours,2)) thu_hours,
8537 to_char(trunc(friday_hours,2)) fri_hours,
8538 to_char(trunc(saturday_hours,2)) sat_hours,
8539 to_char(trunc(sunday_hours,2)) sun_hours,
8540 status_code,
8541 start_date,
8542 end_date
8543 FROM pa_schedules
8544 WHERE assignment_id = p_assignment_id
8545 AND ( (start_date <= p_start_date AND end_date >= p_end_date)
8546 OR (start_date >= p_start_date AND end_date <= p_end_date)
8547 OR (start_date <= p_start_date AND p_start_date <= end_date)
8548 OR (start_date <= p_end_date AND p_end_date <= end_date));
8549
8550 v_c2_current C2_CURRENT%ROWTYPE;
8551
8552 CURSOR get_apprvl_status_code IS
8553 SELECT apprvl_status_code
8554 FROM pa_project_assignments
8555 WHERE assignment_id = p_assignment_id;
8556
8557 /* Added for bug 1524874*/
8558 TYPE change_hours_check_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
8559
8560 change_hours_check change_hours_check_type;
8561 total_nonzero number;
8562
8563 week_of_day change_hours_check_type;
8564
8565 /* End bug 1524874*/
8566
8567 BEGIN
8568 -- initialize the return value
8569 l_old_value_text := null;
8570
8571 OPEN C1;
8572 FETCH C1 INTO v_c1;
8573 IF C1%FOUND THEN
8574 l_history_exist := 'Y';
8575 ELSE
8576 l_history_exist := 'N';
8577 END IF;
8578 CLOSE C1;
8579
8580 -- get approval status
8581 OPEN get_apprvl_status_code;
8582 FETCH get_apprvl_status_code INTO l_apprvl_status_code;
8583 CLOSE get_apprvl_status_code;
8584
8585 ------------------------------------------------------------------
8586 -- CHANGE_DURATION OR SHIFT_DURATION
8587 ------------------------------------------------------------------
8588 IF p_exception_type_code = 'CHANGE_DURATION' OR p_exception_type_code = 'SHIFT_DURATION' OR p_exception_type_code = 'DURATION_PATTERN_SHIFT' THEN
8589 IF (l_history_exist = 'Y' AND l_apprvl_status_code <> PA_ASSIGNMENT_APPROVAL_PUB.g_approved) THEN
8590 l_old_value_text := PA_SCHEDULE_PVT.get_date_range_text(v_c1.start_date, v_c1.end_date);
8591 ELSE
8592 OPEN C1_CURRENT;
8593 FETCH C1_CURRENT INTO v_c1_current;
8594 CLOSE C1_CURRENT;
8595 l_old_value_text := get_date_range_text(v_c1_current.start_date, v_c1_current.end_date);
8596 END IF;
8597
8598 ------------------------------------------------------------------
8599 -- CHANGE_STATUS
8600 ------------------------------------------------------------------
8601 ELSIF p_exception_type_code = 'CHANGE_STATUS' THEN
8602 l_count := 0;
8603 l_multiple := 'F';
8604
8605 IF (l_history_exist = 'Y' AND l_apprvl_status_code <> PA_ASSIGNMENT_APPROVAL_PUB.g_approved) THEN
8606 FOR v_c2 IN C2 LOOP
8607 IF l_count = 0 THEN
8608 l_current_value := v_c2.status_code;
8609 SELECT project_status_name
8610 INTO l_old_value_text
8611 FROM pa_project_statuses
8612 WHERE project_status_code = v_c2.status_code;
8613 ELSE
8614 l_previous_value := l_current_value;
8615 l_current_value := v_c2.status_code;
8616 IF (l_previous_value <> l_current_value) THEN
8617 SELECT meaning
8618 INTO l_old_value_text
8619 FROM pa_lookups
8620 WHERE lookup_type = 'PA_SCH_UPDATE_TOP'
8621 AND lookup_code = 'PA_MULTIPLE';
8622 l_multiple := 'T';
8623 END IF;
8624 END IF;
8625 l_count := l_count + 1;
8626 EXIT WHEN l_multiple = 'T';
8627 END LOOP;
8628 ELSE
8629 FOR v_c2_current IN C2_CURRENT LOOP
8630 IF l_count = 0 THEN
8631 l_current_value := v_c2_current.status_code;
8632 SELECT project_status_name
8633 INTO l_old_value_text
8634 FROM pa_project_statuses
8635 WHERE project_status_code = v_c2_current.status_code;
8636 ELSE
8637 l_previous_value := l_current_value;
8638 l_current_value := v_c2_current.status_code;
8639 IF (l_previous_value <> l_current_value) THEN
8640 SELECT meaning
8641 INTO l_old_value_text
8642 FROM pa_lookups
8643 WHERE lookup_type = 'PA_SCH_UPDATE_TOP'
8644 AND lookup_code = 'PA_MULTIPLE';
8645 l_multiple := 'T';
8646 END IF;
8647 END IF;
8648 l_count := l_count + 1;
8649 EXIT WHEN l_multiple = 'T';
8650 END LOOP;
8651 END IF;
8652
8653 ------------------------------------------------------------------
8654 -- CHANGE_WORK_PATTERN
8655 ------------------------------------------------------------------
8656 ELSIF p_exception_type_code = 'CHANGE_WORK_PATTERN' THEN
8657 l_count := 0;
8658 l_multiple := 'F';
8659 IF (l_history_exist = 'Y' AND l_apprvl_status_code <> PA_ASSIGNMENT_APPROVAL_PUB.g_approved) THEN
8660 FOR v_c2 IN C2 LOOP
8661 IF l_count = 0 THEN
8662 l_current_value := v_c2.mon_hours||','||v_c2.tue_hours||','||v_c2.wed_hours||','||
8663 v_c2.thu_hours||','||v_c2.fri_hours||','||v_c2.sat_hours||','|| v_c2.sun_hours;
8664 l_old_value_text := l_current_value;
8665 ELSE
8666 l_previous_value := l_current_value;
8667 l_current_value := v_c2.mon_hours||','||v_c2.tue_hours||','||v_c2.wed_hours||','||
8668 v_c2.thu_hours||','||v_c2.fri_hours||','||v_c2.sat_hours||','||v_c2.sun_hours;
8669 IF (l_previous_value <> l_current_value) THEN
8670 SELECT meaning
8671 INTO l_old_value_text
8672 FROM pa_lookups
8673 WHERE lookup_type = 'PA_SCH_UPDATE_TOP'
8674 AND lookup_code = 'PA_MULTIPLE';
8675 l_multiple := 'T';
8676 END IF;
8677 END IF;
8678 l_count := l_count + 1;
8679 EXIT WHEN l_multiple = 'T';
8680 END LOOP;
8681 ELSE
8682 FOR v_c2_current IN C2_CURRENT LOOP
8683 IF l_count = 0 THEN
8684 l_current_value := v_c2_current.mon_hours||','||v_c2_current.tue_hours||','||v_c2_current.wed_hours||','||
8685 v_c2_current.thu_hours||','||v_c2_current.fri_hours||','||v_c2_current.sat_hours||','||
8686 v_c2_current.sun_hours;
8687 l_old_value_text := l_current_value;
8688 ELSE
8689 l_previous_value := l_current_value;
8690 l_current_value := v_c2_current.mon_hours||','||v_c2_current.tue_hours||','||v_c2_current.wed_hours||','||
8691 v_c2_current.thu_hours||','||v_c2_current.fri_hours||','||v_c2_current.sat_hours||','||
8692 v_c2_current.sun_hours;
8693 IF (l_previous_value <> l_current_value) THEN
8694 SELECT meaning
8695 INTO l_old_value_text
8696 FROM pa_lookups
8697 WHERE lookup_type = 'PA_SCH_UPDATE_TOP'
8698 AND lookup_code = 'PA_MULTIPLE';
8699 l_multiple := 'T';
8700 END IF;
8701 END IF;
8702 l_count := l_count + 1;
8703 EXIT WHEN l_multiple = 'T';
8704 END LOOP;
8705 END IF;
8706 ------------------------------------------------------------------
8707 -- CHANGE_HOURS
8708 ------------------------------------------------------------------
8709 ELSIF p_exception_type_code = 'CHANGE_HOURS' THEN
8710 IF ( p_end_date - p_start_date > 7) THEN
8711 SELECT meaning
8712 INTO l_old_value_text
8713 FROM pa_lookups
8714 WHERE lookup_type = 'PA_SCH_UPDATE_TOP'
8715 AND lookup_code = 'PA_MULTIPLE';
8716
8717 ELSE
8718 total_nonzero :=0;
8719
8720 FOR date_check IN 1..7 LOOP
8721 week_of_day(date_check) :=0;
8722 END LOOP;
8723
8724 FOR date_check IN 0..(nvl(p_end_date,p_start_date) - nvl(p_start_date,p_end_date)) LOOP
8725 week_of_day(to_number(to_char(nvl(p_start_date,p_end_date) + date_check,'D'))):=1;
8726 END LOOP;
8727
8728 IF (l_history_exist = 'Y' AND l_apprvl_status_code <> PA_ASSIGNMENT_APPROVAL_PUB.g_approved) THEN
8729 FOR v_c2 IN C2 LOOP
8730 IF(week_of_day(2)=1)then
8731 change_hours_check(total_nonzero) := v_c2.mon_hours;
8732 total_nonzero:=total_nonzero+1;
8733 END IF;
8734 IF(week_of_day(3)=1)then
8735 change_hours_check(total_nonzero):=v_c2.tue_hours;
8736 total_nonzero:=total_nonzero+1;
8737 END IF;
8738 IF(week_of_day(4)=1)then
8739 change_hours_check(total_nonzero):=v_c2.wed_hours;
8740 total_nonzero:=total_nonzero+1;
8741 END IF;
8742 IF(week_of_day(5)=1)then
8743 change_hours_check(total_nonzero):=v_c2.thu_hours;
8744 total_nonzero:=total_nonzero+1;
8745 END IF;
8746 IF(week_of_day(6)=1)then
8747 change_hours_check(total_nonzero):=v_c2.fri_hours;
8748 total_nonzero:=total_nonzero+1;
8749 END IF;
8750 IF(week_of_day(7)=1)then
8751 change_hours_check(total_nonzero):=v_c2.sat_hours;
8752 total_nonzero:=total_nonzero+1;
8753 END IF;
8754 IF(week_of_day(1)=1)then
8755 change_hours_check(total_nonzero):=v_c2.sun_hours;
8756 total_nonzero:=total_nonzero+1;
8757 END IF;
8758 End LOOP;
8759 ELSE
8760 FOR v_c2_current IN C2_CURRENT LOOP
8761 IF(week_of_day(2)=1)then
8762 change_hours_check(total_nonzero) := v_c2_current.mon_hours;
8763 total_nonzero:=total_nonzero+1;
8764 END IF;
8765 IF(week_of_day(3)=1)then
8766 change_hours_check(total_nonzero):=v_c2_current.tue_hours;
8767 total_nonzero:=total_nonzero+1;
8768 END IF;
8769 IF(week_of_day(4)=1)then
8770 change_hours_check(total_nonzero):=v_c2_current.wed_hours;
8771 total_nonzero:=total_nonzero+1;
8772 END IF;
8773 IF(week_of_day(5)=1)then
8774 change_hours_check(total_nonzero):=v_c2_current.thu_hours;
8775 total_nonzero:=total_nonzero+1;
8776 END IF;
8777 IF(week_of_day(6)=1)then
8778 change_hours_check(total_nonzero):=v_c2_current.fri_hours;
8779 total_nonzero:=total_nonzero+1;
8780 END IF;
8781 IF(week_of_day(7)=1)then
8782 change_hours_check(total_nonzero):=v_c2_current.sat_hours;
8783 total_nonzero:=total_nonzero+1;
8784 END IF;
8785 IF(week_of_day(1)=1)then
8786 change_hours_check(total_nonzero):=v_c2_current.sun_hours;
8787 total_nonzero:=total_nonzero+1;
8788 END IF;
8789 End LOOP;
8790 END IF;
8791
8792 FOR i IN 1..total_nonzero-1 LOOP
8793 IF (change_hours_check(i) <>change_hours_check(0)) then
8794 SELECT meaning INTO l_old_value_text
8795 FROM pa_lookups
8796 WHERE lookup_type = 'PA_SCH_UPDATE_TOP'
8797 AND lookup_code = 'PA_MULTIPLE';
8798 EXIT;
8799 END IF;
8800 END LOOP;
8801
8802 IF (l_old_value_text IS NULL) THEN
8803 If(change_hours_check.EXISTS(0)) THEN
8804 l_old_value_text := change_hours_check(0);
8805 ELSE
8806 l_old_value_text := ' ';
8807 END IF;
8808 END IF;
8809
8810 END IF; -- end of change hours
8811
8812 ELSE
8813 l_old_value_text := ' ';
8814 END IF;
8815
8816 RETURN l_old_value_text;
8817
8818 EXCEPTION
8819 WHEN OTHERS THEN
8820 return null;
8821 END get_old_value_text;
8822
8823
8824 --
8825 -- Function : Get_new_value_text
8826 -- Purpose : Returns the display text for the new schedule value of the assignment.
8827 --
8828 FUNCTION Get_new_value_text (p_exception_type_code IN VARCHAR2,
8829 p_new_calendar_id IN NUMBER,
8830 p_new_start_date IN DATE,
8831 p_new_end_date IN DATE,
8832 p_new_status_code IN VARCHAR2,
8833 p_new_change_calendar_id IN NUMBER,
8834 p_new_monday_hours IN NUMBER,
8835 p_new_tuesday_hours IN NUMBER,
8836 p_new_wednesday_hours IN NUMBER,
8837 p_new_thursday_hours IN NUMBER,
8838 p_new_friday_hours IN NUMBER,
8839 p_new_saturday_hours IN NUMBER,
8840 p_new_sunday_hours IN NUMBER,
8841 p_new_change_hours_type_code IN VARCHAR2,
8842 p_new_non_working_day_flag IN VARCHAR2,
8843 p_new_hours_per_day IN NUMBER,
8844 p_new_calendar_percent IN NUMBER,
8845 p_new_change_cal_type_code IN VARCHAR2 := null,
8846 p_new_change_calendar_name IN VARCHAR2 := null)
8847 RETURN VARCHAR2
8848 IS
8849 l_new_value_text VARCHAR2(240);
8850 l_new_calendar_name VARCHAR2(80);
8851 l_non_working_day_flag VARCHAR2(240);
8852
8853 BEGIN
8854 l_new_value_text := '';
8855
8856 --------------------------------------------------------------
8857 -- p_exception_type_code = 'CHANGE_DURATION'/ 'SHIFT_DURATION'
8858 --------------------------------------------------------------
8859 IF p_exception_type_code = 'CHANGE_DURATION' OR p_exception_type_code = 'SHIFT_DURATION' OR p_exception_type_code = 'DURATION_PATTERN_SHIFT' THEN
8860 l_new_value_text := PA_SCHEDULE_PVT.get_date_range_text(p_new_start_date, p_new_end_date);
8861
8862 --------------------------------------------------
8863 -- p_exception_type_code = 'CHANGE_STATUS'
8864 --------------------------------------------------
8865 ELSIF p_exception_type_code = 'CHANGE_STATUS' THEN
8866 SELECT project_status_name
8867 INTO l_new_value_text
8868 FROM pa_project_statuses
8869 WHERE project_status_code = p_new_status_code;
8870
8871 --------------------------------------------------
8872 -- p_exception_type_code = 'CHANGE_WORK_PATTERN'
8873 --------------------------------------------------
8874 ELSIF p_exception_type_code = 'CHANGE_WORK_PATTERN' THEN
8875 l_new_value_text := to_char(trunc(p_new_monday_hours,2)) ||','||
8876 to_char(trunc(p_new_tuesday_hours,2)) ||','||
8877 to_char(trunc(p_new_wednesday_hours,2)) ||','||
8878 to_char(trunc(p_new_thursday_hours,2)) ||','||
8879 to_char(trunc(p_new_friday_hours,2)) ||','||
8880 to_char(trunc(p_new_saturday_hours,2)) ||','||
8881 to_char(trunc(p_new_sunday_hours,2));
8882
8883 --------------------------------------------------
8884 -- p_exception_type_code = 'CHANGE_HOURS'
8885 --------------------------------------------------
8886 ELSIF p_exception_type_code = 'CHANGE_HOURS' THEN
8887 IF p_new_non_working_day_flag = 'Y' THEN
8888 l_non_working_day_flag := get_ak_attribute_label('PA_SCH_UPDATE_TOP','PA_INCLUDE_NON_WORKING');
8889 END IF;
8890
8891 --
8892 -- If Percetage has been selected
8893 --
8894 IF p_new_change_hours_type_code = 'PERCENTAGE' THEN
8895 IF p_new_change_cal_type_code = 'RESOURCE' THEN
8896 l_new_calendar_name := get_ak_attribute_label('PA_SCH_UPDATE_TOP','PA_RESOURCE_CALENDAR');
8897 ELSIF p_new_change_cal_type_code = 'PROJECT' THEN
8898 SELECT calendar_name
8899 INTO l_new_calendar_name
8900 FROM jtf_calendars_vl
8901 WHERE calendar_id = p_new_calendar_id;
8902 -- if Other calendar has been selected
8903 ELSE
8904 IF (p_new_change_calendar_name IS NOT NULL) THEN
8905 l_new_calendar_name := p_new_change_calendar_name;
8906 ELSE
8907 SELECT calendar_name
8908 INTO l_new_calendar_name
8909 FROM jtf_calendars_vl
8910 WHERE calendar_id = p_new_change_calendar_id;
8911 END IF;
8912 END IF;
8913
8914 IF l_non_working_day_flag IS NOT NULL THEN
8915 l_new_value_text := to_char(trunc(p_new_calendar_percent,2))||'%'||
8916 ' - '|| l_new_calendar_name||' - '|| l_non_working_day_flag;
8917 ELSE
8918 l_new_value_text := to_char(trunc(p_new_calendar_percent,2))||'%'|| ' - '|| l_new_calendar_name;
8919 END IF;
8920
8921 --
8922 -- If 'Hours per day' has been selected
8923 --
8924 ELSE
8925 IF l_non_working_day_flag IS NOT NULL THEN
8926 l_new_value_text := to_char(trunc(p_new_hours_per_day,2))||' - '||l_non_working_day_flag;
8927 ELSE
8928 l_new_value_text := to_char(trunc(p_new_hours_per_day,2));
8929 END IF;
8930 END IF;
8931
8932 END IF; -- ELSIF p_exception_type_code = 'CHANGE_HOURS'
8933
8934 RETURN l_new_value_text;
8935
8936 END get_new_value_text;
8937
8938
8939 -- Function : get_num_days_of_conflict
8940 -- Purpose : Return number of days in assignment that are in conflict with
8941 -- existing confirmed assignments, and potentially in conflict
8942 -- with other assignments in transaction including itself.
8943 FUNCTION get_num_days_of_conflict (p_assignment_id IN NUMBER,
8944 p_resource_id IN NUMBER,
8945 p_conflict_group_id IN NUMBER) RETURN NUMBER
8946 IS
8947
8948 G_AVAILABILITY_CAL_PERIOD VARCHAR2(15) := FND_PROFILE.VALUE('PA_AVAILABILITY_CAL_PERIOD');
8949 G_OVERCOMMITMENT_PERCENTAGE NUMBER := FND_NUMBER.CANONICAL_TO_NUMBER(FND_PROFILE.VALUE('PA_OVERCOMMITMENT_PERCENTAGE'))/100;
8950
8951 l_count NUMBER := 0;
8952 l_start_date DATE;
8953 l_end_date DATE;
8954
8955 BEGIN
8956
8957 SELECT start_date, end_date
8958 INTO l_start_date, l_end_date
8959 FROM pa_project_assignments
8960 WHERE assignment_id = p_assignment_id;
8961
8962 IF (G_AVAILABILITY_CAL_PERIOD = 'DAILY' OR G_AVAILABILITY_CAL_PERIOD = 'WEEKLY') THEN
8963 SELECT COUNT(*)
8964 INTO l_count
8965 FROM (
8966 select DISTINCT fi.item_date
8967 from pa_forecast_items fi,
8968 (select resource_id,
8969 sum(item_quantity) assigned_quantity,
8970 item_date,
8971 delete_flag
8972 from
8973 (select fi1.resource_id,
8974 fi1.item_quantity,
8975 fi1.item_date,
8976 fi1.delete_flag
8977 from pa_forecast_items fi1, pa_project_assignments asgn, pa_schedules sch, pa_project_statuses a, pa_project_statuses b
8978 where (fi1.assignment_id = p_assignment_id
8979 or fi1.assignment_id in
8980 (select conflict_assignment_id
8981 from pa_assignment_conflict_hist
8982 where assignment_id = p_assignment_id
8983 and conflict_group_id = p_conflict_group_id
8984 and self_conflict_flag = 'N'
8985 and intra_txn_conflict_flag = 'Y'))
8986 and fi1.assignment_id = asgn.assignment_id
8987 and asgn.assignment_id = sch.assignment_id
8988 and asgn.apprvl_status_code NOT IN ('ASGMT_APPRVL_APPROVED', 'ASGMT_APPRVL_REJECTED')
8989 and fi1.item_date between sch.start_date and sch.end_date
8990 and sch.status_code = a.project_status_code
8991 and a.wf_success_status_code = b.project_status_code
8992 and b.project_system_status_code = 'STAFFED_ASGMT_CONF'
8993 and fi1.forecast_item_type = 'A'
8994 UNION ALL
8995 select fi2.resource_id,
8996 item_quantity,
8997 fi2.item_date,
8998 fi2.delete_flag
8999 from pa_forecast_items fi2, pa_project_assignments asgn, pa_assignment_conflict_hist hist
9000 where fi2.assignment_id = asgn.assignment_id
9001 and fi2.assignment_id = hist.conflict_assignment_id
9002 and hist.conflict_group_id = p_conflict_group_id
9003 and hist.assignment_id = p_assignment_id
9004 and hist.self_conflict_flag = 'N'
9005 and fi2.asgmt_sys_status_code = 'STAFFED_ASGMT_CONF'
9006 and ((asgn.apprvl_status_code in ('ASGMT_APPRVL_APPROVED', 'ASGMT_APPRVL_REJECTED') and hist.intra_txn_conflict_flag = 'Y')
9007 or hist.intra_txn_conflict_flag = 'N')
9008 and fi2.forecast_item_type = 'A'
9009 UNION ALL
9010 select fi2.resource_id,
9011 item_quantity,
9012 fi2.item_date,
9013 fi2.delete_flag
9014 from pa_forecast_items fi2, pa_project_assignments asgn
9015 where fi2.assignment_id = p_assignment_id
9016 and fi2.assignment_id = asgn.assignment_id
9017 and fi2.asgmt_sys_status_code = 'STAFFED_ASGMT_CONF'
9018 and asgn.apprvl_status_code in ('ASGMT_APPRVL_APPROVED', 'ASGMT_APPRVL_REJECTED')
9019 and fi2.forecast_item_type = 'A'
9020 )
9021 group by resource_id, item_date, delete_flag
9022 )FI_ASSIGNED,
9023 (select capacity_quantity,
9024 item_date,
9025 delete_flag,
9026 resource_id
9027 from pa_forecast_items
9028 where forecast_item_type = 'U'
9029 )fi_capacity
9030 where fi.resource_id = p_resource_id
9031 and fi.resource_id = fi_capacity.resource_id
9032 and fi_capacity.resource_id = fi_assigned.resource_id
9033 and fi.assignment_id = p_assignment_id
9034 and fi.item_date BETWEEN l_start_date and l_end_date
9035 and fi.item_date = fi_capacity.item_date
9036 and fi_capacity.item_date = fi_assigned.item_date
9037 and ((fi_capacity.capacity_quantity*(1+G_OVERCOMMITMENT_PERCENTAGE) - fi_assigned.assigned_quantity <= 0 and G_OVERCOMMITMENT_PERCENTAGE > 0)
9038 or (fi_capacity.capacity_quantity - fi_assigned.assigned_quantity < 0 and G_OVERCOMMITMENT_PERCENTAGE = 0))
9039 and fi.delete_flag = 'N'
9040 and fi.delete_flag = fi_capacity.delete_flag
9041 and fi_capacity.delete_flag = fi_assigned.delete_flag
9042 and fi.forecast_item_type = 'A'
9043 );
9044
9045 /* Commented out the weekly version due to performance problem and this change is
9046 approved by functional team.
9047 ELSIF G_AVAILABILITY_CAL_PERIOD = 'WEEKLY' THEN
9048 SELECT COUNT(*)
9049 INTO l_count
9050 FROM (
9051 select DISTINCT
9052 fi.item_date
9053 from pa_forecast_items fi,
9054 (select
9055 resource_id,
9056 sum(item_quantity) total_assigned_quantity,
9057 GLOBAL_EXP_PERIOD_END_DATE week_end_date,
9058 delete_flag,
9059 forecast_item_type
9060 from pa_forecast_items fi1, pa_schedules sch, pa_project_statuses a, pa_project_statuses b
9061 where (fi1.assignment_id = p_assignment_id
9062 or fi1.assignment_id in (select conflict_assignment_id
9063 from pa_assignment_conflict_hist
9064 where conflict_group_id = p_conflict_group_id
9065 and assignment_id = p_assignment_id
9066 and self_conflict_flag = 'N'))
9067 and fi1.assignment_id = sch.assignment_id
9068 and item_date BETWEEN l_start_date AND l_end_date
9069 and item_date between sch.start_date and sch.end_date
9070 and sch.status_code = a.project_status_code
9071 and a.wf_success_status_code = b.project_status_code
9072 and b.project_system_status_code = 'STAFFED_ASGMT_CONF'
9073 group by resource_id, GLOBAL_EXP_PERIOD_END_DATE, forecast_item_type, delete_flag
9074 )fi_assigned,
9075 (select resource_id,
9076 sum(capacity_quantity) capacity_quantity,
9077 GLOBAL_EXP_PERIOD_END_DATE week_end_date,
9078 delete_flag
9079 from pa_forecast_items
9080 where forecast_item_type = 'U'
9081 group by resource_id, GLOBAL_EXP_PERIOD_END_DATE, delete_flag
9082 )fi_capacity
9083 where fi.resource_id = p_resource_id
9084 and fi.resource_id = fi_capacity.resource_id
9085 and fi_capacity.resource_id = fi_assigned.resource_id
9086 and fi.item_date BETWEEN l_start_date AND l_end_date
9087 and fi.GLOBAL_EXP_PERIOD_END_DATE = fi_capacity.week_end_date
9088 and fi_capacity.week_end_date = fi_assigned.week_end_date
9089 and ((fi_capacity.capacity_quantity*(1+G_OVERCOMMITMENT_PERCENTAGE) - fi_assigned.total_assigned_quantity <= 0 and G_OVERCOMMITMENT_PERCENTAGE > 0)
9090 or (fi_capacity.capacity_quantity - fi_assigned.total_assigned_quantity < 0 and G_OVERCOMMITMENT_PERCENTAGE = 0))
9091 and fi.delete_flag = 'N'
9092 and fi.delete_flag = fi_capacity.delete_flag
9093 and fi_capacity.delete_flag = fi_assigned.delete_flag
9094 and fi.forecast_item_type = 'A'
9095 and fi.forecast_item_type = fi_assigned.forecast_item_type
9096 and fi.assignment_id = p_assignment_id
9097 );
9098
9099 */
9100 END IF;
9101
9102 RETURN (l_count);
9103
9104 EXCEPTION
9105 WHEN OTHERS THEN
9106 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
9107 p_procedure_name => 'get_num_days_of_conflict');
9108 RAISE;
9109 END get_num_days_of_conflict;
9110
9111
9112 -- Function : column_val_conflict_exists
9113 -- Purpose : Returns lookup code for value to display in 'Conflict Exists'
9114 -- column ('Yes', 'No')
9115 FUNCTION column_val_conflict_exists (p_conflict_group_id IN NUMBER,
9116 p_assignment_id IN NUMBER ) RETURN VARCHAR2
9117 IS
9118
9119 CURSOR c1 IS
9120 SELECT conflict_group_id, assignment_id
9121 FROM pa_assignment_conflict_hist
9122 WHERE conflict_group_id = p_conflict_group_id
9123 AND assignment_id = p_assignment_id;
9124 -- AND processed_flag = 'N';
9125
9126 v_c1 c1%ROWTYPE;
9127 l_result VARCHAR2(80);
9128
9129 BEGIN
9130
9131 OPEN c1;
9132 FETCH c1 INTO v_c1;
9133
9134 IF c1%NOTFOUND THEN
9135 SELECT meaning
9136 INTO l_result
9137 FROM pa_lookups
9138 WHERE lookup_type = 'CONFLICT_EXISTS'
9139 AND lookup_code = 'NO';
9140 RETURN(l_result);
9141 ELSE
9142 SELECT meaning
9143 INTO l_result
9144 FROM pa_lookups
9145 WHERE lookup_type = 'CONFLICT_EXISTS'
9146 AND lookup_code = 'YES';
9147 RETURN(l_result);
9148 END IF;
9149
9150 CLOSE c1;
9151
9152 EXCEPTION
9153 WHEN OTHERS THEN
9154 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
9155 p_procedure_name => 'column_val_conflict_exists');
9156 RAISE;
9157 END column_val_conflict_exists;
9158
9159
9160 -- Function : column_val_conflict_action
9161 -- Purpose : Returns value to display in 'Action on Approval' column
9162 -- ('Remove Conflicts', Continue with Conflicts', ''). A
9163 -- self-conflict would imply 'Continue with Conflicts'. No value
9164 -- would be shown for those assignments not causing
9165 -- overcommitment.
9166 FUNCTION column_val_conflict_action (p_conflict_group_id IN NUMBER,
9167 p_assignment_id IN NUMBER ) RETURN VARCHAR2
9168 IS
9169
9170 l_action_code VARCHAR2(30);
9171
9172 CURSOR c1 IS
9173 SELECT resolve_conflicts_action_code
9174 FROM pa_assignment_conflict_hist
9175 WHERE conflict_group_id = p_conflict_group_id
9176 AND assignment_id = p_assignment_id;
9177
9178 v_c1 c1%ROWTYPE;
9179 l_result VARCHAR2(80);
9180
9181 BEGIN
9182 OPEN c1;
9183 FETCH c1 INTO v_c1;
9184
9185 IF c1%NOTFOUND THEN
9186 RETURN (NULL);
9187 ELSE
9188 SELECT meaning
9189 INTO l_result
9190 FROM pa_lookups
9191 WHERE lookup_type = 'RESOLVE_CONFLICTS_ACTION_CODE'
9192 AND lookup_code = v_c1.resolve_conflicts_action_code;
9193 RETURN (l_result);
9194 END IF;
9195
9196 close c1;
9197
9198 EXCEPTION
9199 WHEN OTHERS THEN
9200 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
9201 p_procedure_name => 'column_val_conflict_action');
9202 RAISE;
9203 END column_val_conflict_action;
9204
9205
9206 -- Function : check_conflict_proj_affected
9207 -- Purpose : Returns a value to the View Conflicts page to filter for
9208 -- the assignments that are in conflict with the assignments in
9209 -- a particular conflicting project.
9210 FUNCTION check_conflict_proj_affected (p_conflict_group_id IN NUMBER,
9211 p_assignment_id IN NUMBER,
9212 p_conflict_project_id IN NUMBER) RETURN VARCHAR2
9213
9214 IS
9215
9216 l_affected VARCHAR2(1) := 'N';
9217 CURSOR c1 IS
9218 SELECT DISTINCT asgn.project_id
9219 FROM pa_project_assignments asgn, pa_assignment_conflict_hist hist
9220 WHERE asgn.assignment_id = hist.conflict_assignment_id
9221 AND hist.conflict_group_id = p_conflict_group_id
9222 AND hist.assignment_id = p_assignment_id;
9223
9224 BEGIN
9225
9226 FOR v_c1 IN c1 LOOP
9227 IF v_c1.project_id = p_conflict_project_id THEN
9228 l_affected := 'Y';
9229 EXIT;
9230 END IF;
9231 END LOOP;
9232
9233 RETURN (l_affected);
9234
9235 EXCEPTION
9236 WHEN OTHERS THEN
9237 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
9238 p_procedure_name => 'check_conflict_proj_affected');
9239 RAISE;
9240 END check_conflict_proj_affected;
9241
9242
9243 -- Function : check_self_conflict_exist
9244 -- Purpose : Returns a value to the View Conflicts page to filter for
9245 -- the assignments with self_conflict_flag = 'Y' and being chosen to
9246 -- remove conflicts.
9247 FUNCTION check_self_conflict_exist (p_conflict_group_id IN NUMBER,
9248 p_assignment_id IN NUMBER) RETURN VARCHAR2
9249 IS
9250 l_result VARCHAR2(1);
9251
9252 CURSOR c1 IS
9253 SELECT self_conflict_flag
9254 FROM pa_assignment_conflict_hist
9255 WHERE conflict_group_id = p_conflict_group_id
9256 AND assignment_id = p_assignment_id
9257 AND self_conflict_flag = 'Y'
9258 AND resolve_conflicts_action_code = 'REMOVE_CONFLICTS';
9259
9260 v_c1 c1%ROWTYPE;
9261 BEGIN
9262
9263 OPEN c1;
9264 FETCH c1 INTO v_c1;
9265 IF c1%NOTFOUND THEN
9266 l_result := 'N';
9267 ELSE
9268 l_result := 'Y';
9269 END IF;
9270 CLOSE c1;
9271
9272 RETURN (l_result);
9273
9274 EXCEPTION
9275 WHEN OTHERS THEN
9276 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
9277 p_procedure_name => 'check_self_conflict_exist');
9278 RAISE;
9279 END check_self_conflict_exist;
9280
9281
9282 --
9283 -- Returns ak attribute label corresponding p_region_code, p_attribute_code
9284 --
9285 FUNCTION get_ak_attribute_label (p_region_code IN VARCHAR2,
9286 p_attribute_code IN VARCHAR2)
9287 RETURN VARCHAR2
9288 IS
9289 l_attribute_label VARCHAR2(30);
9290 BEGIN
9291 SELECT meaning
9292 INTO l_attribute_label
9293 FROM pa_lookups
9294 WHERE lookup_type = p_region_code
9295 AND lookup_code = p_attribute_code;
9296
9297 RETURN l_attribute_label;
9298
9299 EXCEPTION
9300 WHEN NO_DATA_FOUND THEN
9301 RETURN null;
9302 WHEN OTHERS THEN
9303 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PVT',
9304 p_procedure_name => 'get_ak_attribute_label');
9305 RAISE;
9306 END get_ak_attribute_label;
9307
9308 -- This function determines the day of the week given a particular date
9309 -- Input parameters
9310 -- Parameters Type Required Description
9311 -- P_Date DATE YES Date
9312 --
9313 -- Out parameters
9314 -- PA_SCHEDULE_PVT.DayOfWeekType YES Day of the week (3 character abbreviation)
9315 --
9316 FUNCTION get_day_of_week (p_date IN DATE) RETURN PA_SCHEDULE_PVT.DayOfWeekType IS
9317 BEGIN
9318 -- RETURN to_char(p_date,'DY'); -- Changed for Bug 5364632
9319 RETURN to_char(p_date,'DY','NLS_DATE_LANGUAGE = AMERICAN');
9320 END get_day_of_week;
9321
9322
9323 -- This function returns the number of hours in a given schedule record for a particular day of the week
9324 -- Input parameters
9325 -- Parameters Type Required Description
9326 -- P_Schedule_Record PA_SCHEDULE_GLOB.ScheduleRecord YES Schedule Record
9327 -- P_Day_Of_Week PA_SCHEDULE_PVT.DayOfWeekType YES Day of the week
9328 --
9329 -- Out parameters
9330 -- NUMBER YES Number of hours schedule on that day
9331 --
9332 FUNCTION get_hours_by_day_of_week (
9333 p_schedule_record IN PA_SCHEDULE_GLOB.ScheduleRecord ,
9334 p_day_of_week IN PA_SCHEDULE_PVT.DayOfWeekType )
9335 RETURN NUMBER IS
9336 l_hours NUMBER := 0;
9337 BEGIN
9338 IF p_day_of_week = 'MON' THEN
9339 l_hours := p_schedule_record.monday_hours;
9340 ELSIF p_day_of_week = 'TUE' THEN
9341 l_hours := p_schedule_record.tuesday_hours;
9342 ELSIF p_day_of_week = 'WED' THEN
9343 l_hours := p_schedule_record.wednesday_hours;
9344 ELSIF p_day_of_week = 'THU' THEN
9345 l_hours := p_schedule_record.thursday_hours;
9346 ELSIF p_day_of_week = 'FRI' THEN
9347 l_hours := p_schedule_record.friday_hours;
9348 ELSIF p_day_of_week = 'SAT' THEN
9349 l_hours := p_schedule_record.saturday_hours;
9350 ELSIF p_day_of_week = 'SUN' THEN
9351 l_hours := p_schedule_record.sunday_hours;
9352 END IF;
9353 RETURN l_hours;
9354 END get_hours_by_day_of_week;
9355
9356 END PA_SCHEDULE_PVT;