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