1 PACKAGE BODY JTF_CALENDAR_PUB AS
2 /* $Header: jtfclavb.pls 120.4.12010000.3 2009/09/18 08:23:40 anangupt ship $ */
3
4 -- ************************************************************************
5 -- Start of Comments
6 -- Package Name : JTF_CLAENDAR_PUB
7 -- Purpose : Joint Task Force core Calendar Public API's
8 -- This package is for finding the availability,
9 -- working shift hours of a particular resource
10 -- during a specified period
11 -- Procedures : (See below for specification)
12 -- Notes : This package is publicly available for use
13 -- History : 09/29/99 VMOVVA created
14 -- History : 11/02/01 Chan-ik Jang Changed jtf_task_assignments
15 -- to jtf_task_all_assignments
16 -- History : 01/08/02 JAWANG Undo Chan-ik's Changes
17 -- 03/05/02 JAWANG returned attribute1 - 15
18 -- in Get_Resource_Shifts API.
19 -- 03/13/02 JAWANG Fixed GSCC Warning of to_date
20 -- 03/27/03 ABRAINA Modified cursors in Get_available_time
21 -- and Get_Res_Schedule.
22 -- 04/10/03 ABRAINA Modified code in Get_Res_Schedule.
23 -- 04/28/03 ABRAINA Modified all cursor c_cal_shift_constr
24 -- and work_hrs for first day of week change
25 -- 06/16/03 ABRAINA Fixed GSCC warning.
26 -- 08/11/03 ABRAINA Added ResourceDt_To_ServerDT
27 -- 12/12/05 SBARAT Changed jtf_rs_resources_vl to jtf_task_resources_vl
28 -- due to MOAC change, bug# 4455792
29 -- End of Comments
30 -- ************************************************************************
31 G_PKG_NAME CONSTANT VARCHAR2(30):= 'JTF_CALENDAR_PUB';
32 G_EXC_REQUIRED_FIELDS_NULL EXCEPTION;
33 --G_EXC_NOT_VALID_RESOURCE EXCEPTION;
34 L_PARAMETERS VARCHAR2(200);
35 --
36 -- Added sort by jawang on 06/27/2002
37 procedure sort_tab(l_tab in out NOCOPY SHIFT_TBL_TYPE ) ;
38 procedure sort_tab_attr(l_tab in out NOCOPY SHIFT_TBL_ATTRIBUTES_TYPE) ;
39 procedure bubble ( p_index in integer ,
40 l_tab in out NOCOPY SHIFT_TBL_TYPE ) ;
41 procedure bubble_attr ( p_index in integer ,
42 l_tab in out NOCOPY SHIFT_TBL_ATTRIBUTES_TYPE ) ;
43
44 Function check_for_required_fields
45 (p_resource_id IN NUMBER := get_g_miss_num ,
46 p_resource_type IN VARCHAR2 := get_g_miss_char,
47 p_start_date IN DATE := get_g_miss_date,
48 p_end_date IN DATE := get_g_miss_date,
49 p_duration IN NUMBER := get_g_miss_num
50 )
51 return boolean is
52 begin
53 if p_resource_id is null or
54 p_resource_type is null or
55 p_start_date is null or
56 p_end_date is null or
57 p_duration is null THEN
58 return(FALSE);
59 else
60 return(TRUE);
61 end if;
62 end;
63
64 -- Added sort by jawang on 06/27/2002
65 /******** Sort Procedure ****************/
66 procedure sort_tab(l_tab in out NOCOPY SHIFT_TBL_TYPE )
67 is
68 l_last number;
69 l_hi number;
70 l_lo number;
71 l_up_datetime date;
72 l_dw_datetime date;
73 begin
74 begin
75 l_last := l_tab.last;
76 exception
77 when collection_is_null then return;
78 end;
79 if l_last is null then return; end if;
80 for l_hi in 2 .. l_last
81 loop
82 --
83 -- Modified for bug 3510573 by ABRAINA
84 --
85 -- Modified for bug 3891896 by ABRAINA
86 --
87 l_up_datetime := to_date( (to_char(l_tab(l_hi).shift_date,'DD/MM/RRRR')||' '||l_tab(l_hi).start_time),'DD/MM/RRRR HH24:MI');
88 l_dw_datetime := to_date( (to_char(l_tab(l_hi-1).shift_date,'DD/MM/RRRR')||' '||l_tab(l_hi-1).start_time),'DD/MM/RRRR HH24:MI');
89 if l_up_datetime < l_dw_datetime then
90 --if l_tab(l_hi).start_time < l_tab(l_hi-1).start_time then
91 --
92 -- End Modification
93 --
94 bubble(l_hi, l_tab);
95 for l_lo in reverse 2 .. l_hi-1
96 loop
97 if l_tab(l_lo).start_time < l_tab(l_lo-1).start_time then
98 bubble(l_lo, l_tab);
99 else
100 exit;
101 end if;
102 end loop;
103 end if;
104 end loop;
105 end sort_tab;
106
107 -- added by sudhir for sorting attribute type table
108
109 /******** Sort Procedure ****************/
110 procedure sort_tab_attr(l_tab in out NOCOPY SHIFT_TBL_ATTRIBUTES_TYPE)
111 is
112 l_last number;
113 l_hi number;
114 l_lo number;
115 l_up_datetime date;
116 l_dw_datetime date;
117 begin
118 begin
119 l_last := l_tab.last;
120 exception
121 when collection_is_null then return;
122 end;
123 if l_last is null then return; end if;
124 for l_hi in 2 .. l_last
125 loop
126 --
127 -- Modified for bug 3510573 by ABRAINA
128 --
129 -- Modified for bug 3891896 by ABRAINA
130 --
131 l_up_datetime := to_date( (to_char(l_tab(l_hi).shift_date,'DD/MM/RRRR')||' '||l_tab(l_hi).start_time),'DD/MM/RRRR HH24:MI');
132 l_dw_datetime := to_date( (to_char(l_tab(l_hi-1).shift_date,'DD/MM/RRRR')||' '||l_tab(l_hi-1).start_time),'DD/MM/RRRR HH24:MI');
133 if l_up_datetime < l_dw_datetime then
134 --if l_tab(l_hi).start_time < l_tab(l_hi-1).start_time then
135 --
136 -- End Modification
137 --
138 bubble_attr(l_hi, l_tab);
139 for l_lo in reverse 2 .. l_hi-1
140 loop
141 if l_tab(l_lo).start_time < l_tab(l_lo-1).start_time then
142 bubble_attr(l_lo, l_tab);
143 else
144 exit;
145 end if;
146 end loop;
147 end if;
148 end loop;
149 end sort_tab_attr;
150
151
152 -- bubble up the row below this one
153 procedure bubble ( p_index in integer ,
154 l_tab in out NOCOPY SHIFT_TBL_TYPE ) is
155 l_rec Shift_Rec_Type;
156 begin
157 l_rec := l_tab(p_index);
158 l_tab(p_index) := l_tab(p_index-1);
159 l_tab(p_index-1) := l_rec;
160 end bubble;
161
162 -- added by sudhir 25/04/2002
163 -- bubble up the row below this one
164 procedure bubble_attr ( p_index in integer ,
165 l_tab in out NOCOPY SHIFT_TBL_ATTRIBUTES_TYPE) is
166 l_rec Shift_Rec_Attributes_Type;
167 begin
168 l_rec := l_tab(p_index);
169 l_tab(p_index) := l_tab(p_index-1);
170 l_tab(p_index-1) := l_rec;
171 end bubble_attr;
172
173 --
174 -- *************** Is Resource Available *********************
175 --
176 PROCEDURE Is_Res_Available
177 ( p_api_version IN NUMBER,
178 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
179 p_resource_id IN NUMBER,
180 p_resource_type IN VARCHAR2,
181 p_start_date_time IN DATE,
182 p_duration IN NUMBER,
183 x_return_status OUT NOCOPY VARCHAR2,
184 x_msg_count OUT NOCOPY NUMBER,
185 x_msg_data OUT NOCOPY VARCHAR2,
186 x_avail OUT NOCOPY VARCHAR2
187 )
188 IS
189 l_api_name CONSTANT VARCHAR2(30) := 'Is_Res_Available';
190 l_api_version CONSTANT NUMBER := 1.0;
191 l_return_status VARCHAR2(1);
192 l_msg_count NUMBER;
193 l_msg_data VARCHAR2(250);
194 l_shift SHIFT_TBL_TYPE;
195 v_begin_time VARCHAR2(5);
196 v_end_time VARCHAR2(5);
197
198 BEGIN
199 -- Standard call to check for call compatibility.
200 IF NOT FND_API.Compatible_API_Call (l_api_version ,
201 p_api_version ,
202 l_api_name ,
203 G_PKG_NAME )
204 THEN
205 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
206 END IF;
207
208 -- Initialize message list if p_init_msg_list is set to TRUE.
209 IF FND_API.to_Boolean( p_init_msg_list ) THEN
210 FND_MSG_PUB.initialize;
211 END IF;
212
213 -- Call to check for required fields
214 IF not check_for_required_fields (p_resource_id =>p_resource_id,
215 p_resource_type =>p_resource_type,
216 p_start_date =>p_start_date_time,
217 p_duration =>p_duration)
218 THEN
219 l_parameters := 'p_resource_id, p_resource_type, p_start_date_time, p_duration';
220 RAISE G_EXC_REQUIRED_FIELDS_NULL;
221 END IF;
222
223 -- Initialize API return status to success
224 x_return_status := FND_API.G_RET_STS_SUCCESS;
225
226 JTF_CALENDAR_PUB.Get_Available_Time
227 ( p_api_version => 1.0,
228 p_resource_id => p_resource_id,
229 p_resource_type => p_resource_type,
230 p_start_date => p_start_date_time,
231 p_end_date => p_start_date_time,
232 x_return_status => l_return_status,
233 x_msg_count => l_msg_count,
234 x_msg_data => l_msg_data,
235 x_shift => l_shift
236 );
237
238 v_begin_time := to_char(p_start_date_time,'HH24.MI');
239 v_end_time := to_char((p_start_date_time + p_duration/24),'HH24.MI');
240
241 x_avail := 'N';
242
243 IF v_end_time > v_begin_time THEN
244 for i in 1 .. l_shift.count loop
245 IF v_begin_time >= l_shift(i).start_time
246 AND v_end_time <= l_shift(i).end_time THEN
247 x_avail := 'Y';
248 EXIT;
249 END IF;
250 end loop;
251 END IF;
252
253 EXCEPTION
254 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
255 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
256 FND_MSG_PUB.Count_And_Get
257 ( p_count => x_msg_count,
258 p_data => x_msg_data
259 );
260 WHEN G_EXC_REQUIRED_FIELDS_NULL THEN
261 x_return_status := FND_API.G_RET_STS_ERROR ;
262 fnd_message.set_name('JTF','JTF_CAL_REQUIRED_PARAMETERS');
263 fnd_message.set_token('P_PARAMETER', l_parameters);
264 fnd_msg_pub.add;
265 FND_MSG_PUB.Count_And_Get
266 (p_count => x_msg_count,
267 p_data => x_msg_data
268 );
269 WHEN OTHERS THEN
270 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
271 fnd_message.set_name('JTF','JTF_CAL_UNEXPECTED_ERROR');
272 fnd_message.set_token('ERROR_CODE',SQLCODE);
273 fnd_message.set_token('ERROR_MESSAGE', SQLERRM);
274 fnd_msg_pub.add;
275 FND_MSG_PUB.Count_And_Get
276 ( p_count => x_msg_count,
277 p_data => x_msg_data
278 );
279
280 END Is_Res_Available;
281 --
282 -- ****************** Get Available Time **********************
283 --
284 PROCEDURE Get_Available_Time
285 ( p_api_version IN NUMBER,
286 p_init_msg_list IN VARCHAR2:=FND_API.G_FALSE,
287 p_resource_id IN NUMBER,
288 p_resource_type IN VARCHAR2,
289 p_start_date IN DATE,
290 p_end_date IN DATE,
291 x_return_status OUT NOCOPY VARCHAR2,
292 x_msg_count OUT NOCOPY NUMBER,
293 x_msg_data OUT NOCOPY VARCHAR2,
294 x_shift OUT NOCOPY SHIFT_TBL_TYPE
295 )
296 IS
297
298 -- we are declaring a table of records here again to manuplate the start and end time in DATE datatype.
299 type rec_type is record
300 ( shift_construct_id number
301 , start_time date
302 , end_time date
303 , availability_type varchar2(40) );
304
305 type tbl_type is table of rec_type index by binary_integer;
306
307 l_api_name CONSTANT VARCHAR2(30):= 'Get_Available_Time';
308 l_api_version CONSTANT NUMBER := 1.0;
309
310 -- Gets the shift_id and duration info, used for calculating the right shift pattern based
311 -- on the calendar id selected using the parameters passed resource_id, resource_type
312 -- and requested_date
313
314 cursor shift_info(p_calendar_id NUMBER) is
315 select shift_id,(shift_end_date - shift_start_date) shift_duration
316 from jtf_cal_shift_assign
317 where calendar_id = p_calendar_id
318 order by shift_sequence_number;
319
320 -- Based on the shift_id corresponding shift construction is found.
321
322 cursor c_cal_shift_constr(p_shift_id NUMBER,p_day date, p_uot_value NUMBER) is
323 select shift_construct_id,
324 begin_time start_constr,
325 end_time end_constr,
326 availability_type_code
327 from jtf_cal_shift_constructs
328 where shift_id = p_shift_id
329 --
330 --Modified condition to take care first Day of week for Bug 1342982
331 --
332 and to_char(begin_time, 'd') = to_char(p_day, 'd')
333 -- and unit_of_time_value = p_uot_value
334 --end
335 -- validate shift construct
336 -- added by jawang on 06/07/2002 to fix bug 2393255
337 and ( ( p_day between start_date_active
338 and end_date_active)
339 or (start_date_active <=p_day
340 and end_date_active IS NULL));
341
342 -- Get all the exceptions and tasks for the resource on the requested date.
343 -- Added two new parameters p_tz_enabled, p_server_tz_id and
344 -- modified the query accordingly. Done by SBARAT on 23/06/2005 for Bug# 4443443
345 cursor c_cal_except(p_calendar_id NUMBER, p_day date, p_res_id NUMBER, p_res_type VARCHAR2,p_tz_enabled VARCHAR2,p_server_tz_id NUMBER,p_res_Timezone_id NUMBER) is
346 select Decode(p_tz_enabled,'Y',
347 Decode(p_res_Timezone_id,NULL, e.start_date_time,
348 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(p_res_Timezone_id,
349 p_server_tz_id,
350 e.start_date_time),
351 e.start_date_time)
352 ),
353 e.start_date_time) start_except,
354 Decode(p_tz_enabled,'Y',
355 Decode(p_res_Timezone_id,NULL, e.end_date_time,
356 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(p_res_Timezone_id,
357 p_server_tz_id,
358 e.end_date_time),
359 e.end_date_time)
360 ),
361 e.end_date_time) end_except
362 from jtf_cal_exception_assign a
363 ,jtf_cal_exceptions_vl e
364 where a.calendar_id = p_calendar_id
365 and a.exception_id = e.exception_id
366 -- validate exception assignment
367 and ( p_day >= trunc(Decode(p_tz_enabled,'Y',
368 Decode(p_res_Timezone_id,NULL, a.start_date_active,
369 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(p_res_Timezone_id,
370 p_server_tz_id,
371 a.start_date_active),
372 a.start_date_active)
373 ),
374 a.start_date_active))
375 or a.start_date_active is null)
376 and ( p_day <= trunc(Decode(p_tz_enabled,'Y',
377 Decode(p_res_Timezone_id,NULL, a.end_date_active,
378 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(p_res_Timezone_id,
379 p_server_tz_id,
380 a.end_date_active),
381 a.end_date_active)
382 ),
383 a.end_date_active))
384 or a.end_date_active is null)
385 -- validate exception
386 and p_day between trunc(Decode(p_tz_enabled,'Y',
387 Decode(p_res_Timezone_id,NULL, e.start_date_time,
388 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(p_res_Timezone_id,
389 p_server_tz_id,
390 e.start_date_time),
391 e.start_date_time)
392 ),
393 e.start_date_time))
394 and trunc(Decode(p_tz_enabled,'Y',
395 Decode(p_res_Timezone_id,NULL, e.end_date_time,
396 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(p_res_Timezone_id,
397 p_server_tz_id,
398 e.end_date_time),
399 e.end_date_time)
400 ),
401 e.end_date_time))
402 UNION ALL
403 -- we are picking up from scheduled date form tasks.
404 select Decode(p_tz_enabled,'Y',
405 Decode(t.timezone_id,NULL, t.scheduled_start_date,
406 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(t.timezone_id,
407 p_server_tz_id,
408 t.scheduled_start_date),
409 t.scheduled_start_date)
410 ),
411 t.scheduled_start_date) start_except,
412 Decode(p_tz_enabled,'Y',
413 Decode(t.timezone_id,NULL, t.scheduled_end_date,
414 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(t.timezone_id,
415 p_server_tz_id,
416 t.scheduled_end_date),
417 t.scheduled_end_date)
418 ),
419 t.scheduled_end_date) end_except
420 from jtf_tasks_b t,
421 jtf_task_assignments a,
422 jtf_task_statuses_b s --changed to table from jtf_task_statuses_vl bug #2473783
423 where a.resource_id = p_res_id
424 and a.resource_type_code = p_res_type
425 and Decode(p_tz_enabled,'Y',
426 Decode(t.timezone_id,NULL, t.scheduled_end_date,
427 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(t.timezone_id,
428 p_server_tz_id,
429 t.scheduled_end_date),
430 t.scheduled_end_date)
431 ),
432 t.scheduled_end_date) >= p_day -- Changed to "schedule_end_date" for bug 2817811 by A.Raina.
433 and Decode(p_tz_enabled,'Y',
434 Decode(t.timezone_id,NULL, t.scheduled_start_date,
435 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(t.timezone_id,
436 p_server_tz_id,
437 t.scheduled_start_date),
438 t.scheduled_start_date)
439 ),
440 t.scheduled_start_date) < p_day+1 --- removed trunc bug #2473783
441 and s.task_status_id = a.assignment_status_id
442 and t.task_id = a.task_id
443 and nvl(s.cancelled_flag,'N') <> 'Y'
444 and nvl(s.completed_flag,'N') <> 'Y'
445 and t.scheduled_start_date <> t.scheduled_end_date ; -- bug # 2520762
446
447 --
448 j INTEGER := 0;
449 l_shift_id NUMBER;
450 l_unit_of_time_value NUMBER;
451 l_begin_time VARCHAR2(5);
452 l_end_time VARCHAR2(5);
453 l_calendar_id NUMBER;
454 l_calendar_name jtf_calendars_vl.calendar_name%TYPE; --bug # 2493461 VARCHAR2(240)
455 l_calendar_start_date DATE;
456 l_shifts_total_duration NUMBER;
457 l_left_days NUMBER;
458 l_availability VARCHAR2(40);
459 l_day date;
460 l_range_start date;
461 l_range_end date;
462 l_utv number;
463 l_cnt number;
464 l_count NUMBER;
465 l_shift_date DATE;
466 l_shift SHIFT_TBL_TYPE;
467 l_tbl tbl_type; -- added by Sarvi.
468 l_idx number := 0;
469 l_resource_name jtf_task_resources_vl.resource_name%TYPE; -- bug #2418561
470 l_st_time date;
471
472 l_tz_enabled VARCHAR2(10):=fnd_profile.value('ENABLE_TIMEZONE_CONVERSIONS'); -- Added by SBARAT on 23/06/2005 for Bug# 4443443
473 l_server_tz_id Number := to_number (fnd_profile.value_specific('SERVER_TIMEZONE_ID'));
474 l_res_Timezone_id Number;
475
476 BEGIN
477 -- Standard call to check for call compatibility.
478 IF NOT FND_API.Compatible_API_Call (l_api_version,
479 p_api_version,
480 l_api_name,
481 G_PKG_NAME)
482 THEN
483 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
484 END IF;
485
486 -- Initialize message list if p_init_msg_list is set to TRUE.
487 IF FND_API.to_Boolean( p_init_msg_list ) THEN
488 FND_MSG_PUB.initialize;
489 END IF;
490
491 -- Call to check for required fields
492 IF not check_for_required_fields (p_resource_id =>p_resource_id,
493 p_resource_type =>p_resource_type,
494 p_start_date =>p_start_date,
495 p_end_date =>p_start_date)
496 THEN
497 l_parameters := 'p_resource_id, p_resource_type, p_start_date, p_end_date';
498 RAISE G_EXC_REQUIRED_FIELDS_NULL;
499 END IF;
500
501 -- Initialize API return status to success
502 x_return_status := FND_API.G_RET_STS_SUCCESS;
503
504 l_shift_date := trunc(p_start_date);
505
506 while l_shift_date <= p_end_date loop
507
508 begin --(1)
509 -- get the primary calendar for a resource on the given date
510 select a.calendar_id,b.start_date_active
511 into l_calendar_id,l_calendar_start_date
512 from jtf_cal_resource_assign a,
513 jtf_calendars_b b
514 where a.resource_id = p_resource_id
515 and a.resource_type_code = p_resource_type
516 and a.calendar_id = b.calendar_id
517 and a.primary_calendar_flag = 'Y'
518 and l_shift_date between trunc(a.start_date_time) and nvl(trunc(a.end_date_time),l_shift_date);
519 -- Commented for bug 3891896 by ABRAINA
520 -- and l_shift_date between trunc(a.start_date_time) and nvl(trunc(a.end_date_time),to_date(get_g_miss_date,'DD/MM/RRRR'));
521 -- end
522
523 -- if condition added for bug 3270116 by ABRAINA
524 IF Validate_Cal_Date(l_calendar_id, l_shift_date) THEN -- (1)
525 -- get the shift in which the given date falls for the above calendar
526 --
527 begin --(2)
528 select sum(shift_end_date - shift_start_date)
529 into l_shifts_total_duration
530 from jtf_cal_shift_assign
531 where calendar_id = l_calendar_id;
532
533 -- Based on the mod value the shift is selected. This happens when two shifts are attached to the
534 -- calendar and a pattern of two in sequence is required.
535 l_left_days := mod((l_shift_date - l_calendar_start_date),l_shifts_total_duration);
536 -- This cursor will have all the shift attached to the resources primary calendar
537 -- We loop thru the cursor and based on the condition we find the correct shift_id
538 l_shift_id := null;
539 for c in shift_info(l_calendar_id) loop
540 l_left_days := l_left_days - c.shift_duration;
541 IF l_left_days < 0 THEN -- earlier it was <= it was not picking the correct shift.
542 l_shift_id := c.shift_id;
543 EXIT;
544 END IF;
545 end loop;
546 --
547 -- Find the day of the Requested Date
548 --
549 l_utv := to_char(l_shift_date, 'd');
550 --
551 -- Find the working hours on the Requested day
552 --
553 l_tbl.delete;
554 l_idx := 0;
555 FOR j in c_cal_shift_constr(l_shift_id,l_shift_date, l_utv) LOOP
556 l_idx := l_idx + 1;
557 l_tbl(l_idx).shift_construct_id := j.shift_construct_id;
558 --added this condition for 24hr shift .. sudarsana 22 Oct 2001
559 IF trunc(j.start_constr) = trunc(j.end_constr) THEN
560 l_tbl(l_idx).start_time := l_shift_date + (j.start_constr - trunc(j.start_constr));
561 l_tbl(l_idx).end_time := l_shift_date + (j.end_constr - trunc(j.end_constr));
562 else
563 l_tbl(l_idx).start_time := l_shift_date + (j.start_constr - trunc(j.start_constr));
564 l_tbl(l_idx).end_time := l_shift_date + (j.end_constr - trunc(j.end_constr)) +
565 (trunc(j.end_constr) - trunc(j.start_constr));
566 end if;
567 l_tbl(l_idx).availability_type := j.availability_type_code;
568 END LOOP;
569
570 --
571 -- Added for Simplex Timezone Enh # 3040681 by ABRAINA
572 --
573 If fnd_profile.value_specific('ENABLE_TIMEZONE_CONVERSIONS') = 'Y' Then
574 l_res_Timezone_id := Get_Res_Timezone_Id (p_resource_id, p_resource_type);
575 If l_res_Timezone_id <> l_server_tz_id Then
576 l_idx := 0;
577 For r in 1..l_tbl.count loop
578 l_idx := l_idx + 1;
579 l_tbl(l_idx).start_time := ResourceDt_To_ServerDT(l_tbl(l_idx).start_time,l_res_Timezone_id,l_server_tz_id);
580 l_tbl(l_idx).end_time := ResourceDt_To_ServerDT(l_tbl(l_idx).end_time,l_res_Timezone_id,l_server_tz_id);
581 End Loop;
582 End If;
583 End If;
584
585 --
586 -- Deduct all Task Assignments, Exceptions from working hours on the requested date
587 --
588 -- Modified by SBARAT on 23/06/2005 for Bug# 4443443
589 for m in c_cal_except(l_calendar_id,l_shift_date, p_resource_id, p_resource_type,l_tz_enabled,l_server_tz_id,l_res_Timezone_id)
590 loop
591 l_cnt := l_tbl.count;
592 for n in 1..l_cnt
593 loop -- loop thru the table loaded with shifts.
594 -- If we find an exception satisfying this condition then, we have
595 -- to change the start/end time of the shifts accordingly. Like shift 8 - 16
596 -- and exception 10-11, then we need to split the record into two like
597 -- 8 - 10 and 11 - 16, showing the resource availablity.
598 -- dbms_output.put_line('shifts: '||to_Char(l_tbl(n).start_time,'DD-MON-YYYY HH24:MI')|| '-' ||to_char(l_tbl(n).end_time,'dd-mon-yyyy hh24:mi'));
599 -- dbms_output.put_line('tasks: '||to_Char(m.start_except,'DD-MON-YYYY HH24:MI')|| '-' ||to_char(m.end_except,'dd-mon-yyyy hh24:mi'));
600
601 if m.start_except > l_tbl(n).start_time
602 and m.start_except < l_tbl(n).end_time
603 and m.end_except > l_tbl(n).start_time
604 and m.end_except < l_tbl(n).end_time
605 then
606 -- an extra entry is created at the end of the pl/sql table
607 -- is it a problem that the ordering is disrupted this way?
608 l_idx := l_tbl.count + 1;
609 l_tbl(l_idx).shift_construct_id := l_tbl(n).shift_construct_id;
610 l_tbl(l_idx).start_time := m.end_except; -- this is for the new entry
611 l_tbl(l_idx).end_time := l_tbl(n).end_time; -- this is for the new entry
612 l_tbl(l_idx).availability_type := l_tbl(n).availability_type;
613 l_tbl(n).end_time := m.start_except; -- This changes the existing entries end_time.
614 -- Various possibilities of exception are checked with shift times, to be chopped off.
615 elsif m.start_except < l_tbl(n).start_time
616 and m.end_except > l_tbl(n).start_time
617 and m.end_except < l_tbl(n).end_time
618 then
619 l_tbl(n).start_time := m.end_except;
620 elsif m.start_except > l_tbl(n).start_time
621 and m.start_except < l_tbl(n).end_time
622 and m.end_except > l_tbl(n).end_time
623 then
624 l_tbl(n).end_time := m.start_except;
625 -- added on 28, Sep 2000 start
626 elsif m.start_except >= l_tbl(n).start_time
627 and m.start_except < l_tbl(n).end_time
628 and m.end_except < l_tbl(n).end_time
629 then
630 l_tbl(n).start_time := m.end_except;
631 elsif m.start_except > l_tbl(n).start_time
632 and m.start_except < l_tbl(n).end_time
633 and m.end_except <= l_tbl(n).end_time
634 then
635 l_tbl(n).end_time := m.start_except;
636 -- added on 28, Sep 2000 end
637 elsif m.start_except = l_tbl(n).start_time
638 and m.end_except = l_tbl(n).end_time
639 then
640 l_tbl(n).start_time := null;
641 l_tbl(n).end_time := null;
642 l_tbl(n).availability_type := null;
643 -- l_tbl.delete; # bug :2595871
644 elsif m.start_except = l_tbl(n).start_time
645 and m.end_except < l_tbl(n).end_time
646 then
647 l_tbl(n).start_time := null;
648 l_tbl(n).end_time := null;
649 l_tbl(n).availability_type := null;
650 l_tbl.delete;
651 -- added Jan10, 2001, start.
652 elsif m.start_except = l_tbl(n).start_time
653 and m.end_except > l_tbl(n).end_time
654 then
655 l_tbl(n).start_time := null;
656 l_tbl(n).end_time := null;
657 l_tbl(n).availability_type := null;
658 -- l_tbl.delete; # bug :2595871
659
660 elsif m.start_except < l_tbl(n).start_time
661 and m.end_except = l_tbl(n).end_time
662 then
663 l_tbl(n).start_time := null;
664 l_tbl(n).end_time := null;
665 l_tbl(n).availability_type := null;
666 -- l_tbl.delete; # bug :2595871
667 -- added Jan10, 2001, end.
668 elsif m.start_except < l_tbl(n).start_time -- When exception falls out of the range
669 and m.end_except >l_tbl(n).end_time
670 then
671 l_tbl(n).start_time := null; -- added for bug #:2595871
672 l_tbl(n).end_time := null;
673 l_tbl(n).availability_type := null;
674 -- l_tbl.delete; # bug :2595871
675 end if;
676 end loop;
677 end loop;
678
679 -- store found shift constructs for this day in output pl/sql table
680 for r in 1..l_tbl.count
681 loop
682 --added this condition for 24hr shift .. sudarsana 22 Oct 2001
683 if ((trunc(l_tbl(r).end_time)) = trunc((l_tbl(r).start_time))) THEN
684 l_idx := x_shift.count + 1;
685 x_shift(l_idx).shift_construct_id := l_tbl(r).shift_construct_id;
686 x_shift(l_idx).shift_date := trunc(l_tbl(r).start_time);
687 -- reformat the start and end times just at the end of the procedure
688 -- when the calculations are done
689 x_shift(l_idx).start_time := to_char(l_tbl(r).start_time,'hh24.mi');
690 x_shift(l_idx).end_time := to_char(l_tbl(r).end_time,'hh24.mi');
691 x_shift(l_idx).availability_type := l_tbl(r).availability_type;
692 else
693 --added this condition for 24hr shift .. sudarsana 22 Oct 2001
694 l_st_time := l_tbl(r).start_time;
695 while(trunc(l_st_time) <= trunc(l_tbl(r).end_time))
696 loop
697 l_idx := x_shift.count + 1;
698 x_shift(l_idx).shift_construct_id := l_tbl(r).shift_construct_id;
699 x_shift(l_idx).shift_date := trunc(l_st_time);
700 if(trunc(l_st_time) = trunc(l_tbl(r).start_time))
701 then
702 x_shift(l_idx).start_time := to_char(l_tbl(r).start_time,'hh24.mi');
703 else
704 x_shift(l_idx).start_time := '00.00';
705 end if;
706 if(trunc(l_st_time) = trunc(l_tbl(r).end_time))
707 then
708 x_shift(l_idx).end_time := to_char(l_tbl(r).end_time,'hh24.mi');
709 else
710 x_shift(l_idx).end_time := '23.59';
711 end if;
712 x_shift(l_idx).availability_type := l_tbl(r).availability_type;
713
714 l_st_time := l_st_time + 1;
715 end loop;
716 end if;
717 end loop;
718 exception
719 when no_data_found then
720 NULL;
721 end; --2
722 end if; --(1)
723 exception
724 when no_data_found then
725 NULL;
726 end; -- 1
727 l_shift_date := l_shift_date + 1;
728 end loop;
729 --
730 -- Update return status to Success if there is atleast one available time slot
731 if x_shift.count = 0 then
732 x_return_status := fnd_api.g_ret_sts_error ;
733 fnd_message.set_name('JTF','JTF_CAL_NO_SHIFT_CONSTR_FOUND');
734 --fnd_message.set_name('JTF','JTF_CAL_NO_SHIFTS_FOR_RESOURCE');
735 --fnd_message.set_token('P_RESOURCE_NAME', l_resource_name);
736 fnd_msg_pub.add;
737 fnd_msg_pub.count_and_get( p_count => x_msg_count
738 , p_data => x_msg_data );
739 end if;
740
741 -- Added sort by jawang on 06/27/2002
742 if x_shift.count > 0
743 then
744 -- sort the out table
745 sort_tab(x_shift);
746 end if;
747
748 EXCEPTION
749 when g_exc_required_fields_null then
750 x_return_status := fnd_api.g_ret_sts_error ;
751 fnd_message.set_name('JTF','JTF_CAL_REQUIRED_PARAMETERS');
752 fnd_message.set_token('P_PARAMETER', l_parameters);
753 fnd_msg_pub.add;
754 fnd_msg_pub.count_and_get ( p_count => x_msg_count
755 , p_data => x_msg_data );
756
757 when fnd_api.g_exc_unexpected_error then
758 x_return_status := fnd_api.g_ret_sts_unexp_error;
759 fnd_msg_pub.count_and_get ( p_count => x_msg_count
760 , p_data => x_msg_data );
761
762 when others then
763 x_return_status := fnd_api.g_ret_sts_unexp_error ;
764 fnd_message.set_name('JTF','JTF_CAL_UNEXPECTED_ERROR');
765 fnd_message.set_token('ERROR_CODE',sqlcode);
766 fnd_message.set_token('ERROR_MESSAGE',sqlerrm);
767 fnd_msg_pub.count_and_get ( p_count => x_msg_count
768 , p_data => x_msg_data );
769 END get_available_time;
770
771
772 --
773 -- ****************** Get Available Time Slot **********************
774 --
775 PROCEDURE Get_Available_Slot
776 (p_api_version IN NUMBER ,
777 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
778 p_resource_id IN NUMBER ,
779 p_resource_type IN VARCHAR2 ,
780 p_start_date_time IN DATE ,
781 p_end_date_time IN DATE ,
782 p_duration IN NUMBER ,
783 x_return_status OUT NOCOPY VARCHAR2 ,
784 x_msg_count OUT NOCOPY NUMBER ,
785 x_msg_data OUT NOCOPY VARCHAR2 ,
786 x_slot_start_date OUT NOCOPY DATE ,
787 x_slot_end_date OUT NOCOPY DATE ,
788 x_shift_construct_id OUT NOCOPY NUMBER ,
789 x_availability_type OUT NOCOPY VARCHAR2
790 )
791 IS
792 l_api_name CONSTANT VARCHAR2(30) := 'Get_Available_Slot';
793 l_api_version CONSTANT NUMBER := 1.0;
794 l_return_status VARCHAR2(1);
795 l_msg_count NUMBER;
796 l_msg_data VARCHAR2(250);
797 l_shift jtf_calendar_pub_24hr.SHIFT_TBL_TYPE;
798 v_start_date DATE;
799 v_end_date DATE;
800 v_slot_start_date DATE;
801 v_slot_end_date DATE;
802 i number;
803
804 BEGIN
805 -- Standard call to check for call compatibility.
806 IF NOT FND_API.Compatible_API_Call (l_api_version ,
807 p_api_version ,
808 l_api_name ,
809 G_PKG_NAME )
810 THEN
811 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
812 END IF;
813
814 -- Initialize message list if p_init_msg_list is set to TRUE.
815 IF FND_API.to_Boolean( p_init_msg_list ) THEN
816 FND_MSG_PUB.initialize;
817 END IF;
818
819 -- Call to check for required fields
820 IF not check_for_required_fields (p_resource_id =>p_resource_id,
821 p_resource_type =>p_resource_type,
822 p_start_date =>p_start_date_time,
823 p_end_date =>p_end_date_time,
824 p_duration =>p_duration)
825 THEN
826 l_parameters := 'p_resource_id, p_resource_type, p_start_date_time, p_end_date_time, p_duration';
827 RAISE G_EXC_REQUIRED_FIELDS_NULL;
828 END IF;
829
830 -- Initialize API return status to success
831 x_return_status := FND_API.G_RET_STS_SUCCESS;
832 --
833 JTF_CALENDAR_PUB_24hr.Get_Available_Slot
834 ( p_api_version => l_api_version ,
835 p_init_msg_list => p_init_msg_list,
836 p_resource_id => p_resource_id,
837 p_resource_type => p_resource_type,
838 p_start_date_time => p_start_date_time,
839 p_end_date_time => p_end_date_time,
840 p_duration => p_duration,
841 x_return_status => x_return_status,
842 x_msg_count => x_msg_count,
843 x_msg_data => x_msg_data,
844 x_slot_start_date => x_slot_start_date,
845 x_slot_end_date => x_slot_end_date,
846 x_shift_construct_id => x_shift_construct_id,
847 x_availability_type => x_availability_type );
848
849 EXCEPTION
850 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
851 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
852 FND_MSG_PUB.Count_And_Get
853 ( p_count => x_msg_count,
854 p_data => x_msg_data
855 );
856 WHEN G_EXC_REQUIRED_FIELDS_NULL THEN
857 x_return_status := FND_API.G_RET_STS_ERROR ;
858 fnd_message.set_name('JTF','JTF_CAL_REQUIRED_PARAMETERS');
859 fnd_message.set_token('P_PARAMETER', l_parameters);
860 fnd_msg_pub.add;
861 FND_MSG_PUB.Count_And_Get
862 (p_count => x_msg_count,
863 p_data => x_msg_data
864 );
865 WHEN OTHERS THEN
866 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
867 fnd_message.set_name('JTF','JTF_CAL_UNEXPECTED_ERROR');
868 fnd_message.set_token('ERROR_CODE',SQLCODE);
869 fnd_message.set_token('ERROR_MESSAGE', SQLERRM);
870 fnd_msg_pub.add;
871 FND_MSG_PUB.Count_And_Get
872 (p_count => x_msg_count,
873 p_data => x_msg_data
874 );
875
876 END Get_Available_Slot;
877 --
878 -- ************* Get Resource Shifts *******************
879 --
880 PROCEDURE get_resource_shifts
881 ( p_api_version in number
882 , p_init_msg_list in varchar2
883 , p_resource_id in number
884 , p_resource_type in varchar2
885 , p_start_date in date
886 , p_end_date in date
887 , x_return_status out NOCOPY varchar2
888 , x_msg_count out NOCOPY number
889 , x_msg_data out NOCOPY varchar2
890 , x_shift out NOCOPY shift_tbl_type
891 )
892 IS
893 type rec_type is record
894 ( shift_construct_id number
895 , start_time date
896 , end_time date
897 , availability_type varchar2(40) );
898
899 type tbl_type is table of rec_type index by binary_integer;
900
901 cursor shift_info(p_calendar_id NUMBER) is
902 select shift_id,(shift_end_date - shift_start_date) shift_duration
903 from jtf_cal_shift_assign
904 where calendar_id = p_calendar_id
905 order by shift_sequence_number;
906
907 cursor c_cal_shift_constr(p_shift_id NUMBER, p_day date, p_uot_value NUMBER) is
908 select shift_construct_id,
909 begin_time start_constr,
910 end_time end_constr,
911 availability_type_code
912 from jtf_cal_shift_constructs
913 where shift_id = p_shift_id
914 --
915 --Modified condition to take care first Day of week for Bug 1342982
916 --
917 and to_char(begin_time, 'd') = to_char(p_day, 'd')
918 -- validate shift construct
919 -- added by jawang on 06/07/2002 to fix bug 2393255
920 and ( ( p_day between start_date_active
921 and end_date_active)
922 or (start_date_active <=p_day
923 and end_date_active IS NULL));
924
925
926 cursor c_cal_except
927 ( p_calendar_id number
928 , p_day date )
929 is
930 select e.start_date_time start_except
931 , e.end_date_time end_except
932 from jtf_cal_exception_assign a
933 , jtf_cal_exceptions_vl e
934 where a.calendar_id = p_calendar_id
935 and a.exception_id = e.exception_id
936 -- validate exception assignment
937 and ( p_day >= trunc(a.start_date_active)
938 or a.start_date_active is null)
939 and ( p_day <= trunc(a.end_date_active)
940 or a.end_date_active is null)
941 -- validate exception
942 and p_day between trunc(e.start_date_time)
943 and trunc(e.end_date_time);
944
945 -- added the date check for bug #1355824
946
947 l_api_name constant varchar2(30) := 'Get_Resource_Shifts';
948 l_api_version constant number := 1.0;
949 l_parameters varchar2(2000) := null;
950 g_exc_required_fields_null exception;
951 l_range_start date;
952 l_range_end date;
953 l_day date;
954 l_utv number;
955 l_idx number := 0;
956 l_tbl tbl_type;
957 l_cnt number;
958 l_shifts_total_duration number;
959 l_shift_date date;
960 l_left_days number;
961 l_calendar_id number;
962 l_shift_id number;
963
964 l_calendar_name jtf_calendars_vl.calendar_name%TYPE; -- bug # 2493461 varchar2(100)
965 l_calendar_start_date date;
966 l_exp_flg varchar2(1) := 'N';
967 l_start_date_time date;
968 l_st_time date;
969
970 l_server_tz_id Number := to_number (fnd_profile.value_specific('SERVER_TIMEZONE_ID'));
971 l_res_Timezone_id Number;
972
973 l_return_status varchar2(1) := FND_API.G_RET_STS_ERROR ;
974
975 l_resource_name jtf_task_resources_vl.resource_name%TYPE;-- bug # 2418561
976
977 BEGIN
978 -- standard call to check for call compatibility.
979 if not fnd_api.compatible_api_call
980 ( l_api_version
981 , p_api_version
982 , l_api_name
983 , JTF_CALENDAR_PUB.g_pkg_name )
984 then
985 raise fnd_api.g_exc_unexpected_error;
986 end if;
987
988 -- initialize message list if p_init_msg_list is set to true.
989 if fnd_api.to_boolean ( p_init_msg_list )
990 then
991 fnd_msg_pub.initialize;
992 end if;
993
994 -- call to check for required fields
995 if not JTF_CALENDAR_PUB.check_for_required_fields
996 ( p_resource_id => p_resource_id
997 , p_resource_type => p_resource_type
998 , p_start_date => p_start_date
999 , p_end_date => p_start_date )
1000 then
1001 l_parameters := 'p_resource_id, p_resource_type, p_start_date, p_end_date';
1002 raise g_exc_required_fields_null;
1003 end if;
1004
1005 -- initialize api return status to success
1006 x_return_status := fnd_api.g_ret_sts_success;
1007
1008 -- bug# 1344222
1009 -- Comment out by jawang on 06/17/2002
1010
1011 -- get all valid resource-to-calendar assignments for this resource in
1012 -- this period ordered by start date
1013 -- because there is a primary flag, only one record is expected
1014
1015 -- This code is added to get resource name to be printed in error message.
1016 BEGIN
1017 select resource_name
1018 into l_resource_name
1019 --from jtf_rs_all_resources_vl
1020 --Modified by jawang to fix the bug 2416932
1021 from jtf_task_resources_vl
1022 where resource_id = p_resource_id
1023 and resource_type = p_resource_type;
1024 EXCEPTION
1025 WHEN Others THEN
1026 NULL;
1027 END;
1028
1029 l_shift_date := trunc(p_start_date);
1030
1031 While l_shift_date <= p_end_date Loop
1032 --added l_shift_date in valid_cal loop bug #1355824
1033
1034 -- get the primary calendar for a resource on the given date
1035 --
1036 BEGIN --(1)
1037 select a.calendar_id,b.calendar_name,b.start_date_active,a.start_date_time
1038 into l_calendar_id,l_calendar_name,l_calendar_start_date,l_start_date_time
1039 from jtf_cal_resource_assign a,
1040 jtf_calendars_vl b
1041 where a.resource_id = p_resource_id
1042 and a.resource_type_code = p_resource_type
1043 and a.calendar_id = b.calendar_id
1044 and a.primary_calendar_flag = 'Y'
1045 -- Commented for bug 3891896 by ABRAINA
1046 -- and l_shift_date between trunc(a.start_date_time) and nvl(trunc(a.end_date_time),to_date(get_g_miss_date,'DD/MM/RRRR'));
1047 and l_shift_date between trunc(a.start_date_time) and nvl(trunc(a.end_date_time),l_shift_date);
1048
1049 -- Added for bug 3270116
1050 l_return_status := FND_API.G_RET_STS_SUCCESS;
1051
1052 -- if condition added for bug 3270116 by ABRAINA
1053 IF Validate_Cal_Date(l_calendar_id, l_shift_date)
1054 THEN
1055
1056 l_tbl.delete;
1057 l_idx := 0;
1058
1059 BEGIN --(2)
1060 select sum(shift_end_date - shift_start_date)
1061 into l_shifts_total_duration
1062 from jtf_cal_shift_assign
1063 where calendar_id = l_calendar_id;
1064
1065 l_left_days := mod((l_shift_date - l_calendar_start_date),l_shifts_total_duration);
1066
1067 l_shift_id := null;
1068 for c in shift_info(l_calendar_id) loop
1069 l_left_days := l_left_days - c.shift_duration;
1070 IF l_left_days < 0 THEN
1071 l_shift_id := c.shift_id;
1072 EXIT;
1073 END IF;
1074 end loop;
1075 -- Added by Sarvi
1076
1077 -- calculate unit of time value
1078 -- this is dependant on nls setting
1079 l_utv := to_char(l_shift_date,'d');
1080 l_tbl.delete;
1081 l_idx := 0;
1082 for j in c_cal_shift_constr ( l_shift_id
1083 , l_shift_date
1084 , l_utv )
1085 loop
1086 l_idx := l_idx + 1;
1087 l_tbl(l_idx).shift_construct_id := j.shift_construct_id;
1088 -- The date part of the shift construct start is just a container
1089 -- without real meaning. In order to process the multi-day
1090 -- exceptions more easily, the requested day is added to it, so
1091 -- that the resulting datetime has a real meaning.
1092 -- added this chg for the 24 hr shift split .. sudarsana 23 oct 2001
1093 IF trunc(j.start_constr) = trunc(j.end_constr) THEN
1094 l_tbl(l_idx).start_time := l_shift_date + (j.start_constr - trunc(j.start_constr));
1095 l_tbl(l_idx).end_time := l_shift_date + (j.end_constr - trunc(j.end_constr));
1096 else
1097 l_tbl(l_idx).start_time := l_shift_date + (j.start_constr - trunc(j.start_constr));
1098 l_tbl(l_idx).end_time := l_shift_date + (j.end_constr - trunc(j.end_constr)) +
1099 (trunc(j.end_constr) - trunc(j.start_constr));
1100 end if;
1101 l_tbl(l_idx).availability_type := j.availability_type_code;
1102 end loop;
1103
1104
1105
1106 -- deduct all exceptions from working hours on the requested day
1107 -- exceptions can consist of more than one day
1108 for m in c_cal_except ( l_calendar_id
1109 , l_shift_date )
1110 loop -- loop the exception cursor
1111 l_cnt := l_tbl.count;
1112
1113 for n in 1..l_cnt
1114 loop -- loop thru the table loaded with shifts.
1115
1116 -- If we find an exception satisfying this condition then, we have
1117 -- to change the start/end time of the shifts accordingly. Like shift 8 - 16
1118 -- and exception 10-11, then we need to split the record into two like
1119 -- 8 - 10 and 11 - 16, showing the resource availablity.
1120 if m.start_except > l_tbl(n).start_time
1121 and m.start_except < l_tbl(n).end_time
1122 and m.end_except > l_tbl(n).start_time
1123 and m.end_except < l_tbl(n).end_time
1124 then
1125 -- an extra entry is created at the end of the pl/sql table
1126 -- is it a problem that the ordering is disrupted this way?
1127 l_idx := l_tbl.count + 1;
1128 l_tbl(l_idx).shift_construct_id := l_tbl(n).shift_construct_id;
1129 l_tbl(l_idx).start_time := m.end_except; -- this is for the new entry
1130 l_tbl(l_idx).end_time := l_tbl(n).end_time; -- this is for the new entry
1131 l_tbl(l_idx).availability_type := l_tbl(n).availability_type;
1132 l_tbl(n).end_time := m.start_except; -- This changes the existing entries end_time.
1133
1134 elsif m.start_except < l_tbl(n).start_time
1135 and m.end_except > l_tbl(n).start_time
1136 and m.end_except < l_tbl(n).end_time
1137 then
1138 l_tbl(n).start_time := m.end_except;
1139 --l_tbl(n).end_time := m.start_except;
1140
1141 elsif m.start_except > l_tbl(n).start_time
1142 and m.start_except < l_tbl(n).end_time
1143 and m.end_except > l_tbl(n).end_time
1144 then
1145 l_tbl(n).end_time := m.start_except;
1146 -- added on 28, Sep 2000 start
1147 elsif m.start_except >= l_tbl(n).start_time
1148 and m.start_except < l_tbl(n).end_time
1149 and m.end_except < l_tbl(n).end_time
1150 then
1151 l_tbl(n).start_time := m.end_except;
1152
1153 elsif m.start_except > l_tbl(n).start_time
1154 and m.start_except < l_tbl(n).end_time
1155 and m.end_except <= l_tbl(n).end_time
1156 then
1157 l_tbl(n).end_time := m.start_except;
1158 -- added on 28, Sep 2000 end
1159
1160 elsif m.start_except = l_tbl(n).start_time
1161 and m.end_except = l_tbl(n).end_time
1162 then
1163 l_tbl(n).start_time := null;
1164 l_tbl(n).end_time := null;
1165 l_tbl(n).availability_type := null;
1166 l_tbl.delete;
1167
1168 elsif m.start_except = l_tbl(n).start_time
1169 and m.end_except < l_tbl(n).end_time
1170 then
1171 l_tbl(n).start_time := null;
1172 l_tbl(n).end_time := null;
1173 l_tbl(n).availability_type := null;
1174 l_tbl.delete;
1175
1176 elsif m.start_except < l_tbl(n).start_time -- When exception falls out of the range
1177 and m.end_except >l_tbl(n).end_time
1178 then
1179 l_tbl.delete;
1180 -- added jan10, 2001 start
1181 elsif m.start_except = l_tbl(n).start_time
1182 and m.end_except > l_tbl(n).end_time
1183 then
1184 l_tbl(n).start_time := null;
1185 l_tbl(n).end_time := null;
1186 l_tbl(n).availability_type := null;
1187 l_tbl.delete;
1188
1189 elsif m.start_except < l_tbl(n).start_time
1190 and m.end_except = l_tbl(n).end_time
1191 then
1192 l_tbl(n).start_time := null;
1193 l_tbl(n).end_time := null;
1194 l_tbl(n).availability_type := null;
1195 l_tbl.delete;
1196 -- added jan10, 2001 end
1197 end if;
1198
1199 if l_exp_flg = 'Y' THEN
1200 l_tbl.delete; -- if we find the exception and shift times are same then delete the row from table of records.
1201 end if;
1202 end loop;
1203 end loop;
1204
1205 -- moved this code here so that exceptions are also adjusted for time zone conversion
1206 --
1207 -- Added for Simplex Timezone Enh # 3040681 by ABRAINA
1208 --
1209 If fnd_profile.value_specific('ENABLE_TIMEZONE_CONVERSIONS') = 'Y' Then
1210 l_res_Timezone_id := Get_Res_Timezone_Id (p_resource_id, p_resource_type);
1211 If l_res_Timezone_id <> l_server_tz_id Then
1212 l_idx := 0;
1213 For r in 1..l_tbl.count loop
1214 l_idx := l_idx + 1;
1215 l_tbl(l_idx).start_time := ResourceDt_To_ServerDT(l_tbl(l_idx).start_time,l_res_Timezone_id,l_server_tz_id);
1216 l_tbl(l_idx).end_time := ResourceDt_To_ServerDT(l_tbl(l_idx).end_time,l_res_Timezone_id,l_server_tz_id);
1217 End Loop;
1218 End If;
1219 End If;
1220
1221 -- store found shift constructs for this day in output pl/sql table
1222 for r in 1..l_tbl.count
1223 loop
1224 if ((trunc(l_tbl(r).end_time)) = trunc((l_tbl(r).start_time))) THEN
1225 l_idx := x_shift.count + 1;
1226 x_shift(l_idx).shift_construct_id := l_tbl(r).shift_construct_id;
1227 x_shift(l_idx).shift_date := trunc(l_tbl(r).start_time);
1228 -- reformat the start and end times just at the end of the procedure
1229 -- when the calculations are done
1230 x_shift(l_idx).start_time := to_char(l_tbl(r).start_time,'hh24.mi');
1231 x_shift(l_idx).end_time := to_char(l_tbl(r).end_time,'hh24.mi');
1232 x_shift(l_idx).availability_type := l_tbl(r).availability_type;
1233 else
1234 --added this condition for 24hr shift .. sudarsana 22 Oct 2001
1235 l_st_time := l_tbl(r).start_time;
1236 while(trunc(l_st_time) <= trunc(l_tbl(r).end_time))
1237 loop
1238 l_idx := x_shift.count + 1;
1239 x_shift(l_idx).shift_construct_id := l_tbl(r).shift_construct_id;
1240 x_shift(l_idx).shift_date := trunc(l_st_time);
1241 if(trunc(l_st_time) = trunc(l_tbl(r).start_time))
1242 then
1243 x_shift(l_idx).start_time := to_char(l_tbl(r).start_time,'hh24.mi');
1244 else
1245 x_shift(l_idx).start_time := '00.00';
1246 end if;
1247 if(trunc(l_st_time) = trunc(l_tbl(r).end_time))
1248 then
1249 x_shift(l_idx).end_time := to_char(l_tbl(r).end_time,'hh24.mi');
1250 else
1251 x_shift(l_idx).end_time := '23.59';
1252 end if;
1253 x_shift(l_idx).availability_type := l_tbl(r).availability_type;
1254
1255 l_st_time := l_st_time + 1;
1256 end loop;
1257 end if;
1258 end loop;
1259 exception
1260 when no_data_found then
1261 x_return_status := FND_API.G_RET_STS_ERROR ;
1262 -- Added for bug 3270116
1263 l_return_status := FND_API.G_RET_STS_ERROR ;
1264 -- end
1265 fnd_message.set_name('JTF','JTF_CAL_NO_SHIFTS');
1266 fnd_message.set_token('P_CAL_NAME', l_calendar_name);
1267 fnd_msg_pub.add;
1268 FND_MSG_PUB.Count_And_Get
1269 (p_count => x_msg_count,
1270 p_data => x_msg_data
1271 );
1272 end; --2
1273 end if; -- valid cal end if
1274 exception
1275 when no_data_found then
1276 x_return_status := FND_API.G_RET_STS_ERROR ;
1277 -- No Need to set l_return_status to FND_API.G_RET_STS_ERROR
1278 -- as for this exception we want to handle it.
1279 -- For a resource, even if a single shift is returned for a search window
1280 -- it will return 'S'. This is as per requirement from Field service and Gantt guys.
1281 l_tbl.delete; -- to delete the record from TOR if no shift found
1282 fnd_message.set_name('JTF','JTF_CAL_RES_NO_CAL');
1283 fnd_message.set_token('P_SHIFT_DATE', l_shift_date);
1284 fnd_message.set_token('P_RES_NAME', l_resource_name);
1285 fnd_msg_pub.add;
1286
1287 FND_MSG_PUB.Count_And_Get
1288 (p_count => x_msg_count,
1289 p_data => x_msg_data
1290 );
1291 end; -- 1
1292 -- end loop; -- valid cal
1293 l_shift_date := l_shift_date + 1;
1294 end loop;
1295
1296 -- see if shift constructs have been found
1297 if x_shift.count = 0
1298 then
1299 x_return_status := fnd_api.g_ret_sts_error ;
1300 -- Added for bug 3270116
1301 l_return_status := FND_API.G_RET_STS_ERROR ;
1302 -- end
1303 fnd_message.set_name('JTF','JTF_CAL_NO_SHIFT_CONSTR_FOUND');
1304 fnd_msg_pub.add;
1305
1306 fnd_msg_pub.count_and_get( p_count => x_msg_count
1307 , p_data => x_msg_data );
1308 end if;
1309
1310 -- Added sort by jawang on 06/27/2002
1311 if x_shift.count > 0
1312 then
1313 -- sort the out table
1314 sort_tab(x_shift);
1315 end if;
1316
1317 -- Added for bug 3270116
1318 -- For a resource, even if a single shift is returned for any search window
1319 -- it will return 'S'. This is as per requirement from Field service and Gantt guys.
1320 if l_return_status = FND_API.G_RET_STS_SUCCESS then
1321 x_return_status := FND_API.G_RET_STS_SUCCESS;
1322 else
1323 x_return_status := FND_API.G_RET_STS_ERROR ;
1324 end if;
1325 -- end
1326 EXCEPTION
1327 when g_exc_required_fields_null then
1328 x_return_status := fnd_api.g_ret_sts_error ;
1329 fnd_message.set_name('JTF','JTF_CAL_REQUIRED_PARAMETERS');
1330 fnd_message.set_token('P_PARAMETER', l_parameters);
1331 fnd_msg_pub.add;
1332 fnd_msg_pub.count_and_get ( p_count => x_msg_count
1333 , p_data => x_msg_data );
1334
1335 when fnd_api.g_exc_unexpected_error then
1336 x_return_status := fnd_api.g_ret_sts_unexp_error;
1337 fnd_msg_pub.count_and_get ( p_count => x_msg_count
1338 , p_data => x_msg_data );
1339 when others then
1340 x_return_status := fnd_api.g_ret_sts_unexp_error ;
1341 fnd_message.set_name('JTF','JTF_CAL_UNEXPECTED_ERROR');
1342 fnd_message.set_token('ERROR_CODE',sqlcode);
1343 fnd_message.set_token('ERROR_MESSAGE',sqlerrm);
1344 fnd_msg_pub.count_and_get ( p_count => x_msg_count
1345 , p_data => x_msg_data );
1346 --END;
1347 END get_resource_shifts;
1348
1349
1350 --
1351 -- ********** Get Resource Shifts with 15 attributes ***********
1352 --
1353
1354 PROCEDURE get_resource_shifts
1355 ( p_api_version in number
1356 , p_init_msg_list in varchar2
1357 , p_resource_id in number
1358 , p_resource_type in varchar2
1359 , p_start_date in date
1360 , p_end_date in date
1361 , x_return_status out NOCOPY varchar2
1362 , x_msg_count out NOCOPY number
1363 , x_msg_data out NOCOPY varchar2
1364 , x_shift out NOCOPY shift_tbl_attributes_type
1365 )
1366 IS
1367 type rec_attributes_type is record
1368 ( shift_construct_id number
1369 , start_time date
1370 , end_time date
1371 , availability_type varchar2(40)
1372 , attribute1 varchar2(150)
1373 , attribute2 varchar2(150)
1374 , attribute3 varchar2(150)
1375 , attribute4 varchar2(150)
1376 , attribute5 varchar2(150)
1377 , attribute6 varchar2(150)
1378 , attribute7 varchar2(150)
1379 , attribute8 varchar2(150)
1380 , attribute9 varchar2(150)
1381 , attribute10 varchar2(150)
1382 , attribute11 varchar2(150)
1383 , attribute12 varchar2(150)
1384 , attribute13 varchar2(150)
1385 , attribute14 varchar2(150)
1386 , attribute15 varchar2(150)
1387 );
1388
1389 type tbl_attributes_type is table of rec_attributes_type index by binary_integer;
1390
1391 cursor shift_info(p_calendar_id NUMBER) is
1392 select shift_id,(shift_end_date - shift_start_date) shift_duration
1393 from jtf_cal_shift_assign
1394 where calendar_id = p_calendar_id
1395 order by shift_sequence_number;
1396
1397 cursor c_cal_shift_constr(p_shift_id NUMBER, p_day date, p_uot_value NUMBER) is
1398 select shift_construct_id,
1399 begin_time start_constr,
1400 end_time end_constr,
1401 availability_type_code,
1402 attribute1,
1403 attribute2,
1404 attribute3,
1405 attribute4,
1406 attribute5,
1407 attribute6,
1408 attribute7,
1409 attribute8,
1410 attribute9,
1411 attribute10,
1412 attribute11,
1413 attribute12,
1414 attribute13,
1415 attribute14,
1416 attribute15
1417 from jtf_cal_shift_constructs
1418 where shift_id = p_shift_id
1419 --
1420 --Modified condition to take care first Day of week for Bug 1342982
1421 --
1422 and to_char(begin_time, 'd') = to_char(p_day, 'd')
1423 -- added by jawang on 06/07/2002 to fix bug 2393255
1424 and ( ( p_day between start_date_active
1425 and end_date_active)
1426 or (start_date_active <=p_day
1427 and end_date_active IS NULL));
1428
1429 cursor c_cal_except
1430 ( p_calendar_id number
1431 , p_day date )
1432 is
1433 select e.start_date_time start_except
1434 , e.end_date_time end_except
1435 from jtf_cal_exception_assign a
1436 , jtf_cal_exceptions_vl e
1437 where a.calendar_id = p_calendar_id
1438 and a.exception_id = e.exception_id
1439 -- validate exception assignment
1440 and ( p_day >= trunc(a.start_date_active)
1441 or a.start_date_active is null)
1442 and ( p_day <= trunc(a.end_date_active)
1443 or a.end_date_active is null)
1444 -- validate exception
1445 and p_day between trunc(e.start_date_time)
1446 and trunc(e.end_date_time);
1447
1448 cursor valid_cal
1449 (p_resource_id number,
1450 p_resource_type varchar2,p_shift_date DATE) IS
1451 -- added p_shift_date bug 1355824
1452 select start_date_time
1453 from jtf_cal_resource_assign
1454 where resource_id = p_resource_id
1455 and resource_type_code = p_resource_type
1456 and primary_calendar_flag = 'Y'
1457 and (( p_shift_date >= trunc(start_date_time) and end_date_time IS NULL )
1458 OR (p_shift_date between trunc(start_date_time)
1459 and trunc(end_date_time)));
1460
1461 l_api_name constant varchar2(30) := 'Get_Resource_Shifts';
1462 l_api_version constant number := 1.0;
1463 l_parameters varchar2(2000) := null;
1464 g_exc_required_fields_null exception;
1465 l_range_start date;
1466 l_range_end date;
1467 l_day date;
1468 l_utv number;
1469 l_idx number := 0;
1470 l_tbl tbl_attributes_type;
1471 l_cnt number;
1472 l_shifts_total_duration number;
1473 l_shift_date date;
1474 l_left_days number;
1475 l_calendar_id number;
1476 l_shift_id number;
1477
1478 l_calendar_name jtf_calendars_vl.calendar_name%TYPE; -- bug # 2493461 varchar2(100)
1479 l_calendar_start_date date;
1480 l_exp_flg varchar2(1) := 'N';
1481 l_start_date_time date;
1482 l_st_time date;
1483 l_server_tz_id Number := to_number (fnd_profile.value_specific('SERVER_TIMEZONE_ID'));
1484 l_res_Timezone_id Number;
1485
1486 l_return_status varchar2(1) := FND_API.G_RET_STS_ERROR ;
1487
1488 l_resource_name jtf_task_resources_vl.resource_name%TYPE;-- bug # 2418561
1489
1490 BEGIN
1491
1492 -- standard call to check for call compatibility.
1493 if not fnd_api.compatible_api_call
1494 ( l_api_version
1495 , p_api_version
1496 , l_api_name
1497 , JTF_CALENDAR_PUB.g_pkg_name )
1498 then
1499 raise fnd_api.g_exc_unexpected_error;
1500 end if;
1501
1502 -- initialize message list if p_init_msg_list is set to true.
1503 if fnd_api.to_boolean ( p_init_msg_list )
1504 then
1505 fnd_msg_pub.initialize;
1506 end if;
1507
1508 -- call to check for required fields
1509 if not JTF_CALENDAR_PUB.check_for_required_fields
1510 ( p_resource_id => p_resource_id
1511 , p_resource_type => p_resource_type
1512 , p_start_date => p_start_date
1513 , p_end_date => p_start_date )
1514 then
1515 l_parameters := 'p_resource_id, p_resource_type, p_start_date, p_end_date';
1516 raise g_exc_required_fields_null;
1517 end if;
1518
1519 -- initialize api return status to success
1520 x_return_status := fnd_api.g_ret_sts_success;
1521
1522 -- bug# 1344222
1523 -- Comment out by jawang on 06/17/2002
1524
1525 -- This code is added to get resource name to be printed in error message.
1526 -- Added for Bug 4063687
1527 BEGIN
1528 select resource_name
1529 into l_resource_name
1530 --from jtf_rs_all_resources_vl
1531 --Modified by jawang to fix the bug 2416932
1532 from jtf_task_resources_vl
1533 where resource_id = p_resource_id
1534 and resource_type = p_resource_type;
1535 EXCEPTION
1536 WHEN Others THEN
1537 NULL;
1538 END;
1539
1540 -- get all valid resource-to-calendar assignments for this resource in
1541 -- this period ordered by start date
1542 -- because there is a primary flag, only one record is expected
1543
1544 l_shift_date := trunc(p_start_date);
1545
1546 while l_shift_date <= p_end_date Loop
1547 -- We first check if there is a valid primary calendar on this date.
1548 -- for v in valid_cal(p_resource_id,p_resource_type,l_shift_date) loop
1549 -- get the primary calendar for a resource on the given date
1550 --
1551 begin --(1)
1552 select a.calendar_id,b.calendar_name,b.start_date_active,a.start_date_time
1553 into l_calendar_id,l_calendar_name,l_calendar_start_date,l_start_date_time
1554 from jtf_cal_resource_assign a,
1555 jtf_calendars_vl b
1556 where a.resource_id = p_resource_id
1557 and a.resource_type_code = p_resource_type
1558 and a.calendar_id = b.calendar_id
1559 and a.primary_calendar_flag = 'Y'
1560 -- Commented for bug 3891896 by ABRAINA
1561 -- and l_shift_date between trunc(a.start_date_time) and nvl(trunc(a.end_date_time),to_date(get_g_miss_date,'DD/MM/RRRR'));
1562 and l_shift_date between trunc(a.start_date_time) and nvl(trunc(a.end_date_time),l_shift_date);
1563
1564 -- Added for bug 3270116
1565 l_return_status := FND_API.G_RET_STS_SUCCESS;
1566
1567 --added l_shift_date in valid_cal loop bug #1355824
1568 -- if condition added for bug 3270116 by ABRAINA
1569 IF Validate_Cal_Date(l_calendar_id, l_shift_date)
1570 THEN
1571 -- This check is not necessary. Can be removed after testing.
1572 begin --(2)
1573 select sum(shift_end_date - shift_start_date)
1574 into l_shifts_total_duration
1575 from jtf_cal_shift_assign
1576 where calendar_id = l_calendar_id;
1577
1578 l_left_days := mod((l_shift_date - l_calendar_start_date),l_shifts_total_duration);
1579
1580 l_shift_id := null;
1581 for c in shift_info(l_calendar_id) loop
1582 l_left_days := l_left_days - c.shift_duration;
1583 IF l_left_days < 0 THEN
1584 l_shift_id := c.shift_id;
1585 EXIT;
1586 END IF;
1587 end loop;
1588 -- Added by Sarvi
1589
1590 -- calculate unit of time value
1591 -- this is dependant on nls setting
1592 l_utv := to_char(l_shift_date,'d');
1593 l_tbl.delete;
1594 l_idx := 0;
1595 for j in c_cal_shift_constr ( l_shift_id
1596 , l_shift_date
1597 , l_utv )
1598 loop
1599 l_idx := l_idx + 1;
1600 l_tbl(l_idx).shift_construct_id := j.shift_construct_id;
1601 -- The date part of the shift construct start is just a container
1602 -- without real meaning. In order to process the multi-day
1603 -- exceptions more easily, the requested day is added to it, so
1604 -- that the resulting datetime has a real meaning.
1605 -- added this chg for the 24 hr shift split .. sudarsana 23 oct 2001
1606 IF trunc(j.start_constr) = trunc(j.end_constr) THEN
1607 l_tbl(l_idx).start_time := l_shift_date + (j.start_constr - trunc(j.start_constr));
1608 l_tbl(l_idx).end_time := l_shift_date + (j.end_constr - trunc(j.end_constr));
1609 else
1610 l_tbl(l_idx).start_time := l_shift_date + (j.start_constr - trunc(j.start_constr));
1611 l_tbl(l_idx).end_time := l_shift_date + (j.end_constr - trunc(j.end_constr)) +
1612 (trunc(j.end_constr) - trunc(j.start_constr));
1613 end if;
1614 l_tbl(l_idx).availability_type := j.availability_type_code;
1615
1616 -- Added by Jane on 03/05/2002
1617 l_tbl(l_idx).attribute1 := j.attribute1;
1618 l_tbl(l_idx).attribute2 := j.attribute2;
1619 l_tbl(l_idx).attribute3 := j.attribute3;
1620 l_tbl(l_idx).attribute4 := j.attribute4;
1621 l_tbl(l_idx).attribute5 := j.attribute5;
1622 l_tbl(l_idx).attribute6 := j.attribute6;
1623 l_tbl(l_idx).attribute7 := j.attribute7;
1624 l_tbl(l_idx).attribute8 := j.attribute8;
1625 l_tbl(l_idx).attribute9 := j.attribute9;
1626 l_tbl(l_idx).attribute10 := j.attribute10;
1627 l_tbl(l_idx).attribute11 := j.attribute11;
1628 l_tbl(l_idx).attribute12 := j.attribute12;
1629 l_tbl(l_idx).attribute13 := j.attribute13;
1630 l_tbl(l_idx).attribute14 := j.attribute14;
1631 l_tbl(l_idx).attribute15 := j.attribute15;
1632
1633 end loop;
1634
1635
1636
1637 -- deduct all exceptions from working hours on the requested day
1638 -- exceptions can consist of more than one day
1639 for m in c_cal_except ( l_calendar_id
1640 , l_shift_date )
1641 loop -- loop the exception cursor
1642 l_cnt := l_tbl.count;
1643
1644 for n in 1..l_cnt
1645 loop -- loop thru the table loaded with shifts.
1646
1647 -- If we find an exception satisfying this condition then, we have
1648 -- to change the start/end time of the shifts accordingly. Like shift 8 - 16
1649 -- and exception 10-11, then we need to split the record into two like
1650 -- 8 - 10 and 11 - 16, showing the resource availablity.
1651 if m.start_except > l_tbl(n).start_time
1652 and m.start_except < l_tbl(n).end_time
1653 and m.end_except > l_tbl(n).start_time
1654 and m.end_except < l_tbl(n).end_time
1655 then
1656 -- an extra entry is created at the end of the pl/sql table
1657 -- is it a problem that the ordering is disrupted this way?
1658 l_idx := l_tbl.count + 1;
1659 l_tbl(l_idx).shift_construct_id := l_tbl(n).shift_construct_id;
1660 l_tbl(l_idx).start_time := m.end_except; -- this is for the new entry
1661 l_tbl(l_idx).end_time := l_tbl(n).end_time; -- this is for the new entry
1662 l_tbl(l_idx).availability_type := l_tbl(n).availability_type;
1663
1664 -- Added by Jane on 03/05/2002
1665 l_tbl(l_idx).attribute1 := l_tbl(n).attribute1;
1666 l_tbl(l_idx).attribute2 := l_tbl(n).attribute2;
1667 l_tbl(l_idx).attribute3 := l_tbl(n).attribute3;
1668 l_tbl(l_idx).attribute4 := l_tbl(n).attribute4;
1669 l_tbl(l_idx).attribute5 := l_tbl(n).attribute5;
1670 l_tbl(l_idx).attribute6 := l_tbl(n).attribute6;
1671 l_tbl(l_idx).attribute7 := l_tbl(n).attribute7;
1672 l_tbl(l_idx).attribute8 := l_tbl(n).attribute8;
1673 l_tbl(l_idx).attribute9 := l_tbl(n).attribute9;
1674 l_tbl(l_idx).attribute10 := l_tbl(n).attribute10;
1675 l_tbl(l_idx).attribute11 := l_tbl(n).attribute11;
1676 l_tbl(l_idx).attribute12 := l_tbl(n).attribute12;
1677 l_tbl(l_idx).attribute13 := l_tbl(n).attribute13;
1678 l_tbl(l_idx).attribute14 := l_tbl(n).attribute14;
1679 l_tbl(l_idx).attribute15 := l_tbl(n).attribute15;
1680
1681
1682 l_tbl(n).end_time := m.start_except; -- This changes the existing entries end_time.
1683
1684 elsif m.start_except < l_tbl(n).start_time
1685 and m.end_except > l_tbl(n).start_time
1686 and m.end_except < l_tbl(n).end_time
1687 then
1688 l_tbl(n).start_time := m.end_except;
1689 --l_tbl(n).end_time := m.start_except;
1690
1691 elsif m.start_except > l_tbl(n).start_time
1692 and m.start_except < l_tbl(n).end_time
1693 and m.end_except > l_tbl(n).end_time
1694 then
1695 l_tbl(n).end_time := m.start_except;
1696 -- added on 28, Sep 2000 start
1697 elsif m.start_except >= l_tbl(n).start_time
1698 and m.start_except < l_tbl(n).end_time
1699 and m.end_except < l_tbl(n).end_time
1700 then
1701 l_tbl(n).start_time := m.end_except;
1702
1703 elsif m.start_except > l_tbl(n).start_time
1704 and m.start_except < l_tbl(n).end_time
1705 and m.end_except <= l_tbl(n).end_time
1706 then
1707 l_tbl(n).end_time := m.start_except;
1708 -- added on 28, Sep 2000 end
1709
1710 elsif m.start_except = l_tbl(n).start_time
1711 and m.end_except = l_tbl(n).end_time
1712 then
1713 l_tbl(n).start_time := null;
1714 l_tbl(n).end_time := null;
1715 l_tbl(n).availability_type := null;
1716
1717 -- Added by Jane on 03/05/2002
1718 l_tbl(n).attribute1 := null;
1719 l_tbl(n).attribute2 := null;
1720 l_tbl(n).attribute3 := null;
1721 l_tbl(n).attribute4 := null;
1722 l_tbl(n).attribute5 := null;
1723 l_tbl(n).attribute6 := null;
1724 l_tbl(n).attribute7 := null;
1725 l_tbl(n).attribute8 := null;
1726 l_tbl(n).attribute9 := null;
1727 l_tbl(n).attribute10 := null;
1728 l_tbl(n).attribute11 := null;
1729 l_tbl(n).attribute12 := null;
1730 l_tbl(n).attribute13 := null;
1731 l_tbl(n).attribute14 := null;
1732 l_tbl(n).attribute15 := null;
1733
1734
1735 l_tbl.delete;
1736
1737 elsif m.start_except = l_tbl(n).start_time
1738 and m.end_except < l_tbl(n).end_time
1739 then
1740 l_tbl(n).start_time := null;
1741 l_tbl(n).end_time := null;
1742 l_tbl(n).availability_type := null;
1743
1744 -- Added by Jane on 03/05/2002
1745 l_tbl(n).attribute1 := null;
1746 l_tbl(n).attribute2 := null;
1747 l_tbl(n).attribute3 := null;
1748 l_tbl(n).attribute4 := null;
1749 l_tbl(n).attribute5 := null;
1750 l_tbl(n).attribute6 := null;
1751 l_tbl(n).attribute7 := null;
1752 l_tbl(n).attribute8 := null;
1753 l_tbl(n).attribute9 := null;
1754 l_tbl(n).attribute10 := null;
1755 l_tbl(n).attribute11 := null;
1756 l_tbl(n).attribute12 := null;
1757 l_tbl(n).attribute13 := null;
1758 l_tbl(n).attribute14 := null;
1759 l_tbl(n).attribute15 := null;
1760
1761
1762 l_tbl.delete;
1763
1764 elsif m.start_except < l_tbl(n).start_time -- When exception falls out of the range
1765 and m.end_except >l_tbl(n).end_time
1766 then
1767 l_tbl.delete;
1768 -- added jan10, 2001 start
1769 elsif m.start_except = l_tbl(n).start_time
1770 and m.end_except > l_tbl(n).end_time
1771 then
1772 l_tbl(n).start_time := null;
1773 l_tbl(n).end_time := null;
1774 l_tbl(n).availability_type := null;
1775
1776 -- Added by Jane on 03/05/2002
1777 l_tbl(n).attribute1 := null;
1778 l_tbl(n).attribute2 := null;
1779 l_tbl(n).attribute3 := null;
1780 l_tbl(n).attribute4 := null;
1781 l_tbl(n).attribute5 := null;
1782 l_tbl(n).attribute6 := null;
1783 l_tbl(n).attribute7 := null;
1784 l_tbl(n).attribute8 := null;
1785 l_tbl(n).attribute9 := null;
1786 l_tbl(n).attribute10 := null;
1787 l_tbl(n).attribute11 := null;
1788 l_tbl(n).attribute12 := null;
1789 l_tbl(n).attribute13 := null;
1790 l_tbl(n).attribute14 := null;
1791 l_tbl(n).attribute15 := null;
1792
1793 l_tbl.delete;
1794
1795 elsif m.start_except < l_tbl(n).start_time
1796 and m.end_except = l_tbl(n).end_time
1797 then
1798 l_tbl(n).start_time := null;
1799 l_tbl(n).end_time := null;
1800 l_tbl(n).availability_type := null;
1801
1802 -- Added by Jane on 03/05/2002
1803 l_tbl(n).attribute1 := null;
1804 l_tbl(n).attribute2 := null;
1805 l_tbl(n).attribute3 := null;
1806 l_tbl(n).attribute4 := null;
1807 l_tbl(n).attribute5 := null;
1808 l_tbl(n).attribute6 := null;
1809 l_tbl(n).attribute7 := null;
1810 l_tbl(n).attribute8 := null;
1811 l_tbl(n).attribute9 := null;
1812 l_tbl(n).attribute10 := null;
1813 l_tbl(n).attribute11 := null;
1814 l_tbl(n).attribute12 := null;
1815 l_tbl(n).attribute13 := null;
1816 l_tbl(n).attribute14 := null;
1817 l_tbl(n).attribute15 := null;
1818
1819 l_tbl.delete;
1820 -- added jan10, 2001 end
1821 end if;
1822
1823 if l_exp_flg = 'Y' THEN
1824 l_tbl.delete; -- if we find the exception and shift times are same then delete the row from table of records.
1825 end if;
1826 end loop; -- end loop thru the table loaded with shifts.
1827 end loop; -- end loop the exception cursor
1828
1829 -- Moved this code here so that exceptions are also considered for timezone conversion
1830 --
1831 -- Added for Simplex Timezone Enh # 3040681 by ABRAINA
1832 --
1833 If fnd_profile.value_specific('ENABLE_TIMEZONE_CONVERSIONS') = 'Y' Then
1834 l_res_Timezone_id := Get_Res_Timezone_Id (p_resource_id, p_resource_type);
1835 If l_res_Timezone_id <> l_server_tz_id Then
1836 l_idx := 0;
1837 For r in 1..l_tbl.count loop
1838 l_idx := l_idx + 1;
1839 l_tbl(l_idx).start_time := ResourceDt_To_ServerDT(l_tbl(l_idx).start_time,l_res_Timezone_id,l_server_tz_id);
1840 l_tbl(l_idx).end_time := ResourceDt_To_ServerDT(l_tbl(l_idx).end_time,l_res_Timezone_id,l_server_tz_id);
1841 End Loop;
1842 End If;
1843 End If;
1844
1845
1846 -- store found shift constructs for this day in output pl/sql table
1847 for r in 1..l_tbl.count
1848 loop
1849 if ((trunc(l_tbl(r).end_time)) = trunc((l_tbl(r).start_time))) THEN
1850 l_idx := x_shift.count + 1;
1851 x_shift(l_idx).shift_construct_id := l_tbl(r).shift_construct_id;
1852 x_shift(l_idx).shift_date := trunc(l_tbl(r).start_time);
1853 -- reformat the start and end times just at the end of the procedure
1854 -- when the calculations are done
1855 x_shift(l_idx).start_time := to_char(l_tbl(r).start_time,'hh24.mi');
1856 x_shift(l_idx).end_time := to_char(l_tbl(r).end_time,'hh24.mi');
1857 x_shift(l_idx).availability_type := l_tbl(r).availability_type;
1858
1859 -- Added by Jane on 03/05/2002
1860 x_shift(l_idx).attribute1 := l_tbl(r).attribute1;
1861 x_shift(l_idx).attribute2 := l_tbl(r).attribute2;
1862 x_shift(l_idx).attribute3 := l_tbl(r).attribute3;
1863 x_shift(l_idx).attribute4 := l_tbl(r).attribute4;
1864 x_shift(l_idx).attribute5 := l_tbl(r).attribute5;
1865 x_shift(l_idx).attribute6 := l_tbl(r).attribute6;
1866 x_shift(l_idx).attribute7 := l_tbl(r).attribute7;
1867 x_shift(l_idx).attribute8 := l_tbl(r).attribute8;
1868 x_shift(l_idx).attribute9 := l_tbl(r).attribute9;
1869 x_shift(l_idx).attribute10 := l_tbl(r).attribute10;
1870 x_shift(l_idx).attribute11 := l_tbl(r).attribute11;
1871 x_shift(l_idx).attribute12 := l_tbl(r).attribute12;
1872 x_shift(l_idx).attribute13 := l_tbl(r).attribute13;
1873 x_shift(l_idx).attribute14 := l_tbl(r).attribute14;
1874 x_shift(l_idx).attribute15 := l_tbl(r).attribute15;
1875
1876 else
1877 --added this condition for 24hr shift .. sudarsana 22 Oct 2001
1878 l_st_time := l_tbl(r).start_time;
1879 while(trunc(l_st_time) <= trunc(l_tbl(r).end_time))
1880 loop
1881 l_idx := x_shift.count + 1;
1882 x_shift(l_idx).shift_construct_id := l_tbl(r).shift_construct_id;
1883 x_shift(l_idx).shift_date := trunc(l_st_time);
1884 if(trunc(l_st_time) = trunc(l_tbl(r).start_time))
1885 then
1886 x_shift(l_idx).start_time := to_char(l_tbl(r).start_time,'hh24.mi');
1887 else
1888 x_shift(l_idx).start_time := '00.00';
1889 end if;
1890 if(trunc(l_st_time) = trunc(l_tbl(r).end_time))
1891 then
1892 x_shift(l_idx).end_time := to_char(l_tbl(r).end_time,'hh24.mi');
1893 else
1894 x_shift(l_idx).end_time := '23.59';
1895 end if;
1896 x_shift(l_idx).availability_type := l_tbl(r).availability_type;
1897
1898 -- Added by Jane on 03/05/2002
1899 x_shift(l_idx).attribute1 := l_tbl(r).attribute1;
1900 x_shift(l_idx).attribute2 := l_tbl(r).attribute2;
1901 x_shift(l_idx).attribute3 := l_tbl(r).attribute3;
1902 x_shift(l_idx).attribute4 := l_tbl(r).attribute4;
1903 x_shift(l_idx).attribute5 := l_tbl(r).attribute5;
1904 x_shift(l_idx).attribute6 := l_tbl(r).attribute6;
1905 x_shift(l_idx).attribute7 := l_tbl(r).attribute7;
1906 x_shift(l_idx).attribute8 := l_tbl(r).attribute8;
1907 x_shift(l_idx).attribute9 := l_tbl(r).attribute9;
1908 x_shift(l_idx).attribute10 := l_tbl(r).attribute10;
1909 x_shift(l_idx).attribute11 := l_tbl(r).attribute11;
1910 x_shift(l_idx).attribute12 := l_tbl(r).attribute12;
1911 x_shift(l_idx).attribute13 := l_tbl(r).attribute13;
1912 x_shift(l_idx).attribute14 := l_tbl(r).attribute14;
1913 x_shift(l_idx).attribute15 := l_tbl(r).attribute15;
1914
1915
1916 l_st_time := l_st_time + 1;
1917 end loop;
1918 end if;
1919 end loop;
1920 exception
1921 when no_data_found then
1922 x_return_status := FND_API.G_RET_STS_ERROR ;
1923 -- Added for bug 3270116
1924 l_return_status := FND_API.G_RET_STS_ERROR ;
1925 -- end
1926 fnd_message.set_name('JTF','JTF_CAL_NO_SHIFTS');
1927 fnd_message.set_token('P_CAL_NAME', l_calendar_name);
1928 fnd_msg_pub.add;
1929 FND_MSG_PUB.Count_And_Get
1930 (p_count => x_msg_count,
1931 p_data => x_msg_data
1932 );
1933 end; --2
1934 end if; -- valid cal end if
1935 exception
1936 when no_data_found then
1937 x_return_status := FND_API.G_RET_STS_ERROR ;
1938 -- No Need to set l_return_status to FND_API.G_RET_STS_ERROR
1939 -- as for this exception we want to handle it.
1940 -- For a resource, even if a single shift is returned for a search window
1941 -- it will return 'S'. This is as per requirement from Field service and Gantt guys.
1942 l_tbl.delete; -- to delete the record from TOR if no shift found
1943 fnd_message.set_name('JTF','JTF_CAL_RES_NO_CAL');
1944 fnd_message.set_token('P_SHIFT_DATE', l_shift_date);
1945 fnd_message.set_token('P_RES_NAME', l_resource_name);
1946 fnd_msg_pub.add;
1947
1948 FND_MSG_PUB.Count_And_Get
1949 (p_count => x_msg_count,
1950 p_data => x_msg_data
1951 );
1952 end; -- 1
1953 -- end loop; -- valid cal
1954 l_shift_date := l_shift_date + 1;
1955 end loop;
1956
1957
1958 -- see if shift constructs have been found
1959 if x_shift.count = 0
1960 then
1961 x_return_status := fnd_api.g_ret_sts_error ;
1962 -- Added for bug 3270116
1963 l_return_status := FND_API.G_RET_STS_ERROR ;
1964 -- end
1965 fnd_message.set_name('JTF','JTF_CAL_NO_SHIFT_CONSTR_FOUND');
1966 fnd_msg_pub.add;
1967
1968 fnd_msg_pub.count_and_get( p_count => x_msg_count
1969 , p_data => x_msg_data );
1970 end if;
1971
1972 -- Added sort by jawang on 06/27/2002
1973 if x_shift.count > 0
1974 then
1975 -- sort the out table
1976 sort_tab_attr(x_shift);
1977 end if;
1978
1979 -- Added for bug 3270116
1980 -- For a resource, even if a single shift is returned for any search window
1981 -- it will return 'S'. This is as per requirement from Field service and Gantt guys.
1982 if l_return_status = FND_API.G_RET_STS_SUCCESS then
1983 x_return_status := FND_API.G_RET_STS_SUCCESS;
1984 else
1985 x_return_status := FND_API.G_RET_STS_ERROR ;
1986 end if;
1987 -- end
1988
1989 EXCEPTION
1990 when g_exc_required_fields_null then
1991 x_return_status := fnd_api.g_ret_sts_error ;
1992 fnd_message.set_name('JTF','JTF_CAL_REQUIRED_PARAMETERS');
1993 fnd_message.set_token('P_PARAMETER', l_parameters);
1994 fnd_msg_pub.add;
1995 fnd_msg_pub.count_and_get ( p_count => x_msg_count
1996 , p_data => x_msg_data );
1997
1998 when fnd_api.g_exc_unexpected_error then
1999 x_return_status := fnd_api.g_ret_sts_unexp_error;
2000 fnd_msg_pub.count_and_get ( p_count => x_msg_count
2001 , p_data => x_msg_data );
2002 when others then
2003 x_return_status := fnd_api.g_ret_sts_unexp_error ;
2004 fnd_message.set_name('JTF','JTF_CAL_UNEXPECTED_ERROR');
2005 fnd_message.set_token('ERROR_CODE',sqlcode);
2006 fnd_message.set_token('ERROR_MESSAGE',sqlerrm);
2007 fnd_msg_pub.count_and_get ( p_count => x_msg_count
2008 , p_data => x_msg_data );
2009 --END;
2010 END get_resource_shifts;
2011
2012 --
2013 -- ********** Get Resource Schedule **************
2014 --
2015 PROCEDURE Get_Res_Schedule
2016 ( p_api_version IN NUMBER ,
2017 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE ,
2018 p_resource_id IN NUMBER ,
2019 p_resource_type IN VARCHAR2 ,
2020 p_start_date IN DATE ,
2021 p_end_date IN DATE ,
2022 x_return_status OUT NOCOPY VARCHAR2 ,
2023 x_msg_count OUT NOCOPY NUMBER ,
2024 x_msg_data OUT NOCOPY VARCHAR2 ,
2025 x_shift OUT NOCOPY SHIFT_TBL_TYPE
2026 )
2027 IS
2028 l_api_name CONSTANT VARCHAR2(30):= 'Get_Rsc_Schedule';
2029 l_api_version CONSTANT NUMBER := 1.0;
2030 --
2031 cursor shift_info(p_calendar_id NUMBER) is
2032 select shift_id,(shift_end_date - shift_start_date) shift_duration
2033 from jtf_cal_shift_assign
2034 where calendar_id = p_calendar_id
2035 order by shift_sequence_number;
2036 --
2037 cursor work_hrs(p_shift_id NUMBER, p_day date, p_uot_value NUMBER) is
2038 select shift_construct_id,
2039 begin_time shift_begin_time,
2040 end_time shift_end_time,
2041 availability_type_code
2042 from jtf_cal_shift_constructs
2043 where shift_id = p_shift_id
2044 --
2045 --Modified condition to take care first Day of week for Bug 1342982
2046 --
2047 and to_char(begin_time, 'd') = to_char(p_day, 'd')
2048 -- added by jawang on 06/07/2002 to fix by 2393255
2049 and ( ( p_day between start_date_active
2050 and end_date_active)
2051 or (start_date_active <=p_day
2052 and end_date_active IS NULL));
2053
2054 --
2055 cursor excp_hrs(p_calendar_id NUMBER, p_req_date DATE) is
2056 select to_char(a.start_date_time,'HH24.MI') excp_start_time,
2057 to_char(a.end_date_time,'HH24.MI') excp_end_time
2058 from jtf_cal_exceptions_vl a, jtf_cal_exception_assign b
2059 where trunc(a.start_date_time) = p_req_date
2060 and a.exception_id = b.exception_id
2061 and b.calendar_id = p_calendar_id;
2062 --
2063
2064 cursor task_hrs(p_res_id NUMBER,p_res_type VARCHAR2,p_req_date DATE,p_tz_enabled VARCHAR2,p_server_tz_id NUMBER) is
2065 -- we are picking up the schedule time from task.
2066
2067 --
2068 -- Removed "distinct" clause added ealier for bug 2817811 by A.Raina
2069 --
2070 -- Added two new parameters p_tz_enabled, p_server_tz_id and
2071 -- modified the query accordingly. Done by SBARAT on 23/06/2005 for Bug# 4443443
2072 --
2073 -- For bug 4547539, added db index skip hint to force db to use second indexed
2074 -- column schedule_end_date for index search
2075 select /*+ index_ss(T JTF_TASKS_B_N12) */
2076 trunc(Decode(p_tz_enabled,'Y',
2077 Decode(t.timezone_id,NULL, t.scheduled_start_date,
2078 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(t.timezone_id,
2079 p_server_tz_id,
2080 t.scheduled_start_date),
2081 t.scheduled_start_date)
2082 ),
2083 t.scheduled_start_date)
2084 ) task_start_date,
2085 trunc(Decode(p_tz_enabled,'Y',
2086 Decode(t.timezone_id,NULL, t.scheduled_end_date,
2087 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(t.timezone_id,
2088 p_server_tz_id,
2089 t.scheduled_end_date),
2090 t.scheduled_end_date)
2091 ),
2092 t.scheduled_end_date)
2093 ) task_end_date,
2094 to_char(Decode(p_tz_enabled,'Y',
2095 Decode(t.timezone_id,NULL, t.scheduled_start_date,
2096 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(t.timezone_id,
2097 p_server_tz_id,
2098 t.scheduled_start_date),
2099 t.scheduled_start_date)
2100 ),
2101 t.scheduled_start_date), 'HH24.MI'
2102 ) task_start_time,
2103 to_char(Decode(p_tz_enabled,'Y',
2104 Decode(t.timezone_id,NULL, t.scheduled_end_date,
2105 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(t.timezone_id,
2106 p_server_tz_id,
2107 t.scheduled_end_date),
2108 t.scheduled_end_date)
2109 ),
2110 t.scheduled_end_date), 'HH24.MI'
2111 ) task_end_time
2112 from jtf_tasks_b t,
2113 jtf_task_assignments a,
2114 jtf_task_statuses_b s
2115 where a.resource_id = p_res_id
2116 and a.resource_type_code = p_res_type
2117 and p_req_date between
2118 trunc(Decode(p_tz_enabled,'Y',
2119 Decode(t.timezone_id,NULL, t.scheduled_start_date,
2120 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(t.timezone_id,
2121 p_server_tz_id,
2122 t.scheduled_start_date),
2123 t.scheduled_start_date)
2124 ),
2125 t.scheduled_start_date)
2126 )
2127 and
2128 Decode(p_tz_enabled,'Y',
2129 Decode(t.timezone_id,NULL, t.scheduled_end_date,
2130 Nvl(HZ_TIMEZONE_PUB.CONVERT_DATETIME(t.timezone_id,
2131 p_server_tz_id,
2132 t.scheduled_end_date),
2133 t.scheduled_end_date)
2134 ),
2135 t.scheduled_end_date)
2136 and s.task_status_id = a.assignment_status_id
2137 AND t.task_id = a.task_id
2138 and nvl(s.cancelled_flag,'N') <> 'Y'
2139 and nvl(s.completed_flag,'N') <> 'Y'
2140 and t.scheduled_start_date <> t.scheduled_end_date ; -- bug # 2520762
2141 --
2142
2143 j INTEGER := 0;
2144 l_shift_id NUMBER;
2145 l_unit_of_time_value NUMBER;
2146 l_calendar_id NUMBER;
2147 l_calendar_name jtf_calendars_vl.calendar_name%TYPE; -- bug # 2493461 VARCHAR2(240)
2148 l_calendar_start_date DATE;
2149 l_shifts_total_duration NUMBER;
2150 l_left_days NUMBER;
2151 l_shift_date DATE;
2152 l_res_type VARCHAR2(30);
2153 l_st_date DATE;
2154 l_ed_time DATE;
2155 l_st_time DATE;
2156 l_shift_b_time varchar2(25);
2157 l_shift_b_date date;
2158 l_shift_e_time varchar2(25);
2159 l_shift_e_date date;
2160 l_tz_enabled VARCHAR2(10):=fnd_profile.value('ENABLE_TIMEZONE_CONVERSIONS'); -- Added by SBARAT on 23/06/2005 for Bug# 4443443
2161 l_server_tz_id Number := to_number (fnd_profile.value_specific('SERVER_TIMEZONE_ID'));
2162 l_res_Timezone_id Number;
2163
2164 l_resource_name jtf_task_resources_vl.resource_name%TYPE;-- bug # 2418561
2165
2166 BEGIN
2167 -- Standard call to check for call compatibility.
2168 IF NOT FND_API.Compatible_API_Call ( l_api_version ,
2169 p_api_version ,
2170 l_api_name ,
2171 G_PKG_NAME )
2172 THEN
2173 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2174 END IF;
2175 -- Initialize message list if p_init_msg_list is set to TRUE.
2176 IF FND_API.to_Boolean( p_init_msg_list ) THEN
2177 FND_MSG_PUB.initialize;
2178 END IF;
2179 -- Call to check for required fields
2180 IF not check_for_required_fields (p_resource_id =>p_resource_id,
2181 p_resource_type =>p_resource_type,
2182 p_start_date =>p_start_date,
2183 p_end_date =>p_end_date)
2184 THEN
2185 l_parameters := 'p_resource_id, p_resource_type, p_start_date, p_end_date';
2186 RAISE G_EXC_REQUIRED_FIELDS_NULL;
2187 END IF;
2188 -- Initialize API return status to success
2189 x_return_status := FND_API.G_RET_STS_SUCCESS;
2190
2191 -- This code is added to get resource name to be printed in error message.
2192 -- Added for Bug 4063687
2193 BEGIN
2194 select resource_name
2195 into l_resource_name
2196 --from jtf_rs_all_resources_vl
2197 --Modified by jawang to fix the bug 2416932
2198 from jtf_task_resources_vl
2199 where resource_id = p_resource_id
2200 and resource_type = p_resource_type;
2201 EXCEPTION
2202 WHEN Others THEN
2203 NULL;
2204 END;
2205
2206 --
2207 l_shift_date := trunc(p_start_date);
2208 x_shift.delete;
2209 While l_shift_date <= p_end_date Loop
2210 -- get the primary calendar for a resource on the given date
2211 --
2212 begin --(1)
2213 select a.calendar_id,b.calendar_name,b.start_date_active
2214 into l_calendar_id,l_calendar_name,l_calendar_start_date
2215 from jtf_cal_resource_assign a,
2216 jtf_calendars_vl b
2217 where a.resource_id = p_resource_id
2218 and a.resource_type_code = p_resource_type
2219 and a.calendar_id = b.calendar_id
2220 and a.primary_calendar_flag = 'Y'
2221 -- Commented for bug 3891896 by ABRAINA
2222 -- and l_shift_date between trunc(a.start_date_time) and nvl(trunc(a.end_date_time),to_date(get_g_miss_date,'DD/MM/RRRR'));
2223 and l_shift_date between trunc(a.start_date_time) and nvl(trunc(a.end_date_time),l_shift_date);
2224
2225 -- if condition added for bug 3270116 by ABRAINA
2226 IF Validate_Cal_Date(l_calendar_id, l_shift_date) THEN -- (1)
2227 --
2228 -- get the shift in which the given date falls for the above calendar
2229 --
2230 begin --(2)
2231 select sum(shift_end_date - shift_start_date)
2232 into l_shifts_total_duration
2233 from jtf_cal_shift_assign
2234 where calendar_id = l_calendar_id;
2235
2236 select mod((l_shift_date - l_calendar_start_date),l_shifts_total_duration)
2237 into l_left_days
2238 from dual;
2239
2240 l_shift_id := null;
2241 for c in shift_info(l_calendar_id) loop
2242 l_left_days := l_left_days - c.shift_duration;
2243 IF l_left_days < 0 THEN
2244 l_shift_id := c.shift_id;
2245 EXIT;
2246 END IF;
2247 end loop;
2248 --
2249 -- Find the day of the Requested Date
2250 --
2251 select to_char(l_shift_date, 'd')
2252 into l_unit_of_time_value
2253 from dual;
2254 --
2255 -- Find the working hours on the Requested day
2256 --
2257 --FOR c1 in work_hrs(l_shift_id, l_unit_of_time_value) LOOP
2258 -- Modified by jawang on 06/07/2002 to fix the bug 2393255
2259 FOR c1 in work_hrs(l_shift_id, l_shift_date, l_unit_of_time_value) LOOP
2260 if(trunc(c1.shift_begin_time) = trunc(c1.shift_end_time))
2261 then
2262 j := x_shift.count + 1;
2263 x_shift(j).shift_construct_id := c1.shift_construct_id;
2264 x_shift(j).shift_date := l_shift_date;
2265 x_shift(j).start_time := to_char(c1.shift_begin_time, 'hh24.mi');
2266 x_shift(j).end_time := to_char(c1.shift_end_time, 'hh24.mi');
2267 --
2268 -- Added for Simplex Timezone Enh # 3040681 by ABRAINA
2269 --
2270 If fnd_profile.value_specific('ENABLE_TIMEZONE_CONVERSIONS') = 'Y' Then
2271 l_res_Timezone_id := Get_Res_Timezone_Id (p_resource_id, p_resource_type);
2272 If l_res_Timezone_id <> l_server_tz_id Then
2273 l_shift_b_time := to_char(l_shift_date,'DD-MON-YYYY')||' '||to_char(c1.shift_begin_time, 'hh24.mi');
2274 l_shift_b_date := to_date(l_shift_b_time,'DD/MM/YYYY HH24:MI');
2275 l_shift_e_time := to_char(l_shift_date,'DD-MON-YYYY')||' '||to_char(c1.shift_end_time, 'hh24.mi');
2276 l_shift_e_date := to_date(l_shift_e_time,'DD/MM/YYYY HH24:MI');
2277 x_shift(j).shift_date := to_char(ResourceDt_To_ServerDT(l_shift_b_date,l_res_Timezone_id,l_server_tz_id),'DD-MON-YYYY');
2278 x_shift(j).start_time := to_char(ResourceDt_To_ServerDT(l_shift_b_date,l_res_Timezone_id,l_server_tz_id),'hh24.mi');
2279 x_shift(j).end_time := to_char(ResourceDt_To_ServerDT(l_shift_e_date,l_res_Timezone_id,l_server_tz_id),'hh24.mi');
2280 End If;
2281 End If;
2282 x_shift(j).availability_type := 'W';
2283 else
2284 --added this condition for 24hr shift .. sudarsana 22 Oct 2001
2285 l_st_time := l_shift_date;
2286 l_ed_time := l_shift_date + (c1.shift_end_time - trunc(c1.shift_end_time)) +
2287 (trunc(c1.shift_end_time) - trunc(c1.shift_begin_time));
2288 while(trunc(l_st_time) <= trunc(l_ed_time))
2289 loop
2290 j := x_shift.count + 1;
2291 x_shift(j).shift_construct_id := c1.shift_construct_id;
2292 x_shift(j).shift_date := trunc(l_st_time);
2293 if(trunc(l_st_time) = trunc(l_shift_date))
2294 then
2295 x_shift(j).start_time := to_char( c1.shift_begin_time,'hh24.mi');
2296 else
2297 x_shift(j).start_time := '00.00';
2298 end if;
2299 if(trunc(l_st_time) = trunc(l_ed_time))
2300 then
2301 x_shift(j).end_time := to_char(c1.shift_end_time,'hh24.mi');
2302 else
2303 x_shift(j).end_time := '23.59';
2304 end if;
2305
2306 --
2307 -- Added for Simplex Timezone Enh # 3040681 by ABRAINA
2308 --
2309 If fnd_profile.value_specific('ENABLE_TIMEZONE_CONVERSIONS') = 'Y' Then
2310 l_res_Timezone_id := Get_Res_Timezone_Id (p_resource_id, p_resource_type);
2311 If l_res_Timezone_id <> l_server_tz_id Then
2312 l_shift_b_time := to_char(l_shift_date,'DD-MON-YYYY')||' '||to_char(c1.shift_begin_time, 'hh24.mi');
2313 l_shift_b_date := to_date(l_shift_b_time,'DD/MM/YYYY HH24:MI');
2314 l_shift_e_time := to_char(l_shift_date,'DD-MON-YYYY')||' '||to_char(c1.shift_end_time, 'hh24.mi');
2315 l_shift_e_date := to_date(l_shift_e_time,'DD/MM/YYYY HH24:MI');
2316 x_shift(j).shift_date := to_char(ResourceDt_To_ServerDT(l_shift_b_date,l_res_Timezone_id,l_server_tz_id),'DD-MON-YYYY');
2317 x_shift(j).start_time := to_char(ResourceDt_To_ServerDT(l_shift_b_date,l_res_Timezone_id,l_server_tz_id),'hh24.mi');
2318 x_shift(j).end_time := to_char(ResourceDt_To_ServerDT(l_shift_e_date,l_res_Timezone_id,l_server_tz_id),'hh24.mi');
2319 End If;
2320 End If;
2321 x_shift(j).availability_type := 'W';
2322
2323 l_st_time := l_st_time + 1;
2324 end loop;
2325 end if;
2326 END LOOP;
2327 --
2328 -- Find all the Exception hours on the requested date
2329 --
2330 For c2 in excp_hrs(l_calendar_id, l_shift_date) LOOP
2331 j := j + 1;
2332 x_shift(j).shift_date := l_shift_date;
2333 x_shift(j).start_time := c2.excp_start_time;
2334 x_shift(j).end_time := c2.excp_end_time;
2335 x_shift(j).availability_type := 'E';
2336 END LOOP;
2337 --
2338 -- Find all the assigned Task hours on the requested date
2339 --
2340 -- Modified by SBARAT on 23/06/2005 for Bug# 4443443
2341
2342 For c3 in task_hrs(p_resource_id,p_resource_type,l_shift_date,l_tz_enabled,l_server_tz_id) loop
2343
2344 --
2345 -- Modified this code for bug 2817811 by A.Raina
2346 --
2347 IF l_shift_date = c3.task_start_date and l_shift_date = c3.task_end_date THEN
2348 j := j + 1;
2349 x_shift(j).shift_date := l_shift_date;
2350 x_shift(j).start_time := c3.task_start_time;
2351 x_shift(j).end_time := c3.task_end_time;
2352 x_shift(j).availability_type := 'T';
2353 ELSIF l_shift_date = c3.task_start_date and l_shift_date <> c3.task_end_date THEN
2354
2355 FOR c1 in work_hrs(l_shift_id, l_shift_date, l_unit_of_time_value) LOOP
2356 IF c3.task_start_time >= to_char(c1.shift_begin_time,'hh24.mi') THEN
2357 j := j + 1;
2358 x_shift(j).shift_date := l_shift_date;
2359 x_shift(j).start_time := c3.task_start_time;
2360 x_shift(j).end_time := to_char(c1.shift_end_time,'hh24.mi');
2361 x_shift(j).availability_type := 'T';
2362 ELSE
2363 j := j + 1;
2364 x_shift(j).shift_date := l_shift_date;
2365 x_shift(j).start_time := to_char(c1.shift_begin_time,'hh24.mi');
2366 x_shift(j).end_time := to_char(c1.shift_end_time,'hh24.mi');
2367 x_shift(j).availability_type := 'T';
2368 END IF;
2369 END LOOP;
2370
2371 ELSIF l_shift_date <> c3.task_start_date and l_shift_date <> c3.task_end_date THEN
2372
2373 FOR c1 in work_hrs(l_shift_id, l_shift_date, l_unit_of_time_value) LOOP
2374 j := j + 1;
2375 x_shift(j).shift_date := l_shift_date;
2376 x_shift(j).start_time := to_char(c1.shift_begin_time,'hh24.mi');
2377 x_shift(j).end_time := to_char(c1.shift_end_time,'hh24.mi');
2378 x_shift(j).availability_type := 'T';
2379 End Loop;
2380
2381 ELSIF l_shift_date <> c3.task_start_date and l_shift_date = c3.task_end_date THEN
2382 FOR c1 in work_hrs(l_shift_id, l_shift_date, l_unit_of_time_value) LOOP
2383 IF c3.task_end_time <= to_char(c1.shift_end_time,'hh24.mi') THEN
2384 j := j + 1;
2385 x_shift(j).shift_date := l_shift_date;
2386 x_shift(j).start_time := to_char(c1.shift_begin_time,'hh24.mi');
2387 x_shift(j).end_time := c3.task_end_time;
2388 x_shift(j).availability_type := 'T';
2389 ELSE
2390 j := j + 1;
2391 x_shift(j).shift_date := l_shift_date;
2392 x_shift(j).start_time := to_char(c1.shift_begin_time,'hh24.mi');
2393 x_shift(j).end_time := to_char(c1.shift_end_time,'hh24.mi');
2394 x_shift(j).availability_type := 'T';
2395 END IF;
2396 END LOOP;
2397 END IF;
2398 --
2399 --End modification
2400 --
2401
2402 END LOOP;
2403 exception
2404 when no_data_found then
2405 x_return_status := FND_API.G_RET_STS_ERROR ;
2406 fnd_message.set_name('JTF','JTF_CAL_NO_SHIFTS');
2407 fnd_message.set_token('P_CAL_NAME', l_calendar_name);
2408 fnd_msg_pub.add;
2409 FND_MSG_PUB.Count_And_Get
2410 (p_count => x_msg_count,
2411 p_data => x_msg_data
2412 );
2413 end; --(2)
2414 end if; --(1)
2415 exception
2416 when no_data_found then
2417 x_return_status := FND_API.G_RET_STS_ERROR ;
2418 fnd_message.set_name('JTF','JTF_CAL_RES_NO_CAL');
2419 fnd_message.set_token('P_RES_NAME', l_resource_name);
2420 fnd_message.set_token('P_SHIFT_DATE', l_shift_date);
2421 fnd_msg_pub.add;
2422 FND_MSG_PUB.Count_And_Get
2423 (p_count => x_msg_count,
2424 p_data => x_msg_data
2425 );
2426 end; --(1)
2427 l_shift_date := l_shift_date + 1;
2428 end loop;
2429 --
2430 -- Update return status to Success if there is atleast one available time slot
2431 IF x_shift.count > 0 and x_return_status = 'E' THEN
2432 x_return_status := FND_API.G_RET_STS_SUCCESS;
2433 END IF;
2434
2435 -- Added sort by jawang on 06/27/2002
2436 if x_shift.count > 0
2437 then
2438 -- sort the out table
2439 sort_tab(x_shift);
2440 end if;
2441
2442 EXCEPTION
2443 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
2444 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
2445 FND_MSG_PUB.Count_And_Get
2446 ( p_count => x_msg_count,
2447 p_data => x_msg_data
2448 );
2449 WHEN G_EXC_REQUIRED_FIELDS_NULL THEN
2450 x_return_status := FND_API.G_RET_STS_ERROR ;
2451 fnd_message.set_name('JTF','JTF_CAL_REQUIRED_PARAMETERS');
2452 fnd_message.set_token('P_PARAMETER', l_parameters);
2453 fnd_msg_pub.add;
2454 FND_MSG_PUB.Count_And_Get
2455 (p_count => x_msg_count,
2456 p_data => x_msg_data
2457 );
2458 WHEN OTHERS THEN
2459 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
2460 fnd_message.set_name('JTF','JTF_CAL_UNEXPECTED_ERROR');
2461 fnd_message.set_token('ERROR_CODE',SQLCODE);
2462 fnd_message.set_token('ERROR_MESSAGE', SQLERRM);
2463 fnd_msg_pub.add;
2464 FND_MSG_PUB.Count_And_Get
2465 (p_count => x_msg_count,
2466 p_data => x_msg_data
2467 );
2468
2469 END Get_Res_Schedule;
2470
2471 function get_g_false return varchar2 is
2472 begin
2473 return(fnd_api.g_false);
2474 end get_g_false;
2475
2476
2477 function get_g_miss_num return number is
2478 begin
2479 return(fnd_api.g_miss_num);
2480 end get_g_miss_num;
2481
2482 function get_g_miss_char return varchar2 is
2483 begin
2484 return(fnd_api.g_miss_char);
2485 end get_g_miss_char;
2486
2487 function get_g_miss_date return date is
2488 begin
2489 return(fnd_api.g_miss_date);
2490 end get_g_miss_date;
2491
2492 --
2493 -- Function ResourceDt_To_ServerDT Added for Simplex Timezone Enh # 3040681 by ABRAINA
2494 --
2495
2496 --
2497 -- Function ResourceDt_To_ServerDT Added for Simplex Timezone Enh # 3040681 by ABRAINA
2498 --
2499
2500 Function ResourceDt_To_ServerDT ( P_Resource_DtTime IN date, P_Resource_TZ_Id IN Number , p_Server_TZ_id IN Number ) RETURN date IS
2501
2502 x_Server_time Date := P_Resource_DtTime;
2503
2504 l_api_name CONSTANT VARCHAR2(30) := 'ResourceDt_To_ServerDT';
2505 l_API_VERSION Number := 1.0 ;
2506 p_API_VERSION Number := 1.0 ;
2507 l_INIT_MSG_LIST varchar2(1) := 'F';
2508 p_INIT_MSG_LIST varchar2(1) := 'F';
2509 X_msg_count Number;
2510 X_msg_data Varchar2(2000);
2511 X_RETURN_STATUS Varchar2(10);
2512
2513 BEGIN
2514
2515 -- Standard call to check for call compatibility.
2516 IF NOT FND_API.Compatible_API_Call (l_api_version ,
2517 p_api_version ,
2518 l_api_name ,
2519 G_PKG_NAME )
2520 THEN
2521 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2522 END IF;
2523
2524 -- Initialize message list if p_init_msg_list is set to TRUE.
2525 IF FND_API.to_Boolean( p_init_msg_list ) THEN
2526 FND_MSG_PUB.initialize;
2527 END IF;
2528
2529 -- Initialize API return status to success
2530 x_return_status := FND_API.G_RET_STS_SUCCESS;
2531
2532 HZ_TIMEZONE_PUB.Get_Time( l_API_VERSION
2533 , l_INIT_MSG_LIST
2534 , P_Resource_TZ_Id
2535 , p_Server_TZ_id
2536 , P_Resource_DtTime
2537 , x_Server_time
2538 , X_RETURN_STATUS
2539 , X_msg_count
2540 , X_msg_data);
2541
2542 Return x_Server_time;
2543
2544 EXCEPTION
2545 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
2546 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
2547 FND_MSG_PUB.Count_And_Get
2548 ( p_count => x_msg_count,
2549 p_data => x_msg_data
2550 );
2551 WHEN G_EXC_REQUIRED_FIELDS_NULL THEN
2552 x_return_status := FND_API.G_RET_STS_ERROR ;
2553 fnd_message.set_name('JTF','JTF_CAL_REQUIRED_PARAMETERS');
2554 fnd_message.set_token('P_PARAMETER', l_parameters);
2555 fnd_msg_pub.add;
2556 FND_MSG_PUB.Count_And_Get
2557 (p_count => x_msg_count,
2558 p_data => x_msg_data
2559 );
2560 WHEN OTHERS THEN
2561 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
2562 fnd_message.set_name('JTF','JTF_CAL_UNEXPECTED_ERROR');
2563 fnd_message.set_token('ERROR_CODE',SQLCODE);
2564 fnd_message.set_token('ERROR_MESSAGE', SQLERRM);
2565 fnd_msg_pub.add;
2566 FND_MSG_PUB.Count_And_Get
2567 ( p_count => x_msg_count,
2568 p_data => x_msg_data
2569 );
2570
2571 END ResourceDt_To_ServerDT;
2572
2573 Function Get_Res_Timezone_Id ( p_resource_Id IN NUMBER, p_resource_type IN VARCHAR2 ) RETURN Number IS
2574
2575 Cursor C_Res_TimeZone Is
2576 Select TIME_ZONE
2577 From JTF_RS_RESOURCE_EXTNS
2578 Where RESOURCE_ID = p_resource_id
2579 AND 'RS_'||category = p_resource_type
2580 And trunc(sysdate) between trunc(nvl(START_DATE_ACTIVE,sysdate))
2581 and trunc(nvl(END_DATE_ACTIVE,sysdate));
2582
2583 CURSOR c_group_res_timezone Is
2584 SELECT TIME_ZONE
2585 FROM JTF_RS_GROUPS_B
2586 WHERE group_id = p_resource_id
2587 AND trunc(SYSDATE) BETWEEN trunc(nvl(START_DATE_ACTIVE,SYSDATE))
2588 AND trunc(nvl(END_DATE_ACTIVE,SYSDATE));
2589
2590 l_res_timezone_id NUMBER;
2591
2592 BEGIN
2593 IF p_resource_type = 'RS_GROUP' THEN
2594 OPEN C_group_res_TimeZone ;
2595 FETCH C_group_res_TimeZone INTO l_res_timezone_id;
2596 CLOSE C_group_res_TimeZone ;
2597 ELSE
2598 OPEN C_Res_TimeZone ;
2599 FETCH C_Res_TimeZone INTO l_res_timezone_id;
2600 CLOSE C_Res_TimeZone ;
2601 END IF;
2602
2603 l_res_timezone_id := nvl(l_res_timezone_id,fnd_profile.value_specific('SERVER_TIMEZONE_ID'));
2604
2605 RETURN l_res_timezone_id;
2606
2607 END Get_Res_Timezone_Id;
2608
2609 -- Function added for bug 3270116 by ABRAINA
2610 Function Validate_Cal_Date ( P_Calendar_Id IN number, P_shift_date IN date ) RETURN boolean IS
2611 v_valid_cal Number;
2612
2613 BEGIN
2614
2615 select 1
2616 into v_valid_cal
2617 from jtf_calendars_b a
2618 where calendar_id = P_Calendar_Id
2619 -- Commented for bug 3891896 by ABRAINA
2620 -- and P_shift_date between trunc(a.start_date_active) and nvl(trunc(a.end_date_active),to_date(get_g_miss_date,'DD/MM/RRRR'));
2621 and P_shift_date between trunc(a.start_date_active) and nvl(trunc(a.end_date_active),P_shift_date);
2622
2623 If v_valid_cal = 1 Then
2624 Return (TRUE);
2625 Else
2626 Return (FALSE);
2627 End If;
2628
2629 End Validate_Cal_Date;
2630
2631 END JTF_CALENDAR_PUB;
2632