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