DBA Data[Home] [Help]

PACKAGE BODY: APPS.HXC_PREFERENCE_EVALUATION

Source


1 PACKAGE BODY hxc_preference_evaluation AS
2 /* $Header: hxcpfevl.pkb 120.20 2011/08/10 10:23:15 asrajago ship $ */
3 
4    g_migration_mode         BOOLEAN       := FALSE;
5    g_package                VARCHAR2 (72) := 'hxc_preference_evaluation';
6    g_debug boolean := hr_utility.debug_enabled;
7 
8 -- will use PL/SQL tables in various places to manipulate preference information
9 
10 TYPE t_str_version_row IS RECORD
11 ( org_Structure_id      per_organization_structures.organization_structure_id%TYPE,
12   org_version_id        per_org_structure_versions.org_structure_version_id%type,
13   time_info             date);
14 
15 TYPE t_requested_pref IS RECORD
16 ( code      hxc_pref_definitions.code%TYPE,
17   attr_list VARCHAR2(90) );
18 
19 TYPE t_dated_pref_row IS RECORD
20 ( start_date  DATE,
21   end_date    DATE,
22   code        hxc_pref_definitions.code%TYPE,
23   rule_evaluation_order NUMBER,
24   pref_ref    NUMBER,
25   edit_allowed hxc_pref_hierarchies.edit_allowed%TYPE);
26 
27 TYPE t_hierarchy_list_row IS RECORD
28 (
29 pref_hierarchy_id NUMBER,
30 start_date DATE,
31 end_date DATE,
32 elig_start_date DATE,
33 elig_end_date DATE,
34 rule_evaluation_order NUMBER);
35 
36 TYPE t_requested_pref_list IS TABLE OF
37   t_requested_pref
38 INDEX BY BINARY_INTEGER;
39 
40 TYPE t_pref_trans IS TABLE OF
41   hxc_pref_definitions.code%TYPE
42 INDEX BY BINARY_INTEGER;
43 
44 TYPE t_hierarchy_list IS TABLE OF
45 t_hierarchy_list_row
46 INDEX BY BINARY_INTEGER;
47 
48 -- when evaluating preferences with a range of dates, its possible to have
49 -- more than one value for a single preference. The following structure is used
50 -- to keep track of which rows in a preference table are for which preference.
51 
52 TYPE t_dated_prefs IS TABLE OF
53 t_dated_pref_row
54 INDEX BY BINARY_INTEGER;
55 
56 TYPE t_str_version is table of t_str_version_row
57 index by binary_integer;
58 
59 g_str_version t_str_version;
60 
61 g_input_separator VARCHAR2(1) := '|';
62 g_raise_fatal_errors BOOLEAN := TRUE;
63 g_fatal_error_occurred BOOLEAN := FALSE;
64 g_fatal_error VARCHAR2(30) :='';
65 
66 -- variables and type for sorted date range preference evaluation
67 
68 g_sort_pref_table t_pref_table;
69 
70 TYPE r_sort_cache IS RECORD ( resource_id NUMBER(15), start_date DATE, end_date DATE);
71 TYPE t_sort_cache IS TABLE OF r_sort_cache INDEX BY BINARY_INTEGER;
72 
73 g_sort_cache t_sort_cache;
74 
75 --------
76 -- Procedure RETURNs all the preferences for a given resource_id
77 --------
78 --------Function added for the bug 3868611
79 
80 Function check_number(p_string in varchar2)  return number is
81 l_string number;
82 BEGIN
83       l_string:= to_number(p_string);
84       return(l_string);
85 EXCEPTION
86  WHEN OTHERS THEN
87  return(null);
88 END;
89 
90 
91 
92 PROCEDURE resource_preferences(p_resource_id IN NUMBER,
93                                p_pref_table  IN OUT NOCOPY t_pref_table,
94                                p_evaluation_date IN DATE default sysdate,
95                                p_user_id IN number default fnd_global.user_id,
96 	     		       p_resp_id IN number default -99,
97 			       p_ignore_user_id in boolean default false,
98 			       p_ignore_resp_id in boolean default false)
99 
100 IS
101 
102 l_req                NUMBER;
103 l_personal_hierarchy NUMBER;
104 l_hier               NUMBER;
105 l_requested_list     t_requested_pref_list;
106 l_pref_trans         t_pref_trans;
107 l_hierarchy_list     t_hierarchy_list;
108 l_evaluation_date    DATE;
109 l_hier_count    number;
110 l_employee_id NUMBER;
111 
112 --Added By Mithun for CWK Terminate Bug
113 cwk_final_process_date	DATE;
114 l_num_of_days_to_add	NUMBER;
115 
116 -- Bug 3297639
117 l_pref_index number;
118 l_preference_id number;
119 l_last_updated_date date;
120 l_use_cache boolean := FALSE;
121 
122 --Added By Mithun
123 l_resp_id		NUMBER;
124 CURSOR c_get_last_updated_date(p_pref_hierarchy_id IN number) IS
125 	Select last_update_date
126 	From hxc_pref_hierarchies
127 	Where pref_hierarchy_id = p_pref_hierarchy_id;
128 
129 -- CURSORs to find the hierarchies a resource is eligible for ...
130 -- To support new criteria add new CURSORs or add to existing CURSOR.
131 
132 CURSOR get_employee_id(p_user_id IN Number) Is
133 
134   Select employee_id from fnd_user
135   Where user_id = p_user_id;
136 
137 
138 /*Cursor Modified By Mithun for CWK Terminate Bug*/
139 -- Modified the cursor to support CWK.
140 CURSOR c_eligible_hierarchies_basic(p_resource_id IN NUMBER,
141                                     p_evaluation_date IN DATE) IS
142 
143   SELECT hrr.pref_hierarchy_id, hrr.rule_evaluation_order
144       FROM hxc_resource_rules hrr,
145            per_all_assignments_f pa
146      WHERE pa.person_id = p_resource_id
147        AND nvl(hrr.business_group_id,pa.business_group_id) = pa.business_group_id
148        AND pa.primary_flag = 'Y'
149        and pa.assignment_type in ('E','C')
150        AND p_evaluation_date
151            BETWEEN pa.effective_start_date
152            AND Decode(pa.assignment_type , 'C',
153 		Decode(cwk_final_process_date,pa.effective_END_date,pa.effective_END_date + l_num_of_days_to_add ,pa.effective_END_date),pa.effective_END_date)
154        AND p_evaluation_date between hrr.start_date and hrr.end_date
155        AND ((   to_char(pa.assignment_id) = hrr.eligibility_criteria_id
156                     AND hrr.eligibility_criteria_type = 'ASSIGNMENT')
157         OR (      to_char(pa.payroll_id) = hrr.eligibility_criteria_id
158                     AND hrr.eligibility_criteria_type = 'PAYROLL')
159         OR (       to_char(pa.person_id) = hrr.eligibility_criteria_id
160                     AND hrr.eligibility_criteria_type = 'PERSON')
161         OR (     to_char(pa.location_id) = hrr.eligibility_criteria_id
162                     AND hrr.eligibility_criteria_type = 'LOCATION')
163         OR (     pa.EMPLOYEE_CATEGORY = hrr.eligibility_criteria_id
164                     AND hrr.eligibility_criteria_type = 'EMP_CATEGORY')
165         OR (     pa.EMPLOYMENT_CATEGORY = hrr.eligibility_criteria_id
166                     AND hrr.eligibility_criteria_type = 'ASGN_CATEGORY')
167         OR (     to_char(pa.organization_id) = hrr.eligibility_criteria_id
168                     AND hrr.eligibility_criteria_type = 'ORGANIZATION')
169         OR (
170              hrr.eligibility_criteria_type = 'ALL_PEOPLE'));
171 
172 
173  -- Bug 7484448
174  -- Added USE_NL in the below query for optimum perf.
175 /*Cursor Modified By Mithun for CWK Terminate Bug*/
176 CURSOR c_eligible_hierarchies_rollup(p_resource_id IN NUMBER,
177                                     p_evaluation_date IN DATE) IS
178     SELECT /*+ USE_NL(PA HRR) */
179            hrr.pref_hierarchy_id, hrr.rule_evaluation_order
180       FROM hxc_resource_rules hrr,
181            per_all_assignments_f pa
182      WHERE pa.person_id = p_resource_id
183        AND nvl(hrr.business_group_id,pa.business_group_id) = pa.business_group_id
184        AND pa.primary_flag = 'Y'
185        and pa.assignment_type in ('E','C')
186        AND p_evaluation_date
187               BETWEEN pa.effective_start_date
188 	                 AND Decode(pa.assignment_type , 'C',
189 	      		Decode(cwk_final_process_date,pa.effective_END_date,pa.effective_END_date + l_num_of_days_to_add ,pa.effective_END_date),pa.effective_END_date)
190        AND p_evaluation_date between hrr.start_date and hrr.end_date
191        AND (
192         ((HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,instr(hrr.eligibility_criteria_id,'-',1,1)+1)) in
193            (SELECT pose.organization_id_parent
194                   FROM
195                  per_org_structure_elements pose
196 		 start with organization_id_child = pa.organization_id
197                  and  pose.org_structure_version_id=
198                       HXC_PREFERENCE_EVALUATION.return_version_id(HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,1,instr(hrr.eligibility_criteria_id,'-',1,1)-1)),
199                                                                            hrr.eligibility_criteria_type)
200                   connect by prior organization_id_parent=organization_id_child
201                   and  pose.org_structure_version_id=
202                                HXC_PREFERENCE_EVALUATION.return_version_id(HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,1,instr(hrr.eligibility_criteria_id,'-',1,1)-1)),
203                                                                            hrr.eligibility_criteria_type)
204                   union
205                   select organization_id
206                   from   hr_all_organization_units
207                   where  organization_id =  pa.organization_id))
208                   AND  hrr.eligibility_criteria_type = 'ROLLUP' )
209         );
210 
211 /*Cursor Modified By Mithun for CWK Terminate Bug*/
212 -- Modified cursor to support CWK.
213 CURSOR c_eligible_hierarchies_flex(p_resource_id IN NUMBER,
214                                    p_evaluation_date IN DATE) IS
215   SELECT hrr.pref_hierarchy_id, hrr.rule_evaluation_order
216     FROM hxc_resource_rules hrr,
217          per_all_assignments_f pa
218    WHERE pa.person_id = p_resource_id
219      AND nvl(hrr.business_group_id,pa.business_group_id) = pa.business_group_id
220      AND pa.primary_flag = 'Y'
221 and pa.assignment_type in ('E','C')
222      AND p_evaluation_date
223               BETWEEN pa.effective_start_date
224            AND Decode(pa.assignment_type , 'C',
225 		Decode(cwk_final_process_date,pa.effective_END_date,pa.effective_END_date + l_num_of_days_to_add ,pa.effective_END_date),pa.effective_END_date)
226      AND p_evaluation_date between hrr.start_date and hrr.end_date
227 AND ( (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 3 ),
228       'SCL', DECODE ( pa.soft_coding_keyflex_id, NULL, -1,
229       hxc_resource_rules_utils.chk_flex_valid ('SCL', pa.soft_coding_keyflex_id,
230       SUBSTR( hrr.eligibility_criteria_type, 5 ),
231                   hrr.eligibility_criteria_id )), -1 ) = 1 )
232 OR
233       (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 6 ),
234       'PEOPLE', DECODE ( pa.people_group_id, NULL, -1,
235       hxc_resource_rules_utils.chk_flex_valid ( 'PEOPLE', pa.people_group_id,
236       SUBSTR( hrr.eligibility_criteria_type, 8 ),
237                   hrr.eligibility_criteria_id )), -1 ) = 1 )
238 OR
239       (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 5 ),
240       'GRADE', DECODE ( pa.grade_id, NULL, -1,
241       hxc_resource_rules_utils.chk_flex_valid ( 'GRADE', pa.grade_id,
242       SUBSTR( hrr.eligibility_criteria_type, 7 ),
243                   hrr.eligibility_criteria_id )), -1 ) = 1 )
244 OR
245 
246       (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 3 ),
247       'JOB', hrr.eligibility_criteria_id, -1 ) = to_char(pa.job_id))-- Issue 4
248 
249 OR
250 
251       (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 8 ),
252       'POSITION', hrr.eligibility_criteria_id, -1 ) = to_char(pa.position_id)) -- Issue 4
253 );
254 
255 -- Cursor to check whether the resource has personalized preferences.
256 -- Note that this CURSOR could be removed in order to possibly boost performance
257 -- But, keep it simple for now.
258 
259 CURSOR c_personal_hierarchy(p_user_id IN NUMBER) IS
260 SELECT hrr.pref_hierarchy_id , hrr.rule_evaluation_order
261 FROM   hxc_resource_rules hrr
262 WHERE  hrr.resource_type='PERSON'
263 AND    hrr.eligibility_criteria_type = 'LOGIN'
264 AND    hrr.eligibility_criteria_id = to_char(p_user_id) ; -- Issue 4
265 
266 
267 
268 -- Cursor to pick up any responsibility based prefs(both responsibility and perst responsibility)
269 
270      CURSOR c_resp_hierarchies(p_responsibility_id IN NUMBER,
271                                p_evaluation_date IN DATE) IS
272      SELECT hrr.pref_hierarchy_id ,
273             hrr.rule_evaluation_order
274        FROM hxc_resource_rules hrr
275       WHERE hrr.resource_type='PERSON'
276         AND p_evaluation_date BETWEEN hrr.start_date
277                                   AND hrr.end_date
278         AND hrr.eligibility_criteria_type IN ('RESPONSIBILITY','PERST_RESPONSIBILITY')
279         AND hrr.eligibility_criteria_id = to_char(p_responsibility_id); -- Issue 4
280 
281 
282 
283 --Added By Mithun
284 --Cursor to pick up only persistent responsibility based preference
285     CURSOR c_perst_resp_hierarchies(p_responsibility_id IN NUMBER,
286                                     p_evaluation_date   IN DATE) IS
287     SELECT hrr.pref_hierarchy_id ,
288            hrr.rule_evaluation_order
289       FROM hxc_resource_rules hrr
290      WHERE hrr.resource_type='PERSON'
291        AND p_evaluation_date BETWEEN hrr.start_date
292                                  AND hrr.end_date
293        AND hrr.eligibility_criteria_type = 'PERST_RESPONSIBILITY'
294        AND hrr.eligibility_criteria_id = to_char(p_responsibility_id);
295 
296  -- Issue 4
297 
298 
299 /*Cursor Modified By Mithun for CWK Terminate Bug*/
300 CURSOR c_person_type_hierarchies(p_resource_id IN NUMBER,p_evaluation_date IN DATE) IS
301 SELECT hrr.pref_hierarchy_id , hrr.rule_evaluation_order
302 FROM   hxc_resource_rules hrr,
303 per_person_types typ,
304 per_person_type_usages_f ptu
305 WHERE  hrr.resource_type='PERSON'
306 AND    p_evaluation_date between hrr.start_date and hrr.end_date
307 AND    hrr.eligibility_criteria_type = 'PERSON_TYPE'
308 AND    hrr.eligibility_criteria_id = to_char(ptu.person_type_id) -- Issue 4
309 AND    ptu.person_id = p_resource_id
310 AND    typ.system_person_type IN ('EMP','EX_EMP','EMP_APL','EX_EMP_APL','CWK','EX_CWK')
311 AND    typ.person_type_id = ptu.person_type_id
312 AND    p_evaluation_date between Ptu.effective_start_date
313 	and Decode(typ.system_person_type , 'CWK',
314 		Decode(cwk_final_process_date,Ptu.effective_end_date, Ptu.effective_end_date + l_num_of_days_to_add , Ptu.effective_end_date) ,Ptu.effective_end_date);
315 ------------------------------------------------------------------------------------
316 -- Cursor to RETURN the preference nodes in a hierarchy. Note that this is based
317 -- on a hierchical query. This can be removed if necessary by denormalization
318 -- on the hxc_pref_hierarchy base table
319 
320 CURSOR c_pref_nodes(p_hierarchy_id IN NUMBER)
321 IS
322  SELECT pref_hierarchy_id
323   ,pref_definition_id preference_id
324   ,attribute1
325   ,attribute2
326   ,attribute3
327   ,attribute4
328   ,attribute5
329   ,attribute6
330   ,attribute7
331   ,attribute8
332   ,attribute9
333   ,attribute10
334   ,attribute11
335   ,attribute12
336   ,attribute13
337   ,attribute14
338   ,attribute15
339   ,attribute16
340   ,attribute17
341   ,attribute18
342   ,attribute19
343   ,attribute20
344   ,attribute21
345   ,attribute22
346   ,attribute23
347   ,attribute24
348   ,attribute25
349   ,attribute26
350   ,attribute27
351   ,attribute28
352   ,attribute29
353   ,attribute30
354   ,edit_allowed
355   ,displayed
356   ,name
357   ,top_level_parent_id --Performance Fix
358   ,code
359   FROM hxc_pref_hierarchies
360   WHERE top_level_parent_id = p_hierarchy_id;
361 --  pref_definition_id is not null
362 --  START WITH pref_hierarchy_id = p_hierarchy_id
363 --  CONNECT BY prior pref_hierarchy_id = parent_pref_hierarchy_id;
364 -- Performance Fix.
365 /*CURSOR c_pref_codes
366 IS
367 SELECT
368  pref_definition_id, code
369 FROM hxc_pref_definitions;*/
370 
371 l_user_id	NUMBER;
372 
373 /* Mikarthi Terminated CWK Enhancement */
374 Cursor c_cwk_terminate_date( p_person_id IN NUMBER, p_evaluation_date IN DATE) is
375 Select NVL(final_process_date, hr_general.end_of_time)
376 from per_periods_of_placement
377 where person_id = p_person_id
378 and date_start <= p_evaluation_date
379 order by date_start desc;
380 
381 /*End of Terminated CWK Enhancement Addtion */
382 
383 l_find_resp_required	BOOLEAN DEFAULT FALSE;
384 
385 BEGIN
386 
387 --Here we are checking whether it is really required to do preference evaluation based on
388 --Responsibility. There can be three conditions
389 --1)  p_resp_id = -99 This is the default value for the parameter. So this could come
390 --    either because no value was passed while calling resource_preference,
391 --    or explicitly -99 was passed while calling resource preference. In either case
392 --    persistent responsibiilty preference evalution would be done. Which means, we
393 --    would obtain the responsibility stored in the timecard and then obtain preferences
394 --    attached to that responsibility, if any. If no valid responsibility is obtained
395 --    from the tc and if employee_id and the resource_id is the same, then we will do
396 --    persistent resp evalution based on the FND_global.resp_id
397 --2)  p_resp_id = -101 we dont have to do preference evalution on persistent responsibility
398 --
399 
400 g_debug := hr_utility.debug_enabled;
401 
402        IF g_debug
403        THEN
404           hr_utility.trace('Evaluation pref for p_evaluation_date ');
405        	  hr_utility.trace('p_resource_id '||p_resource_id);
406        	  hr_utility.trace('p_evaluation_date '||p_evaluation_date);
407        END IF;
408 
409        l_resp_id := p_resp_id;
410        l_user_id := p_user_id;
411 
412        -- Find out if the resource himself is logged in.
413        -- In that case, there is no need of looking into any
414        -- timecard, consider persistent responsibility also as
415        -- session responsibility.
416 
417        OPEN get_employee_id(fnd_global.user_id);
418 
419        FETCH get_employee_id
420         INTO l_employee_id ;
421 
422        CLOSE get_employee_id;
423 
424        IF ( p_resp_id = -99 ) AND (l_employee_id <> p_resource_id)
425        THEN
426 
427            l_find_resp_required := TRUE;
428 
429        ELSE
430 
431  	   l_find_resp_required := FALSE;
432 
433        END IF;
434 
435        -- Either ways, you need this responsibility. This is the key
436        -- in case the user is the employee himself.
437 
438        l_resp_id := FND_GLOBAL.RESP_ID;
439 
440 
441       IF g_debug
442       THEN
443          hr_utility.trace('Current user''s user_id is '||fnd_global.user_id);
444          hr_utility.trace('Current user''s person_id is '||l_employee_id);
445       END IF;
446 
447 -- make sure pref table is empty - otherwise this will interfere with the evaluation
448 p_pref_table.delete;
449 
450 -- l_evaluation_date:=trunc(p_evaluation_date); -- replaced for bug 3097015 with
451 -- the following function call ...
452       l_evaluation_date :=
453             evaluation_date (
454                p_resource_id=> p_resource_id,
455                p_evaluation_date=> p_evaluation_date
456             );
457 
458 -- populate table that will allow us to find a pref_code given an
459 -- pref_definition_id
460 -- note:
461 -- a) could do this join in one of the CURSORs - choose not to do this to avoid
462 --    complexity in the SQL which might lead to overly complex execution plan.
463 -- b) could denormalize the code onto the pref_hierarchies table thus making
464 -- this step redundent.
465 -- c) could turn this into a bulk collect - pick up the values AND THEN
466 -- populate the array later.
467 -- Probably do b) in conjunction with other denormalization
468 
469 -- Performance Fix
470 --FOR pref_rec IN c_pref_codes LOOP
471 --  l_pref_trans(pref_rec.pref_definition_id) := pref_rec.code;
472 --END LOOP;
473 
474 --Added By Mithun for CWK Terminate Bug
475 OPEN c_cwk_terminate_date (p_resource_id, p_evaluation_date);
476 FETCH c_cwk_terminate_date INTO cwk_final_process_date;
477 CLOSE c_cwk_terminate_date;
478 
479 l_num_of_days_to_add := NVL(fnd_profile.value('HXC_CWK_TK_FPD'),0);
480 
481 if g_debug then
482 
483 	HR_UTILITY.trace(g_package || ' cwk_final_process_date ' || cwk_final_process_date);
484 	HR_UTILITY.trace(g_package || 'l_num_of_days_to_add ' || l_num_of_days_to_add);
485 
486 end if;
487 --End of Addition By Mithun for CWK Terminate Bug
488 
489 l_hier_count:=0;
490 -- Now find the hierarchies which the person is eligible for ...
491 -- note:
492 -- a) IF we cycle through the hierarchies in order of increasing precidence
493 --    - dont even need to do evaluation as we cycle. Sort is probably more
494 --      expensive though ...
495 
496 -- basic eligibility, must be at least one
497 
498 FOR hier_rec IN c_eligible_hierarchies_basic(p_resource_id, l_evaluation_date) LOOP
499    l_hierarchy_list(l_hier_count).rule_evaluation_order := hier_rec.rule_evaluation_order;
500    l_hierarchy_list(l_hier_count).pref_hierarchy_id     := hier_rec.pref_hierarchy_id;
501    l_hier_count:=l_hier_count+1;
502 END LOOP;
503 
504 BEGIN
505 FOR hier_rec IN c_eligible_hierarchies_rollup(p_resource_id, l_evaluation_date) LOOP
506    l_hierarchy_list(l_hier_count).rule_evaluation_order := hier_rec.rule_evaluation_order;
507    l_hierarchy_list(l_hier_count).pref_hierarchy_id     := hier_rec.pref_hierarchy_id;
508    l_hier_count:=l_hier_count+1;
509 END LOOP;
510 EXCEPTION
511     WHEN NO_DATA_FOUND THEN null;
512 END;
513 
514 -- Issue 6
515 IF(l_hierarchy_list.count = 0)
516 then
517   IF( g_raise_fatal_errors = TRUE) THEN
518     hr_utility.set_message(809, 'HXC_NO_HIER_FOR_DATE');
519     hr_utility.raise_error;
520   ELSE
521     g_fatal_error_occurred := TRUE;
522     g_fatal_error := 'HXC_NO_HIER_FOR_DATE';
523     RETURN;
524   END IF;
525 END IF;
526 
527 -- more complex eligibility, zero or more
528 
529 BEGIN
530 FOR hier_rec in c_eligible_hierarchies_flex(p_resource_id, l_evaluation_date) LOOP
531    l_hierarchy_list(l_hier_count).rule_evaluation_order := hier_rec.rule_evaluation_order;
532    l_hierarchy_list(l_hier_count).pref_hierarchy_id     := hier_rec.pref_hierarchy_id;
533    l_hier_count                                         := l_hier_count+1;
534 
535 END LOOP;
536 EXCEPTION
537   WHEN NO_DATA_FOUND THEN null;
538 END;
539 
540 --IF(fnd_global.resp_id <> -1) THEN
541 --IF(p_resp_id <> -1) then
542 
543 -- Issue 3
544 /*If (p_user_id = -1) Then
545         -- we are defaulting the value
546         -- from the fnd_global value
547 	l_employee_id 	:= fnd_global.employee_id;
548 	l_user_id	:= fnd_global.user_id;
549 Else*/
550 
551 --End If;
552 
553 -- Responsibility based hierarchies
554 -- ================================
555 --  If the resource himself is in session, you only look for session responsibility
556 --  Otherwise, you have to look into which timecard is in question to find out
557 --  which responsibility last touched the timecard.
558 
559 
560 If (l_resp_id <> -1  AND ( not p_ignore_resp_id)) Then
561 
562         -- Do a session based resp evaluation only when the user himself is logged
563         -- in. But at this point consider even persistent responsibility. Note the
564         -- defn of the cursor that is opened here.
565 
566 	IF  l_employee_id = p_resource_id
567 	THEN
568 		BEGIN
569 			FOR hier_rec in c_resp_hierarchies(l_resp_id, l_evaluation_date) LOOP
570 			      l_hierarchy_list(l_hier_count).rule_evaluation_order := hier_rec.rule_evaluation_order;
571 			      l_hierarchy_list(l_hier_count).pref_hierarchy_id     := hier_rec.pref_hierarchy_id;
572 
573 			      l_hier_count                                         := l_hier_count+1;
574 			END LOOP;
575 		EXCEPTION
576 		    WHEN NO_DATA_FOUND THEN null;
577 		END;
578 	END IF;
579 
580         --Checking If we have to obtain the resp_id value stored in  the timecard
581 	IF l_find_resp_required
582 	THEN
583 		l_resp_id := get_tc_resp(p_resource_id, l_evaluation_date);
584 
585 		--l_resp_id = -101 here indicates that some other user (for eg TK) has modified this timecard
586 		--and the current resp_id stored is the resp_id used by that user. So we should not use
587 		--that resp_id for preference evalution. However we still have to do preference
588 		--evaluation on persistent responsibility using resp id as fnd_global.resp_id
589 		--if l_employee_id = p_resource_id
590 	        IF l_resp_id <> -101
591 	        THEN
592 			BEGIN
593 
594 				FOR hier_rec IN c_perst_resp_hierarchies(l_resp_id, l_evaluation_date)
595 				LOOP
596 				      l_hierarchy_list(l_hier_count).rule_evaluation_order := hier_rec.rule_evaluation_order;
597 				      l_hierarchy_list(l_hier_count).pref_hierarchy_id     := hier_rec.pref_hierarchy_id;
598 
599 				      l_hier_count                                         := l_hier_count+1;
600 				END LOOP;
601 			EXCEPTION
602 			    WHEN NO_DATA_FOUND THEN null;
603 			END;
604 		END IF;
605 	END IF;
606 End If;
607 --End of changes Done By Myth
608 
609 -- personalisation, only one hierarchy possible
610 -- Issue 3 Added p_ignore_user_id
611 
612 BEGIN
613 FOR hier_rec in c_person_type_hierarchies(p_resource_id, l_evaluation_date) LOOP
614    l_hierarchy_list(l_hier_count).rule_evaluation_order := hier_rec.rule_evaluation_order;
615    l_hierarchy_list(l_hier_count).pref_hierarchy_id     := hier_rec.pref_hierarchy_id;
616    l_hier_count                                         := l_hier_count+1;
617 
618 END LOOP;
619 EXCEPTION
620   WHEN NO_DATA_FOUND THEN null;
621 END;
622 
623 -----------------------------------------------------------------------------------------
624 
625 
626 if (( NOT p_ignore_user_id) AND l_employee_id = p_resource_id AND l_user_id <> -1) then
627 BEGIN
628 FOR hier_rec IN c_personal_hierarchy(l_user_id) LOOP
629    l_hierarchy_list(l_hier_count).rule_evaluation_order := hier_rec.rule_evaluation_order;
630    l_hierarchy_list(l_hier_count).pref_hierarchy_id     := hier_rec.pref_hierarchy_id;
631    l_hier_count                                         := l_hier_count+1;
632 END LOOP;
633 EXCEPTION
634   WHEN NO_DATA_FOUND THEN null;
635 END;
636 END if;
637 
638    -- Issue 6
639 /*IF(l_hierarchy_list.count = 0)
640 then
641   IF( g_raise_fatal_errors = TRUE) THEN
642     hr_utility.set_message(809, 'HXC_NO_HIER_FOR_DATE');
643     hr_utility.raise_error;
644   ELSE
645     g_fatal_error_occurred := TRUE;
646     g_fatal_error := 'HXC_NO_HIER_FOR_DATE';
647     RETURN;
648   END IF;
649 END IF;*/
650 
651 -- loop over the hierarchies we have found
652 
653 l_hier := l_hierarchy_list.first;
654 
655 l_hier := l_hierarchy_list.first;
656 g_loop_count := 0;
657 
658 -- Bug 3297639.
659 -- Modified the logic for caching Preference values.
660 LOOP
661   EXIT WHEN NOT l_hierarchy_list.exists(l_hier);
662 
663   --reset for each Pref Id
664   l_use_cache := FALSE;
665 
666   -- Check if the required data is already cached.
667   If ( g_pref_hier_ct.exists(l_hierarchy_list(l_hier).pref_hierarchy_id) ) then
668 
669 	Open c_get_last_updated_date(l_hierarchy_list(l_hier).pref_hierarchy_id);
670 	Fetch c_get_last_updated_date into l_last_updated_date;
671 	Close c_get_last_updated_date;
672 
673 	-- checking if the cache data is outdated.
674 	if ( g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).caching_time >= l_last_updated_date) then
675 		l_use_cache := TRUE;
676 	else
677 	        l_use_cache := FALSE;
678 		-- Delete the Pref Values for this, since it has to be refreshed anyway.
679 		g_pref_values_ct.delete(g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index,g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index); -- table.delete(m,n)
680 	end if;
681   end if;
682 
683   -- If l_use_cache = FALSE, then populate/refresh cache data by db fetch.
684   If (not l_use_cache) then
685 
686     -- initialise main table.
687     g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).caching_time := sysdate;
688     g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index := -1;
689     g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index := -1;
690 
691     -- Initialize Start_Index for the Pref Values
692     If (g_pref_values_ct.count > 0) then
693 	l_pref_index := g_pref_values_ct.last + 1;
694     else
695 	l_pref_index := 1;
696     End If;
697 
698     g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index := l_pref_index;
699 
700     -- populate preference values into cache
701     FOR pref_node in c_pref_nodes(l_hierarchy_list(l_hier).pref_hierarchy_id)
702     LOOP
703 
704     g_pref_values_ct(l_pref_index).pref_hierarchy_id := pref_node.pref_hierarchy_id;
705     g_pref_values_ct(l_pref_index).pref_definition_id := pref_node.preference_id;
706     g_pref_values_ct(l_pref_index).attribute1:= pref_node.attribute1;
707     g_pref_values_ct(l_pref_index).attribute2:= pref_node.attribute2;
708     g_pref_values_ct(l_pref_index).attribute3:= pref_node.attribute3;
709     g_pref_values_ct(l_pref_index).attribute4:= pref_node.attribute4;
710     g_pref_values_ct(l_pref_index).attribute5:= pref_node.attribute5;
711     g_pref_values_ct(l_pref_index).attribute6:= pref_node.attribute6;
712     g_pref_values_ct(l_pref_index).attribute7:= pref_node.attribute7;
713     g_pref_values_ct(l_pref_index).attribute8:= pref_node.attribute8;
714     g_pref_values_ct(l_pref_index).attribute9:= pref_node.attribute9;
715     g_pref_values_ct(l_pref_index).attribute10:= pref_node.attribute10;
716     g_pref_values_ct(l_pref_index).attribute11:= pref_node.attribute11;
717     g_pref_values_ct(l_pref_index).attribute12:= pref_node.attribute12;
718     g_pref_values_ct(l_pref_index).attribute13:= pref_node.attribute13;
719     g_pref_values_ct(l_pref_index).attribute14:= pref_node.attribute14;
720     g_pref_values_ct(l_pref_index).attribute15:= pref_node.attribute15;
721     g_pref_values_ct(l_pref_index).attribute16:= pref_node.attribute16;
722     g_pref_values_ct(l_pref_index).attribute17:= pref_node.attribute17;
723     g_pref_values_ct(l_pref_index).attribute18:= pref_node.attribute18;
724     g_pref_values_ct(l_pref_index).attribute19:= pref_node.attribute19;
725     g_pref_values_ct(l_pref_index).attribute20:= pref_node.attribute20;
726     g_pref_values_ct(l_pref_index).attribute21:= pref_node.attribute21;
727     g_pref_values_ct(l_pref_index).attribute22:= pref_node.attribute22;
728     g_pref_values_ct(l_pref_index).attribute23:= pref_node.attribute23;
729     g_pref_values_ct(l_pref_index).attribute24:= pref_node.attribute24;
730     g_pref_values_ct(l_pref_index).attribute25:= pref_node.attribute25;
731     g_pref_values_ct(l_pref_index).attribute26:= pref_node.attribute26;
732     g_pref_values_ct(l_pref_index).attribute27:= pref_node.attribute27;
733     g_pref_values_ct(l_pref_index).attribute28:= pref_node.attribute28;
734     g_pref_values_ct(l_pref_index).attribute29:= pref_node.attribute29;
735     g_pref_values_ct(l_pref_index).attribute30:= pref_node.attribute30;
736 
737     g_pref_values_ct(l_pref_index).edit_allowed:= pref_node.edit_allowed;
738     g_pref_values_ct(l_pref_index).displayed:= pref_node.displayed;
739     g_pref_values_ct(l_pref_index).name:= pref_node.name;
740     g_pref_values_ct(l_pref_index).top_level_parent_id:= pref_node.top_level_parent_id;
741     g_pref_values_ct(l_pref_index).code:= pref_node.code;
742 
743     l_pref_index := g_pref_values_ct.last + 1;
744     End Loop;
745 
746     g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index := l_pref_index - 1;
747 
748     -- check for valid start and stop index. Incase the only leaf node was deleted or no leaf nodes exists then reset start and stop index accordingly
749     if (g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index < g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index) then
750         g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index := 0;
751 	g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index := 0;
752     end if;
753 
754     l_use_cache := TRUE; -- now data is in cache
755   End If;
756 
757   -- Now required data is in cache. Populate this required data to the main table after evaluation.
758   If (g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index <> 0 ) then     --(case where parent node has no children)
759     For l_index in g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index..g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_index Loop
760     Begin
761 
762         l_preference_id := g_pref_values_ct(l_index).pref_definition_id;
763 	IF( (l_hierarchy_list(l_hier).rule_evaluation_order >
764                          p_pref_table(l_preference_id).rule_evaluation_order
765            AND p_pref_table(l_preference_id).rule_evaluation_order <>0)
766            OR (l_hierarchy_list(l_hier).rule_evaluation_order = 0
767            AND p_pref_table(l_preference_id).edit_allowed = 'Y') ) THEN
768 
769 	    p_pref_table(l_preference_id).attribute1 := g_pref_values_ct(l_index).attribute1;
770 	    p_pref_table(l_preference_id).attribute2 := g_pref_values_ct(l_index).attribute2;
771 	    p_pref_table(l_preference_id).attribute3 := g_pref_values_ct(l_index).attribute3;
772 	    p_pref_table(l_preference_id).attribute4 := g_pref_values_ct(l_index).attribute4;
773 	    p_pref_table(l_preference_id).attribute5 := g_pref_values_ct(l_index).attribute5;
774 	    p_pref_table(l_preference_id).attribute6 := g_pref_values_ct(l_index).attribute6;
775 	    p_pref_table(l_preference_id).attribute7 := g_pref_values_ct(l_index).attribute7;
776 	    p_pref_table(l_preference_id).attribute8 := g_pref_values_ct(l_index).attribute8;
777 	    p_pref_table(l_preference_id).attribute9 := g_pref_values_ct(l_index).attribute9;
778 	    p_pref_table(l_preference_id).attribute10 := g_pref_values_ct(l_index).attribute10;
779 	    p_pref_table(l_preference_id).attribute11 := g_pref_values_ct(l_index).attribute11;
780 	    p_pref_table(l_preference_id).attribute12 := g_pref_values_ct(l_index).attribute12;
781 	    p_pref_table(l_preference_id).attribute13 := g_pref_values_ct(l_index).attribute13;
782 	    p_pref_table(l_preference_id).attribute14 := g_pref_values_ct(l_index).attribute14;
783 	    p_pref_table(l_preference_id).attribute15 := g_pref_values_ct(l_index).attribute15;
784 	    p_pref_table(l_preference_id).attribute16 := g_pref_values_ct(l_index).attribute16;
785 	    p_pref_table(l_preference_id).attribute17 := g_pref_values_ct(l_index).attribute17;
786 	    p_pref_table(l_preference_id).attribute18 := g_pref_values_ct(l_index).attribute18;
787 	    p_pref_table(l_preference_id).attribute19 := g_pref_values_ct(l_index).attribute19;
788 	    p_pref_table(l_preference_id).attribute20 := g_pref_values_ct(l_index).attribute20;
789 	    p_pref_table(l_preference_id).attribute21 := g_pref_values_ct(l_index).attribute21;
790 	    p_pref_table(l_preference_id).attribute22 := g_pref_values_ct(l_index).attribute22;
791 	    p_pref_table(l_preference_id).attribute23 := g_pref_values_ct(l_index).attribute23;
792 	    p_pref_table(l_preference_id).attribute24 := g_pref_values_ct(l_index).attribute24;
793 	    p_pref_table(l_preference_id).attribute25 := g_pref_values_ct(l_index).attribute25;
794 	    p_pref_table(l_preference_id).attribute26 := g_pref_values_ct(l_index).attribute26;
795 	    p_pref_table(l_preference_id).attribute27 := g_pref_values_ct(l_index).attribute27;
796 	    p_pref_table(l_preference_id).attribute28 := g_pref_values_ct(l_index).attribute28;
797 	    p_pref_table(l_preference_id).attribute29 := g_pref_values_ct(l_index).attribute29;
798 	    p_pref_table(l_preference_id).attribute30 := g_pref_values_ct(l_index).attribute30;
799 
800 	    p_pref_table(l_preference_id).edit_allowed := g_pref_values_ct(l_index).edit_allowed;
801 	    p_pref_table(l_preference_id).displayed := g_pref_values_ct(l_index).displayed;
802 	    p_pref_table(l_preference_id).rule_evaluation_order
803 					 := l_hierarchy_list(l_hier).rule_evaluation_order;
804 	    p_pref_table(l_preference_id).name := g_pref_values_ct(l_index).name;
805 
806 	END IF;
807 	EXCEPTION
808 	    WHEN NO_DATA_FOUND THEN
809 		-- exception happens when there is no existing row with preference_code.
810 		-- ie first row of this preference_code
811 
812 	    p_pref_table(l_preference_id).preference_code := g_pref_values_ct(l_index).code;--Performace Fix l_pref_trans(l_preference_id);
813 	    p_pref_table(l_preference_id).attribute1 := g_pref_values_ct(l_index).attribute1;
814 	    p_pref_table(l_preference_id).attribute2 := g_pref_values_ct(l_index).attribute2;
815 	    p_pref_table(l_preference_id).attribute3 := g_pref_values_ct(l_index).attribute3;
816 	    p_pref_table(l_preference_id).attribute4 := g_pref_values_ct(l_index).attribute4;
817 	    p_pref_table(l_preference_id).attribute5 := g_pref_values_ct(l_index).attribute5;
818 	    p_pref_table(l_preference_id).attribute6 := g_pref_values_ct(l_index).attribute6;
819 	    p_pref_table(l_preference_id).attribute7 := g_pref_values_ct(l_index).attribute7;
820 	    p_pref_table(l_preference_id).attribute8 := g_pref_values_ct(l_index).attribute8;
821 	    p_pref_table(l_preference_id).attribute9 := g_pref_values_ct(l_index).attribute9;
822 	    p_pref_table(l_preference_id).attribute10 := g_pref_values_ct(l_index).attribute10;
823 	    p_pref_table(l_preference_id).attribute11 := g_pref_values_ct(l_index).attribute11;
824 	    p_pref_table(l_preference_id).attribute12 := g_pref_values_ct(l_index).attribute12;
825 	    p_pref_table(l_preference_id).attribute13 := g_pref_values_ct(l_index).attribute13;
826 	    p_pref_table(l_preference_id).attribute14 := g_pref_values_ct(l_index).attribute14;
827 	    p_pref_table(l_preference_id).attribute15 := g_pref_values_ct(l_index).attribute15;
828 	    p_pref_table(l_preference_id).attribute16 := g_pref_values_ct(l_index).attribute16;
829 	    p_pref_table(l_preference_id).attribute17 := g_pref_values_ct(l_index).attribute17;
830 	    p_pref_table(l_preference_id).attribute18 := g_pref_values_ct(l_index).attribute18;
831 	    p_pref_table(l_preference_id).attribute19 := g_pref_values_ct(l_index).attribute19;
832 	    p_pref_table(l_preference_id).attribute20 := g_pref_values_ct(l_index).attribute20;
833 	    p_pref_table(l_preference_id).attribute21 := g_pref_values_ct(l_index).attribute21;
834 	    p_pref_table(l_preference_id).attribute22 := g_pref_values_ct(l_index).attribute22;
835 	    p_pref_table(l_preference_id).attribute23 := g_pref_values_ct(l_index).attribute23;
836 	    p_pref_table(l_preference_id).attribute24 := g_pref_values_ct(l_index).attribute24;
837 	    p_pref_table(l_preference_id).attribute25 := g_pref_values_ct(l_index).attribute25;
838 	    p_pref_table(l_preference_id).attribute26 := g_pref_values_ct(l_index).attribute26;
839 	    p_pref_table(l_preference_id).attribute27 := g_pref_values_ct(l_index).attribute27;
840 	    p_pref_table(l_preference_id).attribute28 := g_pref_values_ct(l_index).attribute28;
841 	    p_pref_table(l_preference_id).attribute29 := g_pref_values_ct(l_index).attribute29;
842 	    p_pref_table(l_preference_id).attribute30 := g_pref_values_ct(l_index).attribute30;
843 
844 	    p_pref_table(l_preference_id).edit_allowed := g_pref_values_ct(l_index).edit_allowed;
845 	    p_pref_table(l_preference_id).displayed := g_pref_values_ct(l_index).displayed;
846 	    p_pref_table(l_preference_id).rule_evaluation_order
847 					     := l_hierarchy_list(l_hier).rule_evaluation_order;
848 	    p_pref_table(l_preference_id).name := g_pref_values_ct(l_index).name;
849 	  END;
850     End loop;
851   End if;
852 
853 l_hier := l_hierarchy_list.next(l_hier);
854 
855 --g_loop_count := g_loop_count + 1;
856 
857 IF(g_loop_count > g_maxloop) THEN
858       hr_utility.set_message(809, 'HXC_LPS_GT_MAX');
859       hr_utility.raise_error;
860 END IF;
861 
862 END LOOP;
863 
864 END resource_preferences;
865 
866 
867 
868 ---------
869 -- Procedure takes a string preference mask and parses it into a table preference mask
870 ---------
871 
872 PROCEDURE string_to_table_mask(p_string_mask IN VARCHAR2,
873                                p_table_mask OUT NOCOPY t_requested_pref_list)
874 IS
875 
876 l_pos NUMBER;
877 l_start NUMBER;
878 l_start_attr NUMBER;
879 l_end NUMBER;
880 l_req NUMBER;
881 
882 BEGIN
883 
884 l_start := 1;
885 l_pos := l_start;
886 l_req := 1;
887 
888 g_loop_count := 0;
889 
890 LOOP
891 
892   l_pos := instr(p_string_mask,',',l_start,1);
893 
894   IF l_pos = 0 THEN
895     l_end := length(p_string_mask)+1;
896   ELSE
897     l_end := l_pos;
898   END IF;
899 
900 -- l_start and l_end now bound the description for a single preference code
901 -- such as 'TC_W_TCARD_DISPLAY_DAYS|1|2|'
902 
903   l_start_attr := instr(p_string_mask,g_input_separator,l_start,1);
904 
905   IF l_start_attr = 0 THEN
906     l_start_attr := l_end;
907   END IF;
908 
909   p_table_mask(l_req).code := substr(p_string_mask,l_start,l_start_attr-l_start);
910   p_table_mask(l_req).attr_list := substr(p_string_mask,l_start_attr+1,l_end-l_start_attr);
911 
912   l_start := l_end + 1;
913 
914   l_req := l_req + 1;
915   EXIT WHEN l_pos = 0;
916 
917 --g_loop_count := g_loop_count + 1;
918 
919 IF(g_loop_count > g_maxloop) THEN
920       hr_utility.set_message(809, 'HXC_LPS_GT_MAX');
921       hr_utility.raise_error;
922 END IF;
923 
924 
925 END LOOP;
926 
927 END string_to_table_mask;
928 
929 ---------
930 -- Function to prepare a list of preference values from a preference table and
931 -- a table preference mask
932 ---------
933 
934 FUNCTION string_from_mask_and_prefs(p_pref_table IN t_pref_table,
935                                     p_table_mask IN t_requested_pref_list,
936                                     p_output_separator IN varchar2)
937 RETURN VARCHAR2
938 IS
939 p_pref_value_list VARCHAR2(1000);
940 l_single_pref_str VARCHAR2(1000);
941 l_pref_table t_pref_table;
942 l_pref_start NUMBER;
943 l_first_attr NUMBER;
944 l_next_pipe NUMBER;
945 l_next_pref NUMBER;
946 l_attr NUMBER;
947 l_pref NUMBER;
948 l_req NUMBER;
949 l_found BOOLEAN;
950 p_val_to_append VARCHAR2(150);
951 
952 BEGIN
953 
954 l_req := p_table_mask.first;
955 p_pref_value_list := null;
956 
957 g_loop_count := 0;
958 LOOP
959   EXIT WHEN NOT p_table_mask.exists(l_req);
960   l_pref := p_pref_table.first;
961   g_loop_count := 0;
962   l_found:=FALSE;
963 
964   LOOP
965     EXIT WHEN NOT p_pref_table.exists(l_pref);
966 
967     IF( p_table_mask(l_req).code=p_pref_table(l_pref).preference_code ) THEN
968 
969    l_found:=TRUE;
970 -- go through requested attribute list
971 
972   l_first_attr := 1;
973    g_loop_count := 0;
974    LOOP
975     EXIT WHEN instr(p_table_mask(l_req).attr_list,g_input_separator,l_first_attr,1)  = 0 ;
976     l_next_pipe := instr(p_table_mask(l_req).attr_list,g_input_separator,l_first_attr,1);
977     l_attr := substr(p_table_mask(l_req).attr_list,l_first_attr,l_next_pipe-l_first_attr);
978 
979     IF   (l_attr=1) THEN p_val_to_append := p_pref_table(l_pref).attribute1;
980     ELSIF(l_attr=2) THEN p_val_to_append := p_pref_table(l_pref).attribute2;
981     ELSIF(l_attr=3) THEN p_val_to_append := p_pref_table(l_pref).attribute3;
982     ELSIF(l_attr=4) THEN p_val_to_append := p_pref_table(l_pref).attribute4;
983     ELSIF(l_attr=5) THEN p_val_to_append := p_pref_table(l_pref).attribute5;
984     ELSIF(l_attr=6) THEN p_val_to_append := p_pref_table(l_pref).attribute6;
985     ELSIF(l_attr=7) THEN p_val_to_append := p_pref_table(l_pref).attribute7;
986     ELSIF(l_attr=8) THEN p_val_to_append := p_pref_table(l_pref).attribute8;
987     ELSIF(l_attr=9) THEN p_val_to_append := p_pref_table(l_pref).attribute9;
988     ELSIF(l_attr=10) THEN p_val_to_append := p_pref_table(l_pref).attribute10;
989     ELSIF(l_attr=11) THEN p_val_to_append := p_pref_table(l_pref).attribute11;
990     ELSIF(l_attr=12) THEN p_val_to_append := p_pref_table(l_pref).attribute12;
991     ELSIF(l_attr=13) THEN p_val_to_append := p_pref_table(l_pref).attribute13;
992     ELSIF(l_attr=14) THEN p_val_to_append := p_pref_table(l_pref).attribute14;
993     ELSIF(l_attr=15) THEN p_val_to_append := p_pref_table(l_pref).attribute15;
994     ELSIF(l_attr=16) THEN p_val_to_append := p_pref_table(l_pref).attribute16;
995     ELSIF(l_attr=17) THEN p_val_to_append := p_pref_table(l_pref).attribute17;
996     ELSIF(l_attr=18) THEN p_val_to_append := p_pref_table(l_pref).attribute18;
997     ELSIF(l_attr=19) THEN p_val_to_append := p_pref_table(l_pref).attribute19;
998     ELSIF(l_attr=20) THEN p_val_to_append := p_pref_table(l_pref).attribute20;
999     ELSIF(l_attr=21) THEN p_val_to_append := p_pref_table(l_pref).attribute21;
1000     ELSIF(l_attr=22) THEN p_val_to_append := p_pref_table(l_pref).attribute22;
1001     ELSIF(l_attr=23) THEN p_val_to_append := p_pref_table(l_pref).attribute23;
1002     ELSIF(l_attr=24) THEN p_val_to_append := p_pref_table(l_pref).attribute24;
1003     ELSIF(l_attr=25) THEN p_val_to_append := p_pref_table(l_pref).attribute25;
1004     ELSIF(l_attr=26) THEN p_val_to_append := p_pref_table(l_pref).attribute26;
1005     ELSIF(l_attr=27) THEN p_val_to_append := p_pref_table(l_pref).attribute27;
1006     ELSIF(l_attr=28) THEN p_val_to_append := p_pref_table(l_pref).attribute28;
1007     ELSIF(l_attr=29) THEN p_val_to_append := p_pref_table(l_pref).attribute29;
1008     ELSIF(l_attr=30) THEN p_val_to_append := p_pref_table(l_pref).attribute30;
1009     END IF;
1010 -- Return 'null' when there is no value. This makes the string easier to parse
1011 -- using standard Java class
1012 
1013     IF (p_val_to_append IS null) THEN
1014       p_val_to_append:='null';
1015     END IF;
1016 
1017     p_pref_value_list :=p_pref_value_list||p_val_to_append||p_output_separator;
1018 
1019    l_first_attr := l_next_pipe+1;
1020 
1021 -- debug, to be removed
1022 --  g_loop_count := g_loop_count + 1;
1023 
1024 IF(g_loop_count > g_maxloop) THEN
1025       hr_utility.set_message(809, 'HXC_LPS_GT_MAX');
1026       hr_utility.raise_error;
1027 END IF;
1028 -- debug, to be removed
1029 
1030    END LOOP;
1031     END IF;
1032     l_pref := p_pref_table.next(l_pref);
1033 
1034 --  g_loop_count := g_loop_count + 1;
1035 
1036 IF(g_loop_count > g_maxloop) THEN
1037       hr_utility.set_message(809, 'HXC_LPS_GT_MAX');
1038       hr_utility.raise_error;
1039 END IF;
1040 
1041   END LOOP;
1042 
1043 IF(l_found = FALSE) then
1044 -- Raise an error as the requested preference was not found for the user.
1045 -- This should never happen as all supported preferences MUST occur in the
1046 -- default preference tree (even if the value is left blank)
1047  IF( g_raise_fatal_errors = TRUE) THEN
1048     hr_utility.set_message(809, 'HXC_NO_VALS_FOR_PREF_CODE');
1049     hr_utility.raise_error;
1050   ELSE
1051     g_fatal_error_occurred := TRUE;
1052     g_fatal_error := 'HXC_NO_VALS_FOR_PREF_CODE';
1053     RETURN null;
1054   END IF;
1055 END IF;
1056 
1057   l_req := p_table_mask.next(l_req);
1058 
1059 --  g_loop_count := g_loop_count + 1;
1060 
1061 IF(g_loop_count > g_maxloop) THEN
1062       hr_utility.set_message(809, 'HXC_LPS_GT_MAX');
1063       hr_utility.raise_error;
1064 END IF;
1065 
1066 END LOOP;
1067 RETURN substr(p_pref_value_list,1,length(p_pref_value_list)-1);
1068 END;
1069 
1070 
1071 ---------
1072 -- PROCEDURE to restrict and order a preference table according to a preference table
1073 -- and preference mask
1074 ---------
1075 
1076 PROCEDURE trim_order_prefs(p_pref_table in out nocopy t_pref_table,
1077                            p_table_mask in t_requested_pref_list)
1078 is
1079 l_pref_table t_pref_table;
1080 l_mask NUMBER;
1081 l_pref NUMBER;
1082 
1083 BEGIN
1084 
1085 -- loop through the table mask
1086 
1087 l_mask := p_table_mask.first;
1088 
1089 g_loop_count := 0;
1090 
1091 LOOP
1092  EXIT WHEN NOT p_table_mask.exists(l_mask) ;
1093 
1094 -- loop through pref table
1095 
1096   l_pref := p_pref_table.first;
1097 
1098   g_loop_count := 0;
1099   LOOP
1100  EXIT WHEN NOT p_pref_table.exists(l_pref);
1101 
1102   IF( p_table_mask(l_mask).code =  p_pref_table(l_pref).preference_code )THEN
1103    l_pref_table(l_pref) := p_pref_table(l_pref);
1104   END IF;
1105 
1106   l_pref := p_pref_table.next(l_pref);
1107 
1108 -- debug, to be removed
1109 --  g_loop_count := g_loop_count + 1;
1110 
1111 IF(g_loop_count > g_maxloop) THEN
1112       hr_utility.set_message(809, 'HXC_LPS_GT_MAX');
1113       hr_utility.raise_error;
1114 END IF;
1115 -- debug, to be removed
1116 
1117   END LOOP;
1118 
1119 l_mask := p_table_mask.next(l_mask);
1120 
1121 -- debug, to be removed
1122 --  g_loop_count := g_loop_count + 1;
1123 
1124 IF(g_loop_count > g_maxloop) THEN
1125       hr_utility.set_message(809, 'HXC_LPS_GT_MAX');
1126       hr_utility.raise_error;
1127 END IF;
1128 -- debug, to be removed
1129 END LOOP;
1130 p_pref_table := l_pref_table;
1131 
1132 END trim_order_prefs;
1133 
1134 
1135 ---------
1136 -- FUNCTION useful where results need to be in string format
1137 ---------
1138 
1139 FUNCTION resource_pref_sep(p_resource_id     IN NUMBER ,
1140                               p_pref_spec_list  IN VARCHAR2,
1141                               p_output_separator IN varchar2,
1142                               p_evaluation_date IN DATE DEFAULT sysdate)
1143          RETURN VARCHAR2 IS
1144 
1145 
1146 l_pref_value_list VARCHAR2(1000) :='';
1147 l_pref_table t_pref_table;
1148 
1149 l_requested_list t_requested_pref_list;
1150 
1151 
1152 BEGIN
1153 
1154 -- 1. Find out which preferences are being requested
1155 string_to_table_mask(p_pref_spec_list,l_requested_list);
1156 
1157 -- 2. get the preference for the resource
1158 resource_preferences(p_resource_id,l_pref_table, p_evaluation_date);
1159 
1160 IF(g_fatal_error_occurred = FALSE) THEN
1161 -- 3. Organise the string to RETURN
1162 l_pref_value_list := string_from_mask_and_prefs(l_pref_table,l_requested_list,p_output_separator);
1163 END IF;
1164 
1165 RETURN l_pref_value_list;
1166 
1167 
1168 END resource_pref_sep;
1169 
1170 ---------
1171 -- FUNCTION useful where caller wants any fatal error to be reported but not raised
1172 ---------
1173 
1174 
1175 
1176 FUNCTION resource_pref_errcode(p_resource_id IN NUMBER,
1177                                p_pref_spec_list IN VARCHAR2,
1178                                p_message IN OUT NOCOPY VARCHAR,
1179                                p_evaluation_date IN DATE DEFAULT sysdate) RETURN VARCHAR2
1180 IS
1181 l_pref_spec_list varchar2(2000);
1182 BEGIN
1183 
1184 -- set global variable that controls how fatal errors are handled
1185 g_raise_fatal_errors := FALSE;
1186 g_fatal_error_occurred := FALSE;
1187 g_fatal_error :='';
1188 
1189 -- call base method
1190 l_pref_spec_list := resource_preferences(p_resource_id =>p_resource_id,
1191                     p_pref_spec_list => p_pref_spec_list,
1192                     p_evaluation_date =>p_evaluation_date);
1193 
1194 -- copy any error to p_message, and reset fatal error vars
1195 p_message := g_fatal_error;
1196 g_fatal_error_occurred := FALSE;
1197 g_fatal_error :='';
1198 
1199 -- set global variable back
1200 g_raise_fatal_errors := TRUE;
1201 
1202 RETURN l_pref_spec_list;
1203 
1204 END resource_pref_errcode;
1205 
1206 ---------
1207 -- FUNCTION useful where results need to be in string format. As above but defaults output separator to '|'
1208 ---------
1209 FUNCTION resource_preferences(p_resource_id     IN NUMBER ,
1210                               p_pref_spec_list  IN VARCHAR2,
1211                               p_evaluation_date IN DATE DEFAULT sysdate)
1212          RETURN VARCHAR2 IS
1213 
1214 BEGIN
1215 
1216 return resource_pref_sep(p_resource_id => p_resource_id ,
1217                             p_pref_spec_list => p_pref_spec_list,
1218                             p_output_separator => '|',
1219                             p_evaluation_date => p_evaluation_date);
1220 
1221 
1222 END resource_preferences;
1223 
1224 
1225 
1226 
1227 -------
1228 -- PROCEDURE useful when a limited NUMBER of preferences are needed
1229 -------
1230 
1231 PROCEDURE resource_preferences(p_resource_id      IN NUMBER,
1232                                p_pref_code_list   IN VARCHAR2,
1233                                p_pref_table       IN OUT NOCOPY t_pref_table,
1234                                p_evaluation_date  IN DATE  DEFAULT sysdate,
1235                                p_resp_id	  IN NUMBER DEFAULT -99)
1236 IS
1237 l_table_mask t_requested_pref_list;
1238 BEGIN
1239 
1240 -- Note that this currently only filters and orders the full preference table for a
1241 -- resource. There is currently no performance saving from using this procedure. Will be
1242 -- updating this procedure to improve performance further for this case
1243 
1244 -- 1. Get full set of prefs
1245 --resource_preferences(p_resource_id, p_pref_table, p_evaluation_date);
1246 --Changed By Mithun for Persistent Responsibility Enhancement
1247 resource_preferences(p_resource_id, p_pref_table, p_evaluation_date,FND_GLOBAL.user_id, p_resp_id);
1248 
1249 -- 2. Turn the string into a table mask.
1250 string_to_table_mask(p_pref_code_list,l_table_mask);
1251 
1252 -- 3. filter the results to return only those requested
1253 trim_order_prefs(p_pref_table,l_table_mask);
1254 
1255 END;
1256 
1257 
1258 ------
1259 -- Function useful in case where only one attribute of a given preference is required
1260 ------
1261 
1262 FUNCTION resource_preferences(p_resource_id        IN NUMBER,
1263                               p_pref_code          IN VARCHAR2,
1264                               p_attribute_n        IN NUMBER,
1265                               p_evaluation_date    IN DATE  DEFAULT sysdate,
1266                               p_resp_id IN number default -99)
1267 RETURN VARCHAR2 IS
1268 l_pref_table t_pref_table;
1269 l_table_mask t_requested_pref_list;
1270 l_first NUMBER;
1271 BEGIN
1272 
1273 -- Note that this currently only filters and orders the full preference table for a
1274 -- resource. There is currently no performance saving from using this procedure. Will
1275 -- be updating this procedure to improve performance further for this case
1276 
1277 -- 1. Turn the string into a table mask
1278 string_to_table_mask(p_pref_code,l_table_mask);
1279 
1280 -- 2. Get full set of prefs
1281 --Changed By Mithun for persistent responsibility enhancement
1282 resource_preferences(p_resource_id,l_pref_table, p_evaluation_date,fnd_global.user_id,p_resp_id);
1283 
1284 -- 3. Filter for the pref we want
1285 trim_order_prefs(l_pref_table,l_table_mask);
1286 
1287 l_first := l_pref_table.first;
1288 
1289 IF(p_attribute_n = 1) THEN      RETURN l_pref_table(l_first).attribute1;
1290 ELSIF(p_attribute_n = 2) THEN   RETURN l_pref_table(l_first).attribute2;
1291 ELSIF(p_attribute_n = 3) THEN   RETURN l_pref_table(l_first).attribute3;
1292 ELSIF(p_attribute_n = 4) THEN   RETURN l_pref_table(l_first).attribute4;
1293 ELSIF(p_attribute_n = 5) THEN   RETURN l_pref_table(l_first).attribute5;
1294 ELSIF(p_attribute_n = 6) THEN   RETURN l_pref_table(l_first).attribute6;
1295 ELSIF(p_attribute_n = 7) THEN   RETURN l_pref_table(l_first).attribute7;
1296 ELSIF(p_attribute_n = 8) THEN   RETURN l_pref_table(l_first).attribute8;
1297 ELSIF(p_attribute_n = 9) THEN   RETURN l_pref_table(l_first).attribute9;
1298 ELSIF(p_attribute_n = 10) THEN  RETURN l_pref_table(l_first).attribute10;
1299 ELSIF(p_attribute_n = 11) THEN  RETURN l_pref_table(l_first).attribute11;
1300 ELSIF(p_attribute_n = 12) THEN  RETURN l_pref_table(l_first).attribute12;
1301 ELSIF(p_attribute_n = 13) THEN  RETURN l_pref_table(l_first).attribute13;
1302 ELSIF(p_attribute_n = 14) THEN  RETURN l_pref_table(l_first).attribute14;
1303 ELSIF(p_attribute_n = 15) THEN  RETURN l_pref_table(l_first).attribute15;
1304 ELSIF(p_attribute_n = 16) THEN  RETURN l_pref_table(l_first).attribute16;
1305 ELSIF(p_attribute_n = 17) THEN  RETURN l_pref_table(l_first).attribute17;
1306 ELSIF(p_attribute_n = 18) THEN  RETURN l_pref_table(l_first).attribute18;
1307 ELSIF(p_attribute_n = 19) THEN  RETURN l_pref_table(l_first).attribute19;
1308 ELSIF(p_attribute_n = 20) THEN  RETURN l_pref_table(l_first).attribute20;
1309 ELSIF(p_attribute_n = 21) THEN  RETURN l_pref_table(l_first).attribute21;
1310 ELSIF(p_attribute_n = 22) THEN  RETURN l_pref_table(l_first).attribute22;
1311 ELSIF(p_attribute_n = 23) THEN  RETURN l_pref_table(l_first).attribute23;
1312 ELSIF(p_attribute_n = 24) THEN  RETURN l_pref_table(l_first).attribute24;
1313 ELSIF(p_attribute_n = 25) THEN  RETURN l_pref_table(l_first).attribute25;
1314 ELSIF(p_attribute_n = 26) THEN  RETURN l_pref_table(l_first).attribute26;
1315 ELSIF(p_attribute_n = 27) THEN  RETURN l_pref_table(l_first).attribute27;
1316 ELSIF(p_attribute_n = 28) THEN  RETURN l_pref_table(l_first).attribute28;
1317 ELSIF(p_attribute_n = 29) THEN  RETURN l_pref_table(l_first).attribute29;
1318 ELSIF(p_attribute_n = 30) THEN  RETURN l_pref_table(l_first).attribute30;
1319 END IF;
1320 
1321 END resource_preferences;
1322 ------
1323 -- Function populates the global preference array which can then be read by
1324 -- get_resource_preferences
1325 ------
1326 
1327 PROCEDURE set_resource_preferences(p_resource_id IN NUMBER,
1328                                    p_evaluation_date IN DATE DEFAULT sysdate )
1329 IS
1330 BEGIN
1331 
1332 g_pref_table.delete;
1333 resource_preferences(p_resource_id     => p_resource_id,
1334                      p_pref_table      => g_pref_table,
1335                      p_evaluation_date => p_evaluation_date);
1336 
1337 END set_resource_preferences;
1338 
1339 
1340 ------
1341 -- Function populates the global preference array which can then be read by
1342 -- get_resource_preferences
1343 ------
1344 
1345 PROCEDURE set_resource_preferences(p_resource_id IN NUMBER,
1346                                    p_start_evaluation_date IN DATE,
1347                                    p_end_evaluation_date IN DATE  )
1348 IS
1349 BEGIN
1350 
1351 g_pref_table.delete;
1352 resource_preferences(p_resource_id     => p_resource_id,
1353                      p_pref_table      => g_pref_table,
1354                      p_start_evaluation_date => p_start_evaluation_date,
1355                      p_end_evaluation_date => p_start_evaluation_date);
1356 
1357 END set_resource_preferences;
1358 
1359 ------
1360 -- Function gets resource preferences from global tables
1361 ------
1362 
1363 FUNCTION get_resource_preferences(p_resource_id IN NUMBER,
1364                                   p_pref_id IN NUMBER,
1365                                   p_attn IN VARCHAR2) RETURN VARCHAR2
1366 IS
1367 BEGIN
1368 
1369    IF(p_attn = '1')  then return g_pref_table(p_pref_id).attribute1;
1370 elsif(p_attn = '2')  then return g_pref_table(p_pref_id).attribute2;
1371 elsif(p_attn = '3')  then return g_pref_table(p_pref_id).attribute3;
1372 elsif(p_attn = '4')  then return g_pref_table(p_pref_id).attribute4;
1373 elsif(p_attn = '5')  then return g_pref_table(p_pref_id).attribute5;
1374 elsif(p_attn = '6')  then return g_pref_table(p_pref_id).attribute6;
1375 elsif(p_attn = '7')  then return g_pref_table(p_pref_id).attribute7;
1376 elsif(p_attn = '8')  then return g_pref_table(p_pref_id).attribute8;
1377 elsif(p_attn = '9')  then return g_pref_table(p_pref_id).attribute9;
1378 elsif(p_attn = '10') then return g_pref_table(p_pref_id).attribute10;
1379 elsif(p_attn = '11') then return g_pref_table(p_pref_id).attribute11;
1380 elsif(p_attn = '12') then return g_pref_table(p_pref_id).attribute12;
1381 elsif(p_attn = '13') then return g_pref_table(p_pref_id).attribute13;
1382 elsif(p_attn = '14') then return g_pref_table(p_pref_id).attribute14;
1383 elsif(p_attn = '15') then return g_pref_table(p_pref_id).attribute15;
1384 elsif(p_attn = '16') then return g_pref_table(p_pref_id).attribute16;
1385 elsif(p_attn = '17') then return g_pref_table(p_pref_id).attribute17;
1386 elsif(p_attn = '18') then return g_pref_table(p_pref_id).attribute18;
1387 elsif(p_attn = '19') then return g_pref_table(p_pref_id).attribute19;
1388 elsif(p_attn = '20') then return g_pref_table(p_pref_id).attribute20;
1389 elsif(p_attn = '21') then return g_pref_table(p_pref_id).attribute21;
1390 elsif(p_attn = '22') then return g_pref_table(p_pref_id).attribute22;
1391 elsif(p_attn = '23') then return g_pref_table(p_pref_id).attribute23;
1392 elsif(p_attn = '24') then return g_pref_table(p_pref_id).attribute24;
1393 elsif(p_attn = '25') then return g_pref_table(p_pref_id).attribute25;
1394 elsif(p_attn = '26') then return g_pref_table(p_pref_id).attribute26;
1395 elsif(p_attn = '27') then return g_pref_table(p_pref_id).attribute27;
1396 elsif(p_attn = '28') then return g_pref_table(p_pref_id).attribute28;
1397 elsif(p_attn = '29') then return g_pref_table(p_pref_id).attribute29;
1398 elsif(p_attn = '30') then return g_pref_table(p_pref_id).attribute30;
1399 elsif(p_attn = 'E')  then return g_pref_table(p_pref_id).edit_allowed;
1400 elsif(p_attn = 'D')  then return g_pref_table(p_pref_id).displayed;
1401 END IF;
1402 
1403 END get_resource_preferences;
1404 
1405 ----
1406 -- Procedure to return date range prefrences - complex evaluation
1407 ----
1408 
1409 PROCEDURE resource_preferences(p_resource_id  in NUMBER,
1410                                p_start_evaluation_date DATE,
1411                                p_end_evaluation_date DATE,
1412                                p_pref_table IN OUT NOCOPY t_pref_table,
1413                                p_no_prefs_outside_asg IN BOOLEAN DEFAULT FALSE,
1414                                p_resp_id IN number default -99,
1415                                p_resp_appl_id IN NUMBER DEFAULT fnd_global.resp_appl_id,
1416 			       p_ignore_resp_id in boolean default false)
1417 IS
1418 
1419 l_req                   NUMBER;
1420 l_personal_hierarchy    NUMBER;
1421 l_hier                  NUMBER;
1422 l_requested_list        t_requested_pref_list;
1423 l_pref_trans            t_pref_trans;
1424 l_hierarchy_list        t_hierarchy_list;
1425 
1426 l_pref_table            t_pref_table; --Performance Fix
1427 l_dated_prefs           t_dated_prefs;
1428 
1429 l_pref_count            NUMBER;
1430 l_pref_ref              NUMBER;
1431 l_dated_pref_count      NUMBER;
1432 l_index                 NUMBER;
1433 l_finish                NUMBER;
1434 l_start_evaluation_date DATE;
1435 l_end_evaluation_date   DATE;
1436 l_hier_count            NUMBER;
1437 l_tmp_date              DATE;
1438 
1439 -- Bug 3297639
1440 l_pref_index number;
1441 l_preference_id number;
1442 l_last_updated_date date;
1443 l_use_cache boolean := FALSE;
1444 
1445 CURSOR c_get_last_updated_date(p_pref_hierarchy_id IN number) IS
1446 	Select last_update_date
1447 	From hxc_pref_hierarchies
1448 	Where pref_hierarchy_id = p_pref_hierarchy_id;
1449 
1450 --Performance Fix
1451   TYPE t_pref_encountered IS TABLE OF
1452     number
1453   INDEX BY BINARY_INTEGER;
1454 l_pref_encountered  t_pref_encountered;
1455 
1456 -- CURSORs to find the hierarchies a resource is eligible for ...
1457 -- To support new criteria add new CURSORs or add to existing CURSOR.
1458 
1459 -- Modified cursor to support CWK.
1460 
1461 -- Bug 7484448
1462 -- Added USE_NL in the below query for optimum perf.
1463 CURSOR c_eligible_hierarchies_basic(p_resource_id IN NUMBER,
1464                                     p_start_evaluation_date IN DATE,
1465                                     p_end_evaluation_date IN DATE) IS
1466 
1467   SELECT /*+ USE_NL(PA HRR) */
1468          hrr.pref_hierarchy_id,
1469          hrr.rule_evaluation_order,
1470          hrr.start_date,
1471          hrr.end_date,
1472          decode(hrr.eligibility_criteria_type,
1473                        'ALL_PEOPLE', hr_general.start_of_time
1474                                    , pa.effective_start_date)   elig_start_date,
1475          decode(hrr.eligibility_criteria_type,
1476                        'ALL_PEOPLE', hr_general.end_of_time
1477                                    , pa.effective_END_date)      elig_end_date
1478     FROM hxc_resource_rules hrr,
1479          per_all_assignments_f pa
1480    WHERE pa.person_id = p_resource_id
1481      AND nvl(hrr.business_group_id,pa.business_group_id) = pa.business_group_id
1482      AND pa.primary_flag = 'Y'
1483 and pa.assignment_type in ('E','C')
1484    AND p_start_evaluation_date  <= pa.effective_END_date
1485    and pa.effective_start_date  <= p_end_evaluation_date
1486    and p_start_evaluation_date  <= hrr.end_date
1487    and hrr.start_date           <= p_end_evaluation_date
1488    and hrr.start_date <= pa.effective_end_date
1489    and hrr.end_date >=pa.effective_start_date
1490     AND ((   to_char(pa.assignment_id) = hrr.eligibility_criteria_id
1491                   AND hrr.eligibility_criteria_type = 'ASSIGNMENT')
1492       OR (      to_char(pa.payroll_id) = hrr.eligibility_criteria_id
1493                   AND hrr.eligibility_criteria_type = 'PAYROLL')
1494       OR (       to_char(pa.person_id) = hrr.eligibility_criteria_id
1495                   AND hrr.eligibility_criteria_type = 'PERSON')
1496       OR (     to_char(pa.location_id) = hrr.eligibility_criteria_id
1497                   AND hrr.eligibility_criteria_type = 'LOCATION')
1498       OR (     pa.EMPLOYEE_CATEGORY = hrr.eligibility_criteria_id
1499                   AND hrr.eligibility_criteria_type = 'EMP_CATEGORY')
1500       OR (     pa.EMPLOYMENT_CATEGORY = hrr.eligibility_criteria_id
1501                   AND hrr.eligibility_criteria_type = 'ASGN_CATEGORY')
1502       OR (     to_char(pa.organization_id) = hrr.eligibility_criteria_id
1503                   AND hrr.eligibility_criteria_type = 'ORGANIZATION')
1504       OR ((HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,instr(hrr.eligibility_criteria_id,'-',1,1)+1)) in
1505            (SELECT pose.organization_id_parent
1506                   FROM
1507                  per_org_structure_elements pose
1508 		    start with organization_id_child = pa.organization_id
1509                     and  pose.org_structure_version_id=
1510                                HXC_PREFERENCE_EVALUATION.return_version_id(HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,1,instr(hrr.eligibility_criteria_id,'-',1,1)-1)),
1511                                                                            hrr.eligibility_criteria_type)
1512                     connect by prior organization_id_parent=organization_id_child
1513                     and  pose.org_structure_version_id=
1514                                HXC_PREFERENCE_EVALUATION.return_version_id(HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,1,instr(hrr.eligibility_criteria_id,'-',1,1)-1)),
1515                                                                            hrr.eligibility_criteria_type)
1516                     union
1517                     select organization_id
1518                    from   hr_all_organization_units
1519                    where  organization_id =  pa.organization_id))
1520                  AND  hrr.eligibility_criteria_type = 'ROLLUP' )
1521       OR (
1522                   hrr.eligibility_criteria_type = 'ALL_PEOPLE'));
1523 
1524 
1525 -- for rehired employees with preference breaks
1526 -- Bug 7484448
1527 -- Added USE_NL in the below query for optimum perf.
1528 CURSOR c_rehire_elig_hier_basic(p_resource_id IN NUMBER,
1529                                     p_start_evaluation_date IN DATE,
1530                                     p_end_evaluation_date IN DATE) IS
1531   SELECT /*+ USE_NL(PA HRR) */
1532          hrr.pref_hierarchy_id,
1533          hrr.rule_evaluation_order,
1534          hrr.start_date,
1535          hrr.end_date,
1536          pa.effective_start_date elig_start_date,
1537          pa.effective_END_date elig_end_date
1538     FROM hxc_resource_rules hrr,
1539          per_all_assignments_f pa
1540    WHERE pa.person_id = p_resource_id
1541      AND nvl(hrr.business_group_id,pa.business_group_id) = pa.business_group_id
1542      AND pa.primary_flag = 'Y'
1543 and pa.assignment_type in ('E','C')
1544    AND p_start_evaluation_date  <= pa.effective_END_date
1545    and pa.effective_start_date  <= p_end_evaluation_date
1546    and p_start_evaluation_date  <= hrr.end_date
1547    and hrr.start_date           <= p_end_evaluation_date
1548    and hrr.start_date <= pa.effective_end_date
1549    and hrr.end_date >=pa.effective_start_date
1550     AND ((   to_char(pa.assignment_id) = hrr.eligibility_criteria_id
1551                   AND hrr.eligibility_criteria_type = 'ASSIGNMENT')
1552       OR (      to_char(pa.payroll_id) = hrr.eligibility_criteria_id
1553                   AND hrr.eligibility_criteria_type = 'PAYROLL')
1554       OR (       to_char(pa.person_id) = hrr.eligibility_criteria_id
1555                   AND hrr.eligibility_criteria_type = 'PERSON')
1556       OR (     to_char(pa.location_id) = hrr.eligibility_criteria_id
1557                   AND hrr.eligibility_criteria_type = 'LOCATION')
1558       OR (     pa.EMPLOYEE_CATEGORY = hrr.eligibility_criteria_id
1559                   AND hrr.eligibility_criteria_type = 'EMP_CATEGORY')
1560       OR (     pa.EMPLOYMENT_CATEGORY = hrr.eligibility_criteria_id
1561                   AND hrr.eligibility_criteria_type = 'ASGN_CATEGORY')
1562       OR (     to_char(pa.organization_id) = hrr.eligibility_criteria_id
1563                   AND hrr.eligibility_criteria_type = 'ORGANIZATION')
1564       OR ((HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,instr(hrr.eligibility_criteria_id,'-',1,1)+1)) in
1565            (SELECT pose.organization_id_parent
1566                   FROM
1567                  per_org_structure_elements pose
1568 		    start with organization_id_child = pa.organization_id
1569                     and  pose.org_structure_version_id=
1570                                HXC_PREFERENCE_EVALUATION.return_version_id(HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,1,instr(hrr.eligibility_criteria_id,'-',1,1)-1)),
1571                                                                            hrr.eligibility_criteria_type)
1572                     connect by prior organization_id_parent=organization_id_child
1573                     and  pose.org_structure_version_id=
1574                                HXC_PREFERENCE_EVALUATION.return_version_id(HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,1,instr(hrr.eligibility_criteria_id,'-',1,1)-1)),
1575                                                                            hrr.eligibility_criteria_type)
1576                     union
1577                     select organization_id
1578                    from   hr_all_organization_units
1579                    where  organization_id =  pa.organization_id))
1580                  AND  hrr.eligibility_criteria_type = 'ROLLUP' )
1581       OR (
1582                   hrr.eligibility_criteria_type = 'ALL_PEOPLE'));
1583 
1584 -- Modified cursor to support CWK.
1585 CURSOR c_eligible_hierarchies_flex(p_resource_id IN NUMBER,
1586                                    p_start_evaluation_date IN DATE,
1587                                    p_end_evaluation_date IN DATE) IS
1588 
1589   SELECT hrr.pref_hierarchy_id,
1590          hrr.rule_evaluation_order,
1591          hrr.start_date, hrr.end_date,
1592          pa.effective_start_date elig_start_date,
1593          pa.effective_END_date elig_end_date
1594     FROM hxc_resource_rules hrr,
1595          per_all_assignments_f pa
1596    WHERE pa.person_id = p_resource_id
1597      AND nvl(hrr.business_group_id,pa.business_group_id) = pa.business_group_id
1598      AND pa.primary_flag = 'Y'
1599 and pa.assignment_type in ('E','C')
1600      AND p_start_evaluation_date <= pa.effective_END_date
1601      and pa.effective_start_date  <= p_end_evaluation_date
1602      and p_start_evaluation_date <= hrr.end_date
1603      and hrr.start_date <= p_end_evaluation_date
1604      and hrr.start_date <= pa.effective_end_date
1605      and hrr.end_date >=pa.effective_start_date
1606 AND ( (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 3 ),
1607       'SCL', DECODE ( pa.soft_coding_keyflex_id, NULL, -1,
1608       hxc_resource_rules_utils.chk_flex_valid ( 'SCL', pa.soft_coding_keyflex_id,
1609       SUBSTR( hrr.eligibility_criteria_type, 5 ), hrr.eligibility_criteria_id )), -1 ) = 1 )
1610 OR
1611       (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 6 ),
1612       'PEOPLE', DECODE ( pa.people_group_id, NULL, -1,
1613       hxc_resource_rules_utils.chk_flex_valid ( 'PEOPLE', pa.people_group_id,
1614       SUBSTR( hrr.eligibility_criteria_type, 8 ), hrr.eligibility_criteria_id )), -1 ) = 1 )
1615 OR
1616       (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 5 ),
1617       'GRADE', DECODE ( pa.grade_id, NULL, -1,
1618       hxc_resource_rules_utils.chk_flex_valid ( 'GRADE', pa.grade_id,
1619       SUBSTR( hrr.eligibility_criteria_type, 7 ), hrr.eligibility_criteria_id )), -1 ) = 1 )
1620 OR
1621 
1622       (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 3 ),
1623       'JOB', hrr.eligibility_criteria_id, -1 ) = to_char(pa.job_id)) -- Issue 4
1624 
1625 OR
1626 
1627       (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 8 ),
1628       'POSITION', hrr.eligibility_criteria_id, -1 ) = to_char(pa.position_id)) -- Issue 4
1629 );
1630 
1631 -- Cursor to check whether the resource has personalized preferences.
1632 -- Note that this CURSOR could be removed in order to possible boost performance.
1633 -- Need to alter c_eligible_hierarchies CURSOR to include LOGIN type. We would THEN need
1634 -- to use a DECODE in the SELECT to give LOGIN type rules higest priority.
1635 -- Decode expression would need to include the EDIT_ALLOWED flag.
1636 -- But, keep it simple for now.
1637 
1638 
1639 
1640 CURSOR c_personal_hierarchy(p_resource_id IN NUMBER) IS
1641 
1642 SELECT hrr.pref_hierarchy_id , hrr.rule_evaluation_order, hrr.start_date, hrr.end_date
1643 FROM   hxc_resource_rules hrr,
1644        fnd_user fu
1645 WHERE  hrr.resource_type='PERSON'
1646 AND    hrr.eligibility_criteria_type = 'LOGIN'
1647 AND    hrr.eligibility_criteria_id = to_char(fu.user_id) -- Issue 4
1648 AND    fu.employee_id = p_resource_id;
1649 
1650 -- Cursor to pick up any responsibility based prefs
1651 
1652 CURSOR c_resp_hierarchies(p_responsibility_id IN NUMBER,
1653 		          p_resp_appl_id       IN NUMBER,
1654                           p_start_evaluation_date IN DATE,
1655                           p_end_evaluation_date IN DATE) IS
1656 SELECT hrr.pref_hierarchy_id , hrr.rule_evaluation_order, hrr.start_date, hrr.end_date,
1657        fr.start_date elig_start_date,
1658        fr.end_date elig_end_date
1659   FROM hxc_resource_rules hrr,
1660        fnd_responsibility fr
1661  WHERE hrr.resource_type='PERSON'
1662    and p_start_evaluation_date <= hrr.end_date
1663    and hrr.start_date <= p_end_evaluation_date
1664    AND hrr.eligibility_criteria_type IN ( 'RESPONSIBILITY',
1665                                           'PERST_RESPONSIBILITY' )
1666    AND hrr.eligibility_criteria_id = to_char(p_responsibility_id) -- Issue 4
1667    and fr.responsibility_id = p_responsibility_id
1668    and fr.application_id= p_resp_appl_id
1669    and fr.responsibility_id = hrr.eligibility_criteria_id;
1670 
1671 
1672 
1673      CURSOR c_perst_resp_hierarchies(p_responsibility_id     NUMBER,
1674                                      p_start_evaluation_date DATE,
1675                                      p_end_evaluation_date   DATE)
1676          IS
1677      SELECT hrr.pref_hierarchy_id ,
1678             hrr.rule_evaluation_order,
1679             hrr.start_date,
1680             hrr.end_date,
1681             p_start_evaluation_date   elig_start_date,
1682             p_end_evaluation_date     elig_end_date
1683        FROM hxc_resource_rules hrr
1684       WHERE hrr.resource_type='PERSON'
1685         AND p_start_evaluation_date     BETWEEN hrr.start_date
1686                                             AND hrr.end_date
1687         AND p_end_evaluation_date       BETWEEN hrr.start_date
1688                                             AND hrr.end_date
1689         AND hrr.eligibility_criteria_type = 'PERST_RESPONSIBILITY'
1690         AND hrr.eligibility_criteria_id   = to_char(p_responsibility_id) ;
1691 
1692 
1693 
1694 
1695 
1696 CURSOR get_employee_id(p_user_id IN Number) Is
1697   Select employee_id from fnd_user
1698   Where user_id = p_user_id;
1699 
1700 
1701 CURSOR c_person_type_hierarchies(p_resource_id IN NUMBER,
1702 	                          p_start_evaluation_date IN DATE,
1703 		                  p_end_evaluation_date IN DATE) IS
1704 SELECT	hrr.pref_hierarchy_id , hrr.rule_evaluation_order, hrr.start_date, hrr.end_date,
1705 	ptu.effective_start_date elig_start_date,
1706 	ptu.effective_end_date elig_end_date
1707 FROM	hxc_resource_rules hrr,
1708 	per_person_types typ,
1709 	per_person_type_usages_f ptu
1710 WHERE  hrr.resource_type='PERSON'
1711 and    p_start_evaluation_date <= hrr.end_date
1712 and    hrr.start_date <= p_end_evaluation_date
1713 AND    hrr.eligibility_criteria_type = 'PERSON_TYPE'
1714 AND    hrr.eligibility_criteria_id = to_char(ptu.person_type_id) -- Issue 4
1715 AND    ptu.person_id = p_resource_id
1716 AND    typ.system_person_type IN ('EMP','EX_EMP','EMP_APL','EX_EMP_APL','CWK','EX_CWK')
1717 AND    typ.person_type_id = ptu.person_type_id
1718 AND    p_start_evaluation_date <= ptu.effective_end_date
1719 AND    ptu.effective_start_date <= p_end_evaluation_date;
1720 --------------------------------------------------------------------------
1721 
1722 -- Cursor to RETURN the preference nodes in a hierarchy. Note that this is based on a
1723 -- hierchical query.
1724 -- This can be removed if necessary by denormalization onto the hxc_pref_hierarchies base table
1725 -- About 30% of preference evaluatuation time is spent in this query. Denormalization seems
1726 -- to be appropriate at some point.
1727 
1728 CURSOR c_pref_nodes(p_hierarchy_id IN NUMBER)
1729 IS
1730  SELECT pref_hierarchy_id
1731   ,pref_definition_id preference_id
1732   ,attribute1
1733   ,attribute2
1734   ,attribute3
1735   ,attribute4
1736   ,attribute5
1737   ,attribute6
1738   ,attribute7
1739   ,attribute8
1740   ,attribute9
1741   ,attribute10
1742   ,attribute11
1743   ,attribute12
1744   ,attribute13
1745   ,attribute14
1746   ,attribute15
1747   ,attribute16
1748   ,attribute17
1749   ,attribute18
1750   ,attribute19
1751   ,attribute20
1752   ,attribute21
1753   ,attribute22
1754   ,attribute23
1755   ,attribute24
1756   ,attribute25
1757   ,attribute26
1758   ,attribute27
1759   ,attribute28
1760   ,attribute29
1761   ,attribute30
1762   ,edit_allowed
1763   ,displayed
1764   ,name
1765   ,top_level_parent_id --Performance Fix
1766   ,code
1767   FROM hxc_pref_hierarchies
1768   WHERE top_level_parent_id = p_hierarchy_id;
1769   --pref_definition_id is not null
1770   --START WITH pref_hierarchy_id = p_hierarchy_id
1771   --CONNECT BY prior pref_hierarchy_id = parent_pref_hierarchy_id;
1772 
1773 CURSOR c_pref_codes
1774 IS
1775 SELECT
1776  pref_definition_id, code
1777 FROM hxc_pref_definitions;
1778 
1779 --VARIABLES ADDED by Mithun for Perst Resp enhancement
1780 l_find_resp_required	BOOLEAN DEFAULT FALSE;
1781 l_resp_id	NUMBER;
1782 l_resp_appl_id  NUMBER;
1783 l_employee_id NUMBER;
1784 --l_tc_employee_id  NUMBER;
1785 
1786 l_resptab       resplisttab;
1787 
1788 
1789 BEGIN
1790 
1791 l_resp_id	:= 	p_resp_id;
1792 
1793 
1794 g_debug := hr_utility.debug_enabled;
1795 
1796    IF g_debug
1797    THEN
1798        hr_utility.trace('Evaluating pref for start and stop dates');
1799        hr_utility.trace('p_resource_id '||p_resource_id);
1800        hr_utility.trace('p_start_evaluation_date '||p_start_evaluation_date);
1801        hr_utility.trace('p_end_evaluation_date '||p_end_evaluation_date);
1802    END IF;
1803 
1804 
1805 
1806 Open get_employee_id(fnd_global.user_id);
1807 Fetch get_employee_id into l_employee_id;
1808 Close get_employee_id;
1809 
1810  IF ( p_resp_id = -99 ) AND (l_employee_id <> p_resource_id)
1811  THEN
1812         -- By default we need to consider persistent responsibility also,
1813         -- so set the flag to TRUE.
1814  	l_find_resp_required := TRUE;
1815 
1816  ELSE
1817  	-- The call is by passing -101 explicitly, meaning we are not considering
1818  	-- persistent responsibility. Get the session responsibility and keep it.
1819  	-- Set the flag to FALSE.
1820  	l_find_resp_required := FALSE;
1821 
1822  END IF;
1823 
1824  l_resp_id := fnd_global.resp_id;
1825 
1826 -- make sure pref table is empty - otherwise this will interfere with the evaluation
1827 p_pref_table.delete;
1828 
1829 l_hier_count:=1;
1830 
1831 l_start_evaluation_date:=trunc(p_start_evaluation_date);
1832 l_end_evaluation_date  :=trunc(p_end_evaluation_date);
1833 
1834 l_dated_pref_count:=0;
1835 l_pref_count:=0;
1836 
1837 
1838 
1839 
1840 -- populate table that will allow us to find a pref_code given an pref_definition_id
1841 -- Performance Fix (Loop Commented).
1842 /*FOR pref_rec IN c_pref_codes LOOP
1843   l_pref_trans(pref_rec.pref_definition_id) := pref_rec.code;
1844 
1845 -- set a dummy default preference for each preference code (start and ends at evaluation dates)
1846 -- These will be overriden by default preferences
1847 
1848   l_dated_prefs(l_dated_pref_count).code                   := pref_rec.code;
1849   l_dated_prefs(l_dated_pref_count).start_date             := l_start_evaluation_date;
1850   l_dated_prefs(l_dated_pref_count).end_date               := l_end_evaluation_date;
1851   l_dated_prefs(l_dated_pref_count).rule_evaluation_order  := -1;
1852   l_dated_prefs(l_dated_pref_count).pref_ref               := 1;
1853   l_dated_pref_count                                       := l_dated_pref_count+1;
1854 
1855 END LOOP;*/
1856 
1857 -- Now find the hierarchies which the person is eligible for ...
1858 
1859 -- basic eligibility, must be at least one
1860 
1861 if p_no_prefs_outside_asg = TRUE then
1862 
1863 	FOR hier_rec IN c_rehire_elig_hier_basic(p_resource_id,
1864 						 l_start_evaluation_date,
1865 						 l_end_evaluation_date) LOOP
1866 	-- Performance Fix
1867 	if(hier_rec.rule_evaluation_order = 1) then
1868 	   l_hierarchy_list(0).pref_hierarchy_id        := hier_rec.pref_hierarchy_id;
1869 	   l_hierarchy_list(0).rule_evaluation_order    := hier_rec.rule_evaluation_order;
1870 	   l_hierarchy_list(0).start_date               := hier_rec.start_date;
1871 	   l_hierarchy_list(0).end_date                 := hier_rec.end_date;
1872 	   l_hierarchy_list(0).elig_start_date          := hier_rec.elig_start_date;
1873 	   l_hierarchy_list(0).elig_end_date            := hier_rec.elig_end_date;
1874 
1875 	else
1876 	   l_hierarchy_list(l_hier_count).pref_hierarchy_id        := hier_rec.pref_hierarchy_id;
1877 	   l_hierarchy_list(l_hier_count).rule_evaluation_order    := hier_rec.rule_evaluation_order;
1878 	   l_hierarchy_list(l_hier_count).start_date               := hier_rec.start_date;
1879 	   l_hierarchy_list(l_hier_count).end_date                 := hier_rec.end_date;
1880 	   l_hierarchy_list(l_hier_count).elig_start_date          := hier_rec.elig_start_date;
1881 	   l_hierarchy_list(l_hier_count).elig_end_date            := hier_rec.elig_end_date;
1882 	   l_hier_count                                            := l_hier_count + 1;
1883 	end if;
1884 
1885 	END LOOP;
1886 
1887 ELSE
1888 
1889 	FOR hier_rec IN c_eligible_hierarchies_basic(p_resource_id,
1890                                              l_start_evaluation_date,
1891                                              l_end_evaluation_date) LOOP
1892 	-- Performance Fix
1893 	if(hier_rec.rule_evaluation_order = 1) then
1894 	   l_hierarchy_list(0).pref_hierarchy_id        := hier_rec.pref_hierarchy_id;
1895 	   l_hierarchy_list(0).rule_evaluation_order    := hier_rec.rule_evaluation_order;
1896 	   l_hierarchy_list(0).start_date               := hier_rec.start_date;
1897 	   l_hierarchy_list(0).end_date                 := hier_rec.end_date;
1898 	   l_hierarchy_list(0).elig_start_date          := hier_rec.elig_start_date;
1899 	   l_hierarchy_list(0).elig_end_date            := hier_rec.elig_end_date;
1900 
1901 	else
1902 	   l_hierarchy_list(l_hier_count).pref_hierarchy_id        := hier_rec.pref_hierarchy_id;
1903 	   l_hierarchy_list(l_hier_count).rule_evaluation_order    := hier_rec.rule_evaluation_order;
1904 	   l_hierarchy_list(l_hier_count).start_date               := hier_rec.start_date;
1905 	   l_hierarchy_list(l_hier_count).end_date                 := hier_rec.end_date;
1906 	   l_hierarchy_list(l_hier_count).elig_start_date          := hier_rec.elig_start_date;
1907 	   l_hierarchy_list(l_hier_count).elig_end_date            := hier_rec.elig_end_date;
1908 	   l_hier_count                                            := l_hier_count + 1;
1909 	end if;
1910 
1911 	END LOOP;
1912 END IF;
1913 
1914 -- Issue 6
1915 if(l_hierarchy_list(0).pref_hierarchy_id is null)
1916 then
1917  IF( g_raise_fatal_errors = TRUE) THEN
1918     hr_utility.set_message(809, 'HXC_NO_HIER_FOR_DATE');
1919     hr_utility.raise_error;
1920   ELSE
1921     g_fatal_error := 'HXC_NO_HIER_FOR_DATE';
1922     g_fatal_error_occurred := TRUE;
1923     RETURN;
1924   END IF;
1925 end if;
1926 
1927 -- more complex eligibility, zero or more
1928 
1929 BEGIN
1930 FOR hier_rec in c_eligible_hierarchies_flex(p_resource_id,
1931                                             l_start_evaluation_date,
1932                                             l_end_evaluation_date) LOOP
1933    l_hierarchy_list(l_hier_count).pref_hierarchy_id        := hier_rec.pref_hierarchy_id;
1934    l_hierarchy_list(l_hier_count).rule_evaluation_order    := hier_rec.rule_evaluation_order;
1935    l_hierarchy_list(l_hier_count).start_date               := hier_rec.start_date;
1936    l_hierarchy_list(l_hier_count).end_date                 := hier_rec.end_date;
1937    l_hierarchy_list(l_hier_count).elig_start_date          := hier_rec.elig_start_date;
1938    l_hierarchy_list(l_hier_count).elig_end_date            := hier_rec.elig_end_date;
1939    l_hier_count                                            := l_hier_count + 1;
1940 END LOOP;
1941 EXCEPTION
1942   WHEN NO_DATA_FOUND THEN null;
1943 END;
1944 
1945 
1946 
1947 -------------------------4215885-- ----------------------
1948 BEGIN
1949 FOR hier_rec in c_person_type_hierarchies(p_resource_id,
1950                                           l_start_evaluation_date,
1951                                           l_end_evaluation_date) LOOP
1952    l_hierarchy_list(l_hier_count).pref_hierarchy_id        := hier_rec.pref_hierarchy_id;
1953    l_hierarchy_list(l_hier_count).rule_evaluation_order    := hier_rec.rule_evaluation_order;
1954    l_hierarchy_list(l_hier_count).start_date               := hier_rec.start_date;
1955    l_hierarchy_list(l_hier_count).end_date                 := hier_rec.end_date;
1956    l_hierarchy_list(l_hier_count).elig_start_date          := hier_rec.elig_start_date;
1957    l_hierarchy_list(l_hier_count).elig_end_date            := hier_rec.elig_end_date;
1958    l_hier_count                                            := l_hier_count + 1;
1959 END LOOP;
1960 EXCEPTION
1961   WHEN NO_DATA_FOUND THEN null;
1962 END;
1963 
1964 -------------------------------------------------------------------
1965 --IF(fnd_global.resp_id <> -1) THEN
1966 
1967 --Changes done by Mithun for Persistent Responsibility Enhancement
1968 
1969 If (l_resp_id <> -1  AND ( not p_ignore_resp_id)) Then
1970 
1971 --This is Where we are evaluating for session responsibility.
1972 --We check for l_employee_id = p_resource_id to make sure that employee himself has logged in
1973 	IF  l_employee_id = p_resource_id   THEN
1974 
1975 		BEGIN
1976 			FOR hier_rec in c_resp_hierarchies(l_resp_id, p_resp_appl_id, l_start_evaluation_date, l_end_evaluation_date) LOOP
1977 
1978 			      l_hierarchy_list(l_hier_count).pref_hierarchy_id        := hier_rec.pref_hierarchy_id;
1979 				 l_hierarchy_list(l_hier_count).rule_evaluation_order    := hier_rec.rule_evaluation_order;
1980 				 l_hierarchy_list(l_hier_count).start_date               := hier_rec.start_date;
1981 				 l_hierarchy_list(l_hier_count).end_date                 := hier_rec.end_date;
1982 				 l_hierarchy_list(l_hier_count).elig_start_date          := hier_rec.elig_start_date;
1983 				l_hierarchy_list(l_hier_count).elig_end_date            := hier_rec.elig_end_date;
1984 
1985 			      l_hier_count                                         := l_hier_count+1;
1986 			END LOOP;
1987 		EXCEPTION
1988 		    WHEN NO_DATA_FOUND THEN null;
1989 		END;
1990 	END IF;
1991 
1992 --Checking If we have to obtain the resp_id value stored in  the timecard
1993 -- If we have to then get the responsibilities and calculate the hierarchies
1994 -- associated.
1995 --
1996 	IF l_find_resp_required
1997 	THEN
1998 		-- We need Persistent responsibility, so get the valid responsibilities
1999 		-- within the given date range.
2000 
2001 		get_tc_resp(p_resource_id,
2002 		            l_start_evaluation_date,
2003 		            l_end_evaluation_date,
2004 		            l_resptab );
2005 
2006 
2007 		 -- If you got any timecards in the given date range, do the
2008 		 -- following.
2009 
2010 		 IF l_resptab.COUNT > 0
2011 		 THEN
2012 		     -- Do the following for all timecards.
2013 		     FOR i IN l_resptab.FIRST..l_resptab.LAST
2014 		     LOOP
2015 
2016 		        -- The following condition means that this timecard
2017 		        -- was updated by another person, not the employee
2018 		        -- himself, meaning we dont have to consider persistent
2019 		        -- responsibilities at all.
2020 
2021 		        IF l_resptab(i).resp_id <> -1
2022 		        THEN
2023 
2024 			   BEGIN
2025 				-- Run the cursor for all the responsibilities and
2026 				-- timecards and keep recording the hierarchy rules.
2027 
2028 				FOR hier_rec IN c_perst_resp_hierarchies(l_resptab(i).resp_id,
2029 				                                         TRUNC(l_resptab(i).start_date),
2030 				                                         TRUNC(l_resptab(i).stop_date))
2031 				LOOP
2032 					 l_hierarchy_list(l_hier_count).pref_hierarchy_id        := hier_rec.pref_hierarchy_id;
2033 					 l_hierarchy_list(l_hier_count).rule_evaluation_order    := hier_rec.rule_evaluation_order;
2034 					 l_hierarchy_list(l_hier_count).start_date               := hier_rec.start_date;
2035 					 l_hierarchy_list(l_hier_count).end_date                 := hier_rec.end_date;
2036 					 l_hierarchy_list(l_hier_count).elig_start_date          := hier_rec.elig_start_date;
2037 					 l_hierarchy_list(l_hier_count).elig_end_date            := hier_rec.elig_end_date;
2038 
2039 					l_hier_count                := l_hier_count+1;
2040 				END LOOP;
2041 			     EXCEPTION
2042 			       WHEN NO_DATA_FOUND THEN null;
2043 			   END ; --  BEGIN
2044 		        END IF;	 --  IF l_resptab(i).resp_id <> -1
2045 		     END LOOP;   --  FOR i IN l_resptab.FIRST..l_resptab.LAST
2046 
2047 		 END IF;         --  IF l_resptab.COUNT > 0
2048 
2049 	END IF;                  --  IF l_find_resp_required
2050 
2051 End If;
2052 -- personalisation, only one hierarchy possible. Note we give a start and end date
2053 -- spanning all time. Personalizations are only applied over ranges of time in which the
2054 -- granted preference has the edit_allowed flag. Note the the personalisation MUST
2055 -- be the last hierarchy to be considered. Only when all the other hierarchies have
2056 -- been considered can which ranges of time have the edit allowed flag
2057 
2058 BEGIN
2059 FOR hier_rec IN c_personal_hierarchy(p_resource_id) LOOP
2060    l_hierarchy_list(l_hier_count).pref_hierarchy_id        := hier_rec.pref_hierarchy_id;
2061    l_hierarchy_list(l_hier_count).rule_evaluation_order    := hier_rec.rule_evaluation_order;
2062    l_hierarchy_list(l_hier_count).start_date               := hr_general.start_of_time;
2063    l_hierarchy_list(l_hier_count).end_date                 := hr_general.end_of_time;
2064    l_hierarchy_list(l_hier_count).elig_start_date          := hr_general.start_of_time;
2065    l_hierarchy_list(l_hier_count).elig_end_date            := hr_general.end_of_time;
2066    l_hier_count                                            := l_hier_count+1;
2067 END LOOP;
2068 EXCEPTION
2069   WHEN NO_DATA_FOUND THEN null;
2070 END;
2071 
2072 -- sanity check
2073 --Issue 6
2074 /*if(l_hierarchy_list.count=0)
2075 then
2076  IF( g_raise_fatal_errors = TRUE) THEN
2077     hr_utility.set_message(809, 'HXC_NO_HIER_FOR_DATE');
2078     hr_utility.raise_error;
2079   ELSE
2080     g_fatal_error := 'HXC_NO_HIER_FOR_DATE';
2081     g_fatal_error_occurred := TRUE;
2082     RETURN;
2083   END IF;
2084 end if;*/
2085 
2086 -- Performance Fix.
2087 l_dated_pref_count :=0;
2088 
2089 -- Bug 3297639
2090 -- if data not in cache then fetch from db and populate the cache.
2091 If ( not g_pref_hier_ct.exists(l_hierarchy_list(0).pref_hierarchy_id) ) then
2092 
2093     g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).caching_time := sysdate;
2094     g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).Start_Index := -1;
2095     g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).Stop_Index := -1;
2096 
2097 
2098     l_pref_index := 1;
2099     If (g_pref_values_ct.count > 0) then
2100 	l_pref_index := g_pref_values_ct.last + 1;
2101     end if;
2102 
2103     g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).Start_Index := l_pref_index;
2104 
2105 
2106     FOR pref_node in c_pref_nodes(l_hierarchy_list(0).pref_hierarchy_id)
2107     LOOP
2108     g_pref_values_ct(l_pref_index).pref_hierarchy_id := pref_node.pref_hierarchy_id;
2109     g_pref_values_ct(l_pref_index).pref_definition_id := pref_node.preference_id;
2110     g_pref_values_ct(l_pref_index).attribute1:= pref_node.attribute1;
2111     g_pref_values_ct(l_pref_index).attribute2:= pref_node.attribute2;
2112     g_pref_values_ct(l_pref_index).attribute3:= pref_node.attribute3;
2113     g_pref_values_ct(l_pref_index).attribute4:= pref_node.attribute4;
2114     g_pref_values_ct(l_pref_index).attribute5:= pref_node.attribute5;
2115     g_pref_values_ct(l_pref_index).attribute6:= pref_node.attribute6;
2116     g_pref_values_ct(l_pref_index).attribute7:= pref_node.attribute7;
2117     g_pref_values_ct(l_pref_index).attribute8:= pref_node.attribute8;
2118     g_pref_values_ct(l_pref_index).attribute9:= pref_node.attribute9;
2119     g_pref_values_ct(l_pref_index).attribute10:= pref_node.attribute10;
2120     g_pref_values_ct(l_pref_index).attribute11:= pref_node.attribute11;
2121     g_pref_values_ct(l_pref_index).attribute12:= pref_node.attribute12;
2122     g_pref_values_ct(l_pref_index).attribute13:= pref_node.attribute13;
2123     g_pref_values_ct(l_pref_index).attribute14:= pref_node.attribute14;
2124     g_pref_values_ct(l_pref_index).attribute15:= pref_node.attribute15;
2125     g_pref_values_ct(l_pref_index).attribute16:= pref_node.attribute16;
2126     g_pref_values_ct(l_pref_index).attribute17:= pref_node.attribute17;
2127     g_pref_values_ct(l_pref_index).attribute18:= pref_node.attribute18;
2128     g_pref_values_ct(l_pref_index).attribute19:= pref_node.attribute19;
2129     g_pref_values_ct(l_pref_index).attribute20:= pref_node.attribute20;
2130     g_pref_values_ct(l_pref_index).attribute21:= pref_node.attribute21;
2131     g_pref_values_ct(l_pref_index).attribute22:= pref_node.attribute22;
2132     g_pref_values_ct(l_pref_index).attribute23:= pref_node.attribute23;
2133     g_pref_values_ct(l_pref_index).attribute24:= pref_node.attribute24;
2134     g_pref_values_ct(l_pref_index).attribute25:= pref_node.attribute25;
2135     g_pref_values_ct(l_pref_index).attribute26:= pref_node.attribute26;
2136     g_pref_values_ct(l_pref_index).attribute27:= pref_node.attribute27;
2137     g_pref_values_ct(l_pref_index).attribute28:= pref_node.attribute28;
2138     g_pref_values_ct(l_pref_index).attribute29:= pref_node.attribute29;
2139     g_pref_values_ct(l_pref_index).attribute30:= pref_node.attribute30;
2140     g_pref_values_ct(l_pref_index).edit_allowed:= pref_node.edit_allowed;
2141     g_pref_values_ct(l_pref_index).displayed:= pref_node.displayed;
2142     g_pref_values_ct(l_pref_index).name:= pref_node.name;
2143     g_pref_values_ct(l_pref_index).top_level_parent_id:= pref_node.top_level_parent_id;
2144     g_pref_values_ct(l_pref_index).code:= pref_node.code;
2145     l_pref_index := g_pref_values_ct.last + 1;
2146 
2147     End Loop;
2148 
2149 
2150     g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).Stop_Index := l_pref_index - 1;
2151 
2152     -- check for valid start and stop index. Incase the only leaf node was deleted or no leaf nodes exists then reset start and stop index accordingly
2153     if (g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).Stop_Index < g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).Start_Index) then
2154         g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).Start_Index := 0;
2155 	g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).Stop_Index := 0;
2156     end if;
2157 
2158 end if;
2159 
2160 -- Not checking if cache info for this pref id is outdated since its seed data.
2161     For l_loop_index in g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).Start_Index..g_pref_hier_ct(l_hierarchy_list(0).pref_hierarchy_id).Stop_index
2162     Loop
2163       l_dated_prefs(l_dated_pref_count).code		       := g_pref_values_ct(l_loop_index).code;
2164       l_dated_prefs(l_dated_pref_count).start_date             := l_start_evaluation_date;
2165       l_dated_prefs(l_dated_pref_count).end_date               := l_end_evaluation_date;
2166       l_dated_prefs(l_dated_pref_count).rule_evaluation_order  := -1;
2167       l_dated_prefs(l_dated_pref_count).pref_ref               := 1;
2168       l_dated_pref_count                                       := l_dated_pref_count+1;
2169     end loop;
2170 
2171 /*    FOR pref_node in c_pref_nodes(l_hierarchy_list(0).pref_hierarchy_id) LOOP
2172 
2173       l_dated_prefs(l_dated_pref_count).code := pref_node.code;
2174       l_dated_prefs(l_dated_pref_count).start_date             := l_start_evaluation_date;
2175       l_dated_prefs(l_dated_pref_count).end_date               := l_end_evaluation_date;
2176       l_dated_prefs(l_dated_pref_count).rule_evaluation_order  := -1;
2177       l_dated_prefs(l_dated_pref_count).pref_ref               := 1;
2178       l_dated_pref_count                                       := l_dated_pref_count+1;
2179 
2180     end loop;
2181 */
2182 
2183 l_hier := l_hierarchy_list.first;
2184 
2185 -- loop over the hierarchies we have found
2186 
2187 l_hier := l_hierarchy_list.first;
2188 
2189   g_loop_count := 0;
2190 
2191   LOOP --1
2192     EXIT WHEN NOT l_hierarchy_list.exists(l_hier);
2193 
2194   --reset for each Pref Id
2195   l_use_cache := FALSE;
2196 
2197   -- Check if the required data is already cached.
2198   If ( g_pref_hier_ct.exists(l_hierarchy_list(l_hier).pref_hierarchy_id) ) then
2199 
2200 	Open c_get_last_updated_date(l_hierarchy_list(l_hier).pref_hierarchy_id);
2201 	Fetch c_get_last_updated_date into l_last_updated_date;
2202 	Close c_get_last_updated_date;
2203 
2204 	-- checking if the cache data is outdated.
2205 	if ( g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).caching_time >= l_last_updated_date) then
2206 		l_use_cache := TRUE;
2207 	else
2208 	        l_use_cache := FALSE;
2209 		-- Delete the Pref Values for this, since it has to be refreshed anyway.
2210 		g_pref_values_ct.delete(g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index,g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index); -- table.delete(m,n)
2211 	end if;
2212   end if;
2213 
2214   -- If l_use_cache = FALSE, then populate/refresh cache data by db fetch.
2215   If (not l_use_cache) then
2216 
2217     -- initialise main table.
2218     g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).caching_time := sysdate;
2219     g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index := -1;
2220     g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index := -1;
2221 
2222     -- Initialize Start_Index for the Pref Values
2223     If (g_pref_values_ct.count > 0) then
2224 	l_pref_index := g_pref_values_ct.last + 1;
2225     else
2226 	l_pref_index := 1;
2227     End If;
2228 
2229     g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index := l_pref_index;
2230 
2231     -- populate preference values into cache
2232     FOR pref_node in c_pref_nodes(l_hierarchy_list(l_hier).pref_hierarchy_id)
2233     LOOP
2234 
2235     g_pref_values_ct(l_pref_index).pref_hierarchy_id := pref_node.pref_hierarchy_id;
2236     g_pref_values_ct(l_pref_index).pref_definition_id := pref_node.preference_id;
2237     g_pref_values_ct(l_pref_index).attribute1:= pref_node.attribute1;
2238     g_pref_values_ct(l_pref_index).attribute2:= pref_node.attribute2;
2239     g_pref_values_ct(l_pref_index).attribute3:= pref_node.attribute3;
2240     g_pref_values_ct(l_pref_index).attribute4:= pref_node.attribute4;
2241     g_pref_values_ct(l_pref_index).attribute5:= pref_node.attribute5;
2242     g_pref_values_ct(l_pref_index).attribute6:= pref_node.attribute6;
2243     g_pref_values_ct(l_pref_index).attribute7:= pref_node.attribute7;
2244     g_pref_values_ct(l_pref_index).attribute8:= pref_node.attribute8;
2245     g_pref_values_ct(l_pref_index).attribute9:= pref_node.attribute9;
2246     g_pref_values_ct(l_pref_index).attribute10:= pref_node.attribute10;
2247     g_pref_values_ct(l_pref_index).attribute11:= pref_node.attribute11;
2248     g_pref_values_ct(l_pref_index).attribute12:= pref_node.attribute12;
2249     g_pref_values_ct(l_pref_index).attribute13:= pref_node.attribute13;
2250     g_pref_values_ct(l_pref_index).attribute14:= pref_node.attribute14;
2251     g_pref_values_ct(l_pref_index).attribute15:= pref_node.attribute15;
2252     g_pref_values_ct(l_pref_index).attribute16:= pref_node.attribute16;
2253     g_pref_values_ct(l_pref_index).attribute17:= pref_node.attribute17;
2254     g_pref_values_ct(l_pref_index).attribute18:= pref_node.attribute18;
2255     g_pref_values_ct(l_pref_index).attribute19:= pref_node.attribute19;
2256     g_pref_values_ct(l_pref_index).attribute20:= pref_node.attribute20;
2257     g_pref_values_ct(l_pref_index).attribute21:= pref_node.attribute21;
2258     g_pref_values_ct(l_pref_index).attribute22:= pref_node.attribute22;
2259     g_pref_values_ct(l_pref_index).attribute23:= pref_node.attribute23;
2260     g_pref_values_ct(l_pref_index).attribute24:= pref_node.attribute24;
2261     g_pref_values_ct(l_pref_index).attribute25:= pref_node.attribute25;
2262     g_pref_values_ct(l_pref_index).attribute26:= pref_node.attribute26;
2263     g_pref_values_ct(l_pref_index).attribute27:= pref_node.attribute27;
2264     g_pref_values_ct(l_pref_index).attribute28:= pref_node.attribute28;
2265     g_pref_values_ct(l_pref_index).attribute29:= pref_node.attribute29;
2266     g_pref_values_ct(l_pref_index).attribute30:= pref_node.attribute30;
2267 
2268     g_pref_values_ct(l_pref_index).edit_allowed:= pref_node.edit_allowed;
2269     g_pref_values_ct(l_pref_index).displayed:= pref_node.displayed;
2270     g_pref_values_ct(l_pref_index).name:= pref_node.name;
2271     g_pref_values_ct(l_pref_index).top_level_parent_id:= pref_node.top_level_parent_id;
2272     g_pref_values_ct(l_pref_index).code:= pref_node.code;
2273 
2274     l_pref_index := g_pref_values_ct.last + 1;
2275     End Loop;
2276 
2277     g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index := l_pref_index - 1;
2278 
2279     -- check for valid start and stop index. Incase the only leaf node was deleted or no leaf nodes exists then reset start and stop index accordingly
2280     if (g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index < g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index) then
2281         g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index := 0;
2282 	g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index := 0;
2283     end if;
2284 
2285     l_use_cache := TRUE; -- now data is in cache
2286   End If;
2287 
2288   -- Now all required data is in cache.
2289     If (g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_Index <> 0 ) then     --(case where parent node has no children)
2290     For l_loop_index in g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Start_Index..g_pref_hier_ct(l_hierarchy_list(l_hier).pref_hierarchy_id).Stop_index Loop -- 2
2291 
2292     -- record node details in list
2293     -- Note. We shouldnt actually make these assignments before we know we are goiing to
2294     -- need the values. Need some reordering of code to achieve this. Also note that should
2295     -- try to make the assignments in bulk (i.e. record to record) for performance
2296     -- AND readability
2297 
2298     l_pref_count := l_pref_count+1;
2299     l_pref_table(l_pref_count).preference_code := g_pref_values_ct(l_loop_index).code;--Performance Fix l_pref_trans(pref_node.preference_id);
2300     l_pref_table(l_pref_count).attribute1 := g_pref_values_ct(l_loop_index).attribute1;
2301     l_pref_table(l_pref_count).attribute2 := g_pref_values_ct(l_loop_index).attribute2;
2302     l_pref_table(l_pref_count).attribute3 := g_pref_values_ct(l_loop_index).attribute3;
2303     l_pref_table(l_pref_count).attribute4 := g_pref_values_ct(l_loop_index).attribute4;
2304     l_pref_table(l_pref_count).attribute5 := g_pref_values_ct(l_loop_index).attribute5;
2305     l_pref_table(l_pref_count).attribute6 := g_pref_values_ct(l_loop_index).attribute6;
2306     l_pref_table(l_pref_count).attribute7 := g_pref_values_ct(l_loop_index).attribute7;
2307     l_pref_table(l_pref_count).attribute8 := g_pref_values_ct(l_loop_index).attribute8;
2308     l_pref_table(l_pref_count).attribute9 := g_pref_values_ct(l_loop_index).attribute9;
2309     l_pref_table(l_pref_count).attribute10 := g_pref_values_ct(l_loop_index).attribute10;
2310     l_pref_table(l_pref_count).attribute11 := g_pref_values_ct(l_loop_index).attribute11;
2311     l_pref_table(l_pref_count).attribute12 := g_pref_values_ct(l_loop_index).attribute12;
2312     l_pref_table(l_pref_count).attribute13 := g_pref_values_ct(l_loop_index).attribute13;
2313     l_pref_table(l_pref_count).attribute14 := g_pref_values_ct(l_loop_index).attribute14;
2314     l_pref_table(l_pref_count).attribute15 := g_pref_values_ct(l_loop_index).attribute15;
2315     l_pref_table(l_pref_count).attribute16 := g_pref_values_ct(l_loop_index).attribute16;
2316     l_pref_table(l_pref_count).attribute17 := g_pref_values_ct(l_loop_index).attribute17;
2317     l_pref_table(l_pref_count).attribute18 := g_pref_values_ct(l_loop_index).attribute18;
2318     l_pref_table(l_pref_count).attribute19 := g_pref_values_ct(l_loop_index).attribute19;
2319     l_pref_table(l_pref_count).attribute20 := g_pref_values_ct(l_loop_index).attribute20;
2320     l_pref_table(l_pref_count).attribute21 := g_pref_values_ct(l_loop_index).attribute21;
2321     l_pref_table(l_pref_count).attribute22 := g_pref_values_ct(l_loop_index).attribute22;
2322     l_pref_table(l_pref_count).attribute23 := g_pref_values_ct(l_loop_index).attribute23;
2323     l_pref_table(l_pref_count).attribute24 := g_pref_values_ct(l_loop_index).attribute24;
2324     l_pref_table(l_pref_count).attribute25 := g_pref_values_ct(l_loop_index).attribute25;
2325     l_pref_table(l_pref_count).attribute26 := g_pref_values_ct(l_loop_index).attribute26;
2326     l_pref_table(l_pref_count).attribute27 := g_pref_values_ct(l_loop_index).attribute27;
2327     l_pref_table(l_pref_count).attribute28 := g_pref_values_ct(l_loop_index).attribute28;
2328     l_pref_table(l_pref_count).attribute29 := g_pref_values_ct(l_loop_index).attribute29;
2329     l_pref_table(l_pref_count).attribute30 := g_pref_values_ct(l_loop_index).attribute30;
2330     l_pref_table(l_pref_count).edit_allowed := g_pref_values_ct(l_loop_index).edit_allowed;
2331     l_pref_table(l_pref_count).displayed := g_pref_values_ct(l_loop_index).displayed;
2332     l_pref_table(l_pref_count).rule_evaluation_order
2333                              := l_hierarchy_list(l_hier).rule_evaluation_order;
2334 
2335     -- the start date and end dates take into account eligibilty dates. Want the overlap between
2336 -- eligbility range and rule range
2337 
2338     if(l_hierarchy_list(l_hier).start_date>=l_hierarchy_list(l_hier).elig_start_date) then
2339       l_pref_table(l_pref_count).start_date := l_hierarchy_list(l_hier).start_date;
2340     else
2341       l_pref_table(l_pref_count).start_date := l_hierarchy_list(l_hier).elig_start_date;
2342     end if;
2343 
2344     if(l_hierarchy_list(l_hier).end_date>=l_hierarchy_list(l_hier).elig_end_date) then
2345       l_pref_table(l_pref_count).end_date := l_hierarchy_list(l_hier).elig_end_date;
2346     else
2347       l_pref_table(l_pref_count).end_date := l_hierarchy_list(l_hier).end_date;
2348     end if;
2349 
2350 -- further restrict by start / end evaluation_dates
2351     if(l_pref_table(l_pref_count).start_date<l_start_evaluation_date) then
2352       l_pref_table(l_pref_count).start_date := l_start_evaluation_date;
2353     end if;
2354 
2355     if(l_pref_table(l_pref_count).end_date>l_end_evaluation_date) then
2356       l_pref_table(l_pref_count).end_date := l_end_evaluation_date;
2357     end if;
2358 
2359     l_pref_table(l_pref_count).name := g_pref_values_ct(l_loop_index).name;
2360 
2361 -- now work out what to do with this row by looping over the l_dated_prefs structure.
2362 -- Note we only want to compare against nodes of the same pref code. Shouldnt have to
2363 -- loop through entire l_dated_prefs table to do this. Should structure the data so that
2364 -- it can be accessed faster.
2365 
2366      -- Performance Fix.
2367 /*     if(not l_pref_encountered.exists(pref_node.preference_id)) THEN
2368      -- set a dummy default preference for each preference code (start and ends at evaluation dates)
2369      -- These will be overridden by default preferences
2370        l_dated_prefs(l_dated_pref_count).start_date             := l_hierarchy_list(0).start_date;
2371        l_dated_prefs(l_dated_pref_count).end_date               := l_hierarchy_list(0).end_date;
2372        l_dated_prefs(l_dated_pref_count).rule_evaluation_order  := -1;
2373        l_dated_prefs(l_dated_pref_count).pref_ref               := 1;
2374        l_dated_pref_count                                       := l_dated_pref_count+1;
2375      -- mark this preference as having being defaulted (initialized).
2376        l_pref_encountered(pref_node.preference_id) := '1';
2377      end if;*/
2378 
2379     l_index:=l_dated_prefs.first;
2380     l_finish:=l_dated_prefs.last;
2381 
2382     LOOP --3
2383 
2384        -- for all dated pref rows with the same code as the new pref and that the precidence
2385        -- of the new pref is higher
2386        -- (also take into account personalization - which has a rule_evaluation_order of 0
2387        -- but overrides everything where the base pref has the edit allowed flag
2388 
2389        if(     l_dated_prefs(l_index).code = l_pref_table(l_pref_count).preference_code
2390            AND (
2391                   (
2392                      (l_dated_prefs(l_index).rule_evaluation_order <=
2393                              l_pref_table(l_pref_count).rule_evaluation_order)
2394                       AND l_dated_prefs(l_index).rule_evaluation_order <>0
2395                   )
2396                   OR
2397                   (
2398                      l_pref_table(l_pref_count).rule_evaluation_order = 0
2399                     AND l_dated_prefs(l_index).edit_allowed = 'Y'
2400                   )
2401                )
2402           ) THEN
2403 
2404        -- check that new / old pref overlap
2405 
2406        if(l_dated_prefs(l_index).start_date<=l_pref_table(l_pref_count).end_date and
2407          l_pref_table(l_pref_count).start_date<=l_dated_prefs(l_index).end_date) then
2408 
2409          -- overlap of rows: Four possible cases - one special case
2410 
2411          if(  l_dated_prefs(l_index).start_date =  l_pref_table(l_pref_count).start_date
2412           and l_dated_prefs(l_index).end_date   =  l_pref_table(l_pref_count).end_date  )  then
2413 
2414            l_dated_prefs(l_index).pref_ref := l_pref_count;
2415            l_dated_prefs(l_index).rule_evaluation_order
2416                                  := l_pref_table(l_pref_count).rule_evaluation_order;
2417            l_dated_prefs(l_index).edit_allowed := l_pref_table(l_pref_count).edit_allowed;
2418 
2419       elsif(  l_dated_prefs(l_index).start_date >= l_pref_table(l_pref_count).start_date
2420           and l_dated_prefs(l_index).end_date   <= l_pref_table(l_pref_count).end_date  )  then
2421 
2422       -- case 1: New row spans /equivalent to old row.
2423       --         Change row attribution but keep dates
2424       --         Number of rows does not change
2425       --         |++++++++|
2426       --             +
2427       --         |-------|
2428       --             =
2429       --         |+++++++|
2430 
2431            l_dated_prefs(l_index).pref_ref := l_pref_count;
2432            l_dated_prefs(l_index).rule_evaluation_order
2433                                     := l_pref_table(l_pref_count).rule_evaluation_order;
2434            l_dated_prefs(l_index).edit_allowed := l_pref_table(l_pref_count).edit_allowed;
2435 
2436 
2437       elsif(  l_dated_prefs(l_index).start_date >= l_pref_table(l_pref_count).start_date
2438           and l_dated_prefs(l_index).end_date   >= l_pref_table(l_pref_count).end_date)  then
2439 
2440       -- case 2: New row paritally overlaps old row (spans old row start_date)
2441       --         Create row with new row attribution between old row start date and new row
2442       --         stop date
2443       --         Change start date of old row to end date of new row
2444       --         Number of rows increased by 1
2445       --      |+++++|
2446       --             +
2447       --         |-------|
2448       --             =
2449       --         |++|----|
2450 
2451    l_dated_prefs(l_index).start_date := l_pref_table(l_pref_count).end_date+1;
2452    l_dated_pref_count:=l_dated_pref_count+1;
2453    l_dated_prefs(l_dated_pref_count).start_date := l_pref_table(l_pref_count).start_date;
2454    l_dated_prefs(l_dated_pref_count).end_date := l_pref_table(l_pref_count).end_date;
2455    l_dated_prefs(l_dated_pref_count).rule_evaluation_order
2456                      := l_pref_table(l_pref_count).rule_evaluation_order;
2457    l_dated_prefs(l_dated_pref_count).edit_allowed := l_pref_table(l_pref_count).edit_allowed;
2458    l_dated_prefs(l_dated_pref_count).code := l_pref_table(l_pref_count).preference_code;
2459    l_dated_prefs(l_dated_pref_count).pref_ref := l_pref_count;
2460 
2461        elsif(   l_dated_prefs(l_index).start_date <= l_pref_table(l_pref_count).start_date
2462               and l_dated_prefs(l_index).end_date <= l_pref_table(l_pref_count).end_date)  then
2463 
2464       -- case 3: New row paritally overlaps old row (spans old row stop_date)
2465       --         Create row with new row attribution between old row start date and new
2466       --         row stop date
2467       --         Change end of old row to start date of new row
2468       --         Number of rows increased by 1
2469       --              |+++++|
2470       --             +
2471       --         |-------|
2472       --             =
2473       --         |----|++|
2474    l_tmp_date:=l_dated_prefs(l_index).end_date;
2475    l_dated_prefs(l_index).end_date := l_pref_table(l_pref_count).start_date-1;
2476 -- -1 because new row has precedence
2477    l_dated_pref_count:=l_dated_pref_count+1;
2478    l_dated_prefs(l_dated_pref_count).start_date := l_pref_table(l_pref_count).start_date;
2479    l_dated_prefs(l_dated_pref_count).end_date :=  l_tmp_date;
2480    l_dated_prefs(l_dated_pref_count).rule_evaluation_order
2481                         := l_pref_table(l_pref_count).rule_evaluation_order;
2482    l_dated_prefs(l_dated_pref_count).edit_allowed := l_pref_table(l_pref_count).edit_allowed;
2483    l_dated_prefs(l_dated_pref_count).code := l_pref_table(l_pref_count).preference_code;
2484    l_dated_prefs(l_dated_pref_count).pref_ref := l_pref_count;
2485 
2486         elsif( l_dated_prefs(l_index).start_date <= l_pref_table(l_pref_count).start_date
2487              and l_dated_prefs(l_index).end_date >= l_pref_table(l_pref_count).end_date)  then
2488 
2489       -- case 4: New row spanned / equivalent to old row
2490       --         Create 2 new rows.
2491       --         Change end date of old row to be start date of new row
2492       --         create row with start date of new row and end date of new row with new
2493       --         row attribution
2494       --         create new row with start date of end date of new row and end date of old
2495       --         row with attribution of old row
2496       --           |+++|
2497       --             +
2498       --         |-------|
2499       --             =
2500       --         |-|+++|-|
2501    l_tmp_date:=l_dated_prefs(l_index).start_date;
2502    l_dated_prefs(l_index).start_date := l_pref_table(l_pref_count).end_date+1;
2503    l_dated_pref_count:=l_dated_pref_count+1;
2504    l_dated_prefs(l_dated_pref_count).start_date := l_pref_table(l_pref_count).start_date;
2505    l_dated_prefs(l_dated_pref_count).end_date := l_pref_table(l_pref_count).end_date;
2506    l_dated_prefs(l_dated_pref_count).rule_evaluation_order
2507                         := l_pref_table(l_pref_count).rule_evaluation_order;
2508    l_dated_prefs(l_dated_pref_count).edit_allowed := l_pref_table(l_pref_count).edit_allowed;
2509    l_dated_prefs(l_dated_pref_count).code := l_pref_table(l_pref_count).preference_code;
2510    l_dated_prefs(l_dated_pref_count).pref_ref := l_pref_count;
2511    l_dated_pref_count:=l_dated_pref_count+1;
2512    l_dated_prefs(l_dated_pref_count).start_date := l_tmp_date;
2513    l_dated_prefs(l_dated_pref_count).end_date := l_pref_table(l_pref_count).start_date-1;
2514    l_dated_prefs(l_dated_pref_count).rule_evaluation_order
2515                                :=l_dated_prefs(l_index).rule_evaluation_order;
2516    l_dated_prefs(l_dated_pref_count).edit_allowed :=l_dated_prefs(l_index).edit_allowed;
2517    l_dated_prefs(l_dated_pref_count).code := l_pref_table(l_pref_count).preference_code;
2518    l_dated_prefs(l_dated_pref_count).pref_ref := l_dated_prefs(l_index).pref_ref;
2519           end if;
2520 
2521         end if;
2522       end if;
2523 
2524       exit when (l_index = l_finish);
2525 
2526       l_index := l_dated_prefs.next(l_index);
2527 
2528 --      IF(g_loop_count > g_maxloop) THEN
2529 --        hr_utility.set_message(809, 'HXC_LPS_GT_MAX');
2530 --        hr_utility.raise_error;
2531 --      END IF;
2532 
2533 --      g_loop_count := g_loop_count + 1;
2534 
2535     END LOOP; --3 update of existing dated prefrences
2536 
2537   END LOOP; --2 node loop;
2538  End if;
2539 
2540   l_hier := l_hierarchy_list.next(l_hier);
2541 
2542 --  g_loop_count := g_loop_count + 1;
2543 
2544   IF(g_loop_count > g_maxloop) THEN
2545       hr_utility.set_message(809, 'HXC_LPS_GT_MAX');
2546       hr_utility.raise_error;
2547   END IF;
2548 
2549 END LOOP; --1 hierarchy loop;
2550 
2551 -- now build out results table based on calculations
2552 -- create an entry for each pref - also assign dates
2553 
2554 
2555 l_index:=l_dated_prefs.first;
2556 l_pref_count:=0;
2557 
2558 
2559 LOOP
2560   EXIT when not l_dated_prefs.exists(l_index);
2561 
2562   IF (p_no_prefs_outside_asg = TRUE AND l_dated_prefs(l_index).rule_evaluation_order <> -1)
2563 	OR p_no_prefs_outside_asg = FALSE
2564   THEN
2565 
2566   l_pref_ref := l_dated_prefs(l_index).pref_ref;
2567 
2568   p_pref_table(l_pref_count).preference_code        := l_dated_prefs(l_index).code;
2569   p_pref_table(l_pref_count).start_date             := l_dated_prefs(l_index).start_date;
2570   p_pref_table(l_pref_count).end_date               := l_dated_prefs(l_index).end_date;
2571   p_pref_table(l_pref_count).rule_evaluation_order
2572                  := l_dated_prefs(l_index).rule_evaluation_order;
2573   p_pref_table(l_pref_count).attribute1
2574                  := l_pref_table(l_pref_ref).attribute1;
2575   p_pref_table(l_pref_count).attribute2 := l_pref_table(l_pref_ref).attribute2;
2576   p_pref_table(l_pref_count).attribute3 := l_pref_table(l_pref_ref).attribute3;
2577   p_pref_table(l_pref_count).attribute4 := l_pref_table(l_pref_ref).attribute4;
2578   p_pref_table(l_pref_count).attribute5 := l_pref_table(l_pref_ref).attribute5;
2579   p_pref_table(l_pref_count).attribute6 := l_pref_table(l_pref_ref).attribute6;
2580   p_pref_table(l_pref_count).attribute7 := l_pref_table(l_pref_ref).attribute7;
2581   p_pref_table(l_pref_count).attribute8 := l_pref_table(l_pref_ref).attribute8;
2582   p_pref_table(l_pref_count).attribute9 := l_pref_table(l_pref_ref).attribute9;
2583   p_pref_table(l_pref_count).attribute10 := l_pref_table(l_pref_ref).attribute10;
2584   p_pref_table(l_pref_count).attribute11 := l_pref_table(l_pref_ref).attribute11;
2585   p_pref_table(l_pref_count).attribute12 := l_pref_table(l_pref_ref).attribute12;
2586   p_pref_table(l_pref_count).attribute13 := l_pref_table(l_pref_ref).attribute13;
2587   p_pref_table(l_pref_count).attribute14 := l_pref_table(l_pref_ref).attribute14;
2588   p_pref_table(l_pref_count).attribute15 := l_pref_table(l_pref_ref).attribute15;
2589   p_pref_table(l_pref_count).attribute16 := l_pref_table(l_pref_ref).attribute16;
2590   p_pref_table(l_pref_count).attribute17 := l_pref_table(l_pref_ref).attribute17;
2591   p_pref_table(l_pref_count).attribute18 := l_pref_table(l_pref_ref).attribute18;
2592   p_pref_table(l_pref_count).attribute19 := l_pref_table(l_pref_ref).attribute19;
2593   p_pref_table(l_pref_count).attribute20 := l_pref_table(l_pref_ref).attribute20;
2594   p_pref_table(l_pref_count).attribute21 := l_pref_table(l_pref_ref).attribute21;
2595   p_pref_table(l_pref_count).attribute22 := l_pref_table(l_pref_ref).attribute22;
2596   p_pref_table(l_pref_count).attribute23 := l_pref_table(l_pref_ref).attribute23;
2597   p_pref_table(l_pref_count).attribute24 := l_pref_table(l_pref_ref).attribute24;
2598   p_pref_table(l_pref_count).attribute25 := l_pref_table(l_pref_ref).attribute25;
2599   p_pref_table(l_pref_count).attribute26 := l_pref_table(l_pref_ref).attribute26;
2600   p_pref_table(l_pref_count).attribute27 := l_pref_table(l_pref_ref).attribute27;
2601   p_pref_table(l_pref_count).attribute28 := l_pref_table(l_pref_ref).attribute28;
2602   p_pref_table(l_pref_count).attribute29 := l_pref_table(l_pref_ref).attribute29;
2603   p_pref_table(l_pref_count).attribute30 := l_pref_table(l_pref_ref).attribute30;
2604   p_pref_table(l_pref_count).edit_allowed := l_pref_table(l_pref_ref).edit_allowed;
2605   p_pref_table(l_pref_count).displayed := l_pref_table(l_pref_ref).displayed;
2606 
2607   END IF;
2608 
2609 l_index:=l_dated_prefs.next(l_index);
2610 
2611      IF(g_loop_count > g_maxloop) THEN
2612         hr_utility.set_message(809, 'HXC_LPS_GT_MAX');
2613         hr_utility.raise_error;
2614       END IF;
2615 
2616 --      g_loop_count := g_loop_count + 1;
2617 
2618 l_pref_count:=l_pref_count+1;
2619 
2620 END LOOP;
2621 
2622 END resource_preferences;
2623 
2624 
2625 ----
2626 -- Supporting function to allow inquiries as to whether specific values have been used
2627 -- in preference hierarchies. Useful for data integrity checking.
2628 ----
2629 
2630 FUNCTION  num_hierarchy_occurances(p_preference_code IN VARCHAR2,
2631                                    p_attributen      IN NUMBER,
2632                                    p_value           IN VARCHAR2) RETURN NUMBER
2633 IS
2634 
2635 -- note this cursor contains a decode in the WHERE clause. Could cause performance issue.
2636 -- Hovever the SQL is very light and this is a function that will be called during application
2637 -- setup and is therefore not performance critical
2638 
2639 l_count NUMBER;
2640 
2641 CURSOR get_num_hierarchy_occurances(p_preference_code VARCHAR2,
2642                                     p_attributen NUMBER,
2643                                     p_value VARCHAR2)
2644 IS
2645 SELECT count(*)
2646 FROM   hxc_pref_hierarchies hph,
2647        hxc_pref_definitions hpd
2648 WHERE  hph.pref_definition_id = hpd.pref_definition_id
2649 AND    hpd.code = p_preference_code
2650 AND    decode (p_attributen, 1, hph.attribute1,  2, hph.attribute2,  3, hph.attribute3,
2651                              4, hph.attribute4,  5, hph.attribute5,  6, hph.attribute6,
2652                              7, hph.attribute7,  8, hph.attribute8,  9, hph.attribute9,
2653                             10, hph.attribute10,11, hph.attribute11,12, hph.attribute12,
2654                             13, hph.attribute13,14, hph.attribute14,15, hph.attribute15,
2655                             16, hph.attribute16,17, hph.attribute17,18, hph.attribute18,
2656                             19, hph.attribute19,20, hph.attribute20,21, hph.attribute21,
2657                             22, hph.attribute22,23, hph.attribute23,24, hph.attribute24,
2658                             25, hph.attribute25,26, hph.attribute26,27, hph.attribute27,
2659                             28, hph.attribute28,29, hph.attribute29,30, hph.attribute30) = p_value;
2660 
2661 BEGIN
2662 
2663 OPEN get_num_hierarchy_occurances(p_preference_code,
2664                                   p_attributen,
2665                                   p_value);
2666 
2667 FETCH get_num_hierarchy_occurances INTO l_count;
2668 
2669 RETURN l_count;
2670 
2671 END num_hierarchy_occurances;
2672 
2673 
2674 PROCEDURE resource_preferences(p_resource_id  in NUMBER,
2675 			       p_preference_code IN VARCHAR2,
2676                                p_start_evaluation_date DATE,
2677                                p_end_evaluation_date DATE,
2678                                p_sorted_pref_table IN OUT NOCOPY  t_pref_table,
2679 			       p_clear_cache BOOLEAN DEFAULT FALSE,
2680                                p_no_prefs_outside_asg IN BOOLEAN DEFAULT FALSE ) IS
2681 
2682 l_prefs t_pref_table;
2683 
2684 l_prefs_filter t_pref_table; -- filtered table
2685 l_prefs_sorted t_pref_table; -- filtered in date order table
2686 
2687 l_ind BINARY_INTEGER;
2688 l_sort_ind BINARY_INTEGER := 1;
2689 
2690 l_not_sorted BOOLEAN := TRUE;
2691 
2692 l_temp_pref_rec t_pref_table_row;
2693 l_temp_ind BINARY_INTEGER;
2694 
2695 BEGIN
2696 
2697 IF ( g_sort_pref_table.COUNT <> 0 )
2698 THEN
2699 
2700 	IF (     p_clear_cache
2701              OR (   g_sort_cache(1).resource_id <> p_resource_id )
2702              OR ( ( g_sort_cache(1).start_date <> p_start_evaluation_date ) OR
2703                   ( g_sort_cache(1).end_date   <> p_end_evaluation_date   ) ) )
2704 	THEN
2705 
2706 		g_sort_pref_table.DELETE;
2707 
2708 		hxc_preference_evaluation.resource_preferences(p_resource_id => p_resource_id,
2709                                p_start_evaluation_date => p_start_evaluation_date,
2710                                p_end_evaluation_date => p_end_evaluation_date,
2711                                p_pref_table => g_sort_pref_table,
2712                                p_no_prefs_outside_asg => p_no_prefs_outside_asg );
2713 
2714 		g_sort_cache(1).resource_id := p_resource_id;
2715 		g_sort_cache(1).start_date := p_start_evaluation_date;
2716 		g_sort_cache(1).end_date   := p_end_evaluation_date;
2717 
2718 	END IF;
2719 
2720 ELSE
2721 
2722 	hxc_preference_evaluation.resource_preferences(p_resource_id => p_resource_id,
2723                               p_start_evaluation_date => p_start_evaluation_date,
2724                               p_end_evaluation_date => p_end_evaluation_date,
2725                               p_pref_table => g_sort_pref_table,
2726                               p_no_prefs_outside_asg => p_no_prefs_outside_asg );
2727 
2728 	g_sort_cache(1).resource_id := p_resource_id;
2729 	g_sort_cache(1).start_date := p_start_evaluation_date;
2730 	g_sort_cache(1).end_date   := p_end_evaluation_date;
2731 
2732 
2733 END IF;
2734 
2735 
2736 l_ind := g_sort_pref_table.FIRST;
2737 
2738 -- filter out the desired preference
2739 
2740 WHILE l_ind IS NOT NULL
2741 LOOP
2742 
2743 	IF ( g_sort_pref_table(l_ind).preference_code = p_preference_code )
2744 	THEN
2745 		l_temp_ind := to_char(g_sort_pref_table(l_ind).start_date,'J');
2746 
2747 		IF l_prefs_filter.exists(l_temp_ind) AND
2748 		   l_prefs_filter(l_temp_ind).end_date >= g_sort_pref_table(l_ind).end_date THEN
2749 
2750 		   	NULL;
2751 		ELSE
2752   		   l_prefs_filter(l_temp_ind) := g_sort_pref_table(l_ind);
2753 		END IF;
2754 
2755 		END IF;
2756 
2757 	l_ind := g_sort_pref_table.NEXT(l_ind);
2758 
2759 END LOOP;
2760 
2761 -- now copy sorted table into table with binary index incremented by 1
2762 
2763 l_ind := l_prefs_filter.FIRST;
2764 
2765 WHILE l_ind IS NOT NULL
2766 LOOP
2767 
2768 	l_prefs_sorted(l_sort_ind) := l_prefs_filter(l_ind);
2769 
2770 	l_ind := l_prefs_filter.NEXT(l_ind);
2771 
2772 	l_sort_ind := l_sort_ind + 1;
2773 
2774 END LOOP;
2775 
2776 l_prefs_filter.DELETE;
2777 
2778 p_sorted_pref_table := l_prefs_sorted;
2779 
2780 end resource_preferences;
2781 
2782 PROCEDURE resource_preferences(p_resource_id  in NUMBER,
2783 			       p_preference_code IN VARCHAR2,
2784                                p_start_evaluation_date DATE,
2785                                p_end_evaluation_date DATE,
2786                                p_sorted_pref_table IN OUT NOCOPY  t_pref_table,
2787 			       p_clear_cache BOOLEAN DEFAULT FALSE,
2788 			       p_master_pref_table t_pref_table ) IS
2789 
2790 l_tmp_pref_table t_pref_table;
2791 
2792 l_ind BINARY_INTEGER := 1;
2793 
2794 BEGIN
2795 
2796 	g_sort_pref_table.DELETE;
2797 
2798 	g_sort_pref_table := p_master_pref_table;
2799 
2800 	g_sort_cache(1).resource_id := p_resource_id;
2801 	g_sort_cache(1).start_date := p_start_evaluation_date;
2802 	g_sort_cache(1).end_date   := p_end_evaluation_date;
2803 
2804 	resource_preferences (
2805 		       p_resource_id           => p_resource_id,
2806 		       p_preference_code       => p_preference_code,
2807                        p_start_evaluation_date => p_start_evaluation_date,
2808                        p_end_evaluation_date   => p_end_evaluation_date,
2809                        p_sorted_pref_table     => p_sorted_pref_table,
2810 		       p_clear_cache           => FALSE );
2811 
2812 	-- GPM 115.27 start
2813 	-- the preference table passed here was for all dates
2814 	-- filter out the unwanted dates
2815 
2816 	FOR x in 1 .. p_sorted_pref_table.LAST
2817 	LOOP
2818 		-- Bug 6123330
2819 		IF ( to_date(to_char(p_sorted_pref_table(x).end_date,'DD-MM-YYYY'),'DD-MM-YYYY')   >= to_date(to_char(p_start_evaluation_date,'DD-MM-YYYY'),'DD-MM-YYYY') AND
2820                      to_date(to_char(p_sorted_pref_table(x).start_date,'DD-MM-YYYY'),'DD-MM-YYYY') <= to_date(to_char(p_end_evaluation_date,'DD-MM-YYYY'),'DD-MM-YYYY') )
2821 		THEN
2822 
2823 			l_tmp_pref_table(l_ind) := p_sorted_pref_table(x);
2824 
2825 			l_ind := l_ind + 1;
2826 
2827 		END IF;
2828 
2829 	END LOOP;
2830 
2831 	p_sorted_pref_table := l_tmp_pref_table;
2832 
2833 	l_tmp_pref_table.DELETE;
2834 
2835 	-- GPM 115.27 end
2836 
2837 END resource_preferences;
2838 
2839 -- this clears the pref table cache when preference evaluation is finished
2840 -- to allow memory saving.
2841 
2842 PROCEDURE clear_sort_pref_table_cache IS
2843 
2844 BEGIN
2845 
2846 	g_sort_pref_table.DELETE;
2847 
2848 END clear_sort_pref_table_cache;
2849 
2850    FUNCTION migration_mode
2851        RETURN BOOLEAN
2852     IS
2853        l_proc    VARCHAR2 (72);
2854     BEGIN
2855        g_debug := hr_utility.debug_enabled;
2856 
2857        if g_debug then
2858         l_proc := g_package|| 'migration_mode';
2859        	hr_utility.set_location (   'Entering:'
2860        	                         || l_proc, 10);
2861        end if;
2862 
2863        IF (g_migration_mode)
2864        THEN
2865           if g_debug then
2866           	hr_utility.set_location ('   returning g_migration_mode = TRUE', 20);
2867           end if;
2868        ELSE
2869           if g_debug then
2870           	hr_utility.set_location ('   returning g_migration_mode = FALSE', 30);
2871           end if;
2872        END IF;
2873 
2874        if g_debug then
2875        	hr_utility.set_location (   'Leaving:'
2876        	                         || l_proc, 100);
2877        end if;
2878        RETURN g_migration_mode;
2879     END migration_mode;
2880     PROCEDURE set_migration_mode (p_migration_mode IN BOOLEAN)
2881     IS
2882        l_proc    VARCHAR2 (72);
2883     BEGIN
2884        g_debug := hr_utility.debug_enabled;
2885 
2886        if g_debug then
2887        	l_proc := g_package||'set_migration_mode';
2888        	hr_utility.set_location (   'Entering:'|| l_proc, 10);
2889        end if;
2890 
2891        IF (p_migration_mode)
2892        THEN
2893           if g_debug then
2894           	hr_utility.set_location ('   setting g_migration_mode to TRUE', 20);
2895           end if;
2896        ELSE
2897           if g_debug then
2898           	hr_utility.set_location ('   setting g_migration_mode to FALSE', 30);
2899           end if;
2900        END IF;
2901 
2902        g_migration_mode := p_migration_mode;
2903        if g_debug then
2904        	hr_utility.set_location (   'Leaving:'
2905        	                         || l_proc, 100);
2906        end if;
2907     END set_migration_mode;
2908     FUNCTION employment_ended (
2909        p_person_id        per_all_people_f.person_id%TYPE,
2910        p_effective_date   per_all_assignments_f.effective_start_date%TYPE
2911              DEFAULT SYSDATE
2912     )
2913        RETURN BOOLEAN
2914     IS
2915        l_proc          VARCHAR2 (72);
2916        l_employment_ended      BOOLEAN;
2917 
2918        CURSOR csr_existing_employment (
2919           p_person_id        per_all_people_f.person_id%TYPE,
2920           p_effective_date   per_all_assignments_f.effective_start_date%TYPE
2921        )
2922        IS
2923           SELECT 1
2924             FROM per_all_assignments_f paaf, per_assignment_status_types past
2925            WHERE paaf.person_id = p_person_id
2926              AND p_effective_date BETWEEN paaf.effective_start_date
2927                                       AND paaf.effective_end_date
2928              AND paaf.assignment_type IN ( 'E','C')
2929              AND past.assignment_status_type_id = paaf.assignment_status_type_id
2930              AND past.per_system_status IN ('ACTIVE_ASSIGN','ACTIVE_CWK');
2931 
2932        l_existing_employment   csr_existing_employment%ROWTYPE;
2933     BEGIN
2934        g_debug := hr_utility.debug_enabled;
2935 
2936        if g_debug then
2937        	l_proc := g_package|| 'employment_ended';
2938        	hr_utility.set_location (   'Entering:'
2939        	                         || l_proc, 10);
2940        end if;
2941        OPEN csr_existing_employment (p_person_id, p_effective_date);
2942        FETCH csr_existing_employment INTO l_existing_employment;
2943 
2944        IF (csr_existing_employment%NOTFOUND)
2945        THEN
2946           if g_debug then
2947           	hr_utility.set_location (
2948           	      '   The employment for '
2949           	   || p_person_id
2950           	   || 'ended.',
2951           	   20
2952           	);
2953           end if;
2954           l_employment_ended := TRUE;
2955        ELSE
2956           l_employment_ended := FALSE;
2957        END IF;
2958 
2959        CLOSE csr_existing_employment;
2960        if g_debug then
2961        	hr_utility.set_location (   'Leaving:'
2962        	                         || l_proc, 100);
2963        end if;
2964        RETURN l_employment_ended;
2965     END employment_ended;
2966 
2967     FUNCTION assignment_last_eff_dt (
2968        p_person_id        per_all_people_f.person_id%TYPE,
2969        p_effective_date   per_all_assignments_f.effective_start_date%TYPE
2970              DEFAULT SYSDATE
2971     )
2972        RETURN per_all_assignments_f.effective_start_date%TYPE
2973     IS
2974        l_proc             VARCHAR2 (72);
2975        l_assignment_last_eff_dt   per_all_assignments_f.effective_start_date%TYPE;
2976 
2977        CURSOR csr_assignment_last_eff_dt (
2978           p_person_id        per_all_people_f.person_id%TYPE,
2979           p_effective_date   per_all_assignments_f.effective_start_date%TYPE
2980        )
2981        IS
2982           SELECT MAX (paaf.effective_end_date)
2983             FROM per_all_assignments_f paaf, per_assignment_status_types past
2984            WHERE paaf.person_id = p_person_id
2985              AND paaf.effective_end_date <= p_effective_date
2986              AND paaf.assignment_type IN ( 'E', 'C')
2987              AND past.assignment_status_type_id = paaf.assignment_status_type_id
2988              AND past.per_system_status IN ( 'ACTIVE_ASSIGN','ACTIVE_CWK');
2989     BEGIN
2990        g_debug := hr_utility.debug_enabled;
2991 
2992        if g_debug then
2993        	l_proc := g_package|| 'assignment_last_eff_dt';
2994        	hr_utility.set_location (   'Entering:'
2995        	                         || l_proc, 10);
2996        end if;
2997        OPEN csr_assignment_last_eff_dt (p_person_id, p_effective_date);
2998        FETCH csr_assignment_last_eff_dt INTO l_assignment_last_eff_dt;
2999 
3000        IF (csr_assignment_last_eff_dt%NOTFOUND)
3001        THEN
3002           -- this will get handled during the actuall preference evaluation, we don't
3003           -- have to act on it here.
3004           l_assignment_last_eff_dt := NULL;
3005        ELSE
3006           if g_debug then
3007           	hr_utility.set_location (
3008           	      '   The last available effective date for person '
3009           	   || p_person_id
3010           	   || ' is '
3011           	   || l_assignment_last_eff_dt,
3012           	   20
3013           	);
3014           end if;
3015        END IF;
3016 
3017        CLOSE csr_assignment_last_eff_dt;
3018        if g_debug then
3019        	hr_utility.set_location (   'Leaving:'
3020        	                         || l_proc, 100);
3021        end if;
3022        RETURN l_assignment_last_eff_dt;
3023     END assignment_last_eff_dt;
3024 
3025     FUNCTION evaluation_date (
3026        p_resource_id       hxc_time_building_blocks.resource_id%TYPE,
3027        p_evaluation_date   DATE
3028     )
3029        RETURN DATE
3030     IS
3031        l_proc      VARCHAR2 (72);
3032        l_evaluation_date   DATE;
3033     BEGIN
3034        g_debug := hr_utility.debug_enabled;
3035 
3036        if g_debug then
3037        	l_proc := g_package|| 'evaluation_date';
3038        	hr_utility.set_location (   'Entering:'
3039        	                         || l_proc, 10);
3040        end if;
3041 
3042        IF (    (migration_mode)
3043            AND (employment_ended (p_person_id => p_resource_id))
3044            AND TRUNC (p_evaluation_date) = TRUNC (SYSDATE)
3045           )
3046        THEN
3047           l_evaluation_date :=
3048                             assignment_last_eff_dt (p_person_id => p_resource_id);
3049        ELSE
3050           l_evaluation_date := TRUNC (p_evaluation_date);
3051        END IF;
3052 
3053        if g_debug then
3054        	hr_utility.set_location (
3055        	      '   Returning evaluation_date ='
3056        	   || l_evaluation_date,
3057        	   20
3058        	);
3059        	hr_utility.set_location (   'Leaving:'
3060        	                         || l_proc, 100);
3061        end if;
3062        RETURN l_evaluation_date;
3063     END evaluation_date;
3064 
3065 -- Procedure for Bulk preference evaluation. Calculates the preference for a set of resource_ids.
3066 -- Its a single date evaluation and does not consider responsibility or login based preferences.
3067 
3068 procedure resource_prefs_bulk (p_evaluation_date in date,
3069                                 p_pref_table IN OUT NOCOPY t_pref_table,
3070                                 p_resource_pref_table IN OUT NOCOPY t_resource_pref_table,
3071                                 p_resource_sql in varchar2  )
3072                                 is
3073 
3074 
3075 l_current_resource_id number;
3076 l_matches number;
3077 
3078 l_pref_sets_index_table t_pref_sets_index_table;
3079 l_pref_sets_index_table_idx number;
3080 
3081 l_pref_sets_table       t_pref_sets_table;
3082 l_pref_sets_table_idx number;
3083 
3084 l_flat_table t_pref_sets_table;
3085 l_flat_table_idx number;
3086 
3087 l_resource_elig_table t_resource_elig_table;
3088 l_resource_elig_table_idx number;
3089 
3090 
3091 l_pref_table_idx number;
3092 
3093 l_eval_pref_table hxc_preference_evaluation.t_pref_table;
3094 l_eval_pref_table_idx number;
3095 
3096 l_set_start number;
3097 l_set_stop number;
3098 l_result_start number;
3099 l_result_stop number;
3100 
3101 l_index number;
3102 
3103 l_sql_statement varchar2(32000);
3104 TYPE PrefCurTyp IS REF CURSOR;
3105 
3106 prefs_cv   PrefCurTyp;
3107 
3108 
3109 begin
3110 
3111 -- Bug 7484448
3112 -- Added USE_NL in the below query for optimum perf.
3113 l_sql_statement :=  ' SELECT /*+ USE_NL(PA HRR) */
3114                              pa.person_id as criteria_id,
3115                              hrr.pref_hierarchy_id,
3116 			     hrr.rule_evaluation_order
3117     FROM hxc_resource_rules hrr,
3118          per_all_assignments_f pa
3119    WHERE  pa.person_id  '||p_resource_sql||'
3120       AND nvl(hrr.business_group_id,pa.business_group_id) = pa.business_group_id
3121       AND pa.primary_flag =''Y''
3122       AND pa.assignment_type in (''E'',''C'')
3123       AND :evaluation_date
3124             BETWEEN pa.effective_start_date AND pa.effective_END_date
3125       AND :evaluation_date between hrr.start_date and hrr.end_date
3126       AND ((   to_char(pa.assignment_id) = hrr.eligibility_criteria_id
3127                   AND hrr.eligibility_criteria_type = ''ASSIGNMENT'')
3128         OR (      to_char(pa.payroll_id) = hrr.eligibility_criteria_id
3129                   AND hrr.eligibility_criteria_type = ''PAYROLL'')
3130         OR (       to_char(pa.person_id) = hrr.eligibility_criteria_id
3131                   AND hrr.eligibility_criteria_type = ''PERSON'')
3132         OR (     pa.EMPLOYEE_CATEGORY = hrr.eligibility_criteria_id
3133                   AND hrr.eligibility_criteria_type = ''EMP_CATEGORY'')
3134         OR (     pa.EMPLOYMENT_CATEGORY = hrr.eligibility_criteria_id
3135                   AND hrr.eligibility_criteria_type = ''ASGN_CATEGORY'')
3136         OR (     to_char(pa.location_id) = hrr.eligibility_criteria_id
3137                   AND hrr.eligibility_criteria_type = ''LOCATION'')
3138         OR (     to_char(pa.organization_id) = hrr.eligibility_criteria_id
3139                   AND hrr.eligibility_criteria_type = ''ORGANIZATION'')
3140       	OR  ((HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,instr(hrr.eligibility_criteria_id,''-'',1,1)+1)) in
3141            (SELECT pose.organization_id_parent
3142                   FROM
3143                  per_org_structure_elements pose
3144 		 start with organization_id_child = pa.organization_id
3145                     and  pose.org_structure_version_id=
3146                                HXC_PREFERENCE_EVALUATION.return_version_id(HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,1,instr(hrr.eligibility_criteria_id,''-'',1,1)-1)),
3147                                                          hrr.eligibility_criteria_type)
3148                     connect by prior organization_id_parent=organization_id_child
3149                     and  pose.org_structure_version_id=
3150                                HXC_PREFERENCE_EVALUATION.return_version_id(HXC_PREFERENCE_EVALUATION.check_number(substr(hrr.eligibility_criteria_id,1,instr(hrr.eligibility_criteria_id,''-'',1,1)-1)),
3151                                                          hrr.eligibility_criteria_type)
3152                     union
3153                     select organization_id
3154                    from   hr_all_organization_units
3155                    where  organization_id =  pa.organization_id))
3156                  AND  hrr.eligibility_criteria_type = ''ROLLUP'' )
3157         OR (     HXC_PREFERENCE_EVALUATION.check_number(hrr.eligibility_criteria_id)
3158                             in ( SELECT typ.person_type_id
3159                                                FROM per_person_types typ
3160                                                    ,per_person_type_usages_f ptu
3161                                                WHERE typ.system_person_type IN (''EMP'',''EX_EMP'',''EMP_APL'',''EX_EMP_APL'',''CWK'',''EX_CWK'')
3162                                                  AND typ.person_type_id = ptu.person_type_id
3163                                                  AND :evaluation_date BETWEEN ptu.effective_start_date AND ptu.effective_end_date
3164                                                  AND pa.effective_start_date <= ptu.effective_end_date
3165                                                  AND  pa.effective_end_date >=ptu.effective_start_date
3166                                                  AND ptu.person_id = pa.person_id)
3167                  AND hrr.eligibility_criteria_type = ''PERSON_TYPE'')
3168         OR (
3169                   hrr.eligibility_criteria_type = ''ALL_PEOPLE''))'|| 'union '||
3170     ' SELECT pa.person_id as criteria_id,hrr.pref_hierarchy_id, hrr.rule_evaluation_order
3171     FROM hxc_resource_rules hrr,
3172          per_all_assignments_f pa
3173    WHERE pa.person_id  '||p_resource_sql||'
3174      AND nvl(hrr.business_group_id,pa.business_group_id) = pa.business_group_id
3175      AND pa.primary_flag = ''Y''
3176      AND pa.assignment_type in (''E'',''C'')
3177      AND :evaluation_date
3178               BETWEEN pa.effective_start_date AND pa.effective_END_date
3179      AND :evaluation_date between hrr.start_date and hrr.end_date
3180      AND ( (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 3 ),
3181                    ''SCL'', DECODE ( pa.soft_coding_keyflex_id, NULL, -1,
3182                    hxc_resource_rules_utils.chk_flex_valid (''SCL'', pa.soft_coding_keyflex_id,
3183                    SUBSTR( hrr.eligibility_criteria_type, 5 ),
3184                    hrr.eligibility_criteria_id )), -1 ) = 1 )
3185       OR  (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 6 ),
3186                   ''PEOPLE'', DECODE ( pa.people_group_id, NULL, -1,
3187                   hxc_resource_rules_utils.chk_flex_valid ( ''PEOPLE'', pa.people_group_id,
3188                   SUBSTR( hrr.eligibility_criteria_type, 8 ),
3189                   hrr.eligibility_criteria_id )), -1 ) = 1 )
3190       OR  (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 5 ),
3191                   ''GRADE'', DECODE ( pa.grade_id, NULL, -1,
3192                   hxc_resource_rules_utils.chk_flex_valid ( ''GRADE'', pa.grade_id,
3193                   SUBSTR( hrr.eligibility_criteria_type, 7 ),
3194                   hrr.eligibility_criteria_id )), -1 ) = 1 )
3195       OR  (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 3 ),
3196                  ''JOB'', hrr.eligibility_criteria_id, -1 ) = to_char(pa.job_id))-- Issue 4
3197       OR  (DECODE ( SUBSTR( hrr.eligibility_criteria_type, 1, 8 ),
3198                  ''POSITION'', hrr.eligibility_criteria_id, -1 ) = to_char(pa.position_id)) -- Issue 4
3199 )
3200 order by criteria_id';
3201 
3202 
3203 l_resource_elig_table_idx := 0;
3204 -- Cache the Rules of all the resource_ids
3205    OPEN prefs_cv FOR l_sql_statement using p_evaluation_date,p_evaluation_date,p_evaluation_date,p_evaluation_date,p_evaluation_date;
3206 
3207    loop
3208       FETCH prefs_cv INTO l_resource_elig_table(l_resource_elig_table_idx);
3209       l_resource_elig_table_idx := l_resource_elig_table_idx + 1;
3210 
3211       EXIT WHEN prefs_cv%NOTFOUND;
3212    end loop;
3213 
3214 
3215 l_resource_elig_table_idx := l_resource_elig_table.first;
3216 l_flat_table_idx := 0;
3217 
3218 while (l_resource_elig_table_idx is not null)
3219 loop
3220 
3221 	l_current_resource_id := l_resource_elig_table(l_resource_elig_table_idx).criteria_id;
3222 
3223 	-- populate the flat table;
3224 	l_flat_table(l_flat_table_idx).pref_hier_id := l_resource_elig_table(l_resource_elig_table_idx).pref_hier_id;
3225 	l_flat_table(l_flat_table_idx).reo := l_resource_elig_table(l_resource_elig_table_idx).reo;
3226 	l_flat_table_idx := l_flat_table_idx + 1;
3227 
3228 	if(l_resource_elig_table.next(l_resource_elig_table_idx) is not null and
3229 	   l_resource_elig_table(l_resource_elig_table.next(l_resource_elig_table_idx)).criteria_id = l_current_resource_id) then
3230 
3231 		-- If there are still rules associated to this resource, then fetch them into flat table before processing
3232 		l_resource_elig_table_idx := l_resource_elig_table.next(l_resource_elig_table_idx);
3233 
3234 	-- The flat table now has all the rules associated to the current resource_id. Hence process.
3235 	else
3236 
3237 		l_matches := 0;
3238 
3239 		l_pref_sets_index_table_idx := l_pref_sets_index_table.first;
3240 		while (l_pref_sets_index_table_idx is not null)
3241 		loop
3242 
3243 			l_flat_table_idx := l_flat_table.first;
3244 
3245 			for l_index in l_pref_sets_index_table(l_pref_sets_index_table_idx).set_start .. l_pref_sets_index_table(l_pref_sets_index_table_idx).set_stop
3246 			loop
3247 				-- if all entries in the flat table match sets-table but number of entries in flat and sets table is diff, then
3248 
3249 				if (l_flat_table_idx is null) then
3250 					--  Flat table no data or is exhausted
3251 					l_matches := 0;
3252 					exit;
3253 				end if;
3254 				l_matches := 1;
3255 				if (l_pref_sets_table(l_index).pref_hier_id <> l_flat_table(l_flat_table_idx).pref_hier_id or
3256 				l_pref_sets_table(l_index).reo <> l_flat_table(l_flat_table_idx).reo) then
3257 				-- No match with the current set. Check the next set.
3258 
3259 					l_matches := 0;
3260 					exit;
3261 
3262 				end if;
3263 				l_flat_table_idx := l_flat_table.next(l_flat_table_idx);
3264 
3265 			end loop;
3266 
3267 
3268 			-- Case where match found for avaliable entries..but number of entries not same
3269 			if ((l_index is null and l_flat_table_idx is not null) or (l_index is not null and l_flat_table_idx is null)) then
3270 				l_matches := 0;
3271 			end if;
3272 
3273 			if (l_matches = 1) then
3274 			-- Found the matching set and hence the preference values
3275 			-- Update the Out table p_resource_pref_table
3276 
3277 				p_resource_pref_table(l_current_resource_id).start_index := l_pref_sets_index_table(l_pref_sets_index_table_idx).result_start;
3278 
3279 				p_resource_pref_table(l_current_resource_id).stop_index := l_pref_sets_index_table(l_pref_sets_index_table_idx).result_stop;
3280 
3281 				exit;
3282 			end if;
3283 
3284 			l_pref_sets_index_table_idx := l_pref_sets_index_table.next(l_pref_sets_index_table_idx);
3285 		end loop;
3286 
3287 		-- if no match found, then need to evaluate preferences.
3288 		if (l_matches = 0) then
3289 			-- Call preference evaluation proc
3290 			hxc_preference_evaluation.resource_preferences(
3291 			                         p_resource_id =>l_current_resource_id,
3292                                                  p_evaluation_date =>p_evaluation_date,
3293                                                  p_pref_table =>l_eval_pref_table,
3294 						 p_ignore_user_id => true,
3295 						 p_ignore_resp_id => true);
3296 
3297 			-- 1. Add the Pref-REO set of this resource into l_pref_sets table
3298 			l_flat_table_idx := l_flat_table.first;
3299 			l_pref_sets_table_idx := l_pref_sets_table.last + 1;
3300 			if (l_pref_sets_table.last is null) then
3301 				l_pref_sets_table_idx := 0;
3302 			end if;
3303 
3304 			l_set_start := l_pref_sets_table_idx;
3305 			while(l_flat_table_idx is not null)
3306 			loop
3307 				l_pref_sets_table(l_pref_sets_table_idx).pref_hier_id := l_flat_table(l_flat_table_idx).pref_hier_id;
3308 
3309 				l_pref_sets_table(l_pref_sets_table_idx).reo := l_flat_table(l_flat_table_idx).reo;
3310 
3311 				l_pref_sets_table_idx := l_pref_sets_table_idx + 1;
3312 				l_flat_table_idx := l_flat_table.next(l_flat_table_idx);
3313 			end loop;
3314 			l_set_stop := l_pref_sets_table_idx - 1;
3315 
3316 			-- 2. Add Preference Values into Out table p_pref_table
3317 			l_eval_pref_table_idx := l_eval_pref_table.first;
3318 			l_pref_table_idx := p_pref_table.last + 1;
3319 			if (l_pref_table_idx is null) then
3320 				l_pref_table_idx  := 0;
3321 			end if;
3322 
3323 			l_result_start := l_pref_table_idx;
3324 			while (l_eval_pref_table_idx is not null)
3325 			loop
3326 				p_pref_table(l_pref_table_idx) := l_eval_pref_table(l_eval_pref_table_idx);
3327 
3328 				l_eval_pref_table_idx := l_eval_pref_table.next(l_eval_pref_table_idx);
3329 				l_pref_table_idx := l_pref_table_idx + 1;
3330 			end loop;
3331 			l_result_stop := l_pref_table_idx - 1;
3332 
3333 			-- 3. Update the sets_index table
3334 			l_pref_sets_index_table_idx := l_pref_sets_index_table.last + 1;
3335 			if (l_pref_sets_index_table_idx is null) then
3336 				l_pref_sets_index_table_idx := 0;
3337 			end if;
3338 			l_pref_sets_index_table(l_pref_sets_index_table_idx).set_start := l_set_start;
3339 			l_pref_sets_index_table(l_pref_sets_index_table_idx).set_stop := l_set_stop;
3340 			l_pref_sets_index_table(l_pref_sets_index_table_idx).result_start := l_result_start;
3341 			l_pref_sets_index_table(l_pref_sets_index_table_idx).result_stop := l_result_stop;
3342 
3343 			-- 4. Update the Out table p_resource_pref_table
3344 			p_resource_pref_table(l_current_resource_id).start_index := l_result_start;
3345 			p_resource_pref_table(l_current_resource_id).stop_index := l_result_stop;
3346 		end if;
3347 
3348 
3349 		-- The current resource has been processed. So delete the l_flat_table for fresh data to be populated.
3350 
3351 		l_flat_table.delete;
3352 		l_flat_table_idx := 0;
3353 
3354 		-- Fetch data for the next resource
3355 		l_resource_elig_table_idx := l_resource_elig_table.next(l_resource_elig_table_idx);
3356 	end if;
3357 end loop;
3358 
3359 end resource_prefs_bulk;
3360 
3361 function return_version_id
3362 		(p_criteria  hxc_resource_rules.eligibility_criteria_id%TYPE,
3363          p_eligibility_type hxc_resource_rules.eligibility_criteria_type%TYPE)
3364 		return number is
3365 
3366 cursor c_version_id(p_number number) is
3367 select   org_structure_version_id
3368   from   per_org_structure_versions
3369             where organization_structure_id  = p_number
3370             and   trunc(sysdate) between nvl(date_from,trunc(sysdate)) and
3371                   nvl(date_to,sysdate);
3372 
3373 l_version_id number;
3374 l_number number;
3375 
3376 begin
3377 
3378 if (p_eligibility_type = 'ROLLUP')  then
3379 
3380 l_number:=to_number(p_criteria);
3381 --Caching logic implemented to improve the performance. If the output for
3382 --given input value exists in global table and not older than 30 second,
3383 --then return the output from global table else hit back the query
3384 --against DB to fetch the output and store the value in global table
3385 --for next reference,,if required-.
3386 
3387 if(g_str_version.exists(l_number)
3388    and (sysdate-g_str_version(l_number).time_info)*24*60*60<30) then
3389 return g_str_version(l_number).org_version_id;
3390 end if;
3391 
3392 
3393 open c_version_id(l_number);
3394 fetch c_version_id into l_version_id;
3395      if(c_version_id %found) then
3396      close c_version_id ;
3397 	g_str_version(l_number).org_version_id:=l_version_id;
3398 	g_str_version(l_number).time_info:=sysdate;
3399         return l_version_id;
3400      else
3401      close c_version_id ;
3402 	g_str_version(l_number).org_version_id:=null;
3403 	g_str_version(l_number).time_info:=sysdate;
3404 	return null;
3405      end if;
3406 
3407 else
3408   return null;
3409 end if;
3410 
3411 end return_version_id;
3412 --==================================================================
3413 FUNCTION get_tc_resp (	p_resource_id NUMBER,
3414 			p_evaluation_date DATE)
3415 RETURN NUMBER
3416 IS
3417 cursor get_resp_id(p_resource_id IN NUMBER, p_evaluation_date IN DATE) is
3418 SELECT  ta.attribute4 , ta.attribute3
3419 from HXC_TIME_ATTRIBUTES ta, HXC_TIME_ATTRIBUTE_USAGES tau, hxc_latest_details ld, hxc_timecard_summary tbd
3420 where ta.time_attribute_id = tau.time_attribute_id
3421 and tau.time_building_block_id = ld.time_building_block_id
3422 and tau.time_building_block_ovn = ld.object_version_number
3423 and ld.resource_id = p_resource_id
3424 and p_evaluation_date between trunc(tbd.START_TIME) and trunc(tbd.STOP_TIME)
3425 and tbd.resource_id = p_resource_id
3426 and trunc(ld.start_time) <= trunc(tbd.STOP_TIME)
3427 and trunc(ld.stop_time) >= trunc(tbd.start_time)
3428 and ta.attribute_category = 'SECURITY'
3429 --and tbd.scope = 'TIMECARD'
3430 order by ld.last_update_date DESC;
3431 resp_id VARCHAR2(100);
3432 l_tc_user_id   VARCHAR2(150);
3433 l_tc_employee_id  NUMBER;
3434 CURSOR get_employee_id(p_user_id IN Number) Is
3435   Select employee_id from fnd_user
3436   Where user_id = p_user_id;
3437 BEGIN
3438 	g_debug := hr_utility.debug_enabled;
3439 	if g_debug then
3440 		hr_utility.set_location ('Starting get_tc_resp' , 10 );
3441 	end if;
3442 	OPEN get_resp_id (p_resource_id,p_evaluation_date);
3443 	FETCH get_resp_id into resp_id, l_tc_user_id;
3444 	close get_resp_id;
3445 	open get_employee_id(l_tc_user_id);
3446 	Fetch get_employee_id into l_tc_employee_id;
3447 	Close get_employee_id;
3448 	IF  p_resource_id = l_tc_employee_id then
3449 		if g_debug then
3450 			hr_utility.set_location ('Returning resp_id =' || resp_id, 20 );
3451 			hr_utility.set_location ('Returning l_tc_employee_id =' || l_tc_employee_id, 20 );
3452 		end if;
3453 		return to_number(resp_id);
3454 	ELSE
3455 		hr_utility.set_location ('Returning resp_id = -101' , 20 );
3456 		return(-101);
3457 	END IF;
3458 	if g_debug then
3459 		hr_utility.set_location ('Stopping get_tc_resp' , 30 );
3460 	end if;
3461 EXCEPTION
3462 	WHEN NO_DATA_FOUND THEN
3463 		hr_utility.set_location ('Resp_id not found in Security attribute ' || resp_id || 'for resource ' || p_resource_id , 40 );
3464 	 	RETURN(-101);
3465 	WHEN INVALID_NUMBER THEN
3466 		hr_utility.set_location ('Invalid Number Value found in resp_id ' || resp_id || 'for resource ' || p_resource_id , 40 );
3467 		RETURN(-101);
3468 END get_tc_resp;
3469 
3470 
3471 
3472 
3473 --================================================================================
3474 
3475 PROCEDURE get_tc_resp (	p_resource_id IN NUMBER,
3476 			p_start_evaluation_date IN DATE,
3477 			p_end_evaluation_date IN DATE,
3478 			p_resp_id OUT NOCOPY NUMBER,
3479 			p_resp_appl_id OUT NOCOPY NUMBER)
3480 IS
3481 
3482 
3483 
3484 cursor get_latest_detail_bbid (p_resource_id IN NUMBER, p_start_evaluation_date IN DATE, p_end_evaluation_date DATE) is
3485 SELECT ld.time_building_block_id, ld.object_version_number
3486 from hxc_latest_details ld
3487 WHERE ld.resource_id = p_resource_id
3488 and trunc(ld.start_time) <= trunc(p_end_evaluation_date)
3489 and trunc(ld.stop_time) >= trunc(p_start_evaluation_date)
3490 order by ld.last_update_date DESC;
3491 
3492 cursor get_resp_id (detail_building_block_id IN NUMBER, detail_builiding_block_ovn IN NUMBER) IS
3493 SELECT ta.attribute4, ta.attribute5, ta.attribute3
3494 FROM HXC_TIME_ATTRIBUTES ta, HXC_TIME_ATTRIBUTE_USAGES tau
3495 WHERE   ta.attribute_category = 'SECURITY'
3496 	and ta.time_attribute_id = tau.time_attribute_id
3497 	and tau.time_building_block_id = detail_building_block_id
3498 	and tau.time_building_block_ovn = detail_builiding_block_ovn;
3499 
3500 
3501 
3502 resp_id VARCHAR2(100);
3503 resp_appl_id VARCHAR2(100);
3504 l_tc_user_id   VARCHAR2(150);
3505 l_tc_employee_id  NUMBER;
3506 CURSOR get_employee_id(p_user_id IN Number) Is
3507   Select employee_id from fnd_user
3508   Where user_id = p_user_id;
3509 
3510 
3511 
3512 Cursor get_tc_start_stop(  p_resource_id IN NUMBER, l_detail_building_block_id IN NUMBER, detail_builiding_block_ovn IN NUMBER) is
3513 select START_TIME, STOP_TIME, DATE_TO from hxc_time_building_blocks t
3514 where scope = 'TIMECARD' AND
3515       resource_id =p_resource_id
3516 connect by  prior parent_building_block_id = time_building_block_id
3517 	and prior parent_building_block_ovn = object_version_number
3518 start with time_building_block_id = l_detail_building_block_id
3519 	and object_version_number = detail_builiding_block_ovn
3520 order by time_building_block_id asc, object_version_number desc;
3521 
3522 l_detail_building_block_id	NUMBER;
3523 l_detail_building_block_ovn	NUMBER;
3524 l_tc_start_time			DATE;
3525 l_tc_stop_time			DATE;
3526 l_tc_date_to			DATE;
3527 
3528 
3529 BEGIN
3530 	g_debug := hr_utility.debug_enabled;
3531 	if g_debug then
3532 		       	hr_utility.set_location ('Starting get_tc_resp' , 40 );
3533 	end if;
3534 
3535 
3536 
3537 	OPEN get_latest_detail_bbid (p_resource_id,p_start_evaluation_date,p_end_evaluation_date );
3538 	FETCH get_latest_detail_bbid into l_detail_building_block_id, l_detail_building_block_ovn ;
3539 	close get_latest_detail_bbid;
3540 
3541 	/*OPEN get_resp_id (p_resource_id,p_start_evaluation_date,p_end_evaluation_date );
3542 	FETCH get_resp_id into resp_id, resp_appl_id, l_tc_user_id,l_detail_building_block_id, l_detail_building_block_ovn ;
3543 	close get_resp_id;*/
3544 
3545 
3546 
3547 
3548 	OPEN get_tc_start_stop(p_resource_id, l_detail_building_block_id, l_detail_building_block_ovn);
3549 	FETCH get_tc_start_stop INTO l_tc_start_time, l_tc_stop_time,l_tc_date_to;
3550 	CLOSE get_tc_start_stop;
3551 
3552 	IF trunc(l_tc_start_time) = trunc(p_start_evaluation_date)
3553 		AND trunc(l_tc_stop_time) = trunc(p_end_evaluation_date)
3554 		AND trunc(l_tc_date_to) = trunc(hr_general.end_of_time) THEN
3555 
3556 
3557 		OPEN get_resp_id (l_detail_building_block_id, l_detail_building_block_ovn );
3558 		FETCH get_resp_id into resp_id, resp_appl_id, l_tc_user_id;
3559 		close get_resp_id;
3560 
3561 
3562 		open get_employee_id(l_tc_user_id);
3563 		Fetch get_employee_id into l_tc_employee_id;
3564 		Close get_employee_id;
3565 
3566 
3567 		IF p_resource_id = l_tc_employee_id then
3568 
3569 			--return to_number(resp_id);
3570 			p_resp_id := to_number(resp_id);
3571 			p_resp_appl_id := to_number(resp_appl_id);
3572 
3573 
3574 			if g_debug then
3575 				hr_utility.set_location ('Returning resp_id =' || resp_id, 50 );
3576 				hr_utility.set_location ('Returning resp_appl_id =' || resp_appl_id, 50 );
3577 			end if;
3578 
3579 		ELSE
3580 			p_resp_id := -101;
3581 			p_resp_appl_id := to_number(fnd_global.resp_appl_id);
3582 			if g_debug then
3583 				hr_utility.set_location ('Returning resp_id =' || p_resp_id, 55 );
3584 				hr_utility.set_location ('Returning resp_appl_id =' || p_resp_appl_id, 55 );
3585 			end if;
3586 		END IF;
3587 	ELSE
3588 
3589 
3590 		p_resp_id := to_number(fnd_global.resp_id);
3591 		p_resp_appl_id := to_number(fnd_global.resp_appl_id);
3592 
3593 		if g_debug then
3594 			hr_utility.set_location ('10 Returning resp_id =' || p_resp_id, 58 );
3595 			hr_utility.set_location ('10 Returning resp_appl_id =' || p_resp_appl_id, 58 );
3596 		end if;
3597 
3598 	END IF;
3599 
3600 
3601 	if g_debug then
3602 		hr_utility.set_location ('Stopping get_tc_resp' , 60 );
3603 	end if;
3604 EXCEPTION
3605 	WHEN NO_DATA_FOUND THEN
3606 		p_resp_id := -101;
3607 		p_resp_appl_id := to_number(fnd_global.resp_appl_id);
3608 	WHEN INVALID_NUMBER THEN
3609 		p_resp_id := -101;
3610 		p_resp_appl_id := to_number(fnd_global.resp_appl_id);
3611 		hr_utility.set_location ('Invalid Number Value found in resp_id ' || resp_id || 'for resource ' || p_resource_id , 70 );
3612 END get_tc_resp;
3613 
3614 
3615 
3616 
3617 
3618 -- PROCEDURE get_tc_resp
3619 -- Returns a PL/SQL table structure holding the timecard start and
3620 -- stop dates and the last touched responsibility for that timecard.
3621 -- Overloaded from get_tc_resp used above, but this version is used
3622 -- for actual persistent responsibility evaluation.
3623 
3624 
3625 PROCEDURE get_tc_resp (	p_resource_id           IN  NUMBER,
3626 			p_start_evaluation_date IN  DATE,
3627 			p_end_evaluation_date   IN  DATE,
3628                         p_resplist              OUT NOCOPY resplisttab )
3629 IS
3630 
3631 
3632 
3633   -- The below cursor would return all the timecard start, stop
3634   -- dates within the given range. The WHERE clause looks at
3635   -- the passed in resource_id, and start and end evaluation
3636   -- dates. Since we anyway have to do this, why not pull out
3637   -- the last touched time building block id and ovn ?
3638   -- The RANK function will partition based on resource_id,
3639   -- start_time and stop_time, meaning for a logical timecard
3640   -- structure for a resource, it will rank the available records
3641   -- based on these -- and we identify one valid timecard per
3642   -- resource_id-start_time-stop_time combination in the system.
3643   -- The Rank is determined ordering by date_to, tbb_id, and ovn
3644   -- This means that the first record out there would be the
3645   -- latest timecard, hence the outer query is looking at only
3646   -- the first rank.
3647   -- Since the rank is partitioned on resource_id, start_time
3648   -- and stop_time, we would get only one record even if there
3649   -- are multiple deletions and resubmissions for the same
3650   -- time periods -- we always get the latest one.
3651 
3652 
3653 
3654   CURSOR get_time_periods ( p_resource_id           NUMBER,
3655                             p_start_evaluation_date DATE,
3656                             p_end_evaluation_date   DATE )
3657       IS SELECT timecard_id,
3658                 timecard_ovn,
3659                 start_time,
3660                 stop_time,
3661                 date_to
3662            FROM ( SELECT time_building_block_id timecard_id,
3663                          object_version_number timecard_ovn,
3664 	                 start_time,
3665 	                 stop_time,
3666 	                 date_to,
3667     	                 RANK() OVER ( PARTITION BY resource_id,
3668     	                                            start_time,
3669     	                                            stop_time
3670 	                                   ORDER BY date_to DESC,
3671 	                                            time_building_block_id DESC,
3672 	                                            object_version_number DESC ) rank
3673                     FROM hxc_time_building_blocks
3674                    WHERE resource_id       = p_resource_id
3675                      AND scope             = 'TIMECARD'
3676                      AND TRUNC(start_time) BETWEEN p_start_evaluation_date
3677                                                AND p_end_evaluation_date
3678                      AND TRUNC(stop_time)  BETWEEN p_start_evaluation_date
3679                                                AND p_end_evaluation_date
3680                 )
3681           WHERE rank = 1;
3682 
3683 
3684   -- This cursor pulls out the SECURITY attribute values
3685   -- for the given time_building_block_id and OVN.
3686 
3687 
3688   CURSOR get_tc_resp_id ( p_timecard_id  NUMBER,
3689                           p_timecard_ovn NUMBER )
3690       IS SELECT ha.attribute4,
3691                 ha.attribute5,
3692                 ha.attribute3
3693            FROM hxc_time_attribute_usages hau,
3694                 hxc_time_attributes       ha
3695           WHERE hau.time_building_block_id  = p_timecard_id
3696             AND hau.time_building_block_ovn = p_timecard_ovn
3697             AND ha.time_attribute_id        = hau.time_attribute_id
3698             AND attribute_category = 'SECURITY' ;
3699 
3700 
3701   -- This cursor would pull out SECURITY attributes for
3702   -- the latest updated detail from hxc_latest_details.
3703   -- We pick only one record from the below cursor, the first
3704   -- one when its ordered Descending based on last_update_date.
3705 
3706   -- Bug 12700547
3707   -- Added hints.
3708 
3709   CURSOR get_tc_det_resp_id ( p_resource_id NUMBER,
3710                               p_start_date  DATE,
3711                               p_stop_date   DATE )
3712       IS SELECT /*+ LEADING(hld)
3713                     INDEX(hld hxc_lastest_details_n3) */
3714                 ha.attribute4,
3715                 ha.attribute5,
3716                 ha.attribute3
3717            FROM hxc_time_attribute_usages hau,
3718                 hxc_time_attributes       ha,
3719                 hxc_latest_details        hld
3720           WHERE hld.resource_id              = p_resource_id
3721             AND TRUNC(hld.start_time)       >= p_start_date
3722             AND TRUNC(hld.stop_time)        <= TRUNC(p_stop_date)
3723             AND hau.time_building_block_id   = hld.time_building_block_id
3724             AND hau.time_building_block_ovn  = hld.object_version_number
3725             AND hau.time_attribute_id        = ha.time_attribute_id
3726             AND attribute_category           = 'SECURITY'
3727             ORDER BY hld.last_update_date DESC ;
3728 
3729 
3730   CURSOR get_user_person_id ( p_user_id  NUMBER )
3731       IS SELECT employee_id
3732            FROM fnd_user
3733           WHERE user_id = p_user_id;
3734 
3735   TYPE time_periodsrec IS RECORD
3736   (  timecard_id   NUMBER,
3737      timecard_ovn  NUMBER,
3738      start_time    DATE,
3739      stop_time     DATE,
3740      date_to       DATE ) ;
3741 
3742   TYPE time_periodstab IS TABLE OF time_periodsrec ;
3743 
3744   time_periods  time_periodstab;
3745 
3746   l_resp_id    NUMBER;
3747   l_user_id    NUMBER;
3748   l_resp_appln_id NUMBER;
3749   l_resource_id   NUMBER;
3750 
3751   resplist resplisttab := resplisttab () ;
3752 
3753   cnt  NUMBER;
3754 
3755 
3756 
3757 
3758 BEGIN
3759 	-- Public Procedure get_tc_resp
3760 	-- Takes in the resource_id for whom the process is executed
3761 	--    and the evaluation start and end dates.
3762 	-- Get the valid time periods from hxc_time_building_blocks
3763 	--    table falling within the given start and end dates for
3764 	--    evaluation. Need to consider only those periods which
3765 	--    fall within the given range, not the ones crossing over
3766 	--    the boundaries, because Persistent responsibility can
3767 	--    be evaluated only when the whole timecard is looked at.
3768 	--    While the time periods ( timecard start dates and stop dates
3769 	--    are picked up, also pick up the latest OVNs and tbb ids
3770 	--    for each tc start- stop times.
3771 	-- If the last touched upon timecard record is deleted, there
3772 	--    is no point in looking at latest details, rather look
3773 	--    into the timecard record's SECURITY attributes.
3774 	-- If the last touched upon timecard is still live look at
3775 	--    HXC_LATEST_DETAILS table to find out who touched the
3776 	--    timecard last and get the SECURITY attribute.
3777 	-- Get the resource_id attached to the user.
3778 	-- If its the same resource_id as the parameter of this procedure
3779 	--    it means its the employee himself, and we need his
3780 	--    persistent responsibility preferences. Record the fetched
3781 	--    responsibility ids and periods into the data structure.
3782 	-- If its somebody else, it is a Time Keeper or a Line Manager
3783 	--    or an Authorized Delegate, never mind his preferences;
3784 	--    put down -1 for responsibilities.
3785 	-- Repeat the above steps for all the valid time periods
3786 	--    ( timecard start-stop dates in the given date range)
3787 	--
3788 
3789 
3790 
3791 	IF g_debug
3792 	THEN
3793            hr_utility.trace ('get_tc_resp');
3794 	END IF;
3795 
3796 	OPEN get_time_periods ( p_resource_id           => p_resource_id,
3797 	                        p_start_evaluation_date => p_start_evaluation_date,
3798 	                        p_end_evaluation_date   => p_end_evaluation_date ) ;
3799 
3800         FETCH get_time_periods
3801          BULK COLLECT INTO time_periods ;
3802 
3803         CLOSE get_time_periods;
3804 
3805         cnt := 0;
3806 
3807         IF time_periods.COUNT > 0
3808         THEN
3809            FOR i IN time_periods.FIRST..time_periods.LAST
3810            LOOP
3811 
3812                -- For all the available time periods and tbb_ids and OVNs
3813                -- last updated for those time periods, check if the last
3814                -- updation was a deletion -- meaning there would not be
3815                -- end of time in the date_to column. For these timecards,
3816                -- neednt go to details, just get the responsibility which
3817                -- deleted the timecard.
3818 
3819                IF time_periods(i).date_to <> hr_general.end_of_time
3820                THEN
3821                       OPEN get_tc_resp_id( time_periods(i).timecard_id,
3822                                            time_periods(i).timecard_ovn );
3823                       FETCH get_tc_resp_id
3824                        INTO l_resp_id,
3825                             l_resp_appln_id,
3826                             l_user_id ;
3827                       CLOSE get_tc_resp_id;
3828 
3829 
3830 	       -- For others, you have to go to the details and find
3831 	       -- out which one was last modified. You take only one
3832 	       -- record -- meaning, even if there are multiple records
3833 	       -- out there, we take only the last one for each timecard.
3834 
3835                ELSE
3836                       OPEN get_tc_det_resp_id ( p_resource_id,
3837                                                 time_periods(i).start_time,
3838                                                 time_periods(i).stop_time) ;
3839                       FETCH get_tc_det_resp_id
3840                        INTO l_resp_id,
3841                             l_resp_appln_id,
3842                             l_user_id ;
3843 
3844                       CLOSE get_tc_det_resp_id;
3845                END IF;
3846 
3847                OPEN get_user_person_id( l_user_id );
3848 
3849                FETCH get_user_person_id
3850                 INTO l_resource_id ;
3851 
3852                CLOSE get_user_person_id ;
3853 
3854 
3855 
3856                resplist.EXTEND(1);
3857                cnt := cnt + 1;
3858 
3859                -- Only if the person who touched the timecard last is
3860                -- the same person to whom the timecard belongs to, need
3861                -- the responsibility be recorded. Else record -1.
3862                IF l_resource_id = p_resource_id
3863                THEN
3864                   resplist(cnt).resp_id          := l_resp_id;
3865                   resplist(cnt).start_date       := time_periods(i).start_time ;
3866                   resplist(cnt).stop_date        := time_periods(i).stop_time;
3867                ELSE
3868                   resplist(cnt).resp_id          := -1 ;
3869                   resplist(cnt).start_date       := time_periods(i).start_time ;
3870                   resplist(cnt).stop_date        := time_periods(i).stop_time;
3871                END IF;
3872 
3873                l_resp_id       := NULL;
3874                l_user_id       := NULL;
3875                l_resp_appln_id := NULL;
3876 
3877            END LOOP;
3878 
3879         END IF;
3880 
3881 
3882         -- Return the responsibility table to resource_preferences.
3883         p_resplist  := resplist;
3884 
3885 
3886 
3887 END get_tc_resp;
3888 
3889 
3890 
3891 
3892 
3893 
3894 
3895 FUNCTION resource_preferences(p_resource_id        IN NUMBER,
3896                               p_pref_code          IN VARCHAR2,
3897                               p_attribute_n        IN NUMBER,
3898                               p_resp_id 	   IN NUMBER  )
3899 RETURN VARCHAR2 IS
3900 l_pref_table t_pref_table;
3901 l_table_mask t_requested_pref_list;
3902 l_first NUMBER;
3903 BEGIN
3904 RETURN resource_preferences(p_resource_id,p_pref_code,p_attribute_n,SYSDATE,p_resp_id);
3905 END resource_preferences;
3906 --===============================================
3907 
3908 END hxc_preference_evaluation;
3909