DBA Data[Home] [Help]

PACKAGE BODY: APPS.PA_SCHEDULE_PVT

Source


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