DBA Data[Home] [Help]

PACKAGE BODY: APPS.AP_WEB_POLICY_UTILS

Source


1 PACKAGE BODY AP_WEB_POLICY_UTILS AS
2 /* $Header: apwpolub.pls 120.82.12020000.10 2013/03/14 10:05:24 ramnagar ship $ */
3 
4   -- Max Length for Policy Schedule Name and Policy Schedule Period Name
5   C_PolicyNameMaxLength          CONSTANT NUMBER := 60;
6 
7     TYPE hr_assignment_rec IS RECORD (person_id    per_employees_x.employee_id%type,
8                                       eff_start_date per_all_assignments_f.effective_start_date%type,
9                                       eff_end_date   per_all_assignments_f.effective_end_date%type,
10                                       grade_id       per_all_assignments_f.grade_id%type,
11                                       job_id         per_all_assignments_f.job_id%type,
12                                       position_id    per_all_assignments_f.position_id%type);
13 
14     TYPE hr_assignment_cache_type IS TABLE OF hr_assignment_rec;
15     hr_assignment_cache hr_assignment_cache_type;
16 
17 
18 /*========================================================================
19  | PRIVATE FUNCTION getHrAssignmentFromDB
20  |
21  | DESCRIPTION
22  | Helper function to retrieve HR assignment info from HR tables.
23  |
24  | PARAMETERS
25  |    p_person_id  -- Expense Type ID associated to the expense
26  |    p_date       -- Assignment date.
27  | RETURNS
28  |   hr_assignment_rec  -- A record of the employee's assignment
29  |                      -- as of the given date.
30  |
31  | MODIFICATION HISTORY
32  | Date                  Author            Description of Changes
33  | 21-Feb-2006           albowicz          Created
34  |
35  *=======================================================================*/
36     FUNCTION getHrAssignmentFromDB(p_person_id IN per_employees_x.employee_id%type,
37                                    p_date      IN DATE) RETURN hr_assignment_rec IS
38         ret_val hr_assignment_rec;
39     BEGIN
40         -- Bug: 8449406 -- Bug: 16283731
41         SELECT * INTO ret_val FROM (
42             SELECT p_person_id, effective_start_date, effective_end_date, grade_id, job_id, position_id
43             FROM per_all_assignments_f ass,
44                  per_employees_x P
45             WHERE P.EMPLOYEE_ID = p_person_id
46               AND ass.assignment_id = P.assignment_id
47               AND NOT AP_WEB_DB_HR_INT_PKG.isPersonCwk(P.employee_id)='Y'
48               AND p_date >= effective_start_date and p_date <= effective_end_date
49               AND ass.assignment_type = 'E'
50             UNION ALL
51             SELECT p_person_id, effective_start_date, effective_end_date, grade_id, job_id, position_id
52             FROM per_all_assignments_f ass,
53                  per_cont_workers_x P
54             WHERE P.PERSON_ID = p_person_id
55               AND ass.assignment_id = p.assignment_id
56               AND p_date >= effective_start_date and p_date <= effective_end_date
57               AND ass.assignment_type = 'C')
58         WHERE ROWNUM = 1;
59 
60         RETURN ret_val;
61     END getHrAssignmentFromDB;
62 
63 
64 /*========================================================================
65  | PRIVATE FUNCTION getHrAssignment
66  |
67  | DESCRIPTION
68  | Helper function to retrieve HR assignment.
69  |
70  | PARAMETERS
71  |    p_person_id  -- Expense Type ID associated to the expense
72  |    p_date       -- Assignment date.
73  | RETURNS
74  |   hr_assignment_rec  -- A record of the employee's assignment
75  |                      -- as of the given date.
76  |
77  | MODIFICATION HISTORY
78  | Date                  Author            Description of Changes
79  | 21-Feb-2006           albowicz          Created
80  |
81  *=======================================================================*/
82     FUNCTION getHrAssignment(p_person_id IN per_employees_x.employee_id%type,
83                              p_date      IN DATE) RETURN hr_assignment_rec IS
84         l_ret_val hr_assignment_rec;
85         l_temp hr_assignment_rec;
86         l_index INTEGER;
87     BEGIN
88 
89         -- First look for the assignment in the session specific cache
90         IF(hr_assignment_cache IS NOT NULL) THEN
91             FOR i IN hr_assignment_cache.FIRST..hr_assignment_cache.LAST LOOP
92                 l_temp := hr_assignment_cache(i);
93                 IF(l_temp.person_id = p_person_id AND p_date between l_temp.eff_start_date and l_temp.eff_end_date) THEN
94                     l_ret_val := l_temp;
95                     exit;
96                 END IF;
97             END LOOP;
98         END IF;
99 
100         -- If not found, the lookup from HR tables.
101         IF(l_ret_val.person_id IS NULL) THEN
102             l_ret_val := getHrAssignmentFromDB(p_person_id,p_date);
103 
104             IF(l_ret_val.person_id IS NOT NULL) THEN
105                 -- Create session specific cache if necessary.
106                 IF(hr_assignment_cache IS NULL) THEN
107                     hr_assignment_cache := hr_assignment_cache_type(l_ret_val);
108                 ELSE
109                     l_index := hr_assignment_cache.LAST +1;
110                     hr_assignment_cache.EXTEND;
111                     hr_assignment_cache(l_index) := l_ret_val;
112                 END IF;
113             END IF;
114         END IF;
115 
116         RETURN l_ret_val;
117     END getHrAssignment;
118 
119 
120 /*========================================================================
121  | PUBLIC PROCEDURE getHrAssignment
122  |
123  | DESCRIPTION
124  | Public helper procedure to retrieve HR assignment.
125  |
126  | PARAMETERS
127  |    p_person_id   -- Expense Type ID associated to the expense
128  |    p_date        -- Assignment date.
129  |    p_grade_id    -- Returns grade id.
130  |    p_position_id -- Returns position id.
131  |    p_job_id      -- Returns job id.
132  |
133  | MODIFICATION HISTORY
134  | Date                  Author            Description of Changes
135  | 22-Feb-2006           albowicz          Created
136  |
137  *=======================================================================*/
138 
139     PROCEDURE getHrAssignment(p_person_id   IN   per_employees_x.employee_id%type,
140                               p_date        IN   DATE,
141                               p_grade_id    OUT  NOCOPY per_all_assignments_f.grade_id%type,
142                               p_position_id OUT  NOCOPY per_all_assignments_f.position_id%type,
143                               p_job_id      OUT  NOCOPY per_all_assignments_f.job_id%type) IS
144 
145     l_hr_assignment hr_assignment_rec;
146     BEGIN
147 
148     l_hr_assignment := getHrAssignment(p_person_id, p_date);
149 
150     IF (l_hr_assignment.person_id IS NOT NULL) THEN
151         p_grade_id    := l_hr_assignment.grade_id;
152         p_position_id := l_hr_assignment.position_id;
153         p_job_id      := l_hr_assignment.job_id;
154     END IF;
155 
156     END getHrAssignment;
157 
158 
159   -- Delcare the private method upfront so that it can be used
160   -- before the definition.
161 
162   PROCEDURE permutatePolicyLines(p_user_id    IN NUMBER,
163                                  p_policy_id  IN ap_pol_headers.policy_id%TYPE,
164                                  p_rate_type  IN ap_pol_schedule_options.rate_type_code%TYPE);
165 
166   PROCEDURE permutateAddonRates( p_user_id IN NUMBER,
167                                  p_policy_id  IN ap_pol_headers.policy_id%TYPE,
168                                  p_schedule_period_id IN ap_pol_lines.schedule_period_id%TYPE );
169 
170   PROCEDURE permutateNightRates( p_user_id IN NUMBER,
171                                  p_policy_id  IN ap_pol_headers.policy_id%TYPE,
172                                  p_schedule_period_id IN ap_pol_lines.schedule_period_id%TYPE );
173 
174   PROCEDURE permutateConusLines( p_user_id IN NUMBER,
175                                  p_policy_id  IN ap_pol_headers.policy_id%TYPE);
176 
177   FUNCTION get_hash_value(p_component1    IN VARCHAR2,
178                           p_component2    IN VARCHAR2,
179                           p_component3    IN VARCHAR2) RETURN NUMBER;
180 
181   -- ------------------------ END PRIVATE METHOD DECLARATION ---------------------
182 
183 /*========================================================================
184  | PUBLIC FUNCTION get_schedule_status
185  |
186  | DESCRIPTION
187  |   This function fetches the status for a given schedule id.
188  |
189  | PSEUDO CODE/LOGIC
190  |
191  | PARAMETERS
192  |   p_policy_id   IN      policy id
193  |
194  | MODIFICATION HISTORY
195  | Date                  Author            Description of Changes
196  | 26-Sep-2002           V Nama            Created w.r.t. bug 2480382
197  | 04-Feb-2004           V Nama            Changed w.r.t. bug 2480382
198  |                                         accounts new lines after activation
199  |
200  *=======================================================================*/
201 FUNCTION get_schedule_status(p_policy_id   IN NUMBER) RETURN VARCHAR2 IS
202 
203   l_meaning      fnd_lookups.meaning%TYPE := '';
204   l_lookup_code  fnd_lookups.lookup_code%TYPE;
205   l_sch_end_date ap_pol_headers.end_date%TYPE;
206   l_no__saved_or_duplicated NUMBER;
207   l_no__active_or_inactive NUMBER;
208   l_no__need_activation NUMBER;
209 
210 BEGIN
211 
212   IF p_policy_id IS NOT NULL THEN
213 
214     SELECT end_date
215     INTO   l_sch_end_date
216     FROM   ap_pol_headers
217     WHERE  policy_id = p_policy_id;
218 
219 	 -- Bug # 7132415
220     IF ( l_sch_end_date IS NOT NULL ) AND ( l_sch_end_date  +
221 	nvl(FND_PROFILE.VALUE('AP_WEB_POLICY_GRACE_PERIOD') , '0') < sysdate ) THEN
222 
223       l_lookup_code := 'INACTIVE';
224 
225     ELSE
226 
227       --get count of lines for various statuses
228       SELECT count(status)
229       INTO   l_no__saved_or_duplicated
230       FROM   ap_pol_lines
231       WHERE  policy_id = p_policy_id
232       AND    ( status = 'SAVED' OR status = 'DUPLICATED' or status ='INVALID' or status = 'NEW' or status = 'VALID');
233 
234 
235       SELECT count(status)
236       INTO   l_no__active_or_inactive
237       FROM   ap_pol_lines
238       WHERE  policy_id = p_policy_id
239       AND    ( status = 'ACTIVE' OR status = 'INACTIVE' );
240 
241 
242       --if schedule was activated earlier
243       --then atleast one line is active and/or inactive
244       --under such case all saved / duplicated lines require activation
245       --there are two source for lines requiring activation
246       --1) new and never activated lines (will have parent_line_id null)
247       --2) old, activated and edited lines (will have parent_line_id not null)
248       --however the breakup is not relevant for this api
249       IF ( l_no__active_or_inactive > 0 ) THEN
250 
251           l_no__need_activation := l_no__saved_or_duplicated;
252 
253       ELSE --no lines require activation
254 
255           l_no__need_activation := 0;
256 
257       END IF;
258 
259 
260 
261       --if schedule was activated earlier and requires activation
262       IF ( l_no__need_activation > 0 ) THEN
263 
264           l_lookup_code := 'PARTIALLY_ACTIVE';
265 
266       --if schedule was activated earlier and does NOT require activation
267       ELSIF ( l_no__active_or_inactive > 0 ) THEN
268 
269           l_lookup_code := 'FULLY_ACTIVE';
270 
271       --default schedule was never activated
272       ELSE
273 
274           l_lookup_code := 'SAVED';
275 
276       END IF;
277 
278 
279     END IF;
280 
281     l_meaning := get_lookup_meaning('OIE_POLICY_SCHEDULE_STATUS',l_lookup_code);
282 
283   END IF;
284 
285  return(l_meaning);
286 
287 EXCEPTION
288  WHEN no_data_found  THEN
289   return(null);
290  WHEN OTHERS THEN
291   raise;
292 END get_schedule_status;
293 
294 /*========================================================================
295  | PUBLIC FUNCTION get_lookup_meaning
296  |
297  | DESCRIPTION
298  |   This function fetches the meaning for a given lookup type and code
299  |   combination. The values are cached, so the SQL is executed only
300  |   once for the session.
301  |
302  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
303  |   BC4J objects
304  |
305  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
306  |   DBMS_UTILITY.get_hash_value
307  |
308  | PARAMETERS
309  |   p_lookup_type   IN      lookup type
310  |   p_lookup_code   IN      Lookup code, which is part of the lookup
311  |                           type in previous parameter
312  |
313  | MODIFICATION HISTORY
314  | Date                  Author            Description of Changes
315  | 08-May-2002           J Rautiainen      Created
316  |
317  *=======================================================================*/
318 FUNCTION get_lookup_meaning(p_lookup_type  IN VARCHAR2,
319                             p_lookup_code  IN VARCHAR2) RETURN VARCHAR2 IS
320   l_meaning fnd_lookups.meaning%TYPE;
321   l_hash_value NUMBER;
322   l_lang	VARCHAR2(500);
323 BEGIN
324 
325   IF p_lookup_code IS NOT NULL AND
326      p_lookup_type IS NOT NULL THEN
327 
328     BEGIN
329       l_lang := USERENV('LANG');
330     EXCEPTION
331       WHEN OTHERS THEN
332        l_lang := 'US';
333     END;
334 
335 
336     l_hash_value := DBMS_UTILITY.get_hash_value(p_lookup_type||'@*?'||p_lookup_code||l_lang,
337                                                 1000,
338                                                 25000);
339 
340     IF pg_lookups_rec.EXISTS(l_hash_value) THEN
341         l_meaning := pg_lookups_rec(l_hash_value);
342     ELSE
343 
344       SELECT meaning
345       INTO   l_meaning
346       FROM   fnd_lookup_values_vl
347       WHERE  lookup_type = p_lookup_type
348         AND  lookup_code = p_lookup_code ;
349 
350       pg_lookups_rec(l_hash_value) := l_meaning;
351 
352     END IF;
353   END IF;
354 
355   return(l_meaning);
356 
357 EXCEPTION
358  WHEN no_data_found  THEN
359   return(null);
360  WHEN OTHERS THEN
361   raise;
362 END get_lookup_meaning;
363 
364 /*========================================================================
365 | PUBLIC FUNCTION get_lookup_description
366 |
367 | DESCRIPTION
368 |   This function fetches the instruction
369 |   for a given lookup type and code  combination.
370 |   The values are cached, so the SQL is executed only
371 |   once for the session.
372 |
373 | PSEUDO CODE/LOGIC
374 |
375 | PARAMETERS
376 |   p_lookup_type   IN      lookup type
377 |   p_lookup_code   IN      Lookup code, which is part of the lookup
378 |                           type in previous parameter
379 |
380 | MODIFICATION HISTORY
381 | Date                  Author            Description of Changes
382 | 27-Oct-2003           R Langi           Created
383 |
384 *=======================================================================*/
385 FUNCTION get_lookup_description(p_lookup_type  IN VARCHAR2,
386                                 p_lookup_code  IN VARCHAR2) RETURN VARCHAR2 IS
387   l_description fnd_lookups.description%TYPE;
388 BEGIN
389 
390   IF p_lookup_code IS NOT NULL AND
391      p_lookup_type IS NOT NULL THEN
392 
393       SELECT description
394       INTO   l_description
395       FROM   fnd_lookup_values_vl
396       WHERE  lookup_type = p_lookup_type
397         AND  lookup_code = p_lookup_code ;
398 
399   END IF;
400 
401   return(l_description);
402 
403 EXCEPTION
404  WHEN no_data_found  THEN
405   return(null);
406  WHEN OTHERS THEN
407   raise;
408 END get_lookup_description;
409 
410 
411 /*========================================================================
412  | PUBLIC FUNCTION get_high_threshold
413  |
414  | DESCRIPTION
415  |   This function return high threshold for a given low value.
416  |
417  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
418  |
419  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
420  |
421  | PARAMETERS
422  |   p_lookup_type   IN      lookup type
423  |
424  | MODIFICATION HISTORY
425  | Date                  Author            Description of Changes
426  | 10-May-2002           J Rautiainen      Created
427  |
428  *=======================================================================*/
429 FUNCTION get_high_threshold(p_policy_id     IN NUMBER,
430                             p_lookup_type   IN VARCHAR2,
431                             p_low_threshold IN NUMBER) RETURN NUMBER IS
432 
433  CURSOR threshold_c IS
434   SELECT threshold
435   FROM ap_pol_schedule_options
436   WHERE option_type = p_lookup_type
437   AND   policy_id   = p_policy_id
438   ORDER BY threshold;
439 
440   previous_threshold NUMBER;
441   counter NUMBER := 0;
442   l_hash_value     NUMBER;
443   l_hash_value2    NUMBER;
444   l_result         NUMBER;
445 
446 BEGIN
447 
448   IF p_policy_id IS NOT NULL AND
449      p_lookup_type IS NOT NULL AND
450      p_low_threshold IS NOT NULL THEN
451 
452     l_hash_value := get_hash_value(to_char(p_policy_id),
453                                    p_lookup_type,
454                                    to_char(p_low_threshold));
455 
456     IF pg_thresholds_rec.EXISTS(l_hash_value) THEN
457       return pg_thresholds_rec(l_hash_value);
458     ELSE
459       FOR threshold_rec IN threshold_c LOOP
460         IF counter > 0 THEN
461 
462           l_hash_value2 := get_hash_value(to_char(p_policy_id),
463                                           p_lookup_type,
464                                           to_char(previous_threshold));
465 
466           pg_thresholds_rec(l_hash_value2) := threshold_rec.threshold;
467         END IF;
468         counter := counter + 1;
469         previous_threshold := threshold_rec.threshold;
470       END LOOP;
471 
472       l_hash_value2 := get_hash_value(to_char(p_policy_id),
473                                       p_lookup_type,
474                                       to_char(previous_threshold));
475       pg_thresholds_rec(l_hash_value2) := NULL;
476 
477     END IF;
478   END IF;
479 
480   IF pg_thresholds_rec.EXISTS(l_hash_value) THEN
481     l_result := pg_thresholds_rec(l_hash_value);
482     return l_result;
483   ELSE
484     return to_number(l_result);
485   END IF;
486 
487 EXCEPTION
488  WHEN OTHERS THEN
489   raise;
490 END get_high_threshold;
491 
492 FUNCTION get_hash_value(p_component1    IN VARCHAR2,
493                         p_component2    IN VARCHAR2,
494                         p_component3    IN VARCHAR2) RETURN NUMBER IS
495 BEGIN
496   RETURN DBMS_UTILITY.get_hash_value(p_component1||'@*?$'||p_component2||'@*?$'||p_component3,
497                                      1000,
498                                      power(2,30)); --Bug#13767259 , 13835177  - Increasing the hash value range
499 
500 EXCEPTION
501  WHEN OTHERS THEN
502   raise;
503 END get_hash_value;
504 
505 /*========================================================================
506  | PUBLIC FUNCTION get_single_org_context
507  |
508  | DESCRIPTION
509  |   This function returns whether user is working in single org context.
510  |
511  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
512  |   Called from BC4J on a logic deciding switcher bean behaviour
513  |
514  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
515  |
516  | RETURNS
517  |   Y  If user is working in single org context
518  |   N  If user is working in single org context
519  |
520  | PARAMETERS
521  |   p_user_id   IN      User Id
522  |
523  | MODIFICATION HISTORY
524  | Date                  Author            Description of Changes
525  | 13-May-2002           J Rautiainen      Created
526  |
527  *=======================================================================*/
528 FUNCTION get_single_org_context(p_user_id IN NUMBER) RETURN VARCHAR2 IS
529 
530   l_count NUMBER;
531 BEGIN
532   SELECT count(1)
533   INTO l_count
534   FROM AP_POL_CONTEXT
535   WHERE user_id = p_user_id;
536 
537  /*-----------------------------------------------------------------*
538   | The query should never return 0, however if 0 is returned it is |
539   | considered as 'N'. This is because the switcher bean will show  |
540   | enterable fields in 'Y' case. If no orgs have been defined to   |
541   | the user we show an empty table for the user is not allowed to  |
542   | enter context information on the fields page.                   |
543   *-----------------------------------------------------------------*/
544   IF l_count = 1 THEN
545     RETURN 'Y';
546   ELSE
547     RETURN 'N';
548   END IF;
549 
550 END get_single_org_context;
551 
552 
553 /*========================================================================
554  | PUBLIC PROCEDURE initialize_user_cat_options
555  |
556  | DESCRIPTION
557  |   This procedure creates category options user context.
558  |
559  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
560  |   Called from BC4J
561  |
562  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
563  |
564  | PARAMETERS
565  |   p_user_id       IN      User Id
566  |   p_category_code IN  Category Code
567  |
568  | MODIFICATION HISTORY
569  | Date                  Author            Description of Changes
570  | 14-May-2002           J Rautiainen      Created
571  |
572  *=======================================================================*/
573 PROCEDURE initialize_user_cat_options(p_user_id       IN NUMBER,
574                                       p_category_code IN VARCHAR2) IS
575 
576   CURSOR user_cat_options_c IS
577     SELECT pco.CATEGORY_OPTION_ID,
578            pco.CATEGORY_CODE,
579            pco.ORG_ID,
580            pc.user_id,
581            pc.selected_org_id
582     FROM AP_POL_CAT_OPTIONS_ALL pco,
583          AP_POL_CONTEXT         pc
584     WHERE pco.org_id(+)        = pc.selected_org_id
585     AND   pco.category_code(+) = p_category_code
586     AND   pc.user_id           = p_user_id;
587 
588 BEGIN
589   FOR user_cat_options_rec IN user_cat_options_c LOOP
590     IF user_cat_options_rec.category_option_id is null THEN
591       INSERT INTO ap_pol_cat_options_all
592              (category_option_id,
593               category_code,
594               org_id,
595               distance_uom,
596               distance_field,
597               destination_field,
598               license_plate_field,
599               attendees_field,
600               attendees_number_field,
601               end_date_field,
602               merchant_field,
603               ticket_class_field,
604               ticket_number_field,
605               location_to_field,
606               location_from_field,
607               creation_date,
608               created_by,
609               last_update_login,
610               last_update_date,
611               last_updated_by)
612       VALUES (AP_POL_CAT_OPTIONS_S.nextval,
613               p_category_code,
614               user_cat_options_rec.selected_org_id,
615               DECODE(p_category_code,
616                      'MILEAGE','KM',
617                      NULL), --distance_uom
618               DECODE(p_category_code,
619                      'MILEAGE','TRIP_DISTANCE',
620                      NULL), --distance_field,
621               DECODE(p_category_code,
622                      'MILEAGE','ENABLED',
623                      NULL), --destination_field,
624               DECODE(p_category_code,
625                      'MILEAGE','DISABLED',
626                      NULL), --license_plate_field,
627               DECODE(p_category_code,
628                      'MEALS','ENABLED',
629                      NULL), --attendees_field,
630               DECODE(p_category_code,
631                      'MEALS','ENABLED',
632                      NULL), --attendees_number_field,
633               DECODE(p_category_code,
634                      'ACCOMMODATIONS','ENABLED',
635                      NULL), --end_date_field,
636               DECODE(p_category_code,
637                      'ACCOMMODATIONS','ENABLED',
638                      'AIRFARE','ENABLED',
639                      'CAR_RENTAL','ENABLED',
640                      NULL), --merchant_field,
641               DECODE(p_category_code,
642                      'AIRFARE','ENABLED',
643                      NULL), --ticket_class_field,
644               DECODE(p_category_code,
645                      'AIRFARE','ENABLED',
646                      NULL), --ticket_number_field,
647               DECODE(p_category_code,
648                      'AIRFARE','ENABLED',
649                      NULL), --location_to_field,
650               DECODE(p_category_code,
651                      'AIRFARE','ENABLED',
652                      NULL), --location_from_field,
653               SYSDATE,
654               p_user_id,
655               NULL,
656               SYSDATE,
657               p_user_id);
658     END IF;
659   END LOOP;
660 
661 END initialize_user_cat_options;
662 
663 /*========================================================================
664  | PUBLIC FUNCTION location_translation_complete
665  |
666  | DESCRIPTION
667  |   This function returns whether all locations have been translated
668  |   for a given language.
669  |
670  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
671  |   Called from BC4J
672  |
673  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
674  |
675  | RETURNS
676  |   Y  If location has been translated for the given language
677  |   N  If location has not been translated for the given language
678  |
679  | PARAMETERS
680  |   p_language_code IN  Language Code
681  |
682  | MODIFICATION HISTORY
683  | Date                  Author            Description of Changes
684  | 21-May-2002           J Rautiainen      Created
685  | 28-Oct-2002           V Nama            bug 2632830
686  |                                         If no loc defined return N
687  |
688  *=======================================================================*/
689 FUNCTION location_translation_complete(p_language_code IN VARCHAR2) RETURN VARCHAR2 IS
690 
691   CURSOR locations_defined_cur IS
692     SELECT 'Y'
693     FROM dual
694     WHERE exists (select 'x' from ap_pol_locations_b);
695   l_locations_defined VARCHAR2(1);
696 
697   CURSOR missing_translations_cur IS
698     SELECT count(1) missing_translation_count
699     FROM ap_pol_locations_tl
700     WHERE language = p_language_code
701     AND   language <> source_lang;
702 
703   missing_translations_rec missing_translations_cur%ROWTYPE;
704 
705 BEGIN
706 
707 --vnama bug 2632830: check if no locations have been defined
708   l_locations_defined:='N';
709 
710   OPEN locations_defined_cur;
711   FETCH locations_defined_cur INTO l_locations_defined;
712   CLOSE locations_defined_cur;
713 
714   IF (l_locations_defined = 'N') THEN
715     RETURN 'N';
716   END IF; --ELSE continue
717 --vnama bug 2632830
718 
719 
720   OPEN missing_translations_cur;
721   FETCH missing_translations_cur INTO missing_translations_rec;
722   CLOSE missing_translations_cur;
723 
724   IF (missing_translations_rec.missing_translation_count = 0) THEN
725     RETURN 'Y';
726   ELSE
727     RETURN 'N';
728   END IF;
729 
730 END location_translation_complete;
731 
732 /*========================================================================
733  | PUBLIC FUNCTION get_employee_name
734  |
735  | DESCRIPTION
736  |   This function returns the employee name for a given user.
737  |
738  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
739  |   Called from BC4J, needed for the LineHistoryVO, which cannot have joins
740  |   due to connect by clause.
741  |
742  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
743  |
744  | RETURNS
745  |   The employee name for the given user. If employee ID is not defined for
746  |   the user, then the username is returned.
747  |
748  | PARAMETERS
749  |   p_user_id IN  User identifier
750  |
751  | MODIFICATION HISTORY
752  | Date                  Author            Description of Changes
753  | 25-May-2002           J Rautiainen      Created
754  | 19-Aug-2004           skoukunt          3838623:replace per_workforce_x
755  |                                         with per_people_x
756  |
757  *=======================================================================*/
758 FUNCTION get_employee_name(p_user_id IN NUMBER) RETURN VARCHAR2 IS
759 
760  /* 2-Oct-2003 J Rautiainen Contingent project changes
761   * This function is used to fetch the name of a employee, regardless of
762   * the status of the employee.
763   * So in this case we need to use per_workforce_x.
764   */
765   CURSOR user_cur IS
766     select DECODE(per.PERSON_ID,
767                   null, usr.USER_NAME,
768                   per.full_name) employee_name
769     from fnd_user usr, per_people_x per
770     where usr.user_id     = p_user_id
771     and   usr.employee_id = per.person_id(+);
772 
773   user_rec user_cur%ROWTYPE;
774 
775 BEGIN
776   IF p_user_id is null THEN
777     return null;
778   END IF;
779 
780   OPEN user_cur;
781   FETCH user_cur INTO user_rec;
782   CLOSE user_cur;
783 
784   return user_rec.employee_name;
785 
786 END get_employee_name;
787 
788 /*========================================================================
789  | PUBLIC FUNCTION get_location
790  |
791  | DESCRIPTION
792  |   This function returns location.
793  |
794  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
795  |   Called from BC4J, needed for the LineHistoryVO, which cannot have joins
796  |   due to connect by clause.
797  |
798  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
799  |
800  | RETURNS
801  |   Location
802  |
803  | PARAMETERS
804  |   p_location_id IN  Location identifier
805  |
806  | MODIFICATION HISTORY
807  | Date                  Author            Description of Changes
808  | 25-May-2002           J Rautiainen      Created
809  |
810  *=======================================================================*/
811 FUNCTION get_location(p_location_id IN NUMBER) RETURN VARCHAR2 IS
812 
813   CURSOR loc_cur IS
814     select location_id, location
815     from  ap_pol_locations_vl
816     where location_type in ('CITY','COUNTRY');
817   l_location varchar2(240);
818 BEGIN
819   IF p_location_id is null THEN
820     return null;
821   END IF;
822 
823   IF pg_locations_rec.EXISTS(p_location_id) THEN
824       return pg_locations_rec(p_location_id);
825   ELSIF pg_locations_rec.COUNT > 1 THEN
826       select location into l_location from ap_pol_locations_vl where location_id = p_location_id;
827       pg_locations_rec(p_location_id) := l_location;
828   ELSE
829       FOR loc_rec IN loc_cur LOOP
830         pg_locations_rec(loc_rec.location_id) := loc_rec.location;
831       END LOOP;
832   END IF;
833 
834   IF pg_locations_rec.EXISTS(p_location_id) THEN
835     return pg_locations_rec(p_location_id);
836   ELSE
837     return null;
838   END IF;
839 
840 END get_location;
841 
842 /*========================================================================
843  | PUBLIC FUNCTION get_currency_display
844  |
845  | DESCRIPTION
846  |   This function returns currency display.
847  |
848  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
849  |   Called from BC4J, needed for
850  |   PolicyLinesVO/PolicyLinesAdvancedSearchCriteriaVO/CurrencyScheduleOptionsVO
851  |
852  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
853  |
854  | RETURNS
855  |   Currency Name||' - '||Currency Code
856  |
857  | PARAMETERS
858  |   p_currency_code IN  Currency Code
859  |
860  | MODIFICATION HISTORY
861  | Date                  Author            Description of Changes
862  | 17-June-2002          R Langi           Created
863  |
864  *=======================================================================*/
865 FUNCTION get_currency_display(p_currency_code IN VARCHAR2) RETURN VARCHAR2 IS
866 
867   CURSOR currency_cur IS
868     select currency_code, name||' - '||currency_code currency_display
869     from   fnd_currencies_vl;
870 
871 BEGIN
872   IF p_currency_code is null THEN
873     return null;
874   END IF;
875 
876   IF pg_currency_rec.EXISTS(p_currency_code) THEN
877       return pg_currency_rec(p_currency_code);
878   ELSE
879       FOR currency_rec IN currency_cur LOOP
880 	pg_currency_rec(currency_rec.currency_code) := currency_rec.currency_display;
881       END LOOP;
882   END IF;
883 
884   IF pg_currency_rec.EXISTS(p_currency_code) THEN
885     return pg_currency_rec(p_currency_code);
886   ELSE
887     return null;
888   END IF;
889 
890 END get_currency_display;
891 
892 /*========================================================================
893  | PUBLIC FUNCTION get_role
894  |
895  | DESCRIPTION
896  |   This function returns role.
897  |
898  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
899  |   Called from BC4J, needed for the LineHistoryVO, which cannot have joins
900  |   due to connect by clause.
901  |
902  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
903  |
904  | RETURNS
905  |   Role
906  |
907  | PARAMETERS
908  |   p_policy_line_id IN  Policy Line identifier
909  |
910  | MODIFICATION HISTORY
911  | Date                  Author            Description of Changes
912  | 25-May-2002           J Rautiainen      Created
913  |
914  *=======================================================================*/
915 FUNCTION get_role(p_policy_line_id IN NUMBER) RETURN VARCHAR2 IS
916 
917   CURSOR policy_cur IS
918     select ph.role_code,
919            pl.role_id
920     from ap_pol_headers ph,
921          ap_pol_lines   pl
922     where pl.policy_id = ph.policy_id
923     and   pl.policy_line_id = p_policy_line_id;
924 
925   policy_rec policy_cur%ROWTYPE;
926 
927 BEGIN
928   IF p_policy_line_id is null THEN
929     return null;
930   END IF;
931 
932   OPEN  policy_cur;
933   FETCH policy_cur INTO policy_rec;
934   CLOSE policy_cur;
935 
936   return get_role(policy_rec.role_code, policy_rec.role_id);
937 
938 END get_role;
939 
940 /*========================================================================
941  | PUBLIC FUNCTION get_role_for_so
942  |
943  | DESCRIPTION
944  |   This function returns role for a schedule option.
945  |
946  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
947  |   Called from BC4J, needed for RoleScheduleOptionsVO/PolicyLinesAdvancedSearchVO
948  |
949  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
950  |
951  | RETURNS
952  |   Role
953  |
954  | PARAMETERS
955  |   p_policy_schedule_option_id IN  Policy Schedule Option identifier
956  |
957  | MODIFICATION HISTORY
958  | Date                  Author            Description of Changes
959  | 17-June-2002          R Langi           Created
960  |
961  *=======================================================================*/
962 FUNCTION get_role_for_so(p_policy_schedule_option_id IN NUMBER) RETURN VARCHAR2 IS
963 
964   CURSOR policy_cur IS
965     select ph.role_code,
966            pso.role_id
967     from ap_pol_headers ph,
968          ap_pol_schedule_options   pso
969     where ph.policy_id = pso.policy_id
970     and   pso.schedule_option_id = p_policy_schedule_option_id;
971 
972   policy_rec policy_cur%ROWTYPE;
973 
974 BEGIN
975   IF p_policy_schedule_option_id is null THEN
976     return null;
977   END IF;
978 
979   OPEN  policy_cur;
980   FETCH policy_cur INTO policy_rec;
981   CLOSE policy_cur;
982 
983   return get_role(policy_rec.role_code, policy_rec.role_id);
984 
985 END get_role_for_so;
986 
987 /*========================================================================
988  | PUBLIC FUNCTION get_role
989  |
990  | DESCRIPTION
991  |   This function returns role.
992  |
993  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
994  |   Called from local overloaded get_role function
995  |
996  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
997  |
998  | RETURNS
999  |   Role
1000  |
1001  | PARAMETERS
1002  |   p_role_code IN  Role Code, one of the following: GRADE, JOB_GROUP, POSITION
1003  |   p_role_id   IN  Location identifier
1004  |
1005  | MODIFICATION HISTORY
1006  | Date                  Author            Description of Changes
1007  | 30-May-2002           J Rautiainen      Created
1008  |
1009  *=======================================================================*/
1010 FUNCTION get_role(p_role_code VARCHAR2, p_role_id IN NUMBER) RETURN VARCHAR2 IS
1011 
1012   CURSOR job_cur IS
1013     select name,
1014            substrb(name,instrb(name,'.',-1)+1) parsed_name
1015     from   per_jobs
1016     where  job_id = p_role_id;
1017 
1018   CURSOR grade_cur IS
1019     select name,
1020            substrb(name,instrb(name,'.',-1)+1) parsed_name
1021     from   per_grades
1022     where  grade_id = p_role_id;
1023 
1024   CURSOR position_cur IS
1025     select name,
1026            substrb(name,instrb(name,'.',-1)+1) parsed_name
1027     from   hr_all_positions_f
1028     where  position_id = p_role_id;
1029 
1030   job_rec      job_cur%ROWTYPE;
1031   grade_rec    grade_cur%ROWTYPE;
1032   position_rec position_cur%ROWTYPE;
1033 
1034 BEGIN
1035 
1036   IF p_role_id is null or p_role_code is null THEN
1037     return null;
1038   END IF;
1039 
1040   IF p_role_id = -1 THEN
1041     return fnd_message.GET_STRING('SQLAP','OIE_ALL_OTHER');
1042   END IF;
1043 
1044   IF p_role_code = 'JOB_GROUP' THEN
1045 
1046     OPEN  job_cur;
1047     FETCH job_cur INTO job_rec;
1048     CLOSE job_cur;
1049 
1050     return job_rec.name;
1051 
1052   ELSIF p_role_code = 'GRADE' THEN
1053 
1054     OPEN  grade_cur;
1055     FETCH grade_cur INTO grade_rec;
1056     CLOSE grade_cur;
1057 
1058     return grade_rec.name;
1059 
1060   ELSIF p_role_code = 'POSITION' THEN
1061 
1062     OPEN  position_cur;
1063     FETCH position_cur INTO position_rec;
1064     CLOSE position_cur;
1065 
1066     return position_rec.name;
1067 
1068   ELSE
1069     return null;
1070   END IF;
1071 
1072 END get_role;
1073 
1074 /*========================================================================
1075  | PUBLIC FUNCTION get_threshold
1076  |
1077  | DESCRIPTION
1078  |   This function returns threshold string.
1079  |
1080  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
1081  |   Called from BC4J, needed for the LineHistoryVO, which cannot have joins
1082  |   due to connect by clause.
1083  |
1084  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
1085  |
1086  | RETURNS
1087  |   Threshold
1088  |
1089  | PARAMETERS
1090  |   p_range_low  IN  Range low threshold
1091  |   p_range_high IN  Range high threshold
1092  |   p_category_code IN  Category Code
1093  |
1094  | MODIFICATION HISTORY
1095  | Date                  Author            Description of Changes
1096  | 25-May-2002           J Rautiainen      Created
1097  |
1098  *=======================================================================*/
1099 FUNCTION get_threshold(p_range_low  IN NUMBER,
1100                        p_range_high IN NUMBER,
1101                        p_category_code IN VARCHAR2) RETURN VARCHAR2 IS
1102 BEGIN
1103   IF     p_range_low is not null
1104      AND p_range_high is not null THEN
1105 
1106    /*------------------------------------------------------------+
1107     | Fetch the message "Between RANGE_LOW and RANGE_HIGH"       |
1108     +------------------------------------------------------------*/
1109     FND_MESSAGE.SET_NAME ('SQLAP', 'OIE_POL_THRESHOLD_BETWEEN');
1110 
1111    /*-------------------------------------------------------+
1112     | Replace tokens with the values passed in as parameter |
1113     +-------------------------------------------------------*/
1114     if (p_category_code = c_MILEAGE and p_range_low <> 0) then
1115       FND_MESSAGE.SET_TOKEN ('RANGE_LOW', p_range_low+.1);
1116     elsif (p_category_code = c_PER_DIEM and p_range_low <> 0) then
1117 --      FND_MESSAGE.SET_TOKEN ('RANGE_LOW', p_range_low+.01);
1118       FND_MESSAGE.SET_TOKEN ('RANGE_LOW',
1119 			     format_minutes_to_hour_minutes(p_range_low+1));
1120     else
1121       FND_MESSAGE.SET_TOKEN ('RANGE_LOW', p_range_low);
1122     end if;
1123 
1124 --    FND_MESSAGE.SET_TOKEN ('RANGE_HIGH' , p_range_high);
1125     if (p_category_code = c_PER_DIEM) then
1126       FND_MESSAGE.SET_TOKEN ('RANGE_HIGH',
1127 			     format_minutes_to_hour_minutes(p_range_high));
1128     else
1129       FND_MESSAGE.SET_TOKEN ('RANGE_HIGH' , p_range_high);
1130     end if;
1131 
1132     return FND_MESSAGE.get;
1133   ELSIF p_range_low is not null THEN
1134 
1135    /*--------------------------------------------------+
1136     | Fetch the message "Greater Than RANGE_LOW"       |
1137     +--------------------------------------------------*/
1138     FND_MESSAGE.SET_NAME ('SQLAP', 'OIE_POL_THRESHOLD_GREATER');
1139 
1140    /*-------------------------------------------------------+
1141     | Replace tokens with the values passed in as parameter |
1142     +-------------------------------------------------------*/
1143     if (p_category_code = c_PER_DIEM) then
1144       FND_MESSAGE.SET_TOKEN ('RANGE_LOW',
1145 			     format_minutes_to_hour_minutes(p_range_low));
1146     else
1147       FND_MESSAGE.SET_TOKEN ('RANGE_LOW', p_range_low);
1148     end if;
1149     return FND_MESSAGE.get;
1150 
1151   ELSE
1152     return null;
1153   END IF;
1154 
1155 END get_threshold;
1156 
1157 /*========================================================================
1158  | PUBLIC PROCEDURE initialize_user_exrate_options
1159  |
1160  | DESCRIPTION
1161  |   This procedure creates exchange rate options user context.
1162  |
1163  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
1164  |   Called from BC4J
1165  |
1166  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
1167  |
1168  | PARAMETERS
1169  |   p_user_id       IN      User Id
1170  |
1171  | MODIFICATION HISTORY
1172  | Date                  Author            Description of Changes
1173  | 30-May-2002           V Nama            Created
1174  | 30-Jul-2002           V Nama            Altered defaults to null for
1175  |                                         exchange_rate_allowance and
1176  |                                         overall_tolerance
1177  |
1178  *=======================================================================*/
1179 PROCEDURE initialize_user_exrate_options(p_user_id       IN NUMBER) IS
1180 
1181   CURSOR user_exrate_options_c IS
1182     SELECT ex.EXCHANGE_RATE_ID,
1183            ex.ORG_ID,
1184            pc.user_id,
1185            pc.selected_org_id
1186     FROM AP_POL_EXRATE_OPTIONS_ALL ex,
1187          AP_POL_CONTEXT         pc
1188     WHERE ex.org_id(+)        = pc.selected_org_id
1189     AND   pc.user_id          = p_user_id;
1190 
1191 BEGIN
1192   FOR user_exrate_options_rec IN user_exrate_options_c LOOP
1193     IF user_exrate_options_rec.exchange_rate_id is null THEN
1194       INSERT INTO ap_pol_exrate_options_all
1195              (exchange_rate_id,
1196               enabled,
1197               default_exchange_rates,
1198               exchange_rate_type,
1199               exchange_rate_allowance,
1200               overall_tolerance,
1201               org_id,
1202               creation_date,
1203               created_by,
1204               last_update_login,
1205               last_update_date,
1206               last_updated_by)
1207       VALUES (AP_POL_EXRATE_OPTIONS_S.nextval,
1208               'N',
1209               'N',
1210               'Corporate',
1211               null,
1212               null,
1213               user_exrate_options_rec.selected_org_id,
1214               SYSDATE,
1215               p_user_id,
1216               NULL,
1217               SYSDATE,
1218               p_user_id);
1219     END IF;
1220   END LOOP;
1221 
1222 END initialize_user_exrate_options;
1223 
1224 /*========================================================================
1225  | PUBLIC FUNCTION get_context_tab_enabled
1226  |
1227  | DESCRIPTION
1228  |   This function returns whether context tab should be shown or hidden.
1229  |   Context tab is not showed if:
1230  |     - Single org installation
1231  |     - Functional security does not allow it
1232  |
1233  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
1234  |   Called from TabCO.java
1235  |
1236  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
1237  |
1238  | RETURNS
1239  |   'Y' If policy tab should be displayed
1240  |   'N' If policy tab should be displayed
1241  |
1242  | PARAMETERS
1243  |
1244  | MODIFICATION HISTORY
1245  | Date                  Author            Description of Changes
1246  | 10-Jun-2002           J Rautiainen      Created
1247  |
1248  *=======================================================================*/
1249 FUNCTION get_context_tab_enabled RETURN VARCHAR2 IS
1250 
1251   CURSOR multi_org_c IS
1252     SELECT nvl(multi_org_flag, 'N') multi_org_flag
1253     FROM fnd_product_groups;
1254 
1255   multi_org_rec multi_org_c%ROWTYPE;
1256 
1257 BEGIN
1258   OPEN multi_org_c;
1259   FETCH multi_org_c INTO multi_org_rec;
1260   CLOSE multi_org_c;
1261 
1262   IF multi_org_rec.multi_org_flag = 'N' THEN
1263     return 'N';
1264   END IF;
1265 
1266   IF not fnd_function.test('OIE_POL_ALLOW_MULTI_ORG_SETUP') THEN
1267     return 'N';
1268   END IF;
1269 
1270   return 'Y';
1271 
1272 END get_context_tab_enabled;
1273 
1274 
1275 /*========================================================================
1276  | PUBLIC FUNCTION getHighEndOfThreshold
1277  |
1278  | DESCRIPTION
1279  |    This function internally calls the new function which has an additional
1280  |    parameter. This function was kept for backward compatibility reasons.
1281  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
1282  |
1283  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
1284  |
1285  | PARAMETERS
1286  | p_policy_id IN Policy Identifier
1287  | p_threshold IN Threshold
1288  |
1289  | MODIFICATION HISTORY
1290  | Date                  Author            Description of Changes
1291  | 16-May-2002           R Langi           Created
1292  |
1293  *=======================================================================*/
1294 FUNCTION getHighEndOfThreshold(p_policy_id  IN ap_pol_headers.policy_id%TYPE,
1295                                p_threshold  IN ap_pol_schedule_options.threshold%TYPE) RETURN ap_pol_schedule_options.threshold%TYPE IS
1296 BEGIN
1297 
1298    RETURN getHighEndOfThreshold(p_policy_id, p_threshold, 'STANDARD');
1299 
1300 END getHighEndOfThreshold;
1301 
1302 /*========================================================================
1303  | PUBLIC FUNCTION getHighEndOfThreshold
1304  |
1305  | DESCRIPTION
1306  |
1307  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
1308  |
1309  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
1310  |
1311  | PARAMETERS
1312  | p_policy_id IN Policy Identifier
1313  | p_threshold IN Threshold
1314  | p_rate_type IN Rate Type (STANDARD, FIRST, LAST)
1315  |
1316  | MODIFICATION HISTORY
1317  | Date                  Author            Description of Changes
1318  | 01-Nov-2005           krmenon           Created
1319  |
1320  *=======================================================================*/
1321 FUNCTION getHighEndOfThreshold(p_policy_id  IN ap_pol_headers.policy_id%TYPE,
1322                                p_threshold  IN ap_pol_schedule_options.threshold%TYPE,
1323                                p_rate_type  IN ap_pol_schedule_options.rate_type_code%TYPE) RETURN ap_pol_schedule_options.threshold%TYPE IS
1324 
1325   CURSOR c_threshold IS
1326     SELECT threshold
1327     FROM   ap_pol_schedule_options
1328     WHERE  policy_id = p_policy_id
1329     AND    (OPTION_TYPE = 'DISTANCE_THRESHOLD' or OPTION_TYPE = 'TIME_THRESHOLD')
1330     AND    threshold is not null
1331     AND    nvl(rate_type_code, 'STANDARD') = p_rate_type
1332     ORDER BY threshold;
1333 
1334   previous_threshold NUMBER;
1335   counter NUMBER := 0;
1336   l_hash_value     NUMBER;
1337   l_hash_value2    NUMBER;
1338   l_result         NUMBER;
1339 
1340 BEGIN
1341 
1342   IF p_policy_id IS NOT NULL AND
1343      p_rate_type IS NOT NULL AND
1344      p_threshold IS NOT NULL THEN
1345 
1346     l_hash_value := get_hash_value(to_char(p_policy_id),
1347                                    p_rate_type,
1348                                    to_char(p_threshold));
1349 
1350     IF pg_thresholds_rec.EXISTS(l_hash_value) THEN
1351       return pg_thresholds_rec(l_hash_value);
1352     ELSE
1353       FOR threshold_rec IN c_threshold LOOP
1354         IF counter > 0 THEN
1355           l_hash_value2 := get_hash_value(to_char(p_policy_id),
1356                                           p_rate_type,
1357                                           to_char(previous_threshold));
1358 
1359           pg_thresholds_rec(l_hash_value2) := threshold_rec.threshold;
1360         END IF;
1361         counter := counter + 1;
1362         previous_threshold := threshold_rec.threshold;
1363       END LOOP;
1364 
1365       l_hash_value2 := get_hash_value(to_char(p_policy_id),
1366                                       p_rate_type,
1367                                       to_char(previous_threshold));
1368       pg_thresholds_rec(l_hash_value2) := NULL;
1369 
1370     END IF;
1371   END IF;
1372 
1373   IF pg_thresholds_rec.EXISTS(l_hash_value) THEN
1374     l_result := pg_thresholds_rec(l_hash_value);
1375     return l_result;
1376   ELSE
1377     return to_number(l_result);
1378   END IF;
1379 
1380 EXCEPTION
1381  WHEN no_data_found  THEN
1382   return(null);
1383  WHEN OTHERS THEN
1384   raise;
1385 END getHighEndOfThreshold;
1386 
1387 
1388 /*========================================================================
1389  | PUBLIC FUNCTION getPolicyCategoryCode
1390  |
1391  | DESCRIPTION
1392  | Returns the Category Code for a Policy
1393  |
1394  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
1395  |
1396  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
1397  |
1398  | PARAMETERS
1399  | p_policy_id IN Policy Identifier
1400  |
1401  | MODIFICATION HISTORY
1402  | Date                  Author            Description of Changes
1403  | 16-May-2002           R Langi           Created
1404  |
1405  *=======================================================================*/
1406 FUNCTION getPolicyCategoryCode(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN ap_pol_headers.category_code%TYPE IS
1407 
1408   l_category_code ap_pol_headers.category_code%TYPE;
1409 
1410 BEGIN
1411 
1412   IF pg_category_rec.EXISTS(p_policy_id) THEN
1413         l_category_code := pg_category_rec(p_policy_id);
1414   ELSE
1415 	select category_code
1416 	into   l_category_code
1417 	from   ap_pol_headers
1418 	where  policy_id = p_policy_id;
1419 
1420 	pg_category_rec(p_policy_id) := l_category_code;
1421   END IF;
1422 
1423   return l_category_code;
1424 
1425 EXCEPTION
1426  WHEN no_data_found  THEN
1427   return(null);
1428  WHEN OTHERS THEN
1429   raise;
1430 END getPolicyCategoryCode;
1431 
1432 
1433 /*========================================================================
1434  | PUBLIC FUNCTION checkRuleOption
1435  |
1436  | DESCRIPTION
1437  | Checks to see if a Rule is enabled for a Schedule and an Option defined
1438  |
1439  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
1440  |
1441  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
1442  |   isLocationEnabled
1443  |   isRoleEnabled
1444  |   isCurrencyEnabled
1445  |   isVehicleCategoryEnabled
1446  |   isVehicleTypeEnabled
1447  |   isFuelTypeEnabled
1448  |   isTimeThresholdsEnabled
1449  |   isDistanceThresholdsEnabled
1450  |
1451  | PARAMETERS
1452  |
1453  | RETURNS
1454  |   'Y' If a Rule is enabled for a Schedule and an Option defined
1455  |   'N' If a Rule is not enabled for a Schedule or an Option not defined
1456  |
1457  | MODIFICATION HISTORY
1458  | Date                  Author            Description of Changes
1459  | 16-May-2002           R Langi           Created
1460  |
1461  *=======================================================================*/
1462 FUNCTION checkRuleOption(p_policy_id IN ap_pol_headers.policy_id%TYPE,
1463                          p_rule IN VARCHAR2) RETURN VARCHAR2 IS
1464 
1465 
1466   FUNCTION isLocationEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
1467 
1468     l_location_flag			ap_pol_headers.location_flag%TYPE;
1469     l_location_count			number := 0;
1470 
1471   BEGIN
1472     select location_flag
1473     into   l_location_flag
1474     from   ap_pol_headers
1475     where  policy_id = p_policy_id;
1476 
1477     select count(location_id)
1478     into   l_location_count
1479     from   ap_pol_schedule_options
1480     where  policy_id = p_policy_id
1481     and    option_type = c_LOCATION
1482     and    location_id is not null;
1483 
1484     if (l_location_flag = 'Y' and l_location_count > 0)
1485     then
1486       return 'Y';
1487     else
1488       return 'N';
1489     end if;
1490 
1491   EXCEPTION
1492    WHEN no_data_found  THEN
1493     return(null);
1494    WHEN OTHERS THEN
1495     raise;
1496   END isLocationEnabled;
1497 
1498   FUNCTION isRoleEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
1499 
1500     l_employee_role_flag			ap_pol_headers.employee_role_flag%TYPE;
1501     l_role_count				number := 0;
1502 
1503   BEGIN
1504     select employee_role_flag
1505     into   l_employee_role_flag
1506     from   ap_pol_headers
1507     where  policy_id = p_policy_id;
1508 
1509     select count(role_id)
1510     into   l_role_count
1511     from   ap_pol_schedule_options
1512     where  policy_id = p_policy_id
1513     and    option_type = c_EMPLOYEE_ROLE
1514     and    role_id is not null;
1515 
1516     if (l_employee_role_flag = 'Y' and l_role_count > 0)
1517     then
1518       return 'Y';
1519     else
1520       return 'N';
1521     end if;
1522 
1523   EXCEPTION
1524    WHEN no_data_found  THEN
1525     return(null);
1526    WHEN OTHERS THEN
1527     raise;
1528   END isRoleEnabled;
1529 
1530   FUNCTION isCurrencyEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
1531 
1532     l_currency_preference		ap_pol_headers.currency_preference%TYPE;
1533     l_currency_count			number := 0;
1534 
1535   BEGIN
1536     select currency_preference
1537     into   l_currency_preference
1538     from   ap_pol_headers
1539     where  policy_id = p_policy_id;
1540 
1541     select count(currency_code)
1542     into   l_currency_count
1543     from   ap_pol_schedule_options
1544     where  policy_id = p_policy_id
1545     and    option_type = c_CURRENCY
1546     and    currency_code is not null;
1547 
1548     if (l_currency_preference = c_MRC and l_currency_count > 0)
1549     then
1550       return 'Y';
1551     else
1552       return 'N';
1553     end if;
1554 
1555   EXCEPTION
1556    WHEN no_data_found  THEN
1557     return(null);
1558    WHEN OTHERS THEN
1559     raise;
1560   END isCurrencyEnabled;
1561 
1562   FUNCTION isVehicleCategoryEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
1563 
1564     l_vehicle_category_flag		ap_pol_headers.vehicle_category_flag%TYPE;
1565     l_vehicle_category_count		number := 0;
1566 
1567   BEGIN
1568     select vehicle_category_flag
1569     into   l_vehicle_category_flag
1570     from   ap_pol_headers
1571     where  policy_id = p_policy_id;
1572 
1573     select count(option_code)
1574     into   l_vehicle_category_count
1575     from   ap_pol_schedule_options
1576     where  policy_id = p_policy_id
1577     and    option_type  = c_VEHICLE_CATEGORY
1578     and    option_code is not null;
1579 
1580     if (l_vehicle_category_flag = 'Y' and l_vehicle_category_count > 0)
1581     then
1582       return 'Y';
1583     else
1584       return 'N';
1585     end if;
1586 
1587   EXCEPTION
1588    WHEN no_data_found  THEN
1589     return(null);
1590    WHEN OTHERS THEN
1591     raise;
1592   END isVehicleCategoryEnabled;
1593 
1594   FUNCTION isVehicleTypeEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
1595 
1596     l_vehicle_type_flag             ap_pol_headers.vehicle_type_flag%TYPE;
1597     l_vehicle_type_count            number := 0;
1598 
1599   BEGIN
1600     select vehicle_type_flag
1601     into   l_vehicle_type_flag
1602     from   ap_pol_headers
1603     where  policy_id = p_policy_id;
1604 
1605     select count(option_code)
1606     into   l_vehicle_type_count
1607     from   ap_pol_schedule_options
1608     where  policy_id = p_policy_id
1609     and    option_type  = c_VEHICLE_TYPE
1610     and    option_code is not null;
1611 
1612     if (l_vehicle_type_flag = 'Y' and l_vehicle_type_count > 0)
1613     then
1614       return 'Y';
1615     else
1616       return 'N';
1617     end if;
1618 
1619   EXCEPTION
1620    WHEN no_data_found  THEN
1621     return(null);
1622    WHEN OTHERS THEN
1623     raise;
1624   END isVehicleTypeEnabled;
1625 
1626   FUNCTION isFuelTypeEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
1627 
1628     l_fuel_type_flag             ap_pol_headers.fuel_type_flag%TYPE;
1629     l_fuel_type_count            number := 0;
1630 
1631   BEGIN
1632     select fuel_type_flag
1633     into   l_fuel_type_flag
1634     from   ap_pol_headers
1635     where  policy_id = p_policy_id;
1636 
1637     select count(option_code)
1638     into   l_fuel_type_count
1639     from   ap_pol_schedule_options
1640     where  policy_id = p_policy_id
1641     and    option_type  = c_FUEL_TYPE
1642     and    option_code is not null;
1643 
1644     if (l_fuel_type_flag = 'Y' and l_fuel_type_count > 0)
1645     then
1646       return 'Y';
1647     else
1648       return 'N';
1649     end if;
1650 
1651   EXCEPTION
1652    WHEN no_data_found  THEN
1653     return(null);
1654    WHEN OTHERS THEN
1655     raise;
1656   END isFuelTypeEnabled;
1657 
1658   FUNCTION isTimeThresholdsEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
1659 
1660     l_time_based_entry_flag		ap_pol_headers.time_based_entry_flag%TYPE;
1661     l_thresholds_count			number := 0;
1662 
1663   BEGIN
1664     select nvl(time_based_entry_flag, 'N')
1665     into   l_time_based_entry_flag
1666     from   ap_pol_headers
1667     where  policy_id = p_policy_id;
1668 
1669     select count(threshold)
1670     into   l_thresholds_count
1671     from   ap_pol_schedule_options
1672     where  policy_id = p_policy_id
1673     and    (option_type = c_TIME_THRESHOLD)
1674     and    threshold is not null;
1675 
1676     if (l_time_based_entry_flag = 'Y' and l_thresholds_count > 0)
1677     then
1678       return 'Y';
1679     else
1680       return 'N';
1681     end if;
1682 
1683   EXCEPTION
1684    WHEN no_data_found  THEN
1685     return(null);
1686    WHEN OTHERS THEN
1687     raise;
1688   END isTimeThresholdsEnabled;
1689 
1690   FUNCTION isDistanceThresholdsEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
1691 
1692     l_distance_thresholds_flag		ap_pol_headers.distance_thresholds_flag%TYPE;
1693     l_thresholds_count			number := 0;
1694 
1695   BEGIN
1696     select nvl2(distance_thresholds_flag, 'Y', 'N')
1697     into   l_distance_thresholds_flag
1698     from   ap_pol_headers
1699     where  policy_id = p_policy_id;
1700 
1701     select count(threshold)
1702     into   l_thresholds_count
1703     from   ap_pol_schedule_options
1704     where  policy_id = p_policy_id
1705     and    (option_type  = c_DISTANCE_THRESHOLD)
1706     and    threshold is not null;
1707 
1708     if (l_distance_thresholds_flag = 'Y' and l_thresholds_count > 0)
1709     then
1710       return 'Y';
1711     else
1712       return 'N';
1713     end if;
1714 
1715   EXCEPTION
1716    WHEN no_data_found  THEN
1717     return(null);
1718    WHEN OTHERS THEN
1719     raise;
1720   END isDistanceThresholdsEnabled;
1721 
1722   FUNCTION isThresholdsEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
1723 
1724     l_distance_thresholds_flag		ap_pol_headers.distance_thresholds_flag%TYPE;
1725     l_time_thresholds_flag		ap_pol_headers.time_based_entry_flag%TYPE;
1726 
1727   BEGIN
1728 
1729     l_distance_thresholds_flag := isDistanceThresholdsEnabled(p_policy_id);
1730     l_time_thresholds_flag := isTimeThresholdsEnabled(p_policy_id);
1731 
1732     if (l_distance_thresholds_flag IS NULL and l_time_thresholds_flag IS NULL)
1733     then
1734       return (null);
1735     elsif (l_distance_thresholds_flag = 'Y' or l_time_thresholds_flag = 'Y')
1736     then
1737       return 'Y';
1738     else
1739       return 'N';
1740     end if;
1741 
1742   EXCEPTION
1743    WHEN OTHERS THEN
1744     raise;
1745   END isThresholdsEnabled;
1746 
1747   FUNCTION isAddonRatesEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
1748     l_addon_mileage_rates_flag		ap_pol_headers.addon_mileage_rates_flag%TYPE;
1749     l_addon_rates_count			number := 0;
1750   BEGIN
1751 
1752     select nvl(addon_mileage_rates_flag, 'N')
1753     into   l_addon_mileage_rates_flag
1754     from   ap_pol_headers
1755     where  policy_id = p_policy_id;
1756 
1757     select count(1)
1758     into   l_addon_rates_count
1759     from   ap_pol_schedule_options
1760     where  policy_id = p_policy_id
1761     and    (option_type  = c_ADDON_RATES)
1762     and    option_code is not null;
1763 
1764     if (l_addon_mileage_rates_flag = 'Y' and l_addon_rates_count > 0)
1765     then
1766       return 'Y';
1767     else
1768       return 'N';
1769     end if;
1770 
1771   EXCEPTION
1772    WHEN OTHERS THEN
1773     raise;
1774 
1775   END isAddonRatesEnabled;
1776 
1777 BEGIN
1778 
1779   if (p_rule = c_LOCATION) then return isLocationEnabled(p_policy_id); end if;
1780   if (p_rule = c_EMPLOYEE_ROLE) then return isRoleEnabled(p_policy_id); end if;
1781   if (p_rule = c_CURRENCY) then return isCurrencyEnabled(p_policy_id); end if;
1782   if (p_rule = c_VEHICLE_CATEGORY) then return isVehicleCategoryEnabled(p_policy_id); end if;
1783   if (p_rule = c_VEHICLE_TYPE) then return isVehicleTypeEnabled(p_policy_id); end if;
1784   if (p_rule = c_FUEL_TYPE) then return isFuelTypeEnabled(p_policy_id); end if;
1785   if (p_rule = c_TIME_THRESHOLD) then return isTimeThresholdsEnabled(p_policy_id); end if;
1786   if (p_rule = c_DISTANCE_THRESHOLD) then return isDistanceThresholdsEnabled(p_policy_id); end if;
1787   if (p_rule = c_THRESHOLD) then return isThresholdsEnabled(p_policy_id); end if;
1788   if (p_rule = c_ADDON_RATES) then return isAddonRatesEnabled(p_policy_id); end if;
1789 
1790 EXCEPTION
1791  WHEN no_data_found  THEN
1792   return(null);
1793  WHEN OTHERS THEN
1794   raise;
1795 END checkRuleOption;
1796 
1797 
1798 /*========================================================================
1799  | PUBLIC FUNCTION getUnionStmtForRuleOption
1800  |
1801  | DESCRIPTION
1802  | If a Rule is not enabled or Schedule Option not defined for an enabled Rule
1803  | this will return a UNION null statement which is used for perumutatePolicyLines()
1804  |
1805  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
1806  |
1807  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
1808  |
1809  | PARAMETERS
1810  |   p_policy_id IN Policy Identifier
1811  |   p_rule IN Schedule Option Type
1812  |
1813  | MODIFICATION HISTORY
1814  | Date                  Author            Description of Changes
1815  | 16-May-2002           R Langi           Created
1816  |
1817  *=======================================================================*/
1818 FUNCTION getUnionStmtForRuleOption(p_policy_id IN ap_pol_headers.policy_id%TYPE,
1819                                    p_rule IN VARCHAR2) RETURN VARCHAR2 IS
1820 
1821   l_currency_preference               ap_pol_headers.currency_preference%TYPE;
1822 
1823   l_src_stmt			VARCHAR2(160) := 'union all select CURRENCY_CODE from ap_pol_headers where POLICY_ID = :p_policy_id';
1824 
1825   l_vc_stmt			VARCHAR2(80) := 'union all select to_char(null), to_char(null), to_char(null) from sys.dual';
1826   l_number_stmt			VARCHAR2(80) := 'union all select to_number(null) from sys.dual';
1827   l_number2_stmt		VARCHAR2(80) := 'union all select to_number(null), to_number(null) from sys.dual';
1828   l_varchar2_stmt		VARCHAR2(80) := 'union all select to_char(null) from sys.dual';
1829 
1830 BEGIN
1831 
1832   select currency_preference
1833   into   l_currency_preference
1834   from   ap_pol_headers
1835   where  policy_id = p_policy_id;
1836 
1837   if (checkRuleOption(p_policy_id, p_rule) = 'Y')
1838   then
1839     return '';
1840   else
1841     if (p_rule = c_CURRENCY) then
1842       if (l_currency_preference = c_SRC) then
1843       /*
1844         if Single Rate Currency there will be no records in ap_pol_schedule_options
1845         we must still permutate using ap_pol_headers.currency_code
1846       */
1847         return l_src_stmt;
1848       else
1849       /*
1850         if Location Currency Rate there will be no records in ap_pol_schedule_options
1851         if Airfare there will be no records in ap_pol_schedule_options
1852       */
1853         return l_varchar2_stmt;
1854       end if;
1855     elsif (p_rule = c_VEHICLE_CATEGORY) then
1856       /*
1857         if Vehicle Category is not selected
1858         then return 3 nulls (option_code, vehicle_type_code, fuel_type_code)
1859       */
1860       return l_vc_stmt;
1861     elsif (p_rule = c_LOCATION or p_rule = c_EMPLOYEE_ROLE) then
1862       return l_number_stmt;
1863     elsif (p_rule = c_THRESHOLD) then
1864       return l_number2_stmt;
1865     elsif (p_rule = c_VEHICLE_TYPE or p_rule = c_FUEL_TYPE) then
1866       return l_varchar2_stmt;
1867     else
1868       return '';
1869     end if;
1870   end if;
1871 
1872 EXCEPTION
1873  WHEN no_data_found  THEN
1874   return(null);
1875  WHEN OTHERS THEN
1876   raise;
1877 END getUnionStmtForRuleOption;
1878 
1879 
1880 /*========================================================================
1881  | PRIVATE PROCEDURE checkAirfarePolicyLines
1882  |
1883  | DESCRIPTION
1884  | If Airfare Policy Lines, default TICKET_CLASS_DOMESTIC/TICKET_CLASS_INTERNATIONAL
1885  | to 'COACH'.
1886  |
1887  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
1888  |
1889  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
1890  |
1891  | PARAMETERS
1892  |   p_policy_id IN Policy Identifier
1893  |
1894  | MODIFICATION HISTORY
1895  | Date                  Author            Description of Changes
1896  | 24-Dec-2002           R Langi           Created
1897  |
1898  *=======================================================================*/
1899 PROCEDURE checkAirfarePolicyLines(p_policy_id IN ap_pol_headers.policy_id%TYPE) IS
1900 
1901 BEGIN
1902 
1903   if (getPolicyCategoryCode(p_policy_id) <> 'AIRFARE')
1904   then
1905     return;
1906   else
1907     update ap_pol_lines
1908     set    ticket_class_domestic = 'COACH'
1909     where  policy_id = p_policy_id
1910     and    ticket_class_domestic is null;
1911 
1912     update ap_pol_lines
1913     set    ticket_class_international = 'COACH'
1914     where  policy_id = p_policy_id
1915     and    ticket_class_international is null;
1916   end if;
1917 
1918 EXCEPTION
1919  WHEN no_data_found  THEN
1920   return;
1921  WHEN OTHERS THEN
1922   raise;
1923 END checkAirfarePolicyLines;
1924 
1925 
1926 /*========================================================================
1927  | PUBLIC PROCEDURE permutatePolicyLines
1928  |
1929  | DESCRIPTION
1930  | - if a Rule is not enabled or Schedule Option not defined for an enabled Rule then remove the
1931  |   obsoleted Policy Line
1932  | - this will never recreate permutated lines based on existing option (rerunnable)
1933  | - if option doesn't exist then creates permutation for new option
1934  | - if option end dated then set Policy Line status to inactive
1935  |
1936  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
1937  |
1938  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
1939  |
1940  | PARAMETERS
1941  |  p_user_id IN User Identifier
1942  |  p_policy_id IN Policy Identifier
1943  |
1944  | MODIFICATION HISTORY
1945  | Date                  Author            Description of Changes
1946  | 16-May-2002           R Langi           Created
1947  |
1948  *=======================================================================*/
1949 PROCEDURE permutatePolicyLines(p_user_id IN NUMBER,
1950                                p_policy_id  IN ap_pol_headers.policy_id%TYPE) IS
1951 
1952   l_schedule_period_id		ap_pol_schedule_periods.schedule_period_id%TYPE;
1953   l_permutate_curref		INTEGER;
1954   l_rows_permutated		NUMBER := 0;
1955 
1956   l_policy_line_count		NUMBER := 0;
1957 
1958   l_insert_sql_stmt		VARCHAR2(4000);
1959   l_where_sql_stmt		VARCHAR2(4000);
1960   l_not_exists_sql_stmt		VARCHAR2(4000);
1961 
1962   l_l_sql_stmt			VARCHAR2(4000);
1963   l_r_sql_stmt			VARCHAR2(4000);
1964   l_c_sql_stmt			VARCHAR2(4000);
1965   l_vc_sql_stmt			VARCHAR2(4000);
1966   l_vt_sql_stmt			VARCHAR2(4000);
1967   l_ft_sql_stmt			VARCHAR2(4000);
1968   l_dt_sql_stmt			VARCHAR2(4000);
1969 
1970   l_location_enabled            VARCHAR2(80) := getUnionStmtForRuleOption(p_policy_id, c_LOCATION);
1971   l_role_enabled                VARCHAR2(80) := getUnionStmtForRuleOption(p_policy_id, c_EMPLOYEE_ROLE);
1972   l_currency_enabled            VARCHAR2(160) := getUnionStmtForRuleOption(p_policy_id, c_CURRENCY);
1973   l_vehicle_category_enabled    VARCHAR2(80) := getUnionStmtForRuleOption(p_policy_id, c_VEHICLE_CATEGORY);
1974   l_vehicle_type_enabled        VARCHAR2(80) := getUnionStmtForRuleOption(p_policy_id, c_VEHICLE_TYPE);
1975   l_fuel_type_enabled           VARCHAR2(80) := getUnionStmtForRuleOption(p_policy_id, c_FUEL_TYPE);
1976   l_thresholds_enabled          VARCHAR2(80) := getUnionStmtForRuleOption(p_policy_id, c_THRESHOLD);
1977   l_addon_rates_enabled         VARCHAR2(1) := checkRuleOption(p_policy_id, c_ADDON_RATES);
1978   l_night_rates_enabled         VARCHAR2(1) := isNightRatesEnabled(p_policy_id);
1979 
1980   l_schedule_option_rec         ap_pol_schedule_options%ROWTYPE;
1981   l_zero_threshold_count        NUMBER;
1982   l_category_code               ap_pol_headers.category_code%TYPE;
1983   l_rate_type_code              ap_pol_schedule_options.rate_type_code%TYPE;
1984   l_schedule_type                ap_pol_headers.schedule_type_code%TYPE;
1985   l_source                      ap_pol_headers.source%TYPE;
1986 
1987 ---------------------------------------
1988 -- cursor for schedule periods
1989 ---------------------------------------
1990 cursor c_schedule_period_id is
1991   select schedule_period_id
1992   from   ap_pol_schedule_periods
1993   where  policy_id = p_policy_id;
1994 
1995 ---------------------------------------------------
1996 -- cursor for first last and same day  rate periods
1997 --------------------------------------------------
1998 cursor c_rate_types is
1999   select distinct rate_type_code
2000   from   ap_pol_schedule_options
2001   where  policy_id = p_policy_id
2002   and    rate_type_code in ('FIRST_PERIOD', 'LAST_PERIOD', 'SAME_DAY')
2003   and    option_type = 'TIME_THRESHOLD';
2004 
2005 ---------------------------------------
2006 -- cursor for insert/select
2007 ---------------------------------------
2008 cursor l_insert_cursor is
2009 select
2010 '
2011   insert into AP_POL_LINES
2012         (
2013          POLICY_LINE_ID,
2014          POLICY_ID,
2015          SCHEDULE_PERIOD_ID,
2016          LOCATION_ID,
2017          ROLE_ID,
2018          CURRENCY_CODE,
2019          VEHICLE_CATEGORY,
2020          VEHICLE_TYPE,
2021          FUEL_TYPE,
2022          RANGE_LOW,
2023          RANGE_HIGH,
2024          RATE_TYPE_CODE,
2025          STATUS,
2026          CREATION_DATE,
2027          CREATED_BY,
2028          LAST_UPDATE_DATE,
2029          LAST_UPDATED_BY
2030         )
2031   select
2032          AP_POL_LINES_S.NEXTVAL AS POLICY_LINE_ID,
2033          :p_policy_id AS POLICY_ID,
2034          :p_schedule_period_id AS SCHEDULE_PERIOD_ID,
2035          NEW_LOCATION_ID AS LOCATION_ID,
2036          NEW_ROLE_ID AS ROLE_ID,
2037          NEW_CURRENCY_CODE AS CURRENCY_CODE,
2038          NEW_VEHICLE_CATEGORY AS VEHICLE_CATEGORY,
2039          NEW_VEHICLE_TYPE AS VEHICLE_TYPE,
2040          NEW_FUEL_TYPE AS FUEL_TYPE,
2041          NEW_RANGE_LOW AS RANGE_LOW,
2042          NEW_RANGE_HIGH AS RANGE_HIGH,
2043          NEW_RATE_TYPE_CODE AS RATE_TYPE_CODE,
2044          ''NEW'' AS STATUS,
2045          sysdate AS CREATION_DATE,
2046          :p_user_id AS CREATED_BY,
2047          sysdate AS LAST_UPDATE_DATE,
2048          :p_user_id AS LAST_UPDATED_BY
2049   from
2050   (
2051   select distinct
2052          NEW_LOCATION_ID,
2053          NEW_ROLE_ID,
2054          NEW_CURRENCY_CODE,
2055          NEW_VEHICLE_CATEGORY,
2056          NEW_VEHICLE_TYPE,
2057          NEW_FUEL_TYPE,
2058          NEW_RANGE_LOW,
2059          NEW_RANGE_HIGH,
2060          NEW_RATE_TYPE_CODE
2061   from
2062   (
2063   select
2064           l.LOCATION_ID AS NEW_LOCATION_ID,
2065           r.ROLE_ID AS NEW_ROLE_ID,
2066           c.CURRENCY_CODE AS NEW_CURRENCY_CODE,
2067          vc.OPTION_CODE AS NEW_VEHICLE_CATEGORY,
2068          decode(vc.OPTION_CODE, null, vt.OPTION_CODE, decode(vc.VEHICLE_TYPE_CODE, ''R'', vt.OPTION_CODE, null)) AS NEW_VEHICLE_TYPE,
2069          decode(vc.OPTION_CODE, null, ft.OPTION_CODE, decode(vc.FUEL_TYPE_CODE, ''R'', ft.OPTION_CODE, null)) AS NEW_FUEL_TYPE,
2070          dt.THRESHOLD AS NEW_RANGE_LOW,
2071          dt.RANGE_HIGH AS NEW_RANGE_HIGH,
2072          :p_rate_type AS NEW_RATE_TYPE_CODE
2073   from
2074 '
2075 from sys.dual; /* l_insert_cursor */
2076 
2077 ---------------------------------------
2078 -- cursor for all locations to use
2079 ---------------------------------------
2080 cursor l_l_cursor is
2081 select
2082 '
2083       (select LOCATION_ID
2084        from   AP_POL_SCHEDULE_OPTIONS pso
2085        where
2086               POLICY_ID = :p_policy_id
2087        and    OPTION_TYPE = :c_LOCATION
2088        and    LOCATION_ID IS NOT NULL
2089        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
2090          '||l_location_enabled||'
2091       ) l,
2092 '
2093 from sys.dual; /* l_l_cursor */
2094 
2095 ---------------------------------------
2096 -- cursor for all roles to use
2097 ---------------------------------------
2098 cursor l_r_cursor is
2099 select
2100 '
2101       (select ROLE_ID
2102        from   AP_POL_SCHEDULE_OPTIONS pso
2103        where
2104               POLICY_ID = :p_policy_id
2105        and    OPTION_TYPE = :c_EMPLOYEE_ROLE
2106        and    ROLE_ID IS NOT NULL
2107        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
2108          '||l_role_enabled||'
2109       ) r,
2110 '
2111 from sys.dual; /* l_r_cursor */
2112 
2113 ---------------------------------------
2114 -- cursor for all currency codes to use
2115 ---------------------------------------
2116 cursor l_c_cursor is
2117 select
2118 '
2119       (select CURRENCY_CODE
2120        from   AP_POL_SCHEDULE_OPTIONS pso
2121        where
2122               POLICY_ID = :p_policy_id
2123        and    OPTION_TYPE = :c_CURRENCY
2124        and    CURRENCY_CODE IS NOT NULL
2125        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
2126          '||l_currency_enabled||'
2127       ) c,
2128 '
2129 from sys.dual; /* l_c_cursor */
2130 
2131 ---------------------------------------
2132 -- cursor for all vehicle categories to use
2133 ---------------------------------------
2134 cursor l_vc_cursor is
2135 select
2136 '
2137       (select OPTION_CODE, VEHICLE_TYPE_CODE, FUEL_TYPE_CODE
2138        from   AP_POL_SCHEDULE_OPTIONS pso
2139        where
2140               POLICY_ID = :p_policy_id
2141        and    OPTION_TYPE = :c_VEHICLE_CATEGORY
2142        and    OPTION_CODE IS NOT NULL
2143        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
2144          '||l_vehicle_category_enabled||'
2145       ) vc,
2146 '
2147 from sys.dual; /* l_vc_cursor */
2148 
2149 ---------------------------------------
2150 -- cursor for all vehicle types to use
2151 ---------------------------------------
2152 cursor l_vt_cursor is
2153 select
2154 '
2155       (select OPTION_CODE
2156        from   AP_POL_SCHEDULE_OPTIONS pso
2157        where
2158               POLICY_ID = :p_policy_id
2159        and    OPTION_TYPE = :c_VEHICLE_TYPE
2160        and    OPTION_CODE IS NOT NULL
2161        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
2162          '||l_vehicle_type_enabled||'
2163       ) vt,
2164 '
2165 from sys.dual; /* l_vt_cursor */
2166 
2167 ---------------------------------------
2168 -- cursor for all fuel types to use
2169 ---------------------------------------
2170 cursor l_ft_cursor is
2171 select
2172 '
2173       (select OPTION_CODE
2174        from   AP_POL_SCHEDULE_OPTIONS pso
2175        where
2176               POLICY_ID = :p_policy_id
2177        and    OPTION_TYPE = :c_FUEL_TYPE
2178        and    OPTION_CODE IS NOT NULL
2179        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
2180          '||l_fuel_type_enabled||'
2181       ) ft,
2182 '
2183 from sys.dual; /* l_ft_cursor */
2184 
2185 ---------------------------------------
2186 -- cursor for all thresholds to use
2187 ---------------------------------------
2188 cursor l_dt_cursor is
2189 select
2190 '
2191       (select THRESHOLD,
2192               ap_web_policy_UTILS.getHighEndOfThreshold(:p_policy_id, THRESHOLD, nvl(:p_rate_type,''STANDARD'')) AS RANGE_HIGH
2193        from   AP_POL_SCHEDULE_OPTIONS pso
2194        where
2195               POLICY_ID = :p_policy_id
2196        and    (OPTION_TYPE = :c_DISTANCE_THRESHOLD or OPTION_TYPE = :c_TIME_THRESHOLD)
2197        and    THRESHOLD IS NOT NULL
2198        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
2199        and    nvl(rate_type_code, ''NULL'') = nvl(:p_rate_type, ''NULL'')
2200          '||l_thresholds_enabled||'
2201       ) dt
2202 '
2203 from sys.dual; /* l_dt_cursor */
2204 
2205 
2206 ---------------------------------------
2207 -- cursor for where rows
2208 ---------------------------------------
2209 cursor l_where_cursor is
2210 select
2211 '
2212   )
2213   where
2214         (
2215          NEW_LOCATION_ID is not null
2216   or     NEW_ROLE_ID is not null
2217   or     NEW_CURRENCY_CODE is not null
2218   or     NEW_VEHICLE_CATEGORY is not null
2219   or     NEW_VEHICLE_TYPE is not null
2220   or     NEW_FUEL_TYPE is not null
2221   or     NEW_RANGE_LOW is not null
2222   or     NEW_RANGE_HIGH is not null
2223         )
2224   )
2225 '
2226 from sys.dual; /* l_where_cursor */
2227 
2228 
2229 ---------------------------------------
2230 -- cursor for adding new rules/options
2231 ---------------------------------------
2232 cursor l_not_exists_cursor is
2233 select
2234 '
2235   )
2236   where
2237   not exists
2238         (
2239          select epl.POLICY_LINE_ID
2240          from   AP_POL_LINES epl
2241          where  epl.POLICY_ID = :p_policy_id
2242          and    epl.SCHEDULE_PERIOD_ID = :p_schedule_period_id
2243          and    nvl(epl.LOCATION_ID, :dummy_number) = nvl(NEW_LOCATION_ID, :dummy_number)
2244          and    nvl(epl.ROLE_ID, :dummy_number) = nvl(NEW_ROLE_ID, :dummy_number)
2245          and
2246                (
2247                 (nvl(epl.CURRENCY_CODE, :dummy_varchar2) = nvl(NEW_CURRENCY_CODE, :dummy_varchar2))
2248                 or
2249                 (epl.CURRENCY_CODE is not null and NEW_CURRENCY_CODE is null)
2250                )
2251          and    nvl(epl.VEHICLE_CATEGORY, :dummy_varchar2) = nvl(NEW_VEHICLE_CATEGORY, :dummy_varchar2)
2252          and    nvl(epl.VEHICLE_TYPE, :dummy_varchar2) = nvl(NEW_VEHICLE_TYPE, :dummy_varchar2)
2253          and    nvl(epl.FUEL_TYPE, :dummy_varchar2) = nvl(NEW_FUEL_TYPE, :dummy_varchar2)
2254          and    nvl(epl.RANGE_LOW, :dummy_number) = nvl(NEW_RANGE_LOW, :dummy_number)
2255          and    nvl(epl.RANGE_HIGH, :dummy_number) = nvl(NEW_RANGE_HIGH, :dummy_number)
2256          and    nvl(epl.RATE_TYPE_CODE, :dummy_varchar2) = nvl(NEW_RATE_TYPE_CODE, :dummy_varchar2)
2257         )
2258   )
2259 '
2260 from sys.dual; /* l_not_exists_cursor */
2261 
2262 
2263 
2264 
2265 BEGIN
2266 
2267   select category_code, schedule_type_code, source
2268   into   l_category_code, l_schedule_type, l_source
2269   from   ap_pol_headers
2270   where  policy_id = p_policy_id;
2271 
2272   -- ---------------------------------------------------------------
2273   -- If this is a CONUS/OCONUS policy then call the appropriate
2274   -- procedure and return
2275   -- ---------------------------------------------------------------
2276   IF ( l_source = 'CONUS' ) THEN
2277     BEGIN
2278       permutateConusLines(p_user_id, p_policy_id);
2279       return;
2280     END;
2281   END IF;
2282   -- ----------------------------------------------------------
2283   -- Insert zero row threshold before generating permutations
2284   -- ----------------------------------------------------------
2285   IF ( l_category_code = 'PER_DIEM' ) THEN
2286   BEGIN
2287     -- Delete zero threshold rows where not needed
2288     delete from ap_pol_schedule_options
2289     where policy_id = p_policy_id
2290     and   option_type = 'TIME_THRESHOLD'
2291     and   threshold = 0
2292     and   rate_type_code not in
2293           (  select distinct rate_type_code
2294              from   ap_pol_schedule_options
2295              where  policy_id = p_policy_id
2296              and    rate_type_code in ('FIRST_PERIOD', 'LAST_PERIOD', 'SAME_DAY')
2297              and    option_type = 'TIME_THRESHOLD'
2298              and    threshold > 0 )
2299     and rate_type_code <> 'STANDARD';
2300 
2301     FOR rate_type_cur in c_rate_types
2302     LOOP
2303       select count(1)
2304        into  l_zero_threshold_count
2305        from  ap_pol_schedule_options
2306       where  policy_id = p_policy_id
2307         and  rate_type_code = rate_type_cur.rate_type_code
2308         and  threshold = 0;
2309 
2310       IF ( l_zero_threshold_count = 0 ) THEN
2311         BEGIN
2312           SELECT ap_pol_schedule_options_s.NEXTVAL
2313           INTO   l_schedule_option_rec.schedule_option_id
2314           FROM   DUAL;
2315 
2316           INSERT INTO ap_pol_schedule_options
2317              (
2318               policy_id,
2319               schedule_option_id,
2320               option_type,
2321               threshold,
2322               status,
2323               creation_date,
2324               created_by,
2325               last_update_date,
2326               last_updated_by,
2327               rate_type_code
2328              )
2329           VALUES
2330              (
2331               p_policy_id,
2332               l_schedule_option_rec.schedule_option_id,
2333               'TIME_THRESHOLD',
2334               0,
2335               'SAVED',
2336               sysdate,
2337               p_user_id,
2338               sysdate,
2339               p_user_id,
2340               rate_type_cur.rate_type_code
2341              );
2342 
2343           /*--------- COMMENTING THIS CODE SINCE GSCC NOT FIXED FOR REC TYPE --------------
2344           l_schedule_option_rec.policy_id        := p_policy_id;
2345           l_schedule_option_rec.option_type      := 'TIME_THRESHOLD';
2346           l_schedule_option_rec.threshold        := 0;
2347           l_schedule_option_rec.status           := 'SAVED';
2348           l_schedule_option_rec.creation_date    := sysdate;
2349           l_schedule_option_rec.created_by       := p_user_id;
2350           l_schedule_option_rec.last_update_date := sysdate;
2351           l_schedule_option_rec.last_updated_by  := p_user_id;
2352           l_schedule_option_rec.rate_type_code   := rate_type_cur.rate_type_code;
2353 
2354           INSERT INTO ap_pol_schedule_options values  l_schedule_option_rec;
2355           ----------------------------------------------------------------------------------*/
2356         END;
2357       END IF;
2358     END LOOP;
2359 
2360     -- Standard rate is a special case. Should not insert 0 record
2361     -- for midnight to midnight schedules which have first and last rates
2362     -- or for allowance schedules with time rule of start and end times
2363     select  count(1)
2364       into  l_zero_threshold_count
2365       from  ap_pol_headers
2366      where  policy_id = p_policy_id
2367        and  time_based_entry_flag = 'Y'
2368        and  ( day_period_code <> 'MIDNIGHT' or
2369              (nvl(rate_period_type_code, 'STANDARD') = 'STANDARD' and  schedule_type_code = 'PER_DIEM') or
2370              ( schedule_type_code = 'ALLOWANCE' and allowance_time_rule_code = 'TIME_THRESHOLD' )
2371              );
2372 
2373     IF ( l_zero_threshold_count = 1 ) THEN
2374       BEGIN
2375         select  count(1)
2376           into  l_zero_threshold_count
2377           from  ap_pol_schedule_options
2378          where  policy_id = p_policy_id
2379            and  rate_type_code = 'STANDARD'
2380            and  threshold = 0;
2381 
2382         IF ( l_zero_threshold_count = 0 ) THEN
2383           BEGIN
2384             SELECT ap_pol_schedule_options_s.NEXTVAL
2385             INTO   l_schedule_option_rec.schedule_option_id
2386             FROM   DUAL;
2387 
2388             INSERT INTO ap_pol_schedule_options
2389              (
2390               policy_id,
2391               schedule_option_id,
2392               option_type,
2393               threshold,
2394               status,
2395               creation_date,
2396               created_by,
2397               last_update_date,
2398               last_updated_by,
2399               rate_type_code
2400              )
2401             VALUES
2402              (
2403               p_policy_id,
2404               l_schedule_option_rec.schedule_option_id,
2405               'TIME_THRESHOLD',
2406               0,
2407               'SAVED',
2408               sysdate,
2409               p_user_id,
2410               sysdate,
2411               p_user_id,
2412               'STANDARD'
2413              );
2414 
2415           /*--------- COMMENTING THIS CODE SINCE GSCC NOT FIXED FOR REC TYPE --------------
2416              l_schedule_option_rec.policy_id        := p_policy_id;
2417             l_schedule_option_rec.option_type      := 'TIME_THRESHOLD';
2418             l_schedule_option_rec.threshold        := 0;
2419             l_schedule_option_rec.status           := 'SAVED';
2420             l_schedule_option_rec.creation_date    := sysdate;
2421             l_schedule_option_rec.created_by       := p_user_id;
2422             l_schedule_option_rec.last_update_date := sysdate;
2423             l_schedule_option_rec.last_updated_by  := p_user_id;
2424             l_schedule_option_rec.rate_type_code   := 'STANDARD';
2425 
2426             INSERT INTO ap_pol_schedule_options values  l_schedule_option_rec;
2427           ---------------------------------------------------------------------------------*/
2428 
2429           END;
2430         END IF;
2431 
2432       END;
2433     ELSE
2434      -- ---------------------------------------------------------------------
2435      -- This means that we should not have a zero row for standard rate type
2436      -- So delete any such rows
2437      -- ---------------------------------------------------------------------
2438      delete from ap_pol_schedule_options
2439      where  policy_id = p_policy_id
2440      and    rate_type_code = 'STANDARD'
2441      and    threshold      = 0;
2442 
2443     END IF;
2444 
2445     l_rate_type_code := 'STANDARD';
2446   END;
2447   ELSE
2448     l_rate_type_code := null;
2449   END IF;
2450 
2451 
2452 
2453   removeObsoletedPolicyLines(p_policy_id);
2454 
2455   open l_insert_cursor;
2456   open l_where_cursor;
2457   open l_not_exists_cursor;
2458 
2459   open l_l_cursor;
2460   open l_r_cursor;
2461   open l_c_cursor;
2462   open l_vc_cursor;
2463   open l_vt_cursor;
2464   open l_ft_cursor;
2465   open l_dt_cursor;
2466 
2467   fetch l_insert_cursor into l_insert_sql_stmt;
2468   fetch l_where_cursor into l_where_sql_stmt;
2469   fetch l_not_exists_cursor into l_not_exists_sql_stmt;
2470 
2471   fetch l_l_cursor into l_l_sql_stmt;
2472   fetch l_r_cursor into l_r_sql_stmt;
2473   fetch l_c_cursor into l_c_sql_stmt;
2474   fetch l_vc_cursor into l_vc_sql_stmt;
2475   fetch l_vt_cursor into l_vt_sql_stmt;
2476   fetch l_ft_cursor into l_ft_sql_stmt;
2477   fetch l_dt_cursor into l_dt_sql_stmt;
2478 
2479   --------------
2480   -- open cursor
2481   --------------
2482   l_permutate_curref := DBMS_SQL.OPEN_CURSOR;
2483 
2484   --------------
2485   -- begin loop thru all periods
2486   --------------
2487   open c_schedule_period_id;
2488   loop
2489 
2490   fetch c_schedule_period_id into l_schedule_period_id;
2491   exit when c_schedule_period_id%NOTFOUND;
2492 
2493   select count(policy_line_id)
2494   into   l_policy_line_count
2495   from   ap_pol_lines
2496   where  policy_id = p_policy_id
2497   and    schedule_period_id = l_schedule_period_id;
2498 
2499   if (l_policy_line_count = 0) then
2500     --------------
2501     -- parse cursor
2502     --------------
2503     DBMS_SQL.PARSE(l_permutate_curref,
2504                       l_insert_sql_stmt||
2505                       l_l_sql_stmt||
2506                       l_r_sql_stmt||
2507                       l_c_sql_stmt||
2508                       l_vc_sql_stmt||
2509                       l_vt_sql_stmt||
2510                       l_ft_sql_stmt||
2511                       l_dt_sql_stmt || '))', DBMS_SQL.NATIVE);
2512   else
2513     --------------
2514     -- parse cursor
2515     --------------
2516     DBMS_SQL.PARSE(l_permutate_curref,
2517                       l_insert_sql_stmt||
2518                       l_l_sql_stmt||
2519                       l_r_sql_stmt||
2520                       l_c_sql_stmt||
2521                       l_vc_sql_stmt||
2522                       l_vt_sql_stmt||
2523                       l_ft_sql_stmt||
2524                       l_dt_sql_stmt||
2525                       l_not_exists_sql_stmt, DBMS_SQL.NATIVE);
2526     --------------
2527     -- supply binds specific to this case
2528     --------------
2529     DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':dummy_number', -11);
2530     DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':dummy_varchar2', '-11');
2531 
2532   end if;
2533 
2534   --------------
2535   -- supply binds
2536   --------------
2537   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':p_policy_id', p_policy_id);
2538   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':p_schedule_period_id', l_schedule_period_id);
2539   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':p_user_id', p_user_id);
2540   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_LOCATION', c_LOCATION);
2541   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_EMPLOYEE_ROLE', c_EMPLOYEE_ROLE);
2542   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_CURRENCY', c_CURRENCY);
2543   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_VEHICLE_CATEGORY', c_VEHICLE_CATEGORY);
2544   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_VEHICLE_TYPE', c_VEHICLE_TYPE);
2545   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_FUEL_TYPE', c_FUEL_TYPE);
2546   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_DISTANCE_THRESHOLD', c_DISTANCE_THRESHOLD);
2547   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_TIME_THRESHOLD', c_TIME_THRESHOLD);
2548   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':p_rate_type', l_rate_type_code);
2549   --------------
2550   -- execute cursor
2551   --------------
2552   l_rows_permutated := DBMS_SQL.EXECUTE(l_permutate_curref);
2553 
2554   end loop;
2555   close c_schedule_period_id;
2556   --------------
2557   -- end loop thru all periods
2558   --------------
2559 
2560   --------------
2561   -- close cursor
2562   --------------
2563   DBMS_SQL.CLOSE_CURSOR(l_permutate_curref);
2564 
2565   close l_insert_cursor;
2566   close l_where_cursor;
2567   close l_not_exists_cursor;
2568 
2569   close l_l_cursor;
2570   close l_r_cursor;
2571   close l_c_cursor;
2572   close l_vc_cursor;
2573   close l_vt_cursor;
2574   close l_ft_cursor;
2575   close l_dt_cursor;
2576 
2577   ----------------------------------------------------------------------
2578   -- Permutate First Period, Last Period and Same Day Rates if implemented
2579   ----------------------------------------------------------------------
2580   BEGIN
2581 
2582     FOR rate_type_cur in c_rate_types
2583     LOOP
2584        permutatePolicyLines(p_user_id,
2585                             p_policy_id,
2586                             rate_type_cur.rate_type_code);
2587     END LOOP;
2588   END;
2589 
2590   -------------------------------------------------------------------------------
2591   -- Insert addon mileage rate permutations if addon rates have been enabled
2592   -------------------------------------------------------------------------------
2593   IF ( l_addon_rates_enabled = 'Y' ) THEN
2594      permutateAddonRates(p_user_id,
2595                          p_policy_id,
2596                          l_schedule_period_id);
2597   END IF;
2598 
2599   -------------------------------------------------------------------------------
2600   -- Insert addon mileage rate permutations if addon rates have been enabled
2601   -------------------------------------------------------------------------------
2602   IF ( l_night_rates_enabled = 'Y' ) THEN
2603      permutateNightRates(p_user_id,
2604                          p_policy_id,
2605                          l_schedule_period_id);
2606   END IF;
2607 
2608   -- -----------------------------------------------------------------------
2609   -- If this is an allowance schedule set the calculation methods to AMOUNT
2610   -- -----------------------------------------------------------------------
2611   IF ( l_schedule_type = 'ALLOWANCE' ) THEN
2612      update ap_pol_lines
2613      set    calculation_method = 'AMOUNT',
2614             accommodation_calc_method = 'AMOUNT'
2615      where  policy_id = p_policy_id
2616      and    nvl(calculation_method, 'X') <> 'AMOUNT';
2617   END IF;
2618 
2619   updateInactivePolicyLines(p_policy_id);
2620   checkAirfarePolicyLines(p_policy_id);
2621 
2622   status_saved_sched_opts(p_policy_id);
2623 
2624 
2625 EXCEPTION
2626  WHEN OTHERS THEN
2627   raise;
2628 END permutatePolicyLines;
2629 
2630 
2631 /*========================================================================
2632  | PUBLIC PROCEDURE removeObsoletedPolicyLines
2633  |
2634  | DESCRIPTION
2635  | - a policy line is obsolete if:
2636  |   1. if a rule has become disabled for an option already permutated
2637  |   2. if an option has been removed for an enabled rule
2638  |   3. if a new rule has been added then existing blank permutations becomes invalid
2639  |   4. if a new threshold has been added then existing threshold range becomes invalid
2640  |
2641  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
2642  |
2643  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
2644  |
2645  | PARAMETERS
2646  |  p_policy_id IN Policy Identifier
2647  |
2648  | MODIFICATION HISTORY
2649  | Date                  Author            Description of Changes
2650  | 16-May-2002           R Langi           Created
2651  |
2652  *=======================================================================*/
2653 PROCEDURE removeObsoletedPolicyLines(p_policy_id  IN ap_pol_headers.policy_id%TYPE) IS
2654 
2655   l_obsolete_curref		INTEGER;
2656   l_rows_obsoleted		NUMBER := 0;
2657 
2658   l_obsolete_sql_stmt		VARCHAR2(4000);
2659   l_l_sql_stmt                  VARCHAR2(4000);
2660   l_r_sql_stmt                  VARCHAR2(4000);
2661   l_c_sql_stmt                  VARCHAR2(4000);
2662   l_vc_sql_stmt                 VARCHAR2(4000);
2663   l_vt_sql_stmt                 VARCHAR2(4000);
2664   l_ft_sql_stmt                 VARCHAR2(4000);
2665   l_dt_sql_stmt                 VARCHAR2(4000);
2666   l_amr_sql_stmt                VARCHAR2(4000);
2667 
2668   l_currency_preference		ap_pol_headers.currency_preference%TYPE;
2669   l_currency_code		ap_pol_headers.currency_code%TYPE;
2670 
2671 cursor l_l_cursor is
2672 select
2673 '
2674   delete
2675   from   AP_POL_LINES pl
2676   where  pl.POLICY_ID = :p_policy_id
2677   and    ((pl.LOCATION_ID is not null
2678            and not exists
2679              (select pso.LOCATION_ID
2680               from   AP_POL_SCHEDULE_OPTIONS pso
2681               where  pso.POLICY_ID = pl.POLICY_ID
2682               and    pso.OPTION_TYPE = :c_LOCATION
2683               and    pso.LOCATION_ID is not null
2684               and    pso.LOCATION_ID = pl.LOCATION_ID
2685              )
2686           )
2687           or
2688           (pl.LOCATION_ID is null
2689            and exists
2690              (select pso.LOCATION_ID
2691               from   AP_POL_SCHEDULE_OPTIONS pso
2692               where  pso.POLICY_ID = pl.POLICY_ID
2693               and    pso.OPTION_TYPE = :c_LOCATION
2694               and    pso.LOCATION_ID is not null
2695              )
2696           )
2697 '
2698 from sys.dual; /* l_l_cursor */
2699 
2700 cursor l_r_cursor is
2701 select
2702 '
2703          or
2704          (pl.ROLE_ID is not null
2705           and not exists
2706             (select pso.ROLE_ID
2707              from   AP_POL_SCHEDULE_OPTIONS pso
2708              where  pso.POLICY_ID = pl.POLICY_ID
2709              and    pso.OPTION_TYPE = :c_EMPLOYEE_ROLE
2710              and    pso.ROLE_ID is not null
2711              and    pso.ROLE_ID = pl.ROLE_ID
2712             )
2713          )
2714          or
2715          (pl.ROLE_ID is null
2716           and exists
2717             (select pso.ROLE_ID
2718              from   AP_POL_SCHEDULE_OPTIONS pso
2719              where  pso.POLICY_ID = pl.POLICY_ID
2720              and    pso.OPTION_TYPE = :c_EMPLOYEE_ROLE
2721              and    pso.ROLE_ID is not null
2722             )
2723          )
2724 '
2725 from sys.dual; /* l_r_cursor */
2726 
2727 cursor l_c_cursor is
2728 select
2729 '
2730           or
2731           (pl.CURRENCY_CODE is not null
2732            and
2733            (not exists
2734              (select pso.CURRENCY_CODE
2735               from   AP_POL_SCHEDULE_OPTIONS pso
2736               where  pso.POLICY_ID = pl.POLICY_ID
2737               and    pso.OPTION_TYPE = :c_CURRENCY
2738               and    pso.CURRENCY_CODE is not null
2739               and    pso.CURRENCY_CODE = pl.CURRENCY_CODE
2740              )
2741             and
2742             not exists
2743              (select ph.CURRENCY_PREFERENCE
2744               from   AP_POL_HEADERS ph
2745               where  ph.POLICY_ID = pl.POLICY_ID
2746               and    (ph.CURRENCY_PREFERENCE = :c_SRC
2747                       or
2748                       ph.CURRENCY_PREFERENCE = :c_LCR
2749                      )
2750              )
2751            )
2752           )
2753           or
2754           (pl.CURRENCY_CODE is not null
2755            and
2756            exists
2757              (select ph.CURRENCY_PREFERENCE
2758               from   AP_POL_HEADERS ph
2759               where  ph.POLICY_ID = pl.POLICY_ID
2760               and    ph.CURRENCY_PREFERENCE = :c_SRC
2761              )
2762            and
2763            not exists
2764              (select ph.CURRENCY_CODE
2765               from   AP_POL_HEADERS ph
2766               where  ph.POLICY_ID = pl.POLICY_ID
2767               and    ph.CURRENCY_CODE = pl.CURRENCY_CODE
2768              )
2769           )
2770 '
2771 from sys.dual; /* l_c_cursor */
2772 
2773 cursor l_vc_cursor is
2774 select
2775 '
2776           or
2777           (pl.VEHICLE_CATEGORY is not null
2778            and not exists
2779            (select pso.OPTION_CODE
2780             from   AP_POL_SCHEDULE_OPTIONS pso
2781             where  pso.POLICY_ID = pl.POLICY_ID
2782             and    pso.OPTION_TYPE = :c_VEHICLE_CATEGORY
2783             and    pso.OPTION_CODE is not null
2784             and    pso.OPTION_CODE = pl.VEHICLE_CATEGORY
2785            )
2786           )
2787           or
2788           (pl.VEHICLE_CATEGORY is null
2789            and exists
2790            (select pso.OPTION_CODE
2791             from   AP_POL_SCHEDULE_OPTIONS pso
2792             where  pso.POLICY_ID = pl.POLICY_ID
2793             and    pso.OPTION_TYPE = :c_VEHICLE_CATEGORY
2794             and    pso.OPTION_CODE is not null
2795            )
2796           )
2797 '
2798 from sys.dual; /* l_vc_cursor */
2799 
2800 cursor l_vt_cursor is
2801 select
2802 '
2803           or
2804           (pl.VEHICLE_TYPE is not null
2805            and
2806            (not exists
2807            (select pso.OPTION_CODE
2808             from   AP_POL_SCHEDULE_OPTIONS pso
2809             where  pso.POLICY_ID = pl.POLICY_ID
2810             and    pso.OPTION_TYPE = :c_VEHICLE_TYPE
2811             and    pso.OPTION_CODE is not null
2812             and    pso.OPTION_CODE = pl.VEHICLE_TYPE
2813            )
2814            or exists
2815            (select pso.OPTION_CODE
2816             from   AP_POL_SCHEDULE_OPTIONS pso
2817             where  pso.POLICY_ID = pl.POLICY_ID
2818             and    pso.OPTION_TYPE = :c_VEHICLE_CATEGORY
2819             and    pso.OPTION_CODE = pl.VEHICLE_CATEGORY
2820             and    pso.VEHICLE_TYPE_CODE <> ''R''
2821            ))
2822           )
2823           or
2824           (pl.VEHICLE_TYPE is null
2825            and exists
2826            (select pso.OPTION_CODE
2827             from   AP_POL_SCHEDULE_OPTIONS pso
2828             where  pso.POLICY_ID = pl.POLICY_ID
2829             and    pso.OPTION_TYPE = :c_VEHICLE_TYPE
2830             and    pso.OPTION_CODE is not null
2831            )
2832            and not exists
2833            (select pso.OPTION_CODE
2834             from   AP_POL_SCHEDULE_OPTIONS pso
2835             where  pso.POLICY_ID = pl.POLICY_ID
2836             and    pso.OPTION_TYPE = :c_VEHICLE_CATEGORY
2837             and    pso.OPTION_CODE = pl.VEHICLE_CATEGORY
2838             and    pso.VEHICLE_TYPE_CODE <> ''R''
2839            )
2840           )
2841 '
2842 from sys.dual; /* l_vt_cursor */
2843 
2844 cursor l_ft_cursor is
2845 select
2846 '
2847           or
2848           (pl.FUEL_TYPE is not null
2849            and
2850            (not exists
2851            (select pso.OPTION_CODE
2852             from   AP_POL_SCHEDULE_OPTIONS pso
2853             where  pso.POLICY_ID = pl.POLICY_ID
2854             and    pso.OPTION_TYPE = :c_FUEL_TYPE
2855             and    pso.OPTION_CODE is not null
2856             and    pso.OPTION_CODE = pl.FUEL_TYPE
2857            )
2858            or exists
2859            (select pso.OPTION_CODE
2860             from   AP_POL_SCHEDULE_OPTIONS pso
2861             where  pso.POLICY_ID = pl.POLICY_ID
2862             and    pso.OPTION_TYPE = :c_VEHICLE_CATEGORY
2863             and    pso.OPTION_CODE = pl.VEHICLE_CATEGORY
2864             and    pso.FUEL_TYPE_CODE <> ''R''
2865            ))
2866           )
2867           or
2868           (pl.FUEL_TYPE is null
2869            and exists
2870            (select pso.OPTION_CODE
2871             from   AP_POL_SCHEDULE_OPTIONS pso
2872             where  pso.POLICY_ID = pl.POLICY_ID
2873             and    pso.OPTION_TYPE = :c_FUEL_TYPE
2874             and    pso.OPTION_CODE is not null
2875            )
2876            and not exists
2877            (select pso.OPTION_CODE
2878             from   AP_POL_SCHEDULE_OPTIONS pso
2879             where  pso.POLICY_ID = pl.POLICY_ID
2880             and    pso.OPTION_TYPE = :c_VEHICLE_CATEGORY
2881             and    pso.OPTION_CODE = pl.VEHICLE_CATEGORY
2882             and    pso.FUEL_TYPE_CODE <> ''R''
2883            )
2884           )
2885 '
2886 from sys.dual; /* l_ft_cursor */
2887 
2888 cursor l_dt_cursor is
2889 select
2890 '
2891           or
2892           (pl.RANGE_LOW is not null
2893            and not exists
2894            (select pso.THRESHOLD
2895             from   AP_POL_SCHEDULE_OPTIONS pso
2896             where  pso.POLICY_ID = pl.POLICY_ID
2897             and    (pso.OPTION_TYPE = :c_DISTANCE_THRESHOLD or pso.OPTION_TYPE = :c_TIME_THRESHOLD)
2898             and    pso.THRESHOLD is not null
2899             and    pso.THRESHOLD = pl.RANGE_LOW
2900             and    nvl(pso.rate_type_code, ''NULL'') = nvl(pl.rate_type_code, ''NULL'')
2901            )
2902           )
2903           or
2904           (pl.RANGE_HIGH is not null
2905            and not exists
2906            (select pso.THRESHOLD
2907             from   AP_POL_SCHEDULE_OPTIONS pso
2908             where  pso.POLICY_ID = pl.POLICY_ID
2909             and    (pso.OPTION_TYPE = :c_DISTANCE_THRESHOLD or pso.OPTION_TYPE = :c_TIME_THRESHOLD)
2910             and    pso.THRESHOLD is not null
2911             and    pso.THRESHOLD = pl.RANGE_HIGH
2912             and    nvl(pso.rate_type_code, ''NULL'') = nvl(pl.rate_type_code, ''NULL'')
2913            )
2914           )
2915           or
2916           (pl.RANGE_LOW is null
2917            and exists
2918            (select pso.THRESHOLD
2919             from   AP_POL_SCHEDULE_OPTIONS pso
2920             where  pso.POLICY_ID = pl.POLICY_ID
2921             and    (pso.OPTION_TYPE = :c_DISTANCE_THRESHOLD or pso.OPTION_TYPE = :c_TIME_THRESHOLD)
2922             and    pso.THRESHOLD is not null
2923             and    nvl(pso.rate_type_code, ''NULL'') = nvl(pl.rate_type_code, ''NULL'')
2924            )
2925           )
2926           or
2927           (pl.RANGE_LOW is not null
2928            and
2929            nvl(pl.RANGE_HIGH, :dummy_number) <>
2930                  nvl(AP_WEB_POLICY_UTILS.getHighEndOfThreshold(pl.POLICY_ID,
2931                                                                pl.RANGE_LOW,
2932                                                                nvl(pl.rate_type_code,''STANDARD'')), :dummy_number)
2933           )
2934 '
2935 from sys.dual; /* l_dt_cursor */
2936 
2937 ---------------------------------------
2938 -- cursor for addon mileage rates
2939 -- Note: we do not need to remove any addon rate lines
2940 -- for the case of new addon rate rule since these lines
2941 -- would never have existed.
2942 ---------------------------------------
2943 cursor l_amr_cursor is
2944 select
2945 '       or
2946         (pl.ADDON_MILEAGE_RATE_CODE is not null
2947            and not exists
2948              (select pso.OPTION_CODE
2949               from   AP_POL_SCHEDULE_OPTIONS pso
2950               where  pso.POLICY_ID = pl.POLICY_ID
2951               and    pso.OPTION_TYPE = :c_ADDON_RATES
2952               and    pso.OPTION_CODE is not null
2953               and    pso.OPTION_CODE = pl.ADDON_MILEAGE_RATE_CODE
2954              )
2955           )
2956 
2957        )
2958 '
2959 from sys.dual; /* l_amr_cursor */
2960 
2961 
2962 BEGIN
2963 
2964   open l_l_cursor;
2965   open l_r_cursor;
2966   open l_c_cursor;
2967   open l_vc_cursor;
2968   open l_vt_cursor;
2969   open l_ft_cursor;
2970   open l_dt_cursor;
2971   open l_amr_cursor;
2972 
2973   fetch l_l_cursor into l_l_sql_stmt;
2974   fetch l_r_cursor into l_r_sql_stmt;
2975   fetch l_c_cursor into l_c_sql_stmt;
2976   fetch l_vc_cursor into l_vc_sql_stmt;
2977   fetch l_vt_cursor into l_vt_sql_stmt;
2978   fetch l_ft_cursor into l_ft_sql_stmt;
2979   fetch l_dt_cursor into l_dt_sql_stmt;
2980   fetch l_amr_cursor into l_amr_sql_stmt;
2981 
2982 
2983   --------------
2984   -- open cursor
2985   --------------
2986   l_obsolete_curref := DBMS_SQL.OPEN_CURSOR;
2987 
2988   --------------
2989   -- parse cursor
2990   --------------
2991   DBMS_SQL.PARSE(l_obsolete_curref,
2992                  l_l_sql_stmt||
2993                  l_r_sql_stmt||
2994                  l_c_sql_stmt||
2995                  l_vc_sql_stmt||
2996                  l_vt_sql_stmt||
2997                  l_ft_sql_stmt||
2998                  l_dt_sql_stmt||
2999                  l_amr_sql_stmt,
3000                  DBMS_SQL.NATIVE);
3001 
3002   --------------
3003   -- supply binds
3004   --------------
3005   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':p_policy_id', p_policy_id);
3006   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_LOCATION', c_LOCATION);
3007   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_EMPLOYEE_ROLE', c_EMPLOYEE_ROLE);
3008   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_CURRENCY', c_CURRENCY);
3009   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_LCR', c_LCR);
3010   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_SRC', c_SRC);
3011   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_VEHICLE_CATEGORY', c_VEHICLE_CATEGORY);
3012   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_VEHICLE_TYPE', c_VEHICLE_TYPE);
3013   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_FUEL_TYPE', c_FUEL_TYPE);
3014   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_DISTANCE_THRESHOLD', c_DISTANCE_THRESHOLD);
3015   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_TIME_THRESHOLD', c_TIME_THRESHOLD);
3016   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':c_ADDON_RATES', c_ADDON_RATES);
3017   DBMS_SQL.BIND_VARIABLE(l_obsolete_curref, ':dummy_number', -11);
3018 
3019   --------------
3020   -- execute cursor
3021   --------------
3022   l_rows_obsoleted := DBMS_SQL.EXECUTE(l_obsolete_curref);
3023 
3024   --------------
3025   -- close cursor
3026   --------------
3027   DBMS_SQL.CLOSE_CURSOR(l_obsolete_curref);
3028 
3029 
3030   close l_l_cursor;
3031   close l_r_cursor;
3032   close l_c_cursor;
3033   close l_vc_cursor;
3034   close l_vt_cursor;
3035   close l_ft_cursor;
3036   close l_dt_cursor;
3037   close l_amr_cursor;
3038 
3039 EXCEPTION
3040  WHEN OTHERS THEN
3041   raise;
3042 END removeObsoletedPolicyLines;
3043 
3044 
3045 /*========================================================================
3046  | PUBLIC PROCEDURE updateInactivePolicyLines
3047  |
3048  | DESCRIPTION
3049  | - if option end dated then set Policy Line status to inactive
3050  | - reactivate inactive lines if end date updated
3051  |
3052  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
3053  |
3054  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
3055  |
3056  | PARAMETERS
3057  |  p_policy_id IN Policy Identifier
3058  |
3059  | MODIFICATION HISTORY
3060  | Date                  Author            Description of Changes
3061  | 16-May-2002           R Langi           Created
3062  |
3063  *=======================================================================*/
3064 PROCEDURE updateInactivePolicyLines(p_policy_id  IN ap_pol_headers.policy_id%TYPE) IS
3065 
3066   l_inactive_curref		INTEGER;
3067   l_rows_inactivated		NUMBER := 0;
3068 
3069   l_active_curref		INTEGER;
3070   l_rows_activated		NUMBER := 0;
3071 
3072   l_inactive_sql_stmt		VARCHAR2(4000);
3073   l_active_sql_stmt		VARCHAR2(4000);
3074 
3075 
3076 cursor l_inactive_cursor is
3077 select
3078 '
3079   update AP_POL_LINES pl
3080   set    pl.STATUS = :c_INACTIVE
3081   where  pl.POLICY_ID = :p_policy_id
3082   and    pl.STATUS = :c_ACTIVE
3083   and    ((pl.LOCATION_ID is not null
3084            and exists
3085            (select pso.LOCATION_ID
3086             from   AP_POL_SCHEDULE_OPTIONS pso
3087             where  pso.POLICY_ID = pl.POLICY_ID
3088             and    pso.OPTION_TYPE = :c_LOCATION
3089             and    pso.LOCATION_ID is not null
3090             and    pso.LOCATION_ID = pl.LOCATION_ID
3091             and    nvl(pso.END_DATE, SYSDATE+1) < SYSDATE
3092            )
3093           )
3094           or
3095           (pl.ROLE_ID is not null
3096            and exists
3097            (select pso.ROLE_ID
3098             from   AP_POL_SCHEDULE_OPTIONS pso
3099             where  pso.POLICY_ID = pl.POLICY_ID
3100             and    pso.OPTION_TYPE = :c_EMPLOYEE_ROLE
3101             and    pso.ROLE_ID is not null
3102             and    pso.ROLE_ID = pl.ROLE_ID
3103             and    nvl(pso.END_DATE, SYSDATE+1) < SYSDATE
3104            )
3105           )
3106           or
3107           (pl.CURRENCY_CODE is not null
3108            and exists
3109            (select pso.CURRENCY_CODE
3110             from   AP_POL_SCHEDULE_OPTIONS pso
3111             where  pso.POLICY_ID = pl.POLICY_ID
3112             and    pso.OPTION_TYPE = :c_CURRENCY
3113             and    pso.CURRENCY_CODE is not null
3114             and    pso.CURRENCY_CODE = pl.CURRENCY_CODE
3115             and    nvl(pso.END_DATE, SYSDATE+1) < SYSDATE
3116            )
3117           )
3118           or
3119           (pl.VEHICLE_CATEGORY is not null
3120            and exists
3121            (select pso.OPTION_CODE
3122             from   AP_POL_SCHEDULE_OPTIONS pso
3123             where  pso.POLICY_ID = pl.POLICY_ID
3124             and    pso.OPTION_TYPE = :c_VEHICLE_CATEGORY
3125             and    pso.OPTION_CODE is not null
3126             and    pso.OPTION_CODE = pl.VEHICLE_CATEGORY
3127             and    nvl(pso.END_DATE, SYSDATE+1) < SYSDATE
3128            )
3129           )
3130           or
3131           (pl.VEHICLE_TYPE is not null
3132            and exists
3133            (select pso.OPTION_CODE
3134             from   AP_POL_SCHEDULE_OPTIONS pso
3135             where  pso.POLICY_ID = pl.POLICY_ID
3136             and    pso.OPTION_TYPE = :c_VEHICLE_TYPE
3137             and    pso.OPTION_CODE is not null
3138             and    pso.OPTION_CODE = pl.VEHICLE_TYPE
3139             and    nvl(pso.END_DATE, SYSDATE+1) < SYSDATE
3140            )
3141           )
3142           or
3143           (pl.FUEL_TYPE is not null
3144            and exists
3145            (select pso.OPTION_CODE
3146             from   AP_POL_SCHEDULE_OPTIONS pso
3147             where  pso.POLICY_ID = pl.POLICY_ID
3148             and    pso.OPTION_TYPE = :c_FUEL_TYPE
3149             and    pso.OPTION_CODE is not null
3150             and    pso.OPTION_CODE = pl.FUEL_TYPE
3151             and    nvl(pso.END_DATE, SYSDATE+1) < SYSDATE
3152            )
3153           )
3154           or
3155           (pl.RANGE_LOW is not null
3156            and exists
3157            (select pso.THRESHOLD
3158             from   AP_POL_SCHEDULE_OPTIONS pso
3159             where  pso.POLICY_ID = pl.POLICY_ID
3160             and    (pso.OPTION_TYPE = :c_DISTANCE_THRESHOLD or pso.OPTION_TYPE = :c_TIME_THRESHOLD)
3161             and    pso.THRESHOLD is not null
3162             and    pso.THRESHOLD = pl.RANGE_LOW
3163             and    nvl(pso.END_DATE, SYSDATE+1) < SYSDATE
3164            )
3165           )
3166          )
3167 '
3168 from sys.dual; /* l_inactive_cursor */
3169 
3170 
3171 cursor l_active_cursor is
3172 select
3173 '
3174   update AP_POL_LINES pl
3175   set    pl.STATUS = :c_ACTIVE
3176   where  pl.POLICY_ID = :p_policy_id
3177   and    pl.STATUS = :c_INACTIVE
3178   and    (((pl.LOCATION_ID is not null
3179             and exists
3180             (select pso.LOCATION_ID
3181              from   AP_POL_SCHEDULE_OPTIONS pso
3182              where  pso.POLICY_ID = pl.POLICY_ID
3183              and    pso.OPTION_TYPE = :c_LOCATION
3184              and    pso.LOCATION_ID is not null
3185              and    pso.LOCATION_ID = pl.LOCATION_ID
3186              and    nvl(pso.END_DATE, SYSDATE+1) > SYSDATE
3187             )
3188            ) or pl.LOCATION_ID is null
3189           )
3190           and
3191           ((pl.ROLE_ID is not null
3192             and exists
3193             (select pso.ROLE_ID
3194              from   AP_POL_SCHEDULE_OPTIONS pso
3195              where  pso.POLICY_ID = pl.POLICY_ID
3196              and    pso.OPTION_TYPE = :c_EMPLOYEE_ROLE
3197              and    pso.ROLE_ID is not null
3198              and    pso.ROLE_ID = pl.ROLE_ID
3199              and    nvl(pso.END_DATE, SYSDATE+1) > SYSDATE
3200             )
3201            ) or pl.ROLE_ID is null
3202           )
3203           and
3204           ((pl.CURRENCY_CODE is not null
3205             and
3206             (exists
3207               (select pso.CURRENCY_CODE
3208                from   AP_POL_SCHEDULE_OPTIONS pso
3209                where  pso.POLICY_ID = pl.POLICY_ID
3210                and    pso.OPTION_TYPE = :c_CURRENCY
3211                and    pso.CURRENCY_CODE is not null
3212                and    pso.CURRENCY_CODE = pl.CURRENCY_CODE
3213                and    nvl(pso.END_DATE, SYSDATE+1) > SYSDATE
3214               )
3215              or exists
3216               (select ph.CURRENCY_CODE
3217                from   AP_POL_HEADERS ph
3218                where  ph.POLICY_ID = pl.POLICY_ID
3219                and    ((ph.CURRENCY_CODE is not null and ph.CURRENCY_CODE = pl.CURRENCY_CODE)
3220                       or
3221                        (ph.CURRENCY_CODE is null and ph.CURRENCY_PREFERENCE <> :c_SRC)))
3222             )
3223            )
3224            or pl.CURRENCY_CODE is null
3225           )
3226           and
3227           ((pl.VEHICLE_CATEGORY is not null
3228             and exists
3229             (select pso.OPTION_CODE
3230              from   AP_POL_SCHEDULE_OPTIONS pso
3231              where  pso.POLICY_ID = pl.POLICY_ID
3232              and    pso.OPTION_TYPE = :c_VEHICLE_CATEGORY
3233              and    pso.OPTION_CODE is not null
3234              and    pso.OPTION_CODE = pl.VEHICLE_CATEGORY
3235              and    nvl(pso.END_DATE, SYSDATE+1) > SYSDATE
3236             )
3237            ) or pl.VEHICLE_CATEGORY is null
3238           )
3239           and
3240           ((pl.VEHICLE_TYPE is not null
3241             and exists
3242             (select pso.OPTION_CODE
3243              from   AP_POL_SCHEDULE_OPTIONS pso
3244              where  pso.POLICY_ID = pl.POLICY_ID
3245              and    pso.OPTION_TYPE = :c_VEHICLE_TYPE
3246              and    pso.OPTION_CODE is not null
3247              and    pso.OPTION_CODE = pl.VEHICLE_TYPE
3248              and    nvl(pso.END_DATE, SYSDATE+1) > SYSDATE
3249             ) or pl.VEHICLE_TYPE is null
3250            )
3251           )
3252           and
3253           ((pl.FUEL_TYPE is not null
3254             and exists
3255             (select pso.OPTION_CODE
3256              from   AP_POL_SCHEDULE_OPTIONS pso
3257              where  pso.POLICY_ID = pl.POLICY_ID
3258              and    pso.OPTION_TYPE = :c_FUEL_TYPE
3259              and    pso.OPTION_CODE is not null
3260              and    pso.OPTION_CODE = pl.FUEL_TYPE
3261              and    nvl(pso.END_DATE, SYSDATE+1) > SYSDATE
3262             )
3263            ) or pl.FUEL_TYPE is null
3264           )
3265           and
3266           ((pl.RANGE_LOW is not null
3267             and exists
3268             (select pso.THRESHOLD
3269              from   AP_POL_SCHEDULE_OPTIONS pso
3270              where  pso.POLICY_ID = pl.POLICY_ID
3271              and    (pso.OPTION_TYPE = :c_DISTANCE_THRESHOLD or pso.OPTION_TYPE = :c_TIME_THRESHOLD)
3272              and    pso.THRESHOLD is not null
3273              and    pso.THRESHOLD = pl.RANGE_LOW
3274              and    nvl(pso.END_DATE, SYSDATE+1) > SYSDATE
3275             )
3276            ) or pl.RANGE_LOW is null
3277           )
3278          )
3279 '
3280 from sys.dual; /* l_active_cursor */
3281 
3282 BEGIN
3283 
3284   --------------------------------------------------------------
3285   -- if option end dated then set Policy Line status to inactive
3286   --------------------------------------------------------------
3287   open l_inactive_cursor;
3288   fetch l_inactive_cursor into l_inactive_sql_stmt;
3289 
3290   --------------
3291   -- open cursor
3292   --------------
3293   l_inactive_curref := DBMS_SQL.OPEN_CURSOR;
3294 
3295   --------------
3296   -- parse cursor
3297   --------------
3298   DBMS_SQL.PARSE(l_inactive_curref,
3299                  l_inactive_sql_stmt,
3300                  DBMS_SQL.NATIVE);
3301 
3302   --------------
3303   -- supply binds
3304   --------------
3305   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':p_policy_id', p_policy_id);
3306   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':c_INACTIVE', c_INACTIVE);
3307   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':c_ACTIVE', c_ACTIVE);
3308   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':c_LOCATION', c_LOCATION);
3309   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':c_EMPLOYEE_ROLE', c_EMPLOYEE_ROLE);
3310   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':c_CURRENCY', c_CURRENCY);
3311   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':c_VEHICLE_CATEGORY', c_VEHICLE_CATEGORY);
3312   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':c_VEHICLE_TYPE', c_VEHICLE_TYPE);
3313   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':c_FUEL_TYPE', c_FUEL_TYPE);
3314   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':c_DISTANCE_THRESHOLD', c_DISTANCE_THRESHOLD);
3315   DBMS_SQL.BIND_VARIABLE(l_inactive_curref, ':c_TIME_THRESHOLD', c_TIME_THRESHOLD);
3316 
3317   --------------
3318   -- execute cursor
3319   --------------
3320   l_rows_inactivated := DBMS_SQL.EXECUTE(l_inactive_curref);
3321 
3322   --------------
3323   -- close cursor
3324   --------------
3325   DBMS_SQL.CLOSE_CURSOR(l_inactive_curref);
3326 
3327   close l_inactive_cursor;
3328 
3329 
3330   --------------------------------------------------------------
3331   -- reactivate inactive lines if end date updated
3332   --------------------------------------------------------------
3333   open l_active_cursor;
3334   fetch l_active_cursor into l_active_sql_stmt;
3335 
3336   --------------
3337   -- open cursor
3338   --------------
3339   l_active_curref := DBMS_SQL.OPEN_CURSOR;
3340 
3341   --------------
3342   -- parse cursor
3343   --------------
3344   DBMS_SQL.PARSE(l_active_curref,
3345                  l_active_sql_stmt,
3346                  DBMS_SQL.NATIVE);
3347 
3348   --------------
3349   -- supply binds
3350   --------------
3351   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':p_policy_id', p_policy_id);
3352   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_INACTIVE', c_INACTIVE);
3353   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_ACTIVE', c_ACTIVE);
3354   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_LOCATION', c_LOCATION);
3355   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_EMPLOYEE_ROLE', c_EMPLOYEE_ROLE);
3356   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_CURRENCY', c_CURRENCY);
3357   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_SRC', c_SRC);
3358   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_VEHICLE_CATEGORY', c_VEHICLE_CATEGORY);
3359   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_VEHICLE_TYPE', c_VEHICLE_TYPE);
3360   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_FUEL_TYPE', c_FUEL_TYPE);
3361   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_DISTANCE_THRESHOLD', c_DISTANCE_THRESHOLD);
3362   DBMS_SQL.BIND_VARIABLE(l_active_curref, ':c_TIME_THRESHOLD', c_TIME_THRESHOLD);
3363 
3364   --------------
3365   -- execute cursor
3366   --------------
3367   l_rows_activated := DBMS_SQL.EXECUTE(l_active_curref);
3368 
3369   --------------
3370   -- close cursor
3371   --------------
3372   DBMS_SQL.CLOSE_CURSOR(l_active_curref);
3373 
3374   close l_active_cursor;
3375 
3376 EXCEPTION
3377  WHEN OTHERS THEN
3378   raise;
3379 END updateInactivePolicyLines;
3380 
3381 
3382 /*========================================================================
3383  | PUBLIC PROCEDURE duplicatePolicyLines
3384  |
3385  | DESCRIPTION
3386  |  Duplicates Policy Lines from one Policy Schedule Period to another
3387  |
3388  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
3389  |
3390  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
3391  |
3392  | PARAMETERS
3393  |  p_user_id IN User Identifier
3394  |  p_from_policy_id IN Policy Identifier to duplicate From
3395  |  p_from_schedule_period_id IN Policy Schedule Period Identifier to duplicate From
3396  |  p_to_policy_id IN Policy Identifier to duplicate To
3397  |  p_to_schedule_period_id IN Policy Schedule Period Identifier to duplicate To
3398  |
3399  | MODIFICATION HISTORY
3400  | Date                  Author            Description of Changes
3401  | 16-May-2002           R Langi           Created
3402  |
3403  *=======================================================================*/
3404 PROCEDURE duplicatePolicyLines(p_user_id IN NUMBER,
3405                                p_from_policy_id  IN ap_pol_headers.policy_id%TYPE,
3406                                p_from_schedule_period_id  IN ap_pol_schedule_periods.schedule_period_id%TYPE,
3407                                p_to_policy_id  IN ap_pol_headers.policy_id%TYPE,
3408                                p_to_schedule_period_id  IN ap_pol_schedule_periods.schedule_period_id%TYPE) IS
3409 
3410   l_duplicate_curref		INTEGER;
3411   l_rows_duplicated		NUMBER := 0;
3412 
3413   l_duplicate_sql_stmt		VARCHAR2(4000);
3414 
3415 cursor l_duplicate_cursor is
3416 select
3417 '
3418   insert into AP_POL_LINES
3419         (
3420          POLICY_LINE_ID,
3421          POLICY_ID,
3422          SCHEDULE_PERIOD_ID,
3423          LOCATION_ID,
3424          ROLE_ID,
3425          CURRENCY_CODE,
3426          MEAL_LIMIT,
3427          RATE,
3428          TOLERANCE,
3429          TICKET_CLASS_DOMESTIC,
3430          TICKET_CLASS_INTERNATIONAL,
3431          VEHICLE_CATEGORY,
3432          VEHICLE_TYPE,
3433          FUEL_TYPE,
3434          RANGE_LOW,
3435          RANGE_HIGH,
3436          CALCULATION_METHOD,
3437          MEALS_DEDUCTION,
3438          BREAKFAST_DEDUCTION,
3439          LUNCH_DEDUCTION,
3440          DINNER_DEDUCTION,
3441          ACCOMMODATION_ADJUSTMENT,
3442          ADDON_MILEAGE_RATE_CODE,
3443          RATE_PER_PASSENGER,
3444          RATE_TYPE_CODE,
3445          ONE_MEAL_DEDUCTION_AMT,
3446          TWO_MEALS_DEDUCTION_AMT,
3447          THREE_MEALS_DEDUCTION_AMT,
3448          NIGHT_RATE_TYPE_CODE,
3449          ACCOMMODATION_CALC_METHOD,
3450          START_OF_SEASON,
3451          END_OF_SEASON,
3452          MAX_LODGING_AMT,
3453          NO_GOVT_MEALS_AMT,
3454          PROP_MEALS_AMT,
3455          OFF_BASE_INC_AMT,
3456          FOOTNOTE_AMT,
3457          FOOTNOTE_RATE_AMT,
3458          MAX_PER_DIEM_AMT,
3459          EFFECTIVE_START_DATE,
3460          EFFECTIVE_END_DATE,
3461          STATUS,
3462          CREATION_DATE,
3463          CREATED_BY,
3464          LAST_UPDATE_DATE,
3465          LAST_UPDATED_BY,
3466          REIMBURSEMENT_PERCENTAGE,
3467          MAX_RECEIPT_AMT
3468         )
3469   select
3470          AP_POL_LINES_S.NEXTVAL AS POLICY_LINE_ID,
3471          :p_to_policy_id AS POLICY_ID,
3472          :p_to_schedule_period_id AS SCHEDULE_PERIOD_ID,
3473          LOCATION_ID,
3474          ROLE_ID,
3475          CURRENCY_CODE,
3476          MEAL_LIMIT,
3477          RATE,
3478          TOLERANCE,
3479          TICKET_CLASS_DOMESTIC,
3480          TICKET_CLASS_INTERNATIONAL,
3481          VEHICLE_CATEGORY,
3482          VEHICLE_TYPE,
3483          FUEL_TYPE,
3484          RANGE_LOW,
3485          RANGE_HIGH,
3486          CALCULATION_METHOD,
3487          MEALS_DEDUCTION,
3488          BREAKFAST_DEDUCTION,
3489          LUNCH_DEDUCTION,
3490          DINNER_DEDUCTION,
3491          ACCOMMODATION_ADJUSTMENT,
3492          ADDON_MILEAGE_RATE_CODE,
3493          RATE_PER_PASSENGER,
3494          RATE_TYPE_CODE,
3495          ONE_MEAL_DEDUCTION_AMT,
3496          TWO_MEALS_DEDUCTION_AMT,
3497          THREE_MEALS_DEDUCTION_AMT,
3498          NIGHT_RATE_TYPE_CODE,
3499          ACCOMMODATION_CALC_METHOD,
3500          START_OF_SEASON,
3501          END_OF_SEASON,
3502          MAX_LODGING_AMT,
3503          NO_GOVT_MEALS_AMT,
3504          PROP_MEALS_AMT,
3505          OFF_BASE_INC_AMT,
3506          FOOTNOTE_AMT,
3507          FOOTNOTE_RATE_AMT,
3508          MAX_PER_DIEM_AMT,
3509          EFFECTIVE_START_DATE,
3510          EFFECTIVE_END_DATE,
3511          decode(status, ''ACTIVE'', ''VALID'', ''VALID'', ''VALID'', :c_DUPLICATED) AS STATUS,
3512          sysdate AS CREATION_DATE,
3513          :p_user_id AS CREATED_BY,
3514          sysdate AS LAST_UPDATE_DATE,
3515          :p_user_id AS LAST_UPDATED_BY,
3516          REIMBURSEMENT_PERCENTAGE,
3517          MAX_RECEIPT_AMT
3518   from
3519          AP_POL_LINES
3520   where  POLICY_ID = :p_from_policy_id
3521   and    SCHEDULE_PERIOD_ID = :p_from_schedule_period_id
3522   and    PARENT_LINE_ID is null
3523 '
3524 from sys.dual; /* l_duplicate_cursor */
3525 
3526 
3527 BEGIN
3528 
3529   open l_duplicate_cursor;
3530   fetch l_duplicate_cursor into l_duplicate_sql_stmt;
3531 
3532   --------------
3533   -- open cursor
3534   --------------
3535   l_duplicate_curref := DBMS_SQL.OPEN_CURSOR;
3536 
3537   --------------
3538   -- parse cursor
3539   --------------
3540   DBMS_SQL.PARSE(l_duplicate_curref,
3541                  l_duplicate_sql_stmt,
3542                  DBMS_SQL.NATIVE);
3543 
3544   --------------
3545   -- supply binds
3546   --------------
3547   DBMS_SQL.BIND_VARIABLE(l_duplicate_curref, ':p_from_policy_id', p_from_policy_id);
3548   DBMS_SQL.BIND_VARIABLE(l_duplicate_curref, ':p_from_schedule_period_id', p_from_schedule_period_id);
3549   DBMS_SQL.BIND_VARIABLE(l_duplicate_curref, ':p_to_policy_id', p_to_policy_id);
3550   DBMS_SQL.BIND_VARIABLE(l_duplicate_curref, ':p_to_schedule_period_id', p_to_schedule_period_id);
3551   DBMS_SQL.BIND_VARIABLE(l_duplicate_curref, ':p_user_id', p_user_id);
3552   DBMS_SQL.BIND_VARIABLE(l_duplicate_curref, ':c_DUPLICATED', c_DUPLICATED);
3553 
3554   --------------
3555   -- execute cursor
3556   --------------
3557   l_rows_duplicated := DBMS_SQL.EXECUTE(l_duplicate_curref);
3558 
3559   --------------
3560   -- close cursor
3561   --------------
3562   DBMS_SQL.CLOSE_CURSOR(l_duplicate_curref);
3563 
3564   close l_duplicate_cursor;
3565 
3566 EXCEPTION
3567  WHEN OTHERS THEN
3568   raise;
3569 END duplicatePolicyLines;
3570 
3571 
3572 
3573 /*========================================================================
3574  | PUBLIC PROCEDURE preservePolicyLine
3575  |
3576  | DESCRIPTION
3577  |  Preserve a modified Active Policy Line
3578  |
3579  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
3580  |
3581  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
3582  |
3583  | PARAMETERS
3584  |  p_user_id IN User Identifier
3585  |  p_policy_id IN Policy Identifier
3586  |  p_schedule_period_id IN Policy Schedule Period Identifier
3587  |  p_policy_line_id IN Policy Line Identifier to preserve
3588  |
3589  | MODIFICATION HISTORY
3590  | Date                  Author            Description of Changes
3591  | 12-Aug-2002           R Langi           Created
3592  |
3593  *=======================================================================*/
3594 PROCEDURE preservePolicyLine(p_user_id IN NUMBER,
3595                              p_policy_id  IN ap_pol_lines.policy_id%TYPE,
3596                              p_schedule_period_id  IN ap_pol_lines.schedule_period_id%TYPE,
3597                              p_policy_line_id  IN ap_pol_lines.policy_line_id%TYPE) IS
3598 
3599   l_preserve_count 	NUMBER := 0;
3600 
3601 BEGIN
3602 
3603   ---------------------------------------
3604   -- sanity check if modified Active policy
3605   -- line is already preserved
3606   ---------------------------------------
3607   select count(*)
3608   into   l_preserve_count
3609   from   AP_POL_LINES
3610   where  parent_line_id = p_policy_line_id
3611   and    policy_id = p_policy_id
3612   and    schedule_period_id = p_schedule_period_id;
3613 
3614   if (l_preserve_count > 0) then
3615     return;
3616   end if;
3617 
3618   ---------------------------------------
3619   -- preserve modified Active policy line
3620   ---------------------------------------
3621   insert into AP_POL_LINES
3622         (
3623          PARENT_LINE_ID,
3624          POLICY_LINE_ID,
3625          POLICY_ID,
3626          SCHEDULE_PERIOD_ID,
3627          LOCATION_ID,
3628          ROLE_ID,
3629          CURRENCY_CODE,
3630          MEAL_LIMIT,
3631          RATE,
3632          TOLERANCE,
3633          TICKET_CLASS_DOMESTIC,
3634          TICKET_CLASS_INTERNATIONAL,
3635          VEHICLE_CATEGORY,
3636          VEHICLE_TYPE,
3637          FUEL_TYPE,
3638          RANGE_LOW,
3639          RANGE_HIGH,
3640          CALCULATION_METHOD,
3641          MEALS_DEDUCTION,
3642          BREAKFAST_DEDUCTION,
3643          LUNCH_DEDUCTION,
3644          DINNER_DEDUCTION,
3645          ACCOMMODATION_ADJUSTMENT,
3646          ADDON_MILEAGE_RATE_CODE,
3647          RATE_PER_PASSENGER,
3648          RATE_TYPE_CODE,
3649          ONE_MEAL_DEDUCTION_AMT,
3650          TWO_MEALS_DEDUCTION_AMT,
3651          THREE_MEALS_DEDUCTION_AMT,
3652          NIGHT_RATE_TYPE_CODE,
3653          ACCOMMODATION_CALC_METHOD,
3654          STATUS,
3655          CREATION_DATE,
3656          CREATED_BY,
3657          LAST_UPDATE_DATE,
3658          LAST_UPDATED_BY,
3659          REIMBURSEMENT_PERCENTAGE,
3660          MAX_RECEIPT_AMT
3661         )
3662   select
3663          p_policy_line_id AS PARENT_LINE_ID,
3664          AP_POL_LINES_S.NEXTVAL AS POLICY_LINE_ID,
3665          p_policy_id AS POLICY_ID,
3666          p_schedule_period_id AS SCHEDULE_PERIOD_ID,
3667          LOCATION_ID,
3668          ROLE_ID,
3669          CURRENCY_CODE,
3670          MEAL_LIMIT,
3671          RATE,
3672          TOLERANCE,
3673          TICKET_CLASS_DOMESTIC,
3674          TICKET_CLASS_INTERNATIONAL,
3675          VEHICLE_CATEGORY,
3676          VEHICLE_TYPE,
3677          FUEL_TYPE,
3678          RANGE_LOW,
3679          RANGE_HIGH,
3680          CALCULATION_METHOD,
3681          MEALS_DEDUCTION,
3682          BREAKFAST_DEDUCTION,
3683          LUNCH_DEDUCTION,
3684          DINNER_DEDUCTION,
3685          ACCOMMODATION_ADJUSTMENT,
3686          ADDON_MILEAGE_RATE_CODE,
3687          RATE_PER_PASSENGER,
3688          RATE_TYPE_CODE,
3689          ONE_MEAL_DEDUCTION_AMT,
3690          TWO_MEALS_DEDUCTION_AMT,
3691          THREE_MEALS_DEDUCTION_AMT,
3692          NIGHT_RATE_TYPE_CODE,
3693          ACCOMMODATION_CALC_METHOD,
3694          STATUS,
3695          CREATION_DATE,
3696          CREATED_BY,
3697          LAST_UPDATE_DATE,
3698          LAST_UPDATED_BY,
3699          REIMBURSEMENT_PERCENTAGE,
3700          MAX_RECEIPT_AMT
3701   from
3702          AP_POL_LINES
3703   where  POLICY_ID = p_policy_id
3704   and    SCHEDULE_PERIOD_ID = p_schedule_period_id
3705   and    POLICY_LINE_ID = p_policy_line_id;
3706 
3707 
3708 EXCEPTION
3709  WHEN OTHERS THEN
3710   raise;
3711 END preservePolicyLine;
3712 
3713 
3714 /*========================================================================
3715  | PUBLIC PROCEDURE archivePreservedPolicyLines
3716  |
3717  | DESCRIPTION
3718  |  Archive and remove a preserved Active Policy Line after it has been reactivated
3719  |
3720  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
3721  |
3722  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
3723  |
3724  | PARAMETERS
3725  |  p_user_id IN User Identifier
3726  |  p_policy_id IN Policy Identifier
3727  |
3728  | MODIFICATION HISTORY
3729  | Date                  Author            Description of Changes
3730  | 12-Aug-2002           R Langi           Created
3731  |
3732  *=======================================================================*/
3733 PROCEDURE archivePreservedPolicyLines(p_user_id IN NUMBER,
3734                                       p_policy_id  IN ap_pol_lines.policy_id%TYPE) IS
3735 
3736 BEGIN
3737 
3738   ---------------------------------------
3739   -- archive preserved Active policy lines
3740   ---------------------------------------
3741   insert into AP_POL_LINES_HISTORY
3742         (
3743          POLICY_LINE_HISTORY_ID,
3744          POLICY_LINE_ID,
3745          SCHEDULE_PERIOD_ID,
3746          --CURRENCY_CODE, -- need to add CURRENCY_CODE to AP_POL_LINES_HISTORY because of LCR
3747          MEAL_LIMIT,
3748          RATE,
3749          TOLERANCE,
3750          TICKET_CLASS_DOMESTIC,
3751          TICKET_CLASS_INTERNATIONAL,
3752          CALCULATION_METHOD,
3753          MEALS_DEDUCTION,
3754          BREAKFAST_DEDUCTION,
3755          LUNCH_DEDUCTION,
3756          DINNER_DEDUCTION,
3757          ACCOMMODATION_ADJUSTMENT,
3758          ADDON_MILEAGE_RATE_CODE,
3759          RATE_PER_PASSENGER,
3760          RATE_TYPE_CODE,
3761          ONE_MEAL_DEDUCTION_AMT,
3762          TWO_MEALS_DEDUCTION_AMT,
3763          THREE_MEALS_DEDUCTION_AMT,
3764          NIGHT_RATE_TYPE_CODE,
3765          ACCOMMODATION_CALC_METHOD,
3766          CREATION_DATE,
3767          CREATED_BY,
3768          LAST_UPDATE_DATE,
3769          LAST_UPDATED_BY,
3770          REIMBURSEMENT_PERCENTAGE,
3771          MAX_RECEIPT_AMT
3772         )
3773   select
3774          AP_POL_LINES_HISTORY_S.NEXTVAL AS POLICY_LINE_HISTORY_ID,
3775          PARENT_LINE_ID AS POLICY_LINE_ID,
3776          SCHEDULE_PERIOD_ID,
3777          --CURRENCY_CODE,
3778          MEAL_LIMIT,
3779          RATE,
3780          TOLERANCE,
3781          TICKET_CLASS_DOMESTIC,
3782          TICKET_CLASS_INTERNATIONAL,
3783          CALCULATION_METHOD,
3784          MEALS_DEDUCTION,
3785          BREAKFAST_DEDUCTION,
3786          LUNCH_DEDUCTION,
3787          DINNER_DEDUCTION,
3788          ACCOMMODATION_ADJUSTMENT,
3789          ADDON_MILEAGE_RATE_CODE,
3790          RATE_PER_PASSENGER,
3791          RATE_TYPE_CODE,
3792          ONE_MEAL_DEDUCTION_AMT,
3793          TWO_MEALS_DEDUCTION_AMT,
3794          THREE_MEALS_DEDUCTION_AMT,
3795          NIGHT_RATE_TYPE_CODE,
3796          ACCOMMODATION_CALC_METHOD,
3797          CREATION_DATE,
3798          CREATED_BY,
3799          LAST_UPDATE_DATE,
3800          LAST_UPDATED_BY,
3801          REIMBURSEMENT_PERCENTAGE,
3802          MAX_RECEIPT_AMT
3803   from
3804          AP_POL_LINES
3805   where  POLICY_ID = p_policy_id
3806   and    PARENT_LINE_ID is not null;
3807 
3808   ---------------------------------------
3809   -- remove preserved Active Policy Lines
3810   ---------------------------------------
3811   delete
3812   from
3813          AP_POL_LINES
3814   where  POLICY_ID = p_policy_id
3815   and    PARENT_LINE_ID is not null;
3816 
3817 EXCEPTION
3818  WHEN OTHERS THEN
3819   raise;
3820 END archivePreservedPolicyLines;
3821 
3822 
3823 /*========================================================================
3824  | PUBLIC FUNCTION createSchedulePeriod
3825  |
3826  | DESCRIPTION
3827  |  Creates a new Policy Schedule Period
3828  |
3829  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
3830  |
3831  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
3832  |
3833  | PARAMETERS
3834  |  p_user_id IN User Identifier
3835  |  p_policy_id IN Policy Identifier
3836  |  p_schedule_period_name IN Schedule Period Name
3837  |  p_start_date IN Start Date
3838  |  p_end_date IN End Date
3839  |  p_rate_per_passenger IN Rate Per Passenger
3840  |  p_min_days IN Minimum Number of Days
3841  |  p_tolerance IN Tolerance
3842  |  p_min_rate_per_period         IN Minimum Rate per Period
3843  |  p_max_breakfast_deduction     IN Maximum Breakfast Deduction Allowed per Period
3844  |  p_max_lunch_deduction         IN Maximum Lunch Deduction Allowed per Period
3845  |  p_max_dinner_deduction        IN Maximum Dinner Deduction Allowed per Period
3846  |  p_first_day_rate              IN First day rate
3847  |  p_last_day_rate               IN Last day rate
3848  |
3849  | MODIFICATION HISTORY
3850  | Date                  Author            Description of Changes
3851  | 16-May-2002           R Langi           Created
3852  |
3853  *=======================================================================*/
3854 FUNCTION createSchedulePeriod(p_user_id IN NUMBER,
3855                               p_policy_id  IN ap_pol_schedule_periods.policy_id%TYPE,
3856                               p_schedule_period_name  IN ap_pol_schedule_periods.schedule_period_name%TYPE,
3857                               p_start_date  IN ap_pol_schedule_periods.start_date%TYPE,
3858                               p_end_date  IN ap_pol_schedule_periods.end_date%TYPE,
3859                               p_rate_per_passenger  IN ap_pol_schedule_periods.rate_per_passenger%TYPE,
3860                               p_min_days  IN ap_pol_schedule_periods.min_days%TYPE,
3861                               p_tolerance  IN ap_pol_schedule_periods.tolerance%TYPE,
3862                               p_min_rate_per_period  IN ap_pol_schedule_periods.min_rate_per_period%TYPE,
3863                               p_max_breakfast_deduction IN ap_pol_schedule_periods.max_breakfast_deduction_amt%TYPE,
3864                               p_max_lunch_deduction  IN ap_pol_schedule_periods.max_lunch_deduction_amt%TYPE,
3865                               p_max_dinner_deduction IN ap_pol_schedule_periods.max_dinner_deduction_amt%TYPE,
3866                               p_first_day_rate IN ap_pol_schedule_periods.first_day_rate%TYPE,
3867                               p_last_day_rate IN ap_pol_schedule_periods.last_day_rate%TYPE,
3868                               p_reimbursement_percentage  IN ap_pol_schedule_periods.reimbursement_percentage%TYPE) RETURN ap_pol_schedule_periods.schedule_period_id%TYPE IS
3869 
3870   l_schedule_period_id			ap_pol_schedule_periods.schedule_period_id%TYPE;
3871 
3872 BEGIN
3873 
3874   select AP_POL_SCHEDULE_PERIODS_S.NEXTVAL
3875   into   l_schedule_period_id
3876   from   sys.dual;
3877 
3878   insert into AP_POL_SCHEDULE_PERIODS
3879         (
3880          SCHEDULE_PERIOD_ID,
3881          SCHEDULE_PERIOD_NAME,
3882          POLICY_ID,
3883          START_DATE,
3884          END_DATE,
3885          RATE_PER_PASSENGER,
3886          MIN_DAYS,
3887          TOLERANCE,
3888          MIN_RATE_PER_PERIOD,
3889          MAX_BREAKFAST_DEDUCTION_AMT,
3890          MAX_LUNCH_DEDUCTION_AMT,
3891          MAX_DINNER_DEDUCTION_AMT,
3892          FIRST_DAY_RATE,
3893          LAST_DAY_RATE,
3894          CREATION_DATE,
3895          CREATED_BY,
3896          LAST_UPDATE_DATE,
3897          LAST_UPDATED_BY,
3898          REIMBURSEMENT_PERCENTAGE
3899         )
3900   select
3901          l_schedule_period_id AS SCHEDULE_PERIOD_ID,
3902          decode(p_schedule_period_name, null, fnd_message.GET_STRING('SQLAP','OIE_POL_PERIODS_NEW_PERIOD'), substrb(fnd_message.GET_STRING('SQLAP','OIE_POL_COPY_OF')||' '||p_schedule_period_name, 1, C_PolicyNameMaxLength)) AS SCHEDULE_PERIOD_NAME,
3903          p_policy_id AS POLICY_ID,
3904          p_start_date AS START_DATE,
3905          p_end_date AS END_DATE,
3906          p_rate_per_passenger AS RATE_PER_PASSENGER,
3907          p_min_days AS MIN_DAYS,
3908          p_tolerance AS TOLERANCE,
3909          p_min_rate_per_period as MIN_RATE_PER_PERIOD,
3910          p_max_breakfast_deduction as MAX_BREAKFAST_DEDUCTION,
3911          p_max_lunch_deduction as MAX_LUNCH_DEDUCTION,
3912          p_max_dinner_deduction as MAX_DINNER_DEDUCTION,
3913          p_first_day_rate as FIRST_DAY_RATE,
3914          p_last_day_rate as LAST_DAY_RATE,
3915          sysdate AS CREATION_DATE,
3916          p_user_id AS CREATED_BY,
3917          sysdate AS LAST_UPDATE_DATE,
3918          p_user_id AS LAST_UPDATED_BY,
3919          p_reimbursement_percentage AS REIMBURSEMENT_PERCENTAGE
3920   from
3921          sys.dual;
3922 
3923   return l_schedule_period_id;
3924 
3925 EXCEPTION
3926  WHEN OTHERS THEN
3927   raise;
3928 END createSchedulePeriod;
3929 
3930 
3931 /*========================================================================
3932  | PUBLIC FUNCTION massUpdateValue
3933  |
3934  | DESCRIPTION
3935  |  Using a rounding rule and percentage to update by, a value is returned
3936  |
3937  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
3938  |
3939  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
3940  |
3941  | PARAMETERS
3942  |  p_value IN Value to perform an update on
3943  |  p_update_by IN Percentage to update the value by
3944  |  p_rounding_rule IN Rounding rule to use after the value has been updated
3945  |
3946  | MODIFICATION HISTORY
3947  | Date                  Author            Description of Changes
3948  | 16-May-2002           R Langi           Created
3949  |
3950  *=======================================================================*/
3951 FUNCTION massUpdateValue(p_value  IN NUMBER,
3952                          p_update_by  IN NUMBER,
3953                          p_rounding_rule     IN VARCHAR2) RETURN NUMBER IS
3954 
3955   l_new_value 		NUMBER := 0;
3956 
3957 BEGIN
3958 
3959   select decode(p_rounding_rule,
3960                 '1_DECIMALS', nvl(p_value, 0) + ROUND(nvl(p_value, 0) * (p_update_by/100), 1),
3961                 '2_DECIMALS', nvl(p_value, 0) + ROUND(nvl(p_value, 0) * (p_update_by/100), 2),
3962                 '3_DECIMALS', nvl(p_value, 0) + ROUND(nvl(p_value, 0) * (p_update_by/100), 3),
3963                               nvl(p_value, 0) + ROUND(nvl(p_value, 0) * (p_update_by/100)))
3964   into   l_new_value
3965   from   sys.dual;
3966 
3967   if (p_rounding_rule = c_NEAREST_FIVE) then
3968     if (mod(l_new_value, 5) >= 2.5) then
3969       l_new_value := l_new_value - mod(l_new_value, 5) + 5;
3970     else
3971       l_new_value := l_new_value - mod(l_new_value, 5);
3972     end if;
3973   end if;
3974   if (p_rounding_rule = c_NEAREST_TEN) then
3975     if (mod(l_new_value, 10) >= 5) then
3976       l_new_value := l_new_value - mod(l_new_value, 10) + 10;
3977     else
3978       l_new_value := l_new_value - mod(l_new_value, 10);
3979     end if;
3980   end if;
3981 
3982   return l_new_value;
3983 
3984 EXCEPTION
3985  WHEN no_data_found  THEN
3986   return(null);
3987  WHEN OTHERS THEN
3988   raise;
3989 END massUpdateValue;
3990 
3991 /*========================================================================
3992  | PUBLIC PROCEDURE duplicatePolicy
3993  |
3994  | DESCRIPTION
3995  |  Duplicates a Policy Schedule (General Information/Options/Periods/Lines)
3996  |
3997  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
3998  |  createSchedulePeriod
3999  |  duplicatePolicyLines
4000  |
4001  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4002  |  duplicatePolicyHeader
4003  |  duplicatePolicyScheduleOptions
4004  |
4005  | PARAMETERS
4006  |  p_user_id IN User Identifier
4007  |  p_from_policy_id IN Policy Identifier to duplicate From
4008  |  p_new_policy_id IN New Policy Identifier containing the duplicated Policy
4009  |
4010  | MODIFICATION HISTORY
4011  | Date                  Author            Description of Changes
4012  | 16-May-2002           R Langi           Created
4013  | 09-Mar-2004           sasaxena          Bug 2847928: clear out schedule end
4014  |                                         date when a schedule is duplicated.
4015  |
4016  *=======================================================================*/
4017 PROCEDURE duplicatePolicy(p_user_id IN NUMBER,
4018                           p_from_policy_id  IN  ap_pol_headers.policy_id%TYPE,
4019                           p_new_policy_id   OUT NOCOPY ap_pol_headers.policy_id%TYPE) IS
4020 
4021   l_duplicate_header_sql_stmt           VARCHAR2(4000);
4022   l_duplicate_options_sql_stmt          VARCHAR2(4000);
4023 
4024   l_from_policy_id			ap_pol_headers.policy_id%TYPE;
4025   l_to_policy_id			ap_pol_headers.policy_id%TYPE;
4026 
4027   l_from_schedule_period_id		ap_pol_schedule_periods.schedule_period_id%TYPE;
4028   l_to_schedule_period_id		ap_pol_schedule_periods.schedule_period_id%TYPE;
4029 
4030   l_schedule_period_name		ap_pol_schedule_periods.schedule_period_name%TYPE;
4031   l_start_date				ap_pol_schedule_periods.start_date%TYPE;
4032   l_end_date				ap_pol_schedule_periods.end_date%TYPE;
4033   l_rate_per_passenger			ap_pol_schedule_periods.rate_per_passenger%TYPE;
4034   l_min_days				ap_pol_schedule_periods.min_days%TYPE;
4035   l_tolerance				ap_pol_schedule_periods.tolerance%TYPE;
4036   l_min_rate_per_period     ap_pol_schedule_periods.min_rate_per_period%TYPE;
4037   l_max_breakfast_deduction ap_pol_schedule_periods.max_breakfast_deduction_amt%TYPE;
4038   l_max_lunch_deduction     ap_pol_schedule_periods.max_lunch_deduction_amt%TYPE;
4039   l_max_dinner_deduction    ap_pol_schedule_periods.max_dinner_deduction_amt%TYPE;
4040   l_first_day_rate          ap_pol_schedule_periods.first_day_rate%TYPE;
4041   l_last_day_rate           ap_pol_schedule_periods.last_day_rate%TYPE;
4042   l_reimbursement_percentage           ap_pol_schedule_periods.reimbursement_percentage%TYPE;
4043 
4044 cursor l_duplicate_periods_cursor
4045 is
4046   select
4047          SCHEDULE_PERIOD_ID,
4048          SCHEDULE_PERIOD_NAME,
4049          START_DATE,
4050          END_DATE,
4051          RATE_PER_PASSENGER,
4052          MIN_DAYS,
4053          TOLERANCE,
4054          MIN_RATE_PER_PERIOD,
4055          MAX_BREAKFAST_DEDUCTION_AMT,
4056          MAX_LUNCH_DEDUCTION_AMT,
4057          MAX_DINNER_DEDUCTION_AMT,
4058          FIRST_DAY_RATE,
4059          LAST_DAY_RATE,
4060          REIMBURSEMENT_PERCENTAGE
4061   from   AP_POL_SCHEDULE_PERIODS
4062   where  POLICY_ID = p_from_policy_id; /* l_duplicate_periods_cursor */
4063 
4064 
4065 
4066   PROCEDURE duplicatePolicyHeader(p_user_id IN NUMBER,
4067                                   p_from_policy_id  IN ap_pol_headers.policy_id%TYPE,
4068                                   p_to_policy_id  OUT NOCOPY ap_pol_headers.policy_id%TYPE) IS
4069 
4070   BEGIN
4071 
4072     select AP_POL_HEADERS_S.NEXTVAL
4073     into   p_to_policy_id
4074     from   sys.dual;
4075 
4076 
4077     insert into AP_POL_HEADERS
4078           (
4079            POLICY_ID,
4080            CATEGORY_CODE,
4081            POLICY_NAME,
4082            DESCRIPTION,
4083            CURRENCY_CODE,
4084            BUSINESS_GROUP_ID,
4085            JOB_GROUP_ID,
4086            ROLE_CODE,
4087            DISTANCE_UOM,
4088            CURRENCY_PREFERENCE,
4089            ALLOW_RATE_CONVERSION_CODE,
4090            DAILY_LIMITS_CODE,
4091            START_DATE,
4092            END_DATE,
4093            DISTANCE_THRESHOLDS_FLAG,
4094            VEHICLE_CATEGORY_FLAG,
4095            VEHICLE_TYPE_FLAG,
4096            FUEL_TYPE_FLAG,
4097            PASSENGERS_FLAG,
4098            EMPLOYEE_ROLE_FLAG,
4099            TIME_BASED_ENTRY_FLAG,
4100            FREE_MEALS_FLAG,
4101            FREE_ACCOMMODATIONS_FLAG,
4102            TOLERANCE_LIMITS_FLAG,
4103            DAILY_LIMITS_FLAG,
4104            LOCATION_FLAG,
4105            TOLERANCE_LIMIT_CODE,
4106            FREE_MEALS_CODE,
4107            FREE_ACCOMMODATIONS_CODE,
4108            DAY_PERIOD_CODE,
4109            ADDON_MILEAGE_RATES_FLAG,
4110            SCHEDULE_TYPE_CODE,
4111            MIN_TRIP_DURATION,
4112            SAME_DAY_RATE_CODE,
4113            NIGHT_RATES_CODE,
4114            NIGHT_RATE_ELIGIBILITY,
4115            NIGHT_RATE_START_TIME,
4116            NIGHT_RATE_END_TIME,
4117            MULTI_DEST_RULE_CODE,
4118            MULTI_DEST_START_TIME,
4119            MULTI_DEST_END_TIME,
4120            PER_DIEM_TYPE_CODE,
4121            SOURCE,
4122            RATE_PERIOD_TYPE_CODE,
4123            MEALS_TYPE_CODE,
4124            ALLOWANCE_TIME_RULE_CODE,
4125            BREAKFAST_START_TIME,
4126            BREAKFAST_END_TIME,
4127            LUNCH_START_TIME,
4128            LUNCH_END_TIME,
4129            DINNER_START_TIME,
4130            DINNER_END_TIME,
4131            USE_MAX_DEST_RATE_FLAG,
4132            CREATION_DATE,
4133            CREATED_BY,
4134            LAST_UPDATE_LOGIN,
4135            LAST_UPDATE_DATE,
4136            LAST_UPDATED_BY,
4137            REIMBURSEMENT_PERCENTAGE_FLAG,
4138            REIMBURSEMENT_PERCENTAGE_CODE
4139           )
4140     select
4141            p_to_policy_id AS POLICY_ID,
4142            CATEGORY_CODE,
4143            substrb(fnd_message.GET_STRING('SQLAP','OIE_POL_COPY_OF')||' '||POLICY_NAME, 1, C_PolicyNameMaxLength) AS POLICY_NAME,
4144            DESCRIPTION,
4145            CURRENCY_CODE,
4146            BUSINESS_GROUP_ID,
4147            JOB_GROUP_ID,
4148            ROLE_CODE,
4149            DISTANCE_UOM,
4150            CURRENCY_PREFERENCE,
4151            ALLOW_RATE_CONVERSION_CODE,
4152            DAILY_LIMITS_CODE,
4153            START_DATE,
4154            null, -- Bug 2847928
4155            DISTANCE_THRESHOLDS_FLAG,
4156            VEHICLE_CATEGORY_FLAG,
4157            VEHICLE_TYPE_FLAG,
4158            FUEL_TYPE_FLAG,
4159            PASSENGERS_FLAG,
4160            EMPLOYEE_ROLE_FLAG,
4161            TIME_BASED_ENTRY_FLAG,
4162            FREE_MEALS_FLAG,
4163            FREE_ACCOMMODATIONS_FLAG,
4164            TOLERANCE_LIMITS_FLAG,
4165            DAILY_LIMITS_FLAG,
4166            LOCATION_FLAG,
4167            TOLERANCE_LIMIT_CODE,
4168            FREE_MEALS_CODE,
4169            FREE_ACCOMMODATIONS_CODE,
4170            DAY_PERIOD_CODE,
4171            ADDON_MILEAGE_RATES_FLAG,
4172            SCHEDULE_TYPE_CODE,
4173            MIN_TRIP_DURATION,
4174            SAME_DAY_RATE_CODE,
4175            NIGHT_RATES_CODE,
4176            NIGHT_RATE_ELIGIBILITY,
4177            NIGHT_RATE_START_TIME,
4178            NIGHT_RATE_END_TIME,
4179            MULTI_DEST_RULE_CODE,
4180            MULTI_DEST_START_TIME,
4181            MULTI_DEST_END_TIME,
4182            PER_DIEM_TYPE_CODE,
4183            SOURCE,
4184            RATE_PERIOD_TYPE_CODE,
4185            MEALS_TYPE_CODE,
4186            ALLOWANCE_TIME_RULE_CODE,
4187            BREAKFAST_START_TIME,
4188            BREAKFAST_END_TIME,
4189            LUNCH_START_TIME,
4190            LUNCH_END_TIME,
4191            DINNER_START_TIME,
4192            DINNER_END_TIME,
4193            USE_MAX_DEST_RATE_FLAG,
4194            sysdate AS CREATION_DATE,
4195            p_user_id AS CREATED_BY,
4196            null AS LAST_UPDATE_LOGIN,
4197            sysdate AS LAST_UPDATE_DATE,
4198            p_user_id AS LAST_UPDATED_BY,
4199            REIMBURSEMENT_PERCENTAGE_FLAG,
4200            REIMBURSEMENT_PERCENTAGE_CODE
4201     from
4202            AP_POL_HEADERS
4203     where  POLICY_ID = p_from_policy_id;
4204 
4205   EXCEPTION
4206    WHEN OTHERS THEN
4207     raise;
4208   END duplicatePolicyHeader;
4209 
4210 
4211   PROCEDURE duplicatePolicyScheduleOptions(p_user_id IN NUMBER,
4212                                            p_from_policy_id  IN ap_pol_headers.policy_id%TYPE,
4213                                            p_to_policy_id  IN ap_pol_headers.policy_id%TYPE) IS
4214 
4215   BEGIN
4216 
4217     insert into AP_POL_SCHEDULE_OPTIONS
4218           (
4219            SCHEDULE_OPTION_ID,
4220            POLICY_ID,
4221            OPTION_TYPE,
4222            OPTION_CODE,
4223            THRESHOLD,
4224            ROLE_ID,
4225            LOCATION_ID,
4226            CURRENCY_CODE,
4227            END_DATE,
4228            VEHICLE_TYPE_CODE,
4229            FUEL_TYPE_CODE,
4230            RATE_TYPE_CODE,
4231            STATUS,
4232            CREATION_DATE,
4233            CREATED_BY,
4234            LAST_UPDATE_LOGIN,
4235            LAST_UPDATE_DATE,
4236            LAST_UPDATED_BY
4237           )
4238     select
4239            AP_POL_SCHEDULE_OPTIONS_S.NEXTVAL AS SCHEDULE_OPTION_ID,
4240            p_to_policy_id AS POLICY_ID,
4241            OPTION_TYPE,
4242            OPTION_CODE,
4243            THRESHOLD,
4244            ROLE_ID,
4245            LOCATION_ID,
4246            CURRENCY_CODE,
4247            END_DATE,
4248            VEHICLE_TYPE_CODE,
4249            FUEL_TYPE_CODE,
4250            RATE_TYPE_CODE,
4251            STATUS,
4252            sysdate AS CREATION_DATE,
4253            p_user_id AS CREATED_BY,
4254            null AS LAST_UPDATE_LOGIN,
4255            sysdate AS LAST_UPDATE_DATE,
4256            p_user_id AS LAST_UPDATED_BY
4257     from
4258            AP_POL_SCHEDULE_OPTIONS
4259     where  POLICY_ID = p_from_policy_id;
4260 
4261   EXCEPTION
4262    WHEN OTHERS THEN
4263     raise;
4264   END duplicatePolicyScheduleOptions;
4265 
4266 
4267 BEGIN
4268 
4269   l_from_policy_id := p_from_policy_id;
4270 
4271   duplicatePolicyHeader(p_user_id => p_user_id,
4272                         p_from_policy_id => l_from_policy_id,
4273                         p_to_policy_id => l_to_policy_id);
4274 
4275   duplicatePolicyScheduleOptions(p_user_id => p_user_id,
4276                                  p_from_policy_id => l_from_policy_id,
4277                                  p_to_policy_id => l_to_policy_id);
4278 
4279 
4280   open l_duplicate_periods_cursor;
4281   loop
4282     fetch l_duplicate_periods_cursor into
4283                            l_from_schedule_period_id,
4284                            l_schedule_period_name,
4285                            l_start_date,
4286                            l_end_date,
4287                            l_rate_per_passenger,
4288                            l_min_days,
4289                            l_tolerance,
4290                            l_min_rate_per_period,
4291                            l_max_breakfast_deduction,
4292                            l_max_lunch_deduction,
4293                            l_max_dinner_deduction,
4294                            l_first_day_rate,
4295                            l_last_day_rate,
4296                            l_reimbursement_percentage;
4297 
4298     exit when l_duplicate_periods_cursor%NOTFOUND;
4299 
4300     l_to_schedule_period_id := createSchedulePeriod(p_user_id => p_user_id,
4301                                                     p_policy_id => l_to_policy_id,
4302                                                     p_schedule_period_name => l_schedule_period_name,
4303                                                     p_start_date => l_start_date,
4304                                                     p_end_date => l_end_date,
4305                                                     p_rate_per_passenger => l_rate_per_passenger,
4306                                                     p_min_days => l_min_days,
4307                                                     p_tolerance => l_tolerance,
4308                                                     p_min_rate_per_period => l_min_rate_per_period,
4309                                                     p_max_breakfast_deduction => l_max_breakfast_deduction,
4310                                                     p_max_lunch_deduction => l_max_lunch_deduction,
4311                                                     p_max_dinner_deduction => l_max_dinner_deduction,
4312                                                     p_first_day_rate => l_first_day_rate,
4313                                                     p_last_day_rate => l_last_day_rate,
4314                                                     p_reimbursement_percentage => l_reimbursement_percentage);
4315 
4316     duplicatePolicyLines(p_user_id => p_user_id,
4317                          p_from_policy_id => l_from_policy_id,
4318                          p_from_schedule_period_id => l_from_schedule_period_id,
4319                          p_to_policy_id => l_to_policy_id,
4320                          p_to_schedule_period_id => l_to_schedule_period_id);
4321 
4322 
4323   end loop;
4324   close l_duplicate_periods_cursor;
4325 
4326   p_new_policy_id := l_to_policy_id;
4327 
4328 EXCEPTION
4329  WHEN OTHERS THEN
4330   raise;
4331 END duplicatePolicy;
4332 
4333 
4334 /*========================================================================
4335  | PUBLIC FUNCTION active_option_exists
4336  |
4337  | DESCRIPTION
4338  |  Checks whether a active schedule option exists for a option
4339  |
4340  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4341  |
4342  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4343  |
4344  | PARAMETERS
4345  |  p_option_type   IN Option type, required
4346  |  p_option_code   IN Option code, optional
4347  |  p_threshold     IN Threshold, optional
4348  |  p_role_id       IN Role Id, optional
4349  |  p_location_id   IN Location Id, optional
4350  |  p_currency_code IN Currency Code, optional
4351  |  p_end_date      IN End Date, optional
4352  |
4353  | RETURNS
4354  |  Y If active option exists
4355  |  N If active option does not exist
4356  |
4357  | MODIFICATION HISTORY
4358  | Date                  Author            Description of Changes
4359  | 26-Jun-2002           J Rautiainen      Created
4360  |
4361  *=======================================================================*/
4362 FUNCTION active_option_exists(p_option_type   IN VARCHAR2,
4363                               p_option_code   IN VARCHAR2,
4364                               p_threshold     IN NUMBER,
4365                               p_role_id       IN NUMBER,
4366                               p_location_id   IN NUMBER,
4367                               p_currency_code IN VARCHAR2,
4368                               p_end_date      IN DATE) RETURN VARCHAR2 IS
4369   CURSOR active_cur IS
4370     select schedule_option_id
4371     from ap_pol_schedule_options
4372     where option_type   = p_option_type
4373     and   NVL(option_code,9.99E125)      =  NVL(p_option_code,9.99E125)
4374     and   NVL(threshold,9.99E125)        =  NVL(p_threshold,9.99E125)
4375     and   NVL(role_id,9.99E125)          =  NVL(p_role_id,9.99E125)
4376     and   NVL(location_id,9.99E125)      =  NVL(p_location_id,9.99E125)
4377     and   NVL(currency_code,chr(0))      =  NVL(p_currency_code, chr(0))
4378     and   NVL(end_date,TO_DATE('1','j')) >= DECODE(p_end_date,
4379                                                    null, TO_DATE('1','j'),
4380                                                    DECODE(end_date,
4381                                                           null, TO_DATE('1','j'),
4382                                                           p_end_date));
4383 
4384 
4385   active_rec active_cur%ROWTYPE;
4386 
4387 BEGIN
4388   OPEN active_cur;
4389   FETCH active_cur INTO active_rec;
4390   IF active_cur%FOUND THEN
4391     CLOSE active_cur;
4392     RETURN 'Y';
4393   END IF;
4394 
4395   CLOSE active_cur;
4396   RETURN 'N';
4397 
4398 END active_option_exists;
4399 
4400 /*========================================================================
4401  | PUBLIC PROCEDURE end_date_active_loc_options
4402  |
4403  | DESCRIPTION
4404  |  If locations are end dated on location definitions then corresponding
4405  |  active locations on schedule options should be end dated provided the
4406  |  location option's end date is null or later than the defined end date.
4407  |
4408  | NOTES
4409  |  Created vide bug 2560275
4410  |
4411  | MODIFICATION HISTORY
4412  | Date                  Author            Description of Changes
4413  | 05-Feb-2004           V Nama            Created
4414  |
4415  *=======================================================================*/
4416 PROCEDURE end_date_active_loc_options IS
4417 
4418   CURSOR loc_def_cur IS
4419   select location_id, end_date
4420     from ap_pol_locations_vl
4421    where end_date is not null;
4422 
4423   l_location_id NUMBER;
4424   l_end_date DATE;
4425   loc_def_rec loc_def_cur%ROWTYPE;
4426 
4427 BEGIN
4428 
4429   FOR loc_def_rec IN loc_def_cur LOOP
4430 
4431     l_location_id := loc_def_rec.location_id;
4432     l_end_date := loc_def_rec.end_date;
4433 
4434     IF ( l_end_date is not null )
4435     THEN
4436 
4437       update ap_pol_schedule_options
4438          set end_date = l_end_date
4439        where option_type = 'LOCATION'
4440          and location_id = l_location_id
4441          and NVL(end_date,TO_DATE('1','j')) >=
4442                DECODE(l_end_date,
4443                       null, TO_DATE('1','j'),
4444                       DECODE(end_date,
4445                              null, TO_DATE('1','j'),
4446                              l_end_date));
4447     END IF;
4448   END LOOP;
4449 
4450 END end_date_active_loc_options;
4451 
4452 /*========================================================================
4453  | PUBLIC FUNCTION does_location_exist
4454  |
4455  | DESCRIPTION
4456  |  Checks whether a locations exists
4457  |
4458  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4459  |
4460  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4461  |
4462  | PARAMETERS
4463  |  NONE
4464  |
4465  | RETURNS
4466  |  Y If locations exist
4467  |  N If locations does not exist
4468  |
4469  | MODIFICATION HISTORY
4470  | Date                  Author            Description of Changes
4471  | 26-Jun-2002           J Rautiainen      Created
4472  |
4473  *=======================================================================*/
4474 FUNCTION does_location_exist RETURN VARCHAR2 IS
4475 
4476   CURSOR location_cur IS
4477     select 1 location_count
4478     from dual
4479     where exists
4480     (select 1
4481      from ap_pol_locations_b);
4482 
4483   location_rec location_cur%ROWTYPE;
4484 BEGIN
4485 
4486   OPEN location_cur;
4487   FETCH location_cur INTO location_rec;
4488   CLOSE location_cur;
4489 
4490   IF location_rec.location_count = 1 THEN
4491     RETURN 'Y';
4492   ELSE
4493     RETURN 'N';
4494   END IF;
4495 
4496 EXCEPTION
4497  WHEN no_data_found  THEN
4498   return('N');
4499  WHEN OTHERS THEN
4500   raise;
4501 END does_location_exist;
4502 
4503 /*========================================================================
4504  | PUBLIC PROCEDURE status_saved_sched_opts
4505  |
4506  | DESCRIPTION
4507  |   This procedure sets status of schedule options to 'SAVED' for
4508  |   the given policy_id
4509  |
4510  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4511  |   Called from BC4J
4512  |
4513  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4514  |
4515  | PARAMETERS
4516  |   p_policy_id       IN      Policy Id
4517  |
4518  | MODIFICATION HISTORY
4519  | Date                  Author                     Description of Changes
4520  | 17-JUL-2002           Mohammad Shoaib Jamall     Created
4521  |
4522  *=======================================================================*/
4523 PROCEDURE status_saved_sched_opts(p_policy_id       IN NUMBER) IS
4524 BEGIN
4525   IF p_policy_id IS NOT NULL THEN
4526     update AP_POL_SCHEDULE_OPTIONS set STATUS = 'SAVED' where POLICY_ID = p_policy_id and nvl(STATUS, '~') <> 'ACTIVE';
4527    END IF;
4528 END status_saved_sched_opts;
4529 
4530 /*========================================================================
4531  | PUBLIC PROCEDURE status_active_sched_opts
4532  |
4533  | DESCRIPTION
4534  |   This procedure sets status of schedule options to 'ACTIVE' for
4535  |   the given policy_id
4536  |
4537  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4538  |   Called from BC4J
4539  |
4540  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4541  |
4542  | PARAMETERS
4543  |   p_policy_id       IN      Policy Id
4544  |
4545  | MODIFICATION HISTORY
4546  | Date                  Author                     Description of Changes
4547  | 17-JUL-2002           Mohammad Shoaib Jamall     Created
4548  |
4549  *=======================================================================*/
4550 PROCEDURE status_active_sched_opts(p_policy_id       IN NUMBER) IS
4551 BEGIN
4552   set_status_pol_sched_opts(p_policy_id, 'ACTIVE');
4553 END status_active_sched_opts;
4554 
4555 /*========================================================================
4556  | PUBLIC PROCEDURE set_status_pol_sched_opts
4557  |
4558  | DESCRIPTION
4559  |   This procedure sets status of schedule options for the given policy_id
4560  |
4561  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4562  |   Called from BC4J
4563  |
4564  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4565  |
4566  | PARAMETERS
4567  |   p_policy_id       IN      Policy Id
4568  |   p_status_code     IN      Status Code
4569  |
4570  | MODIFICATION HISTORY
4571  | Date                  Author                     Description of Changes
4572  | 17-JUL-2002           Mohammad Shoaib Jamall     Created
4573  |
4574  *=======================================================================*/
4575 PROCEDURE set_status_pol_sched_opts(p_policy_id       IN NUMBER,
4576                                     p_status_code     IN VARCHAR2) IS
4577 BEGIN
4578   IF p_policy_id IS NOT NULL AND
4579      p_status_code IS NOT NULL THEN
4580     update AP_POL_SCHEDULE_OPTIONS set STATUS = p_status_code where POLICY_ID = p_policy_id;
4581    END IF;
4582 END set_status_pol_sched_opts;
4583 
4584 /*========================================================================
4585  | PUBLIC FUNCTION are_exp_type_enddates_capped
4586  |
4587  | DESCRIPTION
4588  |  Checks to see if end dates on expense templates are capped
4589  |
4590  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4591  |
4592  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4593  |
4594  | PARAMETERS
4595  |  p_policy_id IN Policy Identifier
4596  |  p_end_date IN End Date
4597  |
4598  | MODIFICATION HISTORY
4599  | Date                  Author                     Description of Changes
4600  | 31-JUL-2002           Mohammad Shoaib Jamall     Created
4601  |
4602  *=======================================================================*/
4603 FUNCTION are_exp_type_enddates_capped(p_policy_id  IN ap_pol_headers.policy_id%TYPE,
4604                                       p_end_date  IN ap_pol_headers.end_date%TYPE) RETURN VARCHAR2 IS
4605   l_count_rows NUMBER := 0;
4606   l_return_val VARCHAR2(1);
4607 BEGIN
4608 
4609   l_count_rows :=0;
4610   IF p_policy_id IS NOT NULL AND
4611      p_end_date IS NOT NULL THEN
4612 
4613     SELECT 1 INTO l_count_rows
4614     FROM dual
4615     WHERE exists
4616     (select 1
4617      from   ap_expense_report_params_all
4618      where  company_policy_id = p_policy_id and nvl(end_date,p_end_date+1) > p_end_date);
4619 
4620   END IF;
4621 
4622   IF (l_count_rows = 1) THEN
4623     l_return_val := 'N';
4624   ELSE
4625     l_return_val := 'Y';
4626   END IF;
4627 
4628   RETURN l_return_val;
4629 
4630 EXCEPTION
4631  WHEN no_data_found  THEN
4632   l_return_val := 'Y';
4633   RETURN l_return_val;
4634  WHEN OTHERS THEN
4635   raise;
4636 END are_exp_type_enddates_capped;
4637 
4638 /*========================================================================
4639  | PUBLIC FUNCTION cap_expense_type_enddates
4640  |
4641  | DESCRIPTION
4642  |  Caps end dates on expense type with p_end_date
4643  |
4644  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4645  |
4646  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4647  |
4648  | PARAMETERS
4649  |  p_policy_id IN Policy Identifier
4650  |  p_end_date IN End Date
4651  |
4652  | MODIFICATION HISTORY
4653  | Date                  Author                     Description of Changes
4654  | 31-JUL-2002           Mohammad Shoaib Jamall     Created
4655  |
4656  *=======================================================================*/
4657 PROCEDURE cap_expense_type_enddates(p_policy_id  IN ap_pol_headers.policy_id%TYPE,
4658                                    p_end_date  IN ap_pol_headers.end_date%TYPE) IS
4659   PRAGMA AUTONOMOUS_TRANSACTION;
4660 
4661   l_are_enddates_capped VARCHAR2(1);
4662 BEGIN
4663   l_are_enddates_capped := are_exp_type_enddates_capped(p_policy_id, p_end_date);
4664 
4665   IF (l_are_enddates_capped = 'N') THEN
4666     UPDATE ap_expense_report_params_all SET end_date = p_end_date
4667     WHERE company_policy_id = p_policy_id and nvl(end_date,p_end_date+1) > p_end_date;
4668     commit;
4669   END IF;
4670 
4671 END cap_expense_type_enddates;
4672 
4673 /*========================================================================
4674  | PUBLIC PROCEDURE initialize_user_expense_options
4675  |
4676  | DESCRIPTION
4677  |   This procedure creates expense options for user context.
4678  |
4679  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4680  |   Called from BC4J
4681  |
4682  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4683  |
4684  | PARAMETERS
4685  |   p_user_id       IN      User Id
4686  |
4687  | MODIFICATION HISTORY
4688  | Date                  Author            Description of Changes
4689  | 01-Jul-2003           J Rautiainen      Created
4690  |
4691  *=======================================================================*/
4692 PROCEDURE init_user_expense_options(p_user_id       IN NUMBER) IS
4693 
4694   CURSOR user_exp_options_c IS
4695     SELECT ep.ORG_ID,
4696            pc.user_id,
4697            pc.selected_org_id
4698     FROM AP_EXPENSE_PARAMS_ALL ep,
4699          AP_POL_CONTEXT         pc
4700     WHERE ep.org_id(+)        = pc.selected_org_id
4701     AND   pc.user_id          = p_user_id;
4702 
4703 BEGIN
4704   FOR user_exp_options_rec IN user_exp_options_c LOOP
4705 
4706     IF user_exp_options_rec.org_id is null THEN
4707       INSERT INTO AP_EXPENSE_PARAMS_ALL
4708              (prevent_cash_cc_age_limit,
4709               prevent_future_dated_day_limit,
4710               enforce_cc_acc_limit,
4711               enforce_cc_air_limit,
4712               enforce_cc_car_limit,
4713               enforce_cc_meal_limit,
4714               enforce_cc_misc_limit,
4715               org_id,
4716               creation_date,
4717               created_by,
4718               last_update_login,
4719               last_update_date,
4720               last_updated_by)
4721       VALUES (null,
4722               null,
4723               null,
4724               null,
4725               null,
4726               null,
4727               null,
4728               user_exp_options_rec.selected_org_id,
4729               SYSDATE,
4730               p_user_id,
4731               NULL,
4732               SYSDATE,
4733               p_user_id);
4734     END IF;
4735   END LOOP;
4736 
4737 END init_user_expense_options;
4738 
4739 /*========================================================================
4740  | PUBLIC FUNCTION format_minutes_to_hour_minutes
4741  |
4742  | DESCRIPTION
4743  |
4744  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4745  |
4746  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4747  |
4748  | PARAMETERS
4749  |   p_lookup_type   IN      lookup type
4750  |
4751  | MODIFICATION HISTORY
4752  | Date                  Author            Description of Changes
4753  | 10-May-2002           J Rautiainen      Created
4754  |
4755  *=======================================================================*/
4756 FUNCTION format_minutes_to_hour_minutes(p_minutes IN NUMBER) RETURN VARCHAR2 IS
4757 BEGIN
4758   RETURN lpad(to_char(get_hours_from_threshold(p_minutes)), 2, 0)
4759 	 || ':' ||
4760 	 lpad(to_char(get_minutes_from_threshold(p_minutes)), 2, 0);
4761 EXCEPTION
4762  WHEN OTHERS THEN
4763   raise;
4764 END format_minutes_to_hour_minutes;
4765 
4766 /*========================================================================
4767  | PUBLIC FUNCTION get_hours_from_threshold
4768  |
4769  | DESCRIPTION
4770  |   gets hours from the threshold value stored in minutes
4771  |
4772  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4773  |
4774  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4775  |
4776  | PARAMETERS
4777  |   p_lookup_type   IN      lookup type
4778  |
4779  | MODIFICATION HISTORY
4780  | Date                  Author            Description of Changes
4781  | 10-May-2002           J Rautiainen      Created
4782  |
4783  *=======================================================================*/
4784 FUNCTION get_hours_from_threshold(p_threshold IN NUMBER) RETURN NUMBER IS
4785 BEGIN
4786   IF p_threshold IS NULL THEN
4787     RETURN NULL;
4788   ELSE
4789     RETURN trunc(p_threshold/60);
4790   END IF;
4791 EXCEPTION
4792  WHEN OTHERS THEN
4793   raise;
4794 END get_hours_from_threshold;
4795 
4796 /*========================================================================
4797  | PUBLIC FUNCTION get_minutes_threshold
4798  |
4799  | DESCRIPTION
4800  |   converts threshold stored in minutes to hours:mins and returns mins
4801  |
4802  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4803  |
4804  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4805  |
4806  | PARAMETERS
4807  |   p_lookup_type   IN      lookup type
4808  |
4809  | MODIFICATION HISTORY
4810  | Date                  Author            Description of Changes
4811  | 10-May-2002           J Rautiainen      Created
4812  |
4813  *=======================================================================*/
4814 FUNCTION get_minutes_from_threshold(p_threshold IN NUMBER) RETURN NUMBER IS
4815 BEGIN
4816   IF p_threshold IS NULL THEN
4817     RETURN NULL;
4818   ELSE
4819     RETURN mod(p_threshold,60);
4820   END IF;
4821 EXCEPTION
4822  WHEN OTHERS THEN
4823   raise;
4824 END get_minutes_from_threshold;
4825 
4826 
4827 /*========================================================================
4828  | PUBLIC PROCEDURE deletePolicySchedule
4829  |
4830  | DESCRIPTION
4831  |   This procedure deletes a Policy Schedule
4832  |
4833  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4834  |   Called from BC4J
4835  |
4836  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4837  |
4838  | PARAMETERS
4839  |   p_policy_id       IN     Policy ID
4840  |
4841  | MODIFICATION HISTORY
4842  | Date                  Author            Description of Changes
4843  | 22-Jul-2005         Sameer Saxena       Created
4844  |
4845  *=======================================================================*/
4846 PROCEDURE deletePolicySchedule(p_policy_id       IN NUMBER) IS
4847 
4848 BEGIN
4849 
4850   DELETE FROM AP_POL_SCHEDULE_OPTIONS WHERE POLICY_ID = p_policy_id;
4851 
4852   DELETE FROM AP_POL_SCHEDULE_PERIODS WHERE POLICY_ID = p_policy_id;
4853 
4854   DELETE FROM AP_POL_LINES WHERE POLICY_ID = p_policy_id;
4855 
4856 EXCEPTION
4857  WHEN OTHERS THEN
4858   raise;
4859 
4860 END deletePolicySchedule;
4861 
4862 
4863 /*========================================================================
4864  | PUBLIC PROCEDURE getPolicyLinesCount
4865  |
4866  | DESCRIPTION
4867  |   This procedure returns the number of lines for a policy schedule
4868  |
4869  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4870  |   Called from BC4J to prevent querying large number of rows
4871  |   during initialization.
4872  |
4873  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4874  |
4875  | PARAMETERS
4876  |   p_schedule_period_id       IN     Policy Schedule Period ID
4877  |
4878  | MODIFICATION HISTORY
4879  | Date                  Author            Description of Changes
4880  | 18-Oct-2005           krmenon           Created
4881  |
4882  *=======================================================================*/
4883 FUNCTION getPolicyLinesCount(p_schedule_period_id       IN NUMBER) RETURN NUMBER IS
4884   l_count NUMBER;
4885 BEGIN
4886 
4887   SELECT count(1)
4888   INTO   l_count
4889   FROM   ap_pol_lines
4890   WHERE  schedule_period_id = p_schedule_period_id;
4891 
4892   RETURN nvl(l_count, 0 );
4893 
4894   EXCEPTION
4895     WHEN OTHERS THEN
4896       RETURN 0;
4897 END getPolicyLinesCount;
4898 
4899 /*========================================================================
4900  | PUBLIC PROCEDURE getSingleTokenMessage
4901  |
4902  | DESCRIPTION
4903  |   This function returns the fnd message which has a single token
4904  |
4905  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4906  |   Called from BC4J and is used in the JRAD for setting column headers
4907  |
4908  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4909  |
4910  | PARAMETERS
4911  |   p_message_name       IN     FND Message Name
4912  |   p_token              IN     FND Message Token
4913  |   p_token_value        IN     FND Message Token Value
4914  |
4915  | MODIFICATION HISTORY
4916  | Date                  Author            Description of Changes
4917  | 18-Oct-2005           krmenon           Created
4918  |
4919  *=======================================================================*/
4920 FUNCTION getSingleTokenMessage( p_message_name   IN VARCHAR2,
4921                                 p_token          IN VARCHAR2,
4922                                 p_token_value    IN VARCHAR2 ) RETURN VARCHAR2 IS
4923 BEGIN
4924 
4925   IF ( p_message_name IS NULL OR p_token IS NULL ) THEN
4926     RETURN NULL;
4927   END IF;
4928 
4929   fnd_message.set_name('SQLAP', p_message_name);
4930   fnd_message.set_token( p_token, p_token_value);
4931 
4932   RETURN fnd_message.get;
4933 
4934 END getSingleTokenMessage;
4935 
4936 
4937 /*========================================================================
4938  | PUBLIC FUNCTION get_per_diem_type_meaning
4939  |
4940  | DESCRIPTION
4941  |   This function fetches the meaning for a given lookup type and code
4942  |   combination. The values are cached, so the SQL is executed only
4943  |   once for the session.
4944  |
4945  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4946  |   BC4J objects
4947  |
4948  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4949  |   DBMS_UTILITY.get_hash_value
4950  |
4951  | PARAMETERS
4952  |   p_source        IN      Source (NULL, CONUS)
4953  |   p_lookup_code   IN      Lookup code, which is part of the lookup
4954  |                           type in previous parameter
4955  |
4956  | MODIFICATION HISTORY
4957  | Date                  Author            Description of Changes
4958  | 08-May-2002           J Rautiainen      Created
4959  |
4960  *=======================================================================*/
4961 FUNCTION get_per_diem_type_meaning(p_source  IN VARCHAR2,
4962                                    p_lookup_code  IN VARCHAR2) RETURN VARCHAR2 IS
4963    l_lookup_type fnd_lookups.lookup_type%TYPE;
4964 BEGIN
4965 
4966    IF ( p_source = 'CONUS' ) THEN
4967      l_lookup_type := 'OIE_PER_DIEM_UPLOAD_TYPES';
4968    ELSE
4969      l_lookup_type := 'OIE_PER_DIEM_TYPES';
4970    END IF;
4971 
4972    RETURN get_lookup_meaning( l_lookup_type, p_lookup_code);
4973 
4974 END get_per_diem_type_meaning;
4975 
4976 
4977 /*========================================================================
4978  | PUBLIC PROCEDURE permutatePolicyLines
4979  |
4980  | DESCRIPTION
4981  | - if a Rule is not enabled or Schedule Option not defined for an enabled Rule then remove the
4982  |   obsoleted Policy Line
4983  | - this will never recreate permutated lines based on existing option (rerunnable)
4984  | - if option doesn't exist then creates permutation for new option
4985  | - if option end dated then set Policy Line status to inactive
4986  |
4987  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
4988  |
4989  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
4990  |
4991  | PARAMETERS
4992  |  p_user_id IN User Identifier
4993  |  p_policy_id IN Policy Identifier
4994  |  p_rate_type IN Rate Type (FIRST/LAST)
4995  |
4996  | MODIFICATION HISTORY
4997  | Date                  Author            Description of Changes
4998  | 16-May-2002           R Langi           Created
4999  |
5000  *=======================================================================*/
5001 PROCEDURE permutatePolicyLines(p_user_id    IN NUMBER,
5002                                p_policy_id  IN ap_pol_headers.policy_id%TYPE,
5003                                p_rate_type  IN ap_pol_schedule_options.rate_type_code%TYPE) IS
5004 
5005   l_schedule_period_id		ap_pol_schedule_periods.schedule_period_id%TYPE;
5006   l_permutate_curref		INTEGER;
5007   l_rows_permutated		    NUMBER := 0;
5008   l_policy_line_count		NUMBER := 0;
5009   l_insert_sql_stmt		    VARCHAR2(4000);
5010   l_where_sql_stmt		    VARCHAR2(4000);
5011   l_not_exists_sql_stmt		VARCHAR2(4000);
5012 
5013   l_l_sql_stmt			VARCHAR2(4000);
5014   l_r_sql_stmt			VARCHAR2(4000);
5015   l_c_sql_stmt			VARCHAR2(4000);
5016   l_dt_sql_stmt			VARCHAR2(4000);
5017 
5018 
5019   l_location_enabled            VARCHAR2(80) := getUnionStmtForRuleOption(p_policy_id, c_LOCATION);
5020   l_role_enabled                VARCHAR2(80) := getUnionStmtForRuleOption(p_policy_id, c_EMPLOYEE_ROLE);
5021   l_currency_enabled            VARCHAR2(160) := getUnionStmtForRuleOption(p_policy_id, c_CURRENCY);
5022   l_thresholds_enabled          VARCHAR2(80) := getUnionStmtForRuleOption(p_policy_id, c_THRESHOLD);
5023 
5024 ---------------------------------------
5025 -- cursor for schedule periods
5026 ---------------------------------------
5027 cursor c_schedule_period_id is
5028   select schedule_period_id
5029   from   ap_pol_schedule_periods
5030   where  policy_id = p_policy_id;
5031 
5032 ---------------------------------------
5033 -- cursor for insert/select
5034 ---------------------------------------
5035 cursor l_insert_cursor is
5036 select
5037 '
5038   insert into AP_POL_LINES
5039         (
5040          POLICY_LINE_ID,
5041          POLICY_ID,
5042          SCHEDULE_PERIOD_ID,
5043          LOCATION_ID,
5044          ROLE_ID,
5045          CURRENCY_CODE,
5046          RANGE_LOW,
5047          RANGE_HIGH,
5048          RATE_TYPE_CODE,
5049          STATUS,
5050          CREATION_DATE,
5051          CREATED_BY,
5052          LAST_UPDATE_DATE,
5053          LAST_UPDATED_BY
5054         )
5055   select
5056          AP_POL_LINES_S.NEXTVAL AS POLICY_LINE_ID,
5057          :p_policy_id AS POLICY_ID,
5058          :p_schedule_period_id AS SCHEDULE_PERIOD_ID,
5059          NEW_LOCATION_ID AS LOCATION_ID,
5060          NEW_ROLE_ID AS ROLE_ID,
5061          NEW_CURRENCY_CODE AS CURRENCY_CODE,
5062          NEW_RANGE_LOW AS RANGE_LOW,
5063          NEW_RANGE_HIGH AS RANGE_HIGH,
5064          NEW_RATE_TYPE_CODE AS RATE_TYPE_CODE,
5065          ''NEW'' AS STATUS,
5066          sysdate AS CREATION_DATE,
5067          :p_user_id AS CREATED_BY,
5068          sysdate AS LAST_UPDATE_DATE,
5069          :p_user_id AS LAST_UPDATED_BY
5070   from
5071   (
5072   select distinct
5073          NEW_LOCATION_ID,
5074          NEW_ROLE_ID,
5075          NEW_CURRENCY_CODE,
5076          NEW_RANGE_LOW,
5077          NEW_RANGE_HIGH,
5078          NEW_RATE_TYPE_CODE
5079   from
5080   (
5081   select
5082           l.LOCATION_ID AS NEW_LOCATION_ID,
5083           r.ROLE_ID AS NEW_ROLE_ID,
5084           c.CURRENCY_CODE AS NEW_CURRENCY_CODE,
5085          dt.THRESHOLD AS NEW_RANGE_LOW,
5086          dt.RANGE_HIGH AS NEW_RANGE_HIGH,
5087          :p_rate_type AS NEW_RATE_TYPE_CODE
5088   from
5089 '
5090 from sys.dual; /* l_insert_cursor */
5091 
5092 ---------------------------------------
5093 -- cursor for all locations to use
5094 ---------------------------------------
5095 cursor l_l_cursor is
5096 select
5097 '
5098       (select LOCATION_ID
5099        from   AP_POL_SCHEDULE_OPTIONS pso
5100        where
5101               POLICY_ID = :p_policy_id
5102        and    OPTION_TYPE = :c_LOCATION
5103        and    LOCATION_ID IS NOT NULL
5104        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
5105          '||l_location_enabled||'
5106       ) l,
5107 '
5108 from sys.dual; /* l_l_cursor */
5109 
5110 ---------------------------------------
5111 -- cursor for all roles to use
5112 ---------------------------------------
5113 cursor l_r_cursor is
5114 select
5115 '
5116       (select ROLE_ID
5117        from   AP_POL_SCHEDULE_OPTIONS pso
5118        where
5119               POLICY_ID = :p_policy_id
5120        and    OPTION_TYPE = :c_EMPLOYEE_ROLE
5121        and    ROLE_ID IS NOT NULL
5122        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
5123          '||l_role_enabled||'
5124       ) r,
5125 '
5126 from sys.dual; /* l_r_cursor */
5127 
5128 ---------------------------------------
5129 -- cursor for all currency codes to use
5130 ---------------------------------------
5131 cursor l_c_cursor is
5132 select
5133 '
5134       (select CURRENCY_CODE
5135        from   AP_POL_SCHEDULE_OPTIONS pso
5136        where
5137               POLICY_ID = :p_policy_id
5138        and    OPTION_TYPE = :c_CURRENCY
5139        and    CURRENCY_CODE IS NOT NULL
5140        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
5141          '||l_currency_enabled||'
5142       ) c,
5143 '
5144 from sys.dual; /* l_c_cursor */
5145 
5146 ---------------------------------------
5147 -- cursor for all thresholds to use
5148 ---------------------------------------
5149 cursor l_dt_cursor is
5150 select
5151 '
5152       (select THRESHOLD,
5153               ap_web_policy_UTILS.getHighEndOfThreshold(:p_policy_id, THRESHOLD, nvl(:p_rate_type,''STANDARD'')) AS RANGE_HIGH
5154        from   AP_POL_SCHEDULE_OPTIONS pso
5155        where
5156               POLICY_ID = :p_policy_id
5157        and    (OPTION_TYPE = :c_DISTANCE_THRESHOLD or OPTION_TYPE = :c_TIME_THRESHOLD)
5158        and    THRESHOLD IS NOT NULL
5159        and    nvl(END_DATE, SYSDATE+1) > SYSDATE
5160        and    nvl(rate_type_code, :p_rate_type) = :p_rate_type
5161          '||l_thresholds_enabled||'
5162       ) dt
5163 '
5164 from sys.dual; /* l_dt_cursor */
5165 
5166 ---------------------------------------
5167 -- cursor for where rows
5168 ---------------------------------------
5169 cursor l_where_cursor is
5170 select
5171 '
5172   )
5173   where
5174         (
5175          NEW_LOCATION_ID is not null
5176   or     NEW_ROLE_ID is not null
5177   or     NEW_CURRENCY_CODE is not null
5178   or     NEW_RANGE_LOW is not null
5179   or     NEW_RANGE_HIGH is not null
5180         )
5181   )
5182 '
5183 from sys.dual; /* l_where_cursor */
5184 
5185 
5186 ---------------------------------------
5187 -- cursor for adding new rules/options
5188 ---------------------------------------
5189 cursor l_not_exists_cursor is
5190 select
5191 '
5192   )
5193   where
5194   not exists
5195         (
5196          select epl.POLICY_LINE_ID
5197          from   AP_POL_LINES epl
5198          where  epl.POLICY_ID = :p_policy_id
5199          and    epl.SCHEDULE_PERIOD_ID = :p_schedule_period_id
5200          and    nvl(epl.LOCATION_ID, :dummy_number) = nvl(NEW_LOCATION_ID, :dummy_number)
5201          and    nvl(epl.ROLE_ID, :dummy_number) = nvl(NEW_ROLE_ID, :dummy_number)
5202          and
5203                (
5204                 (nvl(epl.CURRENCY_CODE, :dummy_varchar2) = nvl(NEW_CURRENCY_CODE, :dummy_varchar2))
5205                 or
5206                 (epl.CURRENCY_CODE is not null and NEW_CURRENCY_CODE is null)
5207                )
5208          and    nvl(epl.RANGE_LOW, :dummy_number) = nvl(NEW_RANGE_LOW, :dummy_number)
5209          and    nvl(epl.RANGE_HIGH, :dummy_number) = nvl(NEW_RANGE_HIGH, :dummy_number)
5210          and    nvl(epl.RATE_TYPE_CODE, :dummy_varchar2) = nvl(NEW_RATE_TYPE_CODE, :dummy_varchar2)
5211         )
5212   )
5213 '
5214 from sys.dual; /* l_not_exists_cursor */
5215 
5216 
5217 BEGIN
5218 
5219   --removeObsoletedPolicyLines(p_policy_id);
5220 
5221   open l_insert_cursor;
5222   open l_where_cursor;
5223   open l_not_exists_cursor;
5224 
5225   open l_l_cursor;
5226   open l_r_cursor;
5227   open l_c_cursor;
5228   open l_dt_cursor;
5229 
5230   fetch l_insert_cursor into l_insert_sql_stmt;
5231   fetch l_where_cursor into l_where_sql_stmt;
5232   fetch l_not_exists_cursor into l_not_exists_sql_stmt;
5233 
5234   fetch l_l_cursor into l_l_sql_stmt;
5235   fetch l_r_cursor into l_r_sql_stmt;
5236   fetch l_c_cursor into l_c_sql_stmt;
5237   fetch l_dt_cursor into l_dt_sql_stmt;
5238 
5239   --------------
5240   -- open cursor
5241   --------------
5242   l_permutate_curref := DBMS_SQL.OPEN_CURSOR;
5243 
5244   --------------
5245   -- begin loop thru all periods
5246   --------------
5247   open c_schedule_period_id;
5248   loop
5249 
5250   fetch c_schedule_period_id into l_schedule_period_id;
5251   exit when c_schedule_period_id%NOTFOUND;
5252 
5253   select count(policy_line_id)
5254   into   l_policy_line_count
5255   from   ap_pol_lines
5256   where  policy_id = p_policy_id
5257   and    schedule_period_id = l_schedule_period_id;
5258 
5259   if (l_policy_line_count = 0) then
5260     --------------
5261     -- parse cursor
5262     --------------
5263     DBMS_SQL.PARSE(l_permutate_curref,
5264                       l_insert_sql_stmt||
5265                       l_l_sql_stmt||
5266                       l_r_sql_stmt||
5267                       l_c_sql_stmt||
5268                       l_dt_sql_stmt || '))', DBMS_SQL.NATIVE);
5269   else
5270     --------------
5271     -- parse cursor
5272     --------------
5273     DBMS_SQL.PARSE(l_permutate_curref,
5274                       l_insert_sql_stmt||
5275                       l_l_sql_stmt||
5276                       l_r_sql_stmt||
5277                       l_c_sql_stmt||
5278                       l_dt_sql_stmt||
5279                       l_not_exists_sql_stmt, DBMS_SQL.NATIVE);
5280     --------------
5281     -- supply binds specific to this case
5282     --------------
5283     DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':dummy_number', -11);
5284     DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':dummy_varchar2', '-11');
5285 
5286   end if;
5287 
5288   --------------
5289   -- supply binds
5290   --------------
5291   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':p_policy_id', p_policy_id);
5292   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':p_schedule_period_id', l_schedule_period_id);
5293   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':p_user_id', p_user_id);
5294   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_LOCATION', c_LOCATION);
5295   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_EMPLOYEE_ROLE', c_EMPLOYEE_ROLE);
5296   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_CURRENCY', c_CURRENCY);
5297   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_DISTANCE_THRESHOLD', c_DISTANCE_THRESHOLD);
5298   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':c_TIME_THRESHOLD', c_TIME_THRESHOLD);
5299   DBMS_SQL.BIND_VARIABLE(l_permutate_curref, ':p_rate_type', p_rate_type);
5300 
5301   --------------
5302   -- execute cursor
5303   --------------
5304   l_rows_permutated := DBMS_SQL.EXECUTE(l_permutate_curref);
5305 
5306   end loop;
5307   close c_schedule_period_id;
5308   --------------
5309   -- end loop thru all periods
5310   --------------
5311 
5312   --------------
5313   -- close cursor
5314   --------------
5315   DBMS_SQL.CLOSE_CURSOR(l_permutate_curref);
5316 
5317   close l_insert_cursor;
5318   close l_where_cursor;
5319   close l_not_exists_cursor;
5320 
5321   close l_l_cursor;
5322   close l_r_cursor;
5323   close l_c_cursor;
5324   close l_dt_cursor;
5325 
5326   updateInactivePolicyLines(p_policy_id);
5327   status_saved_sched_opts(p_policy_id);
5328 
5329 
5330 EXCEPTION
5331  WHEN OTHERS THEN
5332   raise;
5333 END permutatePolicyLines;
5334 
5335 /*========================================================================
5336  | PUBLIC PROCEDURE permutateAddonRates
5337  |
5338  | DESCRIPTION
5339  | - if a Rule is not enabled or Schedule Option not defined for an enabled Rule then remove the
5340  |   obsoleted Policy Line
5341  | - this will never recreate permutated lines based on existing option (rerunnable)
5342  | - if option doesn't exist then creates permutation for new option
5343  | - if option end dated then set Policy Line status to inactive
5344  |
5345  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
5346  |
5347  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
5348  |
5349  | PARAMETERS
5350  |  p_user_id IN User Identifier
5351  |  p_policy_id IN Policy Identifier
5352  |  p_schedule_period_id IN Policy Schedule Period Id
5353  |
5354  | MODIFICATION HISTORY
5355  | Date                  Author            Description of Changes
5356  | 10-Nov-2005           krmenon           Created
5357  |
5358  *=======================================================================*/
5359 PROCEDURE permutateAddonRates( p_user_id IN NUMBER,
5360                                p_policy_id  IN ap_pol_headers.policy_id%TYPE,
5361                                p_schedule_period_id IN ap_pol_lines.schedule_period_id%TYPE ) IS
5362 
5363    l_policy_line_count NUMBER;
5364 
5365 BEGIN
5366 
5367    BEGIN
5368       select count(policy_line_id)
5369       into   l_policy_line_count
5370       from   ap_pol_lines
5371       where  policy_id = p_policy_id
5372       and    schedule_period_id = p_schedule_period_id
5373       and    addon_mileage_rate_code is not null;
5374 
5375       EXCEPTION
5376          WHEN OTHERS THEN
5377             NULL;
5378    END;
5379 
5380     IF (l_policy_line_count = 0) THEN
5381         -- No policy lines, so genera all permutations
5382         insert into AP_POL_LINES
5383             (
5384              POLICY_LINE_ID,
5385              POLICY_ID,
5386              SCHEDULE_PERIOD_ID,
5387              LOCATION_ID,
5388              ROLE_ID,
5389              CURRENCY_CODE,
5390              VEHICLE_CATEGORY,
5391              VEHICLE_TYPE,
5392              FUEL_TYPE,
5393              RANGE_LOW,
5394              RANGE_HIGH,
5395              ADDON_MILEAGE_RATE_CODE,
5396              STATUS,
5397              CREATION_DATE,
5398              CREATED_BY,
5399              LAST_UPDATE_DATE,
5400              LAST_UPDATED_BY
5401             )
5402         select
5403              AP_POL_LINES_S.NEXTVAL AS POLICY_LINE_ID,
5404              apl.POLICY_ID,
5405              apl.SCHEDULE_PERIOD_ID,
5406              apl.location_id,
5407              apl.role_id,
5408              apl.currency_code,
5409              vehicle_category,
5410              vehicle_type,
5411              fuel_type,
5412              range_low,
5413              range_high,
5414              option_code as addon_mileage_rate_code,
5415              'NEW' AS STATUS,
5416              sysdate AS CREATION_DATE,
5417              apl.CREATED_BY,
5418              sysdate AS LAST_UPDATE_DATE,
5419              apl.LAST_UPDATED_BY
5420         from ap_pol_lines apl,
5421              ap_pol_schedule_options pso
5422         where apl.POLICY_ID = p_policy_id
5423 	  and apl.schedule_period_id = p_schedule_period_id -- Bug: 15996892
5424           and pso.policy_id = apl.policy_id
5425           and OPTION_TYPE = 'OIE_ADDON_MILEAGE_RATES'
5426           and OPTION_CODE IS NOT NULL
5427           and nvl(END_DATE, SYSDATE+1) > SYSDATE
5428           and apl.addon_mileage_rate_code is null;
5429 
5430     ELSE
5431        -- ---------------------------------------------------------
5432        -- Delete all obsolete addon mileage rate lines
5433        -- ---------------------------------------------------------
5434        delete from   ap_pol_lines pl
5435        where  policy_id   = p_policy_id
5436          and  addon_mileage_rate_code is not null
5437          and  not exists
5438               (
5439                 select 1
5440                   from ap_pol_schedule_options pso
5441                  where pso.policy_id   = pl.policy_id
5442                    and pso.option_code = pl.addon_mileage_rate_code
5443               );
5444         -- ---------------------------------------------------------
5445         -- Policy lines exist so make sure to only generate
5446         -- new permutations for non-existing lines.
5447         -- ---------------------------------------------------------
5448        insert into AP_POL_LINES
5449             (
5450              POLICY_LINE_ID,
5451              POLICY_ID,
5452              SCHEDULE_PERIOD_ID,
5453              LOCATION_ID,
5454              ROLE_ID,
5455              CURRENCY_CODE,
5456              VEHICLE_CATEGORY,
5457              VEHICLE_TYPE,
5458              FUEL_TYPE,
5459              RANGE_LOW,
5460              RANGE_HIGH,
5461              ADDON_MILEAGE_RATE_CODE,
5462              STATUS,
5463              CREATION_DATE,
5464              CREATED_BY,
5465              LAST_UPDATE_DATE,
5466              LAST_UPDATED_BY
5467             )
5468         select
5469              AP_POL_LINES_S.NEXTVAL AS POLICY_LINE_ID,
5470              apl.POLICY_ID,
5471              apl.SCHEDULE_PERIOD_ID,
5472              apl.location_id,
5473              apl.role_id,
5474              apl.currency_code,
5475              apl.vehicle_category,
5476              apl.vehicle_type,
5477              apl.fuel_type,
5478              apl.range_low,
5479              apl.range_high,
5480              option_code as addon_mileage_rate_code,
5481              'NEW' AS STATUS,
5482              sysdate AS CREATION_DATE,
5483              apl.CREATED_BY,
5484              sysdate AS LAST_UPDATE_DATE,
5485              apl.LAST_UPDATED_BY
5486         from ap_pol_lines apl,
5487              ap_pol_schedule_options pso
5488         where apl.POLICY_ID = p_policy_id
5489           and pso.policy_id = apl.policy_id
5490           and OPTION_TYPE = 'OIE_ADDON_MILEAGE_RATES'
5491           and OPTION_CODE IS NOT NULL
5492           and nvl(END_DATE, SYSDATE+1) > SYSDATE
5493           and apl.addon_mileage_rate_code is null
5494           and not exists
5495           ( select 1
5496             from   ap_pol_lines epl
5497             where  epl.POLICY_ID = apl.policy_id
5498               and  epl.SCHEDULE_PERIOD_ID = apl.schedule_period_id
5499               and  nvl(epl.LOCATION_ID, -1) = nvl(apl.location_id, -1)
5500               and  nvl(epl.ROLE_ID, -1) = nvl(apl.role_id, -1)
5501               and  ((nvl(epl.CURRENCY_CODE, 'NULL') = nvl(apl.currency_code, 'NULL'))
5502                      or
5503                     (epl.CURRENCY_CODE is not null and apl.currency_code is null)
5504                    )
5505               and  nvl(epl.VEHICLE_CATEGORY, 'NULL') = nvl(apl.vehicle_category, 'NULL')
5506               and  nvl(epl.VEHICLE_TYPE, 'NULL') = nvl(apl.vehicle_type, 'NULL')
5507               and  nvl(epl.FUEL_TYPE, 'NULL') = nvl(apl.fuel_type, 'NULL')
5508               and  nvl(epl.RANGE_LOW, -1) = nvl(apl.range_low, -1)
5509               and  nvl(epl.RANGE_HIGH, -1) = nvl(apl.range_high, -1)
5510               and  epl.addon_mileage_rate_code = pso.option_code
5511           );
5512 
5513 
5514         END IF;
5515 
5516 
5517 END permutateAddonRates;
5518 
5519 /*========================================================================
5520  | PUBLIC PROCEDURE permutateNightRates
5521  |
5522  | DESCRIPTION
5523  | - if a Rule is not enabled or Schedule Option not defined for an enabled Rule then remove the
5524  |   obsoleted Policy Line
5525  | - this will never recreate permutated lines based on existing option (rerunnable)
5526  | - if option doesn't exist then creates permutation for new option
5527  | - if option end dated then set Policy Line status to inactive
5528  |
5529  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
5530  |
5531  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
5532  |
5533  | PARAMETERS
5534  |  p_user_id IN User Identifier
5535  |  p_policy_id IN Policy Identifier
5536  |  p_schedule_period_id IN Policy Schedule Period Id
5537  |
5538  | MODIFICATION HISTORY
5539  | Date                  Author            Description of Changes
5540  | 10-Nov-2005           krmenon           Created
5541  |
5542  *=======================================================================*/
5543 PROCEDURE permutateNightRates( p_user_id IN NUMBER,
5544                                p_policy_id  IN ap_pol_headers.policy_id%TYPE,
5545                                p_schedule_period_id IN ap_pol_lines.schedule_period_id%TYPE ) IS
5546 
5547 -- -------------------------------------
5548 -- Cursor for inserting new permutation
5549 -- -------------------------------------
5550 cursor c_insert_nighrates is
5551    select distinct
5552           apl.POLICY_ID,
5553           apl.SCHEDULE_PERIOD_ID,
5554           apl.location_id,
5555           apl.role_id,
5556           apl.currency_code,
5557           option_code as night_rate_type_code,
5558           'NEW' AS STATUS
5559      from ap_pol_lines apl,
5560           ap_pol_schedule_options pso
5561      where apl.POLICY_ID = p_policy_id
5562        and apl.schedule_period_id = p_schedule_period_id -- Bug: 15996892
5563        and pso.policy_id(+) = apl.policy_id
5564        and OPTION_TYPE(+) = 'OIE_NIGHT_RATES'
5565        and OPTION_CODE(+) IS NOT NULL
5566        and nvl(END_DATE(+), SYSDATE+1) > SYSDATE
5567        and nvl(apl.rate_type_code, 'STANDARD') = 'STANDARD';
5568 
5569 -- -------------------------------------
5570 -- Cursor for updating permutations
5571 -- -------------------------------------
5572 cursor c_update_nightrates is
5573    select
5574           distinct
5575           apl.POLICY_ID,
5576           apl.SCHEDULE_PERIOD_ID,
5577           apl.location_id,
5578           apl.role_id,
5579           apl.currency_code,
5580           option_code as night_rate_type_code,
5581           'NEW' AS STATUS
5582      from ap_pol_lines apl,
5583           ap_pol_schedule_options pso,
5584           ap_pol_lines epl
5585      where apl.POLICY_ID = p_policy_id
5586        and pso.policy_id(+) = apl.policy_id
5587        and OPTION_TYPE(+) = 'OIE_NIGHT_RATES'
5588        and OPTION_CODE(+) IS NOT NULL
5589        and nvl(END_DATE(+), SYSDATE+1) > SYSDATE
5590        and nvl(apl.rate_type_code, 'STANDARD') = 'STANDARD'
5591        and not exists
5592        ( select 1
5593          from   ap_pol_lines epl
5594          where  epl.POLICY_ID = apl.policy_id
5595          and    epl.SCHEDULE_PERIOD_ID = apl.schedule_period_id
5596          and    nvl(epl.LOCATION_ID, -1) = nvl(apl.location_id, -1)
5597          and    nvl(epl.ROLE_ID, -1) = nvl(apl.role_id, -1)
5598          and    ((nvl(epl.CURRENCY_CODE, 'NULL') = nvl(apl.currency_code, 'NULL'))
5599                  or
5600                  (epl.CURRENCY_CODE is not null and apl.currency_code is null)
5601                 )
5602          and    epl.rate_type_code = 'NIGHT_RATE'
5603          and    ( epl.night_rate_type_code is null or
5604                   ( epl.night_rate_type_code is not null and epl.night_rate_type_code = pso.option_code )
5605                 )
5606         );
5607 
5608 -- ------------------------------------
5609 -- Local variables
5610 -- ------------------------------------
5611    l_policy_line_count NUMBER;
5612    l_night_rates_code  ap_pol_headers.night_rates_code%TYPE;
5613 
5614 BEGIN
5615 
5616    BEGIN
5617       select count(policy_line_id)
5618       into   l_policy_line_count
5619       from   ap_pol_lines
5620       where  policy_id = p_policy_id
5621       and    schedule_period_id = p_schedule_period_id
5622       and    rate_type_code = 'NIGHT_RATE';
5623 
5624       EXCEPTION
5625          WHEN OTHERS THEN
5626             NULL;
5627    END;
5628 
5629     IF (l_policy_line_count = 0) THEN
5630         -- No policy lines, so generate all permutations
5631        FOR c_nightrate IN c_insert_nighrates
5632        LOOP
5633           insert into AP_POL_LINES
5634              (
5635               POLICY_LINE_ID,
5636               POLICY_ID,
5637               SCHEDULE_PERIOD_ID,
5638               LOCATION_ID,
5639               ROLE_ID,
5640               CURRENCY_CODE,
5641               RATE_TYPE_CODE,
5642               NIGHT_RATE_TYPE_CODE,
5643               STATUS,
5644               CREATION_DATE,
5645               CREATED_BY,
5646               LAST_UPDATE_DATE,
5647               LAST_UPDATED_BY
5648              )
5649            values
5650              (
5651               AP_POL_LINES_S.NEXTVAL,
5652               c_nightrate.POLICY_ID,
5653               c_nightrate.SCHEDULE_PERIOD_ID,
5654               c_nightrate.LOCATION_ID,
5655               c_nightrate.ROLE_ID,
5656               c_nightrate.CURRENCY_CODE,
5657               'NIGHT_RATE',
5658               c_nightrate.NIGHT_RATE_TYPE_CODE,
5659               c_nightrate.STATUS,
5660               sysdate,
5661               p_user_id,
5662               sysdate,
5663               p_user_id
5664              );
5665        END LOOP;
5666 
5667     ELSE
5668 
5669        -- ----------------------------------------------------------------
5670        -- Delete all obsolete lines based on the night rates code
5671        --    - If code is single remove rows whic have not null type code
5672        --    - If code is multiple remove rows which have null type code
5673        -- ----------------------------------------------------------------
5674        BEGIN
5675           select night_rates_code
5676           into   l_night_rates_code
5677           from   ap_pol_headers
5678           where  policy_id = p_policy_id;
5679           EXCEPTION WHEN OTHERS THEN
5680              raise;
5681        END;
5682 
5683        IF ( l_night_rates_code = 'SINGLE' ) THEN
5684           -- Delete all policy lines which have night rate type code value
5685           delete from   ap_pol_lines
5686           where  policy_id      = p_policy_id
5687           and    rate_type_code = 'NIGHT_RATE'
5688           and    night_rate_type_code is not null;
5689 
5690        ELSIF ( l_night_rates_code = 'MULTIPLE' ) THEN
5691           -- Delete all policy lines which have night rate type code is null
5692       	  /* delete from   ap_pol_lines
5693              where  policy_id      = p_policy_id
5694              and    rate_type_code = 'NIGHT_RATE'
5695              and    night_rate_type_code is NULL ; */
5696 
5697           -- Modified since deselecting night_rate_types retains values
5698           delete from   ap_pol_lines
5699           where  policy_id      = p_policy_id
5700           and    rate_type_code = 'NIGHT_RATE'
5701           and    (night_rate_type_code is NULL
5702                  or night_rate_type_code not in(select option_code
5703                                                from ap_pol_schedule_options
5704                                                where policy_id = p_policy_id));
5705        END IF;
5706 
5707        -- ---------------------------------------------------------
5708         -- Policy lines exist so make sure to only generate
5709         -- new permutations for non-existing lines.
5710        -- ---------------------------------------------------------
5711        FOR c_nightrate IN c_update_nightrates
5712        LOOP
5713           insert into AP_POL_LINES
5714              (
5715               POLICY_LINE_ID,
5716               POLICY_ID,
5717               SCHEDULE_PERIOD_ID,
5718               LOCATION_ID,
5719               ROLE_ID,
5720               CURRENCY_CODE,
5721               RATE_TYPE_CODE,
5722               NIGHT_RATE_TYPE_CODE,
5723               STATUS,
5724               CREATION_DATE,
5725               CREATED_BY,
5726               LAST_UPDATE_DATE,
5727               LAST_UPDATED_BY
5728              )
5729            values
5730              (
5731               AP_POL_LINES_S.NEXTVAL,
5732               c_nightrate.POLICY_ID,
5733               c_nightrate.SCHEDULE_PERIOD_ID,
5734               c_nightrate.LOCATION_ID,
5735               c_nightrate.ROLE_ID,
5736               c_nightrate.CURRENCY_CODE,
5737               'NIGHT_RATE',
5738               c_nightrate.NIGHT_RATE_TYPE_CODE,
5739               c_nightrate.STATUS,
5740               sysdate,
5741               p_user_id,
5742               sysdate,
5743               p_user_id
5744              );
5745        END LOOP;
5746 
5747         END IF;
5748 
5749 
5750 END permutateNightRates;
5751 
5752 /*========================================================================
5753  | PUBLIC FUNCTION isNightRatesEnabled
5754  |
5755  | DESCRIPTION
5756  | Checks to see if a Rule is enabled for a Schedule and an Option defined
5757  |
5758  | CALLED FROM PROCEDURES/FUNCTIONS this package and from BC4J
5759  |
5760  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
5761  |
5762  | PARAMETERS
5763  |    p_policy_id  IN   Policy Id
5764  | RETURNS
5765  |   TRUE If a Rule is enabled for a Schedule and an Option defined
5766  |   FALSE If a Rule is not enabled for a Schedule or an Option not defined
5767  |
5768  | MODIFICATION HISTORY
5769  | Date                  Author            Description of Changes
5770  | 10-Nov-2005           krmenon           Created
5771  |
5772  *=======================================================================*/
5773 FUNCTION isNightRatesEnabled(p_policy_id IN ap_pol_headers.policy_id%TYPE) RETURN VARCHAR2 IS
5774   l_night_rate_flag VARCHAR2(1) := 'N';
5775 BEGIN
5776 
5777    select nvl2(night_rates_code, 'Y', 'N' )
5778    into   l_night_rate_flag
5779    from   ap_pol_headers
5780    where  policy_id = p_policy_id;
5781 
5782    return l_night_rate_flag;
5783 
5784   EXCEPTION
5785    WHEN NO_DATA_FOUND THEN
5786      return l_night_rate_flag;
5787    WHEN OTHERS THEN
5788      raise;
5789 
5790 END isNightRatesEnabled;
5791 
5792 /*========================================================================
5793  | PUBLIC FUNCTION isFirstPeriodRatesEnabled
5794  |
5795  | DESCRIPTION
5796  | Checks to see if a Rule is enabled for a Schedule and an Option defined
5797  |
5798  | CALLED FROM PROCEDURES/FUNCTIONS this package and from BC4J
5799  |
5800  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
5801  |
5802  | PARAMETERS
5803  |    p_policy_id  IN   Policy Id
5804  | RETURNS
5805  |   TRUE If a Rule is enabled for a Schedule and an Option defined
5806  |   FALSE If a Rule is not enabled for a Schedule or an Option not defined
5807  |
5808  | MODIFICATION HISTORY
5809  | Date                  Author            Description of Changes
5810  | 10-Nov-2005           krmenon           Created
5811  |
5812  *=======================================================================*/
5813 FUNCTION isFirstPeriodRatesEnabled ( p_policy_id    ap_pol_headers.policy_id%TYPE ) RETURN VARCHAR2 IS
5814     l_rate_period_type_code		ap_pol_headers.night_rates_code%TYPE;
5815     l_first_period_count		number := 0;
5816 BEGIN
5817 
5818    select nvl(rate_period_type_code, 'STANDARD')
5819    into   l_rate_period_type_code
5820    from   ap_pol_headers
5821    where  policy_id = p_policy_id;
5822 
5823    select count(1)
5824    into   l_first_period_count
5825    from   ap_pol_schedule_options
5826    where  policy_id = p_policy_id
5827    and    rate_type_code= 'FIRST_PERIOD';
5828 
5829    if (l_rate_period_type_code = 'STANDARD_FIRST_LAST' and l_first_period_count > 0)
5830    then
5831      return 'Y';
5832    else
5833      return 'N';
5834    end if;
5835 
5836   EXCEPTION
5837    WHEN OTHERS THEN
5838     raise;
5839 
5840 END isFirstPeriodRatesEnabled;
5841 
5842 
5843 /*========================================================================
5844  | PUBLIC FUNCTION isLastPeriodRatesEnabled
5845  |
5846  | DESCRIPTION
5847  | Checks to see if a Rule is enabled for a Schedule and an Option defined
5848  |
5849  | CALLED FROM PROCEDURES/FUNCTIONS this package and from BC4J
5850  |
5851  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
5852  |
5853  | PARAMETERS
5854  |    p_policy_id  IN   Policy Id
5855  | RETURNS
5856  |   TRUE If a Rule is enabled for a Schedule and an Option defined
5857  |   FALSE If a Rule is not enabled for a Schedule or an Option not defined
5858  |
5859  | MODIFICATION HISTORY
5860  | Date                  Author            Description of Changes
5861  | 10-Nov-2005           krmenon           Created
5862  |
5863  *=======================================================================*/
5864 FUNCTION isLastPeriodRatesEnabled ( p_policy_id    ap_pol_headers.policy_id%TYPE ) RETURN VARCHAR2 IS
5865     l_rate_period_type_code		ap_pol_headers.night_rates_code%TYPE;
5866     l_last_period_count		number := 0;
5867 BEGIN
5868 
5869    select nvl(rate_period_type_code, 'STANDARD')
5870    into   l_rate_period_type_code
5871    from   ap_pol_headers
5872    where  policy_id = p_policy_id;
5873 
5874    select count(1)
5875    into   l_last_period_count
5876    from   ap_pol_schedule_options
5877    where  policy_id = p_policy_id
5878    and    rate_type_code= 'LAST_PERIOD';
5879 
5880    if (l_rate_period_type_code = 'STANDARD_FIRST_LAST' and l_last_period_count > 0)
5881    then
5882      return 'Y';
5883    else
5884      return 'N';
5885    end if;
5886 
5887   EXCEPTION
5888    WHEN OTHERS THEN
5889     raise;
5890 
5891 END isLastPeriodRatesEnabled;
5892 
5893 /*========================================================================
5894  | PUBLIC FUNCTION isSameDayRatesEnabled
5895  |
5896  | DESCRIPTION
5897  | Checks to see if a Rule is enabled for a Schedule and an Option defined
5898  |
5899  | CALLED FROM PROCEDURES/FUNCTIONS this package and from BC4J
5900  |
5901  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
5902  |
5903  | PARAMETERS
5904  |    p_policy_id  IN   Policy Id
5905  | RETURNS
5906  |   TRUE If a Rule is enabled for a Schedule and an Option defined
5907  |   FALSE If a Rule is not enabled for a Schedule or an Option not defined
5908  |
5909  | MODIFICATION HISTORY
5910  | Date                  Author            Description of Changes
5911  | 10-Nov-2005           krmenon           Created
5912  |
5913  *=======================================================================*/
5914 FUNCTION isSameDayRatesEnabled ( p_policy_id    ap_pol_headers.policy_id%TYPE ) RETURN VARCHAR2 IS
5915     l_same_day_rate_code		ap_pol_headers.night_rates_code%TYPE;
5916     l_same_day_count		number := 0;
5917 BEGIN
5918 
5919    select nvl(same_day_rate_code, 'NULL')
5920    into   l_same_day_rate_code
5921    from   ap_pol_headers
5922    where  policy_id = p_policy_id;
5923 
5924    select count(1)
5925    into   l_same_day_count
5926    from   ap_pol_schedule_options
5927    where  policy_id = p_policy_id
5928    and    rate_type_code= 'SAME_DAY';
5929 
5930    if (l_same_day_rate_code = 'DEFINED' and l_same_day_count > 0)
5931    then
5932      return 'Y';
5933    else
5934      return 'N';
5935    end if;
5936 
5937   EXCEPTION
5938    WHEN OTHERS THEN
5939     raise;
5940 
5941 END isSameDayRatesEnabled;
5942 
5943 
5944 /*========================================================================
5945  | PRIVATE FUNCTION permutateConusLines
5946  |
5947  | DESCRIPTION
5948  |   This procedure will permutate the conus/oconus based policies lines
5949  |   in case where roles have been added as a schedule option
5950  |     - Re-runnable (will not create new permuations for existing options
5951  |     - Creates permutation only for new options
5952  |     - If option end dated then set Policy Line status to inactive
5953  |
5954  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
5955  |
5956  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
5957  |
5958  | PARAMETERS
5959  |  p_user_id IN User Identifier
5960  |  p_policy_id IN Policy Identifier
5961  |
5962  | MODIFICATION HISTORY
5963  | Date                  Author            Description of Changes
5964  | 07-Dec-2005           krmenon           Created |
5965  *=======================================================================*/
5966 PROCEDURE permutateConusLines( p_user_id IN NUMBER,
5967                                p_policy_id  IN ap_pol_headers.policy_id%TYPE) IS
5968 
5969    l_role_enabled VARCHAR2(1);
5970 BEGIN
5971 
5972    -- Check if roles rule is enabled for this schedule
5973    l_role_enabled := checkRuleOption(p_policy_id, c_EMPLOYEE_ROLE);
5974 
5975    -- ------------------------------------------------------
5976    -- Remove all obsolete role permutations
5977    -- ------------------------------------------------------
5978    DELETE FROM ap_pol_lines pl
5979    WHERE  pl.policy_id = p_policy_id
5980    AND    NVL(role_id, -1) <> -1
5981    AND    NOT EXISTS
5982           ( SELECT 1
5983             FROM   ap_pol_schedule_options pso
5984             WHERE  pso.policy_id = pl.policy_id
5985             AND    pso.option_type = 'EMPLOYEE_ROLE'
5986             AND    pso.option_code = pl.role_id
5987           );
5988 
5989    IF ( l_role_enabled = 'Y' ) THEN
5990       BEGIN
5991          -- ----------------------------------------------------------
5992          -- Update all lines which has a null value for the role id
5993          -- as the default All Others row.
5994          -- ----------------------------------------------------------
5995          UPDATE ap_pol_lines
5996          SET    role_id = -1
5997          WHERE  policy_id = p_policy_id
5998          AND    role_id IS NULL;
5999 
6000          -- ---------------------------------------------
6001          -- Insert new permutations
6002          -- ---------------------------------------------
6003          INSERT INTO ap_pol_lines
6004             (   POLICY_LINE_ID,
6005                 POLICY_ID,
6006                 SCHEDULE_PERIOD_ID,
6007                 RATE_TYPE_CODE,
6008                 STATUS,
6009                 ROLE_ID,
6010                 LOCATION_ID,
6011                 CURRENCY_CODE,
6012                 RATE,
6013                 TOLERANCE,
6014                 CALCULATION_METHOD,
6015                 MEALS_DEDUCTION,
6016                 BREAKFAST_DEDUCTION,
6017                 LUNCH_DEDUCTION,
6018                 DINNER_DEDUCTION,
6019                 ONE_MEAL_DEDUCTION_AMT,
6020                 TWO_MEALS_DEDUCTION_AMT,
6021                 THREE_MEALS_DEDUCTION_AMT,
6022                 ACCOMMODATION_ADJUSTMENT,
6023                 ACCOMMODATION_CALC_METHOD,
6024                 NIGHT_RATE_TYPE_CODE,
6025                 START_OF_SEASON,
6026                 END_OF_SEASON,
6027                 MAX_LODGING_AMT,
6028                 NO_GOVT_MEALS_AMT,
6029                 PROP_MEALS_AMT,
6030                 OFF_BASE_INC_AMT,
6031                 FOOTNOTE_AMT,
6032                 FOOTNOTE_RATE_AMT,
6033                 MAX_PER_DIEM_AMT,
6034                 EFFECTIVE_START_DATE,
6035                 EFFECTIVE_END_DATE,
6036                 CREATION_DATE,
6037                 CREATED_BY,
6038                 LAST_UPDATE_LOGIN,
6039                 LAST_UPDATE_DATE,
6040                 LAST_UPDATED_BY,
6041                 REIMBURSEMENT_PERCENTAGE
6042              )
6043          SELECT AP_POL_LINES_S.NEXTVAL,
6044                 apl.POLICY_ID,
6045                 apl.SCHEDULE_PERIOD_ID,
6046                 apl.RATE_TYPE_CODE,
6047                 'NEW' as STATUS,
6048                 pso.option_code as ROLE_ID,
6049                 apl.LOCATION_ID,
6050                 apl.CURRENCY_CODE,
6051                 apl.RATE,
6052                 apl.TOLERANCE,
6053                 apl.CALCULATION_METHOD,
6054                 apl.MEALS_DEDUCTION,
6055                 apl.BREAKFAST_DEDUCTION,
6056                 apl.LUNCH_DEDUCTION,
6057                 apl.DINNER_DEDUCTION,
6058                 apl.ONE_MEAL_DEDUCTION_AMT,
6059                 apl.TWO_MEALS_DEDUCTION_AMT,
6060                 apl.THREE_MEALS_DEDUCTION_AMT,
6061                 apl.ACCOMMODATION_ADJUSTMENT,
6062                 apl.ACCOMMODATION_CALC_METHOD,
6063                 apl.NIGHT_RATE_TYPE_CODE,
6064                 apl.START_OF_SEASON,
6065                 apl.END_OF_SEASON,
6066                 apl.MAX_LODGING_AMT,
6067                 apl.NO_GOVT_MEALS_AMT,
6068                 apl.PROP_MEALS_AMT,
6069                 apl.OFF_BASE_INC_AMT,
6070                 apl.FOOTNOTE_AMT,
6071                 apl.FOOTNOTE_RATE_AMT,
6072                 apl.MAX_PER_DIEM_AMT,
6073                 apl.EFFECTIVE_START_DATE,
6074                 apl.EFFECTIVE_END_DATE,
6075                 sysdate as CREATION_DATE,
6076                 p_user_id as CREATED_BY,
6077                 p_user_id LAST_UPDATE_LOGIN,
6078                 sysdate as LAST_UPDATE_DATE,
6079                 p_user_id as LAST_UPDATED_BY,
6080                 apl.REIMBURSEMENT_PERCENTAGE
6081          FROM   ap_pol_lines apl,
6082                 ap_pol_schedule_options pso
6083          WHERE  apl.policy_id   = pso.policy_id
6084          AND    apl.role_id     = -1
6085          AND    pso.option_type = 'EMPLOYEE_ROLE'
6086          AND    pso.role_id IS NOT NULL
6087          AND    pso.role_id <> -1
6088          AND    nvl(pso.end_date, SYSDATE+1) > SYSDATE
6089          AND NOT EXISTS
6090           ( SELECT 1
6091             FROM   ap_pol_lines epl
6092             WHERE  epl.POLICY_ID = apl.policy_id
6093               AND  epl.SCHEDULE_PERIOD_ID = apl.schedule_period_id
6094               AND  nvl(epl.LOCATION_ID, -1) = nvl(apl.location_id, -1)
6095               AND  nvl(epl.ROLE_ID, -1) = pso.option_code
6096               AND  nvl(epl.CURRENCY_CODE, 'NULL') = nvl(apl.currency_code, 'NULL')
6097           );
6098       END;
6099    ELSE
6100       BEGIN
6101          -- ----------------------------------------------------------
6102          -- Update all lines which has a -1 for the role id to null
6103          -- since there are no roles implemented
6104          -- ----------------------------------------------------------
6105          UPDATE ap_pol_lines
6106          SET    role_id = NULL
6107          WHERE  policy_id = p_policy_id
6108          AND    role_id IS NOT NULL;
6109 
6110       END;
6111    END IF;
6112 
6113 END permutateConusLines;
6114 
6115 
6116 /*========================================================================
6117  | PUBLIC FUNCTION isDateInSeason
6118  |
6119  | DESCRIPTION
6120  | Helper function to determine if a date is contained within a season.
6121  |
6122  | PARAMETERS
6123  |    p_date             -- Expense Date in question
6124  |    p_start_of_season  -- Season Start (mm/dd)
6125  |    p_end_of_season    -- Season End   (mm/dd)
6126  | RETURNS
6127  |   'Y'   if date within season.
6128  |   'N'   otherwise.
6129  |
6130  | MODIFICATION HISTORY
6131  | Date                  Author            Description of Changes
6132  | 21-Feb-2006           albowicz          Created
6133  |
6134  *=======================================================================*/
6135 FUNCTION isDateInSeason (p_date DATE,
6136                          p_start_of_season ap_pol_lines.start_of_season%TYPE,
6137                          p_end_of_season   ap_pol_lines.end_of_season%TYPE) RETURN VARCHAR2 IS
6138   l_start_month INTEGER;
6139   l_start_day   INTEGER;
6140   l_end_month   INTEGER;
6141   l_end_day     INTEGER;
6142   l_start_date  DATE;
6143   l_end_date    DATE;
6144 BEGIN
6145 
6146   IF(p_date IS NULL OR p_start_of_season IS NULL OR p_end_of_season IS NULL) THEN
6147     RETURN 'N';
6148   END IF;
6149 
6150   l_start_month := substr(p_start_of_season, 1, 2) -1;
6151   l_start_day   := substr(p_start_of_season, 4, 5) -1;
6152   l_end_month   := substr(p_end_of_season, 1, 2) -1;
6153   l_end_day     := substr(p_end_of_season, 4, 5) -1;
6154 
6155   l_start_date := TRUNC(p_date, 'YEAR');
6156   l_end_date   := l_start_date;
6157 
6158   l_start_date := ADD_MONTHS(l_start_date, l_start_month) +l_start_day;
6159   l_end_date   := ADD_MONTHS(l_end_date, l_end_month) +l_end_day;
6160 
6161   -- Check if the season wraps the end of the year.
6162   IF(l_start_month > l_end_month) THEN
6163     IF(p_date >= l_start_date OR p_date <= l_end_date) THEN
6164         RETURN 'Y';
6165     END IF;
6166   ELSE
6167     IF(p_date >= l_start_date AND p_date <= l_end_date) THEN
6168         RETURN 'Y';
6169     END IF;
6170   END IF;
6171 
6172   RETURN 'N';
6173 
6174   EXCEPTION
6175    WHEN OTHERS THEN
6176     raise;
6177 
6178 END isDateInSeason;
6179 
6180 /*========================================================================
6181  | PUBLIC FUNCTION getPolicyLocationId
6182  |
6183  | DESCRIPTION
6184  | Helper function to determine the applicable policy location.
6185  |
6186  | PARAMETERS
6187  |    p_expense_type_id  -- Expense Type ID associated to the expense
6188  |    p_expense_date     -- Expense Start Date
6189  |    p_location_id      -- Expense Location
6190  | RETURNS
6191  |   Location Id   -- Location ID to use when selecting the policy line.
6192  |   null          -- otherwise.
6193  |
6194  | MODIFICATION HISTORY
6195  | Date                  Author            Description of Changes
6196  | 21-Feb-2006           albowicz          Created
6197  |
6198  *=======================================================================*/
6199 
6200 FUNCTION getPolicyLocationId( p_expense_type_id    IN NUMBER,
6201                               p_expense_date       IN DATE,
6202                               p_location_id        IN NUMBER ) RETURN NUMBER IS
6203 
6204 l_location_id AP_POL_SCHEDULE_OPTIONS.location_id%type;
6205 
6206 BEGIN
6207     SELECT LOCATION_ID
6208     INTO l_location_id
6209     FROM (
6210       -- This query verifies that a given location is active within a policy
6211       select location_id
6212       from AP_POL_SCHEDULE_OPTIONS opts, ap_expense_report_params_all p
6213       where p.parameter_id = p_expense_type_id
6214         AND policy_id = p.company_policy_id
6215         AND option_type = 'LOCATION'
6216         AND status      = 'ACTIVE'
6217         AND (opts.end_date is null OR opts.end_date >= p_expense_date)
6218         AND LOCATION_ID = p_location_id
6219       UNION ALL
6220       select opts.location_id
6221       from AP_POL_SCHEDULE_OPTIONS opts, AP_POL_LOCATIONS_B loc1, AP_POL_LOCATIONS_B loc2, ap_expense_report_params_all p
6222       where p.parameter_id = p_expense_type_id
6223         AND policy_id = p.company_policy_id
6224         AND opts.option_type = 'LOCATION'
6225         AND opts.status      = 'ACTIVE'
6226         AND (opts.end_date is null OR opts.end_date >= p_expense_date)
6227         AND loc1.location_id = opts.location_id
6228         AND loc1.location_type = 'COUNTRY'
6229         AND loc2.territory_code = loc1.territory_code
6230         AND loc2.location_type <> 'COUNTRY'
6231         AND loc2.location_id = p_location_id
6232       UNION ALL
6233       -- Will find the all other location for a given policy
6234       select loc.location_id
6235       from AP_POL_SCHEDULE_OPTIONS opts, AP_POL_LOCATIONS_B loc, ap_expense_report_params_all p
6236       where p.parameter_id = p_expense_type_id
6237         AND opts.policy_id = p.company_policy_id
6238         AND opts.option_type = 'LOCATION'
6239         AND opts.status      = 'ACTIVE'
6240         AND (opts.end_date is null OR opts.end_date >= p_expense_date)
6241         AND loc.location_id = opts.location_id
6242         AND loc.undefined_location_flag = 'Y'
6243     )
6244     WHERE ROWNUM = 1;
6245 
6246 return l_location_id;
6247 
6248     EXCEPTION WHEN NO_DATA_FOUND THEN
6249     begin
6250         return l_location_id;
6251     end;
6252 
6253 END getPolicyLocationId;
6254 
6255 
6256 
6257 /*========================================================================
6258  | PUBLIC FUNCTION getPolicyLineId
6259  |
6260  | DESCRIPTION
6261  | Determines the applicable policy line given basic expense info.
6262  |
6263  | PARAMETERS
6264  |    p_person_id        -- Person id for whom the expense belongs.
6265  |    p_expense_type_id  -- Expense Type ID associated to the expense
6266  |    p_expense_date     -- Expense Start Date
6267  |    p_location_id      -- Expense Location
6268  |    p_currency_code    -- Reimbursement Currency Code
6269  | RETURNS
6270  |   Policy Line Id    -- if an applicable policy line can be found.
6271  |   null              -- otherwise.
6272  |
6273  | MODIFICATION HISTORY
6274  | Date                  Author            Description of Changes
6275  | 21-Feb-2006           albowicz          Created
6276  |
6277  *=======================================================================*/
6278 FUNCTION getPolicyLineId(p_person_id       IN NUMBER,
6279                          p_expense_type_id IN NUMBER,
6280                          p_expense_date    IN DATE,
6281                          p_location_id     IN NUMBER,
6282                          p_currency_code   IN VARCHAR2) RETURN NUMBER IS
6283 
6284 l_policy_line_id AP_POL_LINES.policy_line_id%type;
6285 l_hr_assignment hr_assignment_rec;
6286 l_location_id NUMBER;
6287 l_location_enabled Varchar2(1);
6288 BEGIN
6289 
6290 l_hr_assignment := Gethrassignment(p_person_id, p_expense_date);
6291 
6292 select nvl(h.location_flag, 'N') into l_location_enabled
6293 from AP_POL_HEADERS h, ap_expense_report_params_all p
6294 where p.parameter_Id = p_expense_type_id
6295 and   h.policy_Id = p.company_policy_id;
6296 
6297 If(l_location_enabled = 'Y' And p_location_id Is Null) Then
6298     l_location_id := p_location_id;
6299 Else
6300     l_location_id   := Getpolicylocationid(p_expense_type_id, p_expense_date, p_location_id);
6301 End If;
6302 
6303 select l.POLICY_LINE_ID
6304 INTO l_policy_line_id
6305 from AP_POL_HEADERS h, AP_POL_LINES l, AP_POL_SCHEDULE_PERIODS sp, AP_SYSTEM_PARAMETERS sys, AP_POL_EXRATE_OPTIONS rate_opts, ap_expense_report_params_all p
6306 where p.parameter_id = p_expense_type_id
6307 AND   h.policy_id = p.company_policy_id
6308 AND   h.category_code <> 'MILEAGE'
6309 AND   h.category_code <> 'PER_DIEM'
6310 AND   p_expense_date between h.start_date and nvl(h.end_date, TO_DATE('31-12-4712', 'DD-MM-YYYY'))
6311 AND   l.policy_id = h.policy_id
6312 AND   l.status = 'ACTIVE'
6313 AND   l.SCHEDULE_PERIOD_ID = sp.SCHEDULE_PERIOD_ID
6314 AND   p_expense_date between sp.start_date and nvl(sp.end_date, TO_DATE('31-12-4712', 'DD-MM-YYYY'))
6315 AND   sys.org_id = rate_opts.org_id(+)
6316 AND   (nvl(h.employee_role_flag, 'N') = 'N' OR
6317        l.role_id = nvl((select ROLE_ID
6318                          from AP_POL_SCHEDULE_OPTIONS
6319                          where policy_id = h.policy_id
6320                          AND option_type = 'EMPLOYEE_ROLE'
6321                          AND status      = 'ACTIVE'
6322                          AND (end_date is null OR end_date >= p_expense_date)
6323                          AND ROLE_ID = decode(h.role_code, 'JOB_GROUP', l_hr_assignment.job_id, 'POSITION', l_hr_assignment.position_id, 'GRADE', l_hr_assignment.grade_id, -1)), -1))
6324 AND   (nvl(h.location_flag, 'N') = 'N' OR
6325        l.location_id = l_location_id)
6326 AND ( (h.category_code = 'AIRFARE') OR
6327       (l.currency_code = p_currency_code) OR
6328       (nvl(h.allow_rate_conversion_code, 'NO_CONVERSION') = 'NO_CONVERSION' AND h.currency_code = p_currency_code) OR
6329       (h.currency_preference = 'SRC' AND h.allow_rate_conversion_code = 'ALLOW_CONVERSION' AND
6330          ('Y' = GL_CURRENCY_API.rate_exists(p_currency_code, l.currency_code, p_expense_date, rate_opts.exchange_rate_type) OR
6331          ('Y' = GL_CURRENCY_API.rate_exists(p_currency_code, sys.base_currency_code, p_expense_date, rate_opts.exchange_rate_type) AND
6332           'Y' = GL_CURRENCY_API.rate_exists(sys.base_currency_code, l.currency_code, p_expense_date, rate_opts.exchange_rate_type)))
6333       ) OR
6334       (nvl(h.currency_preference, 'LCR') = 'LCR' AND ('Y' = GL_CURRENCY_API.rate_exists(p_currency_code, l.currency_code, p_expense_date, rate_opts.exchange_rate_type) OR
6335       ('Y' = GL_CURRENCY_API.rate_exists(p_currency_code, sys.base_currency_code, p_expense_date, rate_opts.exchange_rate_type) AND 'Y' = GL_CURRENCY_API.rate_exists(sys.base_currency_code, l.currency_code, p_expense_date, rate_opts.exchange_rate_type)))
6336       )
6337     )
6338 -- ACC Seasonality condition.
6339 AND (h.category_code <> 'ACCOMMODATIONS' OR l.start_of_season IS NULL OR l.end_of_season IS NULL OR
6340      'Y' = AP_WEB_POLICY_UTILS.isDateInSeason(p_expense_date, l.start_of_season, l.end_of_season))
6341 AND l.parent_line_id is null -- Bug: 6866388, Too Many rows fetched
6342 AND p_expense_date between nvl(l.effective_start_date, p_expense_date) and nvl(l.effective_end_date, p_expense_date+1); -- 6994883
6343 
6344 return l_policy_line_id;
6345 
6346 
6347     EXCEPTION WHEN NO_DATA_FOUND THEN
6348     begin
6349         return l_policy_line_id;
6350     end;
6351 
6352 
6353 END getPolicyLineId;
6354 
6355 
6356 /*========================================================================
6357  | PUBLIC FUNCTION checkForInvalidLines
6358  |
6359  | DESCRIPTION
6360  | Public helper procedure to validate policy lines.
6361  |
6362  | PARAMETERS
6363  |    p_policy_id     IN    Policy Id
6364  |    p_schedule_id   IN    Policy Schedule Id.
6365  |    p_rate_type     IN    Rate Type (STANDARD, SAME_DAY, FIRST_PERIOD,
6366  |                                     LAST_PERIOD, NIGHT_RATE, ADDON)
6367  |    p_std_invalid   OUT   Count of invalid standard lines
6368  |    p_first_invalid OUT   Count of invalid first period lines
6369  |    p_last_invalid  OUT   Count of invalid last period lines
6370  |    p_same_invalid  OUT   Count of invalid same day rate lines
6371  |    p_night_invalid OUT   Count of invalid night rate lines
6372  |    p_addon_invalid OUT   Count of invalid addon lines
6373  |
6374  |
6375  | MODIFICATION HISTORY
6376  | Date                  Author            Description of Changes
6377  | 08-Jun-2006           krmenon           Created
6378  |
6379  *=======================================================================*/
6380 FUNCTION checkForInvalidLines(p_policy_id     IN ap_pol_lines.POLICY_ID%type,
6381                               p_schedule_id   IN ap_pol_lines.SCHEDULE_PERIOD_ID%type,
6382                               p_std_invalid   OUT NOCOPY NUMBER,
6383                               p_first_invalid OUT NOCOPY NUMBER,
6384                               p_last_invalid  OUT NOCOPY NUMBER,
6385                               p_same_invalid  OUT NOCOPY NUMBER,
6386                               p_night_invalid OUT NOCOPY NUMBER,
6387                               p_addon_invalid OUT NOCOPY NUMBER) RETURN VARCHAR2 IS
6388 
6389 -- Cursor to check for invalid lines based on status
6390 cursor c_invalid_policy_lines is
6391    select nvl(rate_type_code, 'STANDARD') rate_type_code, count(1) as number_of_lines
6392    from   ap_pol_lines
6393    where  policy_id = p_policy_id
6394    and    schedule_period_id = p_schedule_id
6395    and    (status <>  'VALID' and status <> 'ACTIVE' and status <> 'INACTIVE' and status <> 'DUPLICATED')--Bug #13390211,13908899
6396    and    addon_mileage_rate_code is null
6397    group by rate_type_code
6398    union all
6399    select nvl(rate_type_code, 'ADDON') rate_type_code,  count(1) as number_of_lines
6400    from   ap_pol_lines
6401    where  policy_id = p_policy_id
6402    and    schedule_period_id = p_schedule_id
6403    and    (status <> 'VALID' and status <> 'ACTIVE' and status <> 'INACTIVE' and status <> 'DUPLICATED')--Bug #13390211,13908899
6404    and    addon_mileage_rate_code is not null
6405    group by rate_type_code;
6406 
6407 l_std_invalid   NUMBER;
6408 l_first_invalid NUMBER;
6409 l_last_invalid  NUMBER;
6410 l_same_invalid  NUMBER;
6411 l_night_invalid NUMBER;
6412 l_addon_invalid NUMBER;
6413 
6414 BEGIN
6415 
6416    -- Initialized
6417    p_std_invalid   :=0;
6418    p_first_invalid :=0;
6419    p_last_invalid  :=0;
6420    p_same_invalid  :=0;
6421    p_night_invalid :=0;
6422    p_addon_invalid :=0;
6423 
6424    -- Loop through the cursor
6425    FOR invalidLines in c_invalid_policy_lines
6426    LOOP
6427       IF ( invalidLines.rate_type_code = 'STANDARD' ) THEN
6428         p_std_invalid := invalidLines.number_of_lines;
6429       ELSIF ( invalidLines.rate_type_code = 'FIRST_PERIOD' ) THEN
6430         p_first_invalid := invalidLines.number_of_lines;
6431       ELSIF ( invalidLines.rate_type_code = 'LAST_PERIOD' ) THEN
6432         p_last_invalid := invalidLines.number_of_lines;
6433       ELSIF ( invalidLines.rate_type_code = 'SAME_DAY' ) THEN
6434         p_same_invalid := invalidLines.number_of_lines;
6435       ELSIF ( invalidLines.rate_type_code = 'NIGHT_RATE' ) THEN
6436         p_night_invalid := invalidLines.number_of_lines;
6437       ELSIF ( invalidLines.rate_type_code = 'ADDON' ) THEN
6438         p_addon_invalid := invalidLines.number_of_lines;
6439       END IF;
6440 
6441    END LOOP;
6442 
6443    IF ( (p_std_invalid + p_first_invalid + p_last_invalid +
6444          p_same_invalid + p_night_invalid + p_addon_invalid) > 0 ) THEN
6445       RETURN 'Y';
6446    ELSE
6447       RETURN 'N';
6448    END IF;
6449 
6450 END checkForInvalidLines;
6451 
6452 /*========================================================================
6453  | PUBLIC FUNCTION activatePolicyLines
6454  |
6455  | DESCRIPTION
6456  | Public helper procedure to activate policy lines for the case where there
6457  | are more than 300 lines.
6458  |
6459  | PARAMETERS
6460  |    p_policy_id     IN    Policy Id
6461  |    p_schedule_id   IN    Policy Schedule Id
6462  |
6463  |
6464  | MODIFICATION HISTORY
6465  | Date                  Author            Description of Changes
6466  | 08-Jun-2006           krmenon           Created
6467  |
6468  *=======================================================================*/
6469 PROCEDURE activatePolicyLines(p_policy_id     IN ap_pol_lines.POLICY_ID%type,
6470                               p_schedule_id   IN ap_pol_lines.SCHEDULE_PERIOD_ID%type) IS
6471 BEGIN
6472 
6473    UPDATE ap_pol_lines
6474    SET    status = 'ACTIVE'
6475    WHERE  policy_id = p_policy_id
6476    AND    schedule_period_id = p_schedule_id
6477    AND    status = 'VALID';
6478 
6479 END activatePolicyLines;
6480 
6481 PROCEDURE massUpdatePolicyLines(l_mass_update_type IN VARCHAR2,
6482                                l_rate IN VARCHAR2,
6483                                l_meal_limit IN VARCHAR2,
6484                                l_calculation_method IN VARCHAR2,
6485                                l_accommodation_calc_method IN VARCHAR2,
6486                                l_breakfast_deduction IN VARCHAR2,
6487                                l_lunch_deduction IN VARCHAR2,
6488                                l_dinner_deduction IN VARCHAR2,
6489                                l_accommodation_adjustment IN VARCHAR2,
6490                                l_meals_deduction IN VARCHAR2,
6491                                l_tolerance IN VARCHAR2,
6492                                l_reimbursement_percentage IN VARCHAR2,
6493                                l_rate_per_passenger IN VARCHAR2,
6494                                l_one_meal_deduction_amt IN VARCHAR2,
6495                                l_two_meals_deduction_amt IN VARCHAR2,
6496                                l_three_meals_deduction_amt IN VARCHAR2,
6497                                l_rounding_rule IN VARCHAR2,
6498                                l_where_clause IN VARCHAR2,
6499                                l_max_receipt_amt IN VARCHAR2
6500 ) IS
6501 
6502 l_stmt VARCHAR2(4000);
6503 BEGIN
6504   l_stmt := null;
6505 
6506     IF(l_mass_update_type = 'AMOUNT') THEN
6507       l_stmt := ' Update ap_pol_lines set ' ||
6508                ' rate = Nvl('|| l_rate || ', rate),' ||
6509                ' meal_limit = Nvl('|| l_meal_limit || ', meal_limit),' ||
6510                ' max_receipt_amt = Nvl('|| l_max_receipt_amt || ', max_receipt_amt),' ||
6511                ' calculation_method = decode('''|| l_calculation_method|| ''',''NULL'',calculation_method,'''||l_calculation_method||'''),' ||
6512                ' accommodation_calc_method = decode('''|| l_accommodation_calc_method|| ''',''NULL'',accommodation_calc_method,'''||l_accommodation_calc_method||'''),' ||
6513                ' breakfast_deduction = Nvl('|| l_breakfast_deduction|| ', breakfast_deduction),' ||
6514                ' lunch_deduction = Nvl('|| l_lunch_deduction|| ',lunch_deduction),' ||
6515                ' dinner_deduction = Nvl('|| l_dinner_deduction|| ',dinner_deduction),' ||
6516                ' accommodation_adjustment = Nvl('|| l_accommodation_adjustment|| ',accommodation_adjustment),' ||
6517                ' meals_deduction = Nvl('|| l_meals_deduction|| ', meals_deduction),' ||
6518                ' tolerance = Nvl('|| l_tolerance|| ', tolerance),' ||
6519                ' reimbursement_percentage = Nvl('|| l_reimbursement_percentage|| ', reimbursement_percentage),' ||
6520                ' rate_per_passenger = Nvl('|| l_rate_per_passenger|| ', rate_per_passenger),' ||
6521                ' one_meal_deduction_amt = Nvl('|| l_one_meal_deduction_amt|| ', one_meal_deduction_amt),' ||
6522                ' two_meals_deduction_amt = Nvl('|| l_two_meals_deduction_amt|| ', two_meals_deduction_amt),' ||
6523                ' three_meals_deduction_amt = Nvl('|| l_three_meals_deduction_amt|| ',three_meals_deduction_amt)' ||
6524                ' WHERE ' || l_where_clause;
6525 
6526     ELSIF(l_mass_update_type = 'PERCENT') THEN
6527       CASE l_rounding_rule
6528 
6529 	WHEN 'WHOLE_NUMBER' THEN
6530             l_stmt := ' Update ap_pol_lines set ' ||
6531                      ' Rate = Nvl(Round(Rate + (('||l_rate ||' * Rate)/100), 0), rate),' ||
6532                      ' max_receipt_amt = Nvl(Round(max_receipt_amt + (('||l_max_receipt_amt ||' * max_receipt_amt)/100), 0), max_receipt_amt),' ||
6533                      ' calculation_method = decode('''|| l_calculation_method|| ''',''NULL'',calculation_method,'''||l_calculation_method||'''),' ||
6534                      ' accommodation_calc_method = decode('''|| l_accommodation_calc_method|| ''',''NULL'',accommodation_calc_method,'''||l_accommodation_calc_method||'''),' ||
6535                      ' meal_limit = Nvl(Round(meal_limit + (('||l_meal_limit  ||' * meal_limit)/100), 0), meal_limit),' ||
6536                      ' breakfast_deduction = Nvl(Round(breakfast_deduction + (('||l_breakfast_deduction ||' * breakfast_deduction)/100), 0), breakfast_deduction),' ||
6537                      ' lunch_deduction = Nvl(Round(lunch_deduction + (('||l_lunch_deduction ||' * lunch_deduction)/100), 0), lunch_deduction),' ||
6538                      ' dinner_deduction = Nvl(Round(dinner_deduction + (('||l_dinner_deduction ||' * dinner_deduction)/100), 0), dinner_deduction), ' ||
6539                      ' accommodation_adjustment = Nvl(Round(accommodation_adjustment + (('||l_accommodation_adjustment ||' * accommodation_adjustment)/100), 0), accommodation_adjustment),' ||
6540                      ' meals_deduction = Nvl(Round(meals_deduction + (('||l_meals_deduction ||' * meals_deduction)/100), 0), meals_deduction),' ||
6541                      ' tolerance = Nvl('||l_tolerance ||', tolerance),' ||
6542                      ' reimbursement_percentage = Nvl('|| l_reimbursement_percentage|| ', reimbursement_percentage),' ||
6543                      ' rate_per_passenger = Nvl(Round(rate_per_passenger + (('||l_rate_per_passenger ||' * rate_per_passenger)/100), 0),rate_per_passenger),' ||
6544                      ' one_meal_deduction_amt = Nvl(Round(one_meal_deduction_amt + (('||l_one_meal_deduction_amt ||' * one_meal_deduction_amt)/100), 0), one_meal_deduction_amt),' ||
6545                      ' two_meals_deduction_amt = Nvl(Round(two_meals_deduction_amt + (('||l_two_meals_deduction_amt ||' * two_meals_deduction_amt)/100), 0), two_meals_deduction_amt),' ||
6546                      ' three_meals_deduction_amt = Nvl(Round(three_meals_deduction_amt + (('||l_three_meals_deduction_amt ||' * three_meals_deduction_amt)/100), 0), three_meals_deduction_amt)' ||
6547                      ' WHERE ' || l_where_clause;
6548 
6549         WHEN '1_DECIMALS' THEN
6550 
6551             l_stmt := ' Update ap_pol_lines set ' ||
6552                      ' Rate = Nvl(Round(Rate + (('||l_rate ||' * Rate)/100), 1), rate),' ||
6553                      ' max_receipt_amt = Nvl(Round(max_receipt_amt + (('||l_max_receipt_amt ||' * max_receipt_amt)/100), 1), max_receipt_amt),' ||
6554                      ' meal_limit = Nvl(Round(meal_limit + (('||l_meal_limit  ||' * meal_limit)/100), 1), meal_limit),' ||
6555                      ' calculation_method = decode('''|| l_calculation_method|| ''',''NULL'',calculation_method,'''||l_calculation_method||'''),' ||
6556                      ' accommodation_calc_method = decode('''|| l_accommodation_calc_method|| ''',''NULL'',accommodation_calc_method,'''||l_accommodation_calc_method||'''),' ||
6557                      ' breakfast_deduction = Nvl(Round(breakfast_deduction + (('||l_breakfast_deduction ||' * breakfast_deduction)/100), 1), breakfast_deduction),' ||
6558                      ' lunch_deduction = Nvl(Round(lunch_deduction + (('||l_lunch_deduction ||' * lunch_deduction)/100), 1), lunch_deduction),' ||
6559                      ' dinner_deduction = Nvl(Round(dinner_deduction + (('||l_dinner_deduction ||' * dinner_deduction)/100), 1), dinner_deduction), ' ||
6560                      ' accommodation_adjustment = Nvl(Round(accommodation_adjustment + (('||l_accommodation_adjustment ||' * accommodation_adjustment)/100), 1), accommodation_adjustment),' ||
6561                      ' meals_deduction = Nvl(Round(meals_deduction + (('||l_meals_deduction ||' * meals_deduction)/100), 1), meals_deduction),' ||
6562                      ' tolerance = Nvl('||l_tolerance ||', tolerance),' ||
6563                      ' reimbursement_percentage = Nvl('|| l_reimbursement_percentage|| ', reimbursement_percentage),' ||
6564                      ' rate_per_passenger = Nvl(Round(rate_per_passenger + (('||l_rate_per_passenger ||' * rate_per_passenger)/100), 1),rate_per_passenger),' ||
6565                      ' one_meal_deduction_amt = Nvl(Round(one_meal_deduction_amt + (('||l_one_meal_deduction_amt ||' * one_meal_deduction_amt)/100), 1), one_meal_deduction_amt),' ||
6566                      ' two_meals_deduction_amt = Nvl(Round(two_meals_deduction_amt + (('||l_two_meals_deduction_amt ||' * two_meals_deduction_amt)/100), 1), two_meals_deduction_amt),' ||
6567                      ' three_meals_deduction_amt = Nvl(Round(three_meals_deduction_amt + (('||l_three_meals_deduction_amt ||' * three_meals_deduction_amt)/100), 1), three_meals_deduction_amt)' ||
6568                      ' WHERE ' || l_where_clause;
6569 
6570         WHEN '2_DECIMALS' THEN
6571 
6572             l_stmt := ' Update ap_pol_lines set ' ||
6573                      ' Rate = Nvl(Round(Rate + (('||l_rate ||' * Rate)/100), 2), rate),' ||
6574                      ' max_receipt_amt = Nvl(Round(max_receipt_amt + (('||l_max_receipt_amt ||' * max_receipt_amt)/100), 2), max_receipt_amt),' ||
6575                      ' meal_limit = Nvl(Round(meal_limit + (('||l_meal_limit  ||' * meal_limit)/100), 2), meal_limit),' ||
6576                      ' calculation_method = decode('''|| l_calculation_method|| ''',''NULL'',calculation_method,'''||l_calculation_method||'''),' ||
6577                      ' accommodation_calc_method = decode('''|| l_accommodation_calc_method|| ''',''NULL'',accommodation_calc_method,'''||l_accommodation_calc_method||'''),' ||
6578                      ' breakfast_deduction = Nvl(Round(breakfast_deduction + (('||l_breakfast_deduction ||' * breakfast_deduction)/100), 2), breakfast_deduction),' ||
6579                      ' lunch_deduction = Nvl(Round(lunch_deduction + (('||l_lunch_deduction ||' * lunch_deduction)/100), 2), lunch_deduction),' ||
6580                      ' dinner_deduction = Nvl(Round(dinner_deduction + (('||l_dinner_deduction ||' * dinner_deduction)/100), 2), dinner_deduction), ' ||
6581                      ' accommodation_adjustment = Nvl(Round(accommodation_adjustment + (('||l_accommodation_adjustment ||' * accommodation_adjustment)/100), 2), accommodation_adjustment),' ||
6582                      ' meals_deduction = Nvl(Round(meals_deduction + (('||l_meals_deduction ||' * meals_deduction)/100), 2), meals_deduction),' ||
6583                      ' tolerance = Nvl('||l_tolerance ||', tolerance),' ||
6584                      ' reimbursement_percentage = Nvl('|| l_reimbursement_percentage|| ', reimbursement_percentage),' ||
6585                      ' rate_per_passenger = Nvl(Round(rate_per_passenger + (('||l_rate_per_passenger ||' * rate_per_passenger)/100), 2),rate_per_passenger),' ||
6586                      ' one_meal_deduction_amt = Nvl(Round(one_meal_deduction_amt + (('||l_one_meal_deduction_amt ||' * one_meal_deduction_amt)/100), 2), one_meal_deduction_amt),' ||
6587                      ' two_meals_deduction_amt = Nvl(Round(two_meals_deduction_amt + (('||l_two_meals_deduction_amt ||' * two_meals_deduction_amt)/100), 2), two_meals_deduction_amt),' ||
6588                      ' three_meals_deduction_amt = Nvl(Round(three_meals_deduction_amt + (('||l_three_meals_deduction_amt ||' * three_meals_deduction_amt)/100), 2), three_meals_deduction_amt)' ||
6589                      ' WHERE ' || l_where_clause;
6590 
6591         WHEN '3_DECIMALS' THEN
6592 
6593 	    l_stmt := ' Update ap_pol_lines set ' ||
6594                      ' Rate = Nvl(Round(Rate + (('||l_rate ||' * Rate)/100), 3), rate),' ||
6595                      ' max_receipt_amt = Nvl(Round(max_receipt_amt + (('||l_max_receipt_amt ||' * max_receipt_amt)/100), 3), max_receipt_amt),' ||
6596                      ' meal_limit = Nvl(Round(meal_limit + (('||l_meal_limit  ||' * meal_limit)/100), 3), meal_limit),' ||
6597                      ' calculation_method = decode('''|| l_calculation_method|| ''',''NULL'',calculation_method,'''||l_calculation_method||'''),' ||
6598                      ' accommodation_calc_method = decode('''|| l_accommodation_calc_method|| ''',''NULL'',accommodation_calc_method,'''||l_accommodation_calc_method||'''),' ||
6599                      ' breakfast_deduction = Nvl(Round(breakfast_deduction + (('||l_breakfast_deduction ||' * breakfast_deduction)/100), 3), breakfast_deduction),' ||
6600                      ' lunch_deduction = Nvl(Round(lunch_deduction + (('||l_lunch_deduction ||' * lunch_deduction)/100), 3), lunch_deduction),' ||
6601                      ' dinner_deduction = Nvl(Round(dinner_deduction + (('||l_dinner_deduction ||' * dinner_deduction)/100), 3), dinner_deduction), ' ||
6602                      ' accommodation_adjustment = Nvl(Round(accommodation_adjustment + (('||l_accommodation_adjustment ||' * accommodation_adjustment)/100), 3), accommodation_adjustment),' ||
6603                      ' meals_deduction = Nvl(Round(meals_deduction + (('||l_meals_deduction ||' * meals_deduction)/100), 3), meals_deduction),' ||
6604                      ' tolerance = Nvl('||l_tolerance ||', tolerance),' ||
6605                      ' reimbursement_percentage = Nvl('|| l_reimbursement_percentage|| ', reimbursement_percentage),' ||
6606                      ' rate_per_passenger = Nvl(Round(rate_per_passenger + (('||l_rate_per_passenger ||' * rate_per_passenger)/100), 3),rate_per_passenger),' ||
6607                      ' one_meal_deduction_amt = Nvl(Round(one_meal_deduction_amt + (('||l_one_meal_deduction_amt ||' * one_meal_deduction_amt)/100), 3), one_meal_deduction_amt),' ||
6608                      ' two_meals_deduction_amt = Nvl(Round(two_meals_deduction_amt + (('||l_two_meals_deduction_amt ||' * two_meals_deduction_amt)/100), 3), two_meals_deduction_amt),' ||
6609                      ' three_meals_deduction_amt = Nvl(Round(three_meals_deduction_amt + (('||l_three_meals_deduction_amt ||' * three_meals_deduction_amt)/100), 3), three_meals_deduction_amt)' ||
6610                      ' WHERE ' || l_where_clause;
6611 
6612         WHEN 'NEAREST_FIVE' THEN
6613 
6614             l_stmt := ' Update ap_pol_lines set ' ||
6615                      ' Rate = Nvl((Round(Round(Rate + (('||l_rate ||'* Rate)/100), 0)/5)*5), Rate), ' ||
6616                      ' max_receipt_amt = Nvl((Round(Round(max_receipt_amt + (('||l_max_receipt_amt ||'* max_receipt_amt)/100), 0)/5)*5), max_receipt_amt), ' ||
6617                      ' meal_limit = Nvl((Round(Round(meal_limit + (('||l_meal_limit ||'* meal_limit)/100), 0)/5)*5), meal_limit),' ||
6618                      ' calculation_method = decode('''|| l_calculation_method|| ''',''NULL'',calculation_method,'''||l_calculation_method||'''),' ||
6619                      ' accommodation_calc_method = decode('''|| l_accommodation_calc_method|| ''',''NULL'',accommodation_calc_method,'''||l_accommodation_calc_method||'''),' ||
6620                      ' breakfast_deduction = Nvl((Round(Round(breakfast_deduction + (('||l_breakfast_deduction ||'* breakfast_deduction)/100), 0)/5)*5), breakfast_deduction),' ||
6621                      ' lunch_deduction = Nvl((Round(Round(lunch_deduction + (('||l_lunch_deduction ||'* lunch_deduction)/100), 0)/5)*5), lunch_deduction),' ||
6622                      ' dinner_deduction = Nvl((Round(Round(dinner_deduction + (('||l_dinner_deduction ||'* dinner_deduction)/100), 0)/5)*5), dinner_deduction),' ||
6623                      ' accommodation_adjustment = Nvl((Round(Round(accommodation_adjustment + (('||l_accommodation_adjustment ||'* accommodation_adjustment)/100), 0)/5)*5), accommodation_adjustment),' ||
6624                      ' meals_deduction = Nvl((Round(Round(meals_deduction + (('||l_meals_deduction ||'* meals_deduction)/100), 0)/5)*5), meals_deduction),' ||
6625                      ' tolerance = Nvl('||l_tolerance||' , tolerance),' ||
6626                      ' reimbursement_percentage = Nvl('|| l_reimbursement_percentage|| ', reimbursement_percentage),' ||
6627                      ' rate_per_passenger = Nvl((Round(Round(rate_per_passenger + (('||l_rate_per_passenger ||'* rate_per_passenger)/100), 0)/5)*5),rate_per_passenger),' ||
6628                      ' one_meal_deduction_amt = Nvl((Round(Round(one_meal_deduction_amt + (('||l_one_meal_deduction_amt ||'* one_meal_deduction_amt)/100), 0)/5)*5), one_meal_deduction_amt),' ||
6629                      ' two_meals_deduction_amt = Nvl((Round(Round(two_meals_deduction_amt + (('||l_two_meals_deduction_amt ||'* two_meals_deduction_amt)/100), 0)/5)*5), two_meals_deduction_amt),' ||
6630                      ' three_meals_deduction_amt = Nvl((Round(Round(three_meals_deduction_amt + (('||l_three_meals_deduction_amt ||'* three_meals_deduction_amt)/100), 0)/5)*5), three_meals_deduction_amt)' ||
6631 		     ' WHERE ' || l_where_clause;
6632 
6633       WHEN 'NEAREST_TEN' THEN
6634 
6635             l_stmt := ' Update ap_pol_lines set ' ||
6636                      ' Rate = Nvl((Round(Round(Rate + (('||l_rate ||'* Rate)/100), 0)/10)*10), Rate), ' ||
6637                      ' max_receipt_amt = Nvl((Round(Round(max_receipt_amt + (('||l_max_receipt_amt ||'* max_receipt_amt)/100), 0)/10)*10), max_receipt_amt), ' ||
6638                      ' meal_limit = Nvl((Round(Round(meal_limit + (('||l_meal_limit ||'* meal_limit)/100), 0)/10)*10), meal_limit),' ||
6639                      ' calculation_method = decode('''|| l_calculation_method|| ''',''NULL'',calculation_method,'''||l_calculation_method||'''),' ||
6640                      ' accommodation_calc_method = decode('''|| l_accommodation_calc_method|| ''',''NULL'',accommodation_calc_method,'''||l_accommodation_calc_method||'''),' ||
6641                      ' breakfast_deduction = Nvl((Round(Round(breakfast_deduction + (('||l_breakfast_deduction ||'* breakfast_deduction)/100), 0)/10)*10), breakfast_deduction),' ||
6642                      ' lunch_deduction = Nvl((Round(Round(lunch_deduction + (('||l_lunch_deduction ||'* lunch_deduction)/100), 0)/10)*10), lunch_deduction),' ||
6643                      ' dinner_deduction = Nvl((Round(Round(dinner_deduction + (('||l_dinner_deduction ||'* dinner_deduction)/100), 0)/10)*10), dinner_deduction),' ||
6644                      ' accommodation_adjustment = Nvl((Round(Round(accommodation_adjustment + (('||l_accommodation_adjustment ||'* accommodation_adjustment)/100), 0)/10)*10), accommodation_adjustment),' ||
6645                      ' meals_deduction = Nvl((Round(Round(meals_deduction + (('||l_meals_deduction ||'* meals_deduction)/100), 0)/10)*10), meals_deduction),' ||
6646                      ' tolerance = Nvl('||l_tolerance||' , tolerance),' ||
6647                      ' reimbursement_percentage = Nvl('|| l_reimbursement_percentage|| ', reimbursement_percentage),' ||
6648                      ' rate_per_passenger = Nvl((Round(Round(rate_per_passenger + (('||l_rate_per_passenger ||'* rate_per_passenger)/100), 0)/10)*10),rate_per_passenger),' ||
6649                      ' one_meal_deduction_amt = Nvl((Round(Round(one_meal_deduction_amt + (('||l_one_meal_deduction_amt ||'* one_meal_deduction_amt)/100), 0)/10)*10), one_meal_deduction_amt),' ||
6650                      ' two_meals_deduction_amt = Nvl((Round(Round(two_meals_deduction_amt + (('||l_two_meals_deduction_amt ||'* two_meals_deduction_amt)/100), 0)/10)*10), two_meals_deduction_amt),' ||
6651                      ' three_meals_deduction_amt = Nvl((Round(Round(three_meals_deduction_amt + (('||l_three_meals_deduction_amt ||'* three_meals_deduction_amt)/100), 0)/10)*10), three_meals_deduction_amt)' ||
6652                      ' WHERE ' || l_where_clause;
6653     END CASE;
6654   END IF;
6655 
6656   IF (l_stmt IS NOT NULL) THEN
6657     execute immediate l_stmt;
6658     COMMIT;
6659   END IF;
6660 
6661 END massUpdatePolicyLines;
6662 
6663 /*========================================================================
6664  | PUBLIC FUNCTION get_dup_rule_assignment_exists
6665  |
6666  | DESCRIPTION
6667  |   This function checks whether assignments exist for a given duplicate detection rule.
6668  |
6669  | RETURNS
6670  |   Y / N depending whether assignment exists for the rule
6671  |
6672  | PARAMETERS
6673  |   p_rule_id IN  Rule Id
6674  |
6675  | MODIFICATION HISTORY
6676  | Date                  Author                   Description of Changes
6677  | 15-Feb-2010           Dharma Theja Reddy S     Created
6678  |
6679  *=======================================================================*/
6680 FUNCTION get_dup_rule_assignment_exists(p_rule_id IN NUMBER) RETURN VARCHAR2 IS
6681 
6682   CURSOR assignment_rule_cur IS
6683     --Bug 16468324: return's count > 0 only if 'rule' is added to 'rule set' (or)
6684     --                                         'rule' assigned to any operating unit
6685     SELECT count(*) assignment_count
6686     FROM oie_dup_detect_rules rule
6687     WHERE rule.rule_id = p_rule_id
6688     AND (EXISTS(SELECT 1 FROM oie_dup_detect_rs_detail rs WHERE rs.rule_id = rule.rule_id)
6689     OR EXISTS(SELECT 1 FROM oie_dup_rule_assignments_all rsa WHERE rsa.rule_id = rule.rule_id));
6690 
6691   assignment_rule_rec assignment_rule_cur%ROWTYPE;
6692 
6693   BEGIN
6694 
6695     AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start get_dup_rule_assignment_exists');
6696 
6697     IF p_rule_id IS NULL THEN
6698       RETURN 'N';
6699     END IF;
6700 
6701     OPEN assignment_rule_cur;
6702     FETCH assignment_rule_cur INTO assignment_rule_rec;
6703     CLOSE assignment_rule_cur;
6704 
6705     IF (assignment_rule_rec.assignment_count > 0) THEN
6706       RETURN 'Y';
6707     ELSE
6708       RETURN 'N';
6709     END IF;
6710 
6711 END get_dup_rule_assignment_exists;
6712 
6713 /*========================================================================
6714  | PUBLIC FUNCTION get_dup_rs_assignment_exists
6715  |
6716  | DESCRIPTION
6717  |   This function checks whether assignments exist for a given duplicate detection rule set.
6718  |
6719  | RETURNS
6720  |   Y / N depending whether assignment exists for the rule set
6721  |
6722  | PARAMETERS
6723  |   p_rule_set_id IN  Rule Set Id
6724  |
6725  | MODIFICATION HISTORY
6726  | Date                  Author                   Description of Changes
6727  | 17-Feb-2010           Dharma Theja Reddy S        Created
6728  |
6729  *=======================================================================*/
6730 FUNCTION get_dup_rs_assignment_exists(p_rule_set_id IN NUMBER) RETURN VARCHAR2 IS
6731 
6732   CURSOR assignment_rule_set_cur IS
6733     SELECT Count(rule_assignment_id) assignment_count
6734     FROM oie_dup_rule_assignments_all
6735     WHERE rule_set_id = p_rule_set_id;
6736 
6737   assignment_rule_set_rec assignment_rule_set_cur%ROWTYPE;
6738 
6739   BEGIN
6740 
6741     AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start get_dup_rs_assignment_exists');
6742 
6743     IF p_rule_set_id IS NULL THEN
6744       RETURN 'N';
6745     END IF;
6746 
6747     OPEN assignment_rule_set_cur;
6748     FETCH assignment_rule_set_cur INTO assignment_rule_set_rec;
6749     CLOSE assignment_rule_set_cur;
6750 
6751     IF (assignment_rule_set_rec.assignment_count > 0) THEN
6752       RETURN 'Y';
6753     ELSE
6754       RETURN 'N';
6755     END IF;
6756 
6757 END get_dup_rs_assignment_exists;
6758 
6759 /*========================================================================
6760  | PUBLIC FUNCTION get_dup_detect_rule_name
6761  |
6762  | DESCRIPTION
6763  |   This function returns duplicate detection rule name using rule id.
6764  |
6765  | RETURNS
6766  |   Duplicate detection rule name.
6767  |
6768  | PARAMETERS
6769  |   p_rule_id IN  Rule Id
6770  |
6771  | MODIFICATION HISTORY
6772  | Date                  Author                   Description of Changes
6773  | 23-Feb-2010           Dharma Theja Reddy S        Created
6774  |
6775  *=======================================================================*/
6776 FUNCTION get_dup_detect_rule_name(p_rule_id IN NUMBER) RETURN VARCHAR2 IS
6777 
6778   l_rule_name oie_dup_detect_rules.rule_name%TYPE;
6779 
6780   BEGIN
6781 
6782     AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start get_dup_detect_rule_name');
6783 
6784     IF p_rule_id IS NULL THEN
6785       RETURN NULL;
6786     END IF;
6787 
6788     IF p_rule_id = -1 THEN
6789       SELECT displayed_field INTO l_rule_name FROM ap_lookup_codes
6790       WHERE lookup_type = 'OIE_DISABLE_DUP_DETECTION' AND lookup_code = 'DISABLE_DUPLICATE_DETECTION';
6791     ELSE
6792       SELECT rule_name INTO l_rule_name FROM oie_dup_detect_rules
6793       WHERE rule_id = p_rule_id;
6794     END IF;
6795 
6796     RETURN l_rule_name;
6797 
6798   EXCEPTION
6799     WHEN No_Data_Found THEN
6800       RETURN NULL;
6801     WHEN OTHERS THEN
6802       RETURN NULL;
6803 
6804 END get_dup_detect_rule_name;
6805 
6806 /*========================================================================
6807  | PUBLIC FUNCTION get_dup_detect_rs_name
6808  |
6809  | DESCRIPTION
6810  |   This function returns duplicate detection rule set name using rule set id.
6811  |
6812  | RETURNS
6813  |   Duplicate Detection Rule Set name
6814  |
6815  | PARAMETERS
6816  |   p_rule_set_id  IN    Rule Set Id
6817  |
6818  | MODIFICATION HISTORY
6819  | Date                  Author                   Description of Changes
6820  | 23-Feb-2010           Dharma Theja Reddy S        Created
6821  |
6822  *=======================================================================*/
6823 FUNCTION get_dup_detect_rs_name(p_rule_set_id IN NUMBER) RETURN VARCHAR2 IS
6824 
6825   l_rule_set_name oie_dup_detect_rs_summary.rule_set_name%TYPE;
6826 
6827   BEGIN
6828 
6829     AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start get_dup_detect_rs_name');
6830 
6831     IF p_rule_set_id IS NULL THEN
6832       RETURN NULL;
6833     END IF;
6834 
6835     SELECT rule_set_name INTO l_rule_set_name FROM oie_dup_detect_rs_summary
6836     WHERE rule_set_id = p_rule_set_id;
6837 
6838     RETURN l_rule_set_name;
6839 
6840   EXCEPTION
6841     WHEN No_Data_Found THEN
6842       RETURN NULL;
6843     WHEN OTHERS THEN
6844       RETURN NULL;
6845 
6846 END get_dup_detect_rs_name;
6847 
6848 /*========================================================================
6849  | PUBLIC FUNCTION validate_dup_detect_rule_name
6850  |
6851  | DESCRIPTION
6852  |   This function validates the duplicate detection rule name.
6853  |
6854  | RETURNS
6855  |   Y / N depending whether the rule name already exists
6856  |
6857  | PARAMETERS
6858  |   p_rule_name  IN    Rule Name
6859  |   p_rule_id    IN    Rule Id
6860  |
6861  | MODIFICATION HISTORY
6862  | Date                  Author                   Description of Changes
6863  | 23-Feb-2010           Dharma Theja Reddy S        Created
6864  |
6865  *=======================================================================*/
6866 FUNCTION validate_dup_detect_rule_name(p_rule_name IN VARCHAR2, p_rule_id IN VARCHAR2) RETURN VARCHAR2 IS
6867 
6868   CURSOR rule_names_cur IS
6869     SELECT rule_name
6870     FROM oie_dup_detect_rules
6871     WHERE rule_id <> p_rule_id;
6872 
6873   rule_names_rec rule_names_cur%ROWTYPE;
6874 
6875 BEGIN
6876 
6877   AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start validate_dup_detect_rule_name');
6878 
6879   IF p_rule_name IS NULL THEN
6880     RETURN 'N';
6881   END IF;
6882 
6883   FOR rule_names_rec IN rule_names_cur LOOP
6884     IF p_rule_name = rule_names_rec.rule_name THEN
6885       RETURN 'Y';
6886     END IF;
6887   END LOOP;
6888 
6889   RETURN 'N';
6890 
6891 END validate_dup_detect_rule_name;
6892 
6893 /*========================================================================
6894  | PUBLIC FUNCTION validate_dup_detect_rs_name
6895  |
6896  | DESCRIPTION
6897  |   This function validates the duplicate detection rule set name.
6898  |
6899  | RETURNS
6900  |   Y / N depending whether the rule set name already exists
6901  |
6902  | PARAMETERS
6903  |   p_rule_set_name  IN    Rule Set Name
6904  |   p_rule_set_id    IN    Rule Set Id
6905  |
6906  | MODIFICATION HISTORY
6907  | Date                  Author                   Description of Changes
6908  | 23-Feb-2010           Dharma Theja Reddy S        Created
6909  |
6910  *=======================================================================*/
6911 FUNCTION validate_dup_detect_rs_name(p_rule_set_name IN VARCHAR2, p_rule_set_id IN VARCHAR2) RETURN VARCHAR2 IS
6912 
6913   CURSOR rs_names_cur IS
6914     SELECT rule_set_name
6915     FROM oie_dup_detect_rs_summary
6916     WHERE rule_set_id <> p_rule_set_id;
6917 
6918   rs_names_rec rs_names_cur%ROWTYPE;
6919 
6920 BEGIN
6921 
6922   AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start validate_dup_detect_rs_name');
6923 
6924   IF p_rule_set_name IS NULL THEN
6925     RETURN 'N';
6926   END IF;
6927 
6928   FOR rs_names_rec IN rs_names_cur LOOP
6929     IF p_rule_set_name = rs_names_rec.rule_set_name THEN
6930       RETURN 'Y';
6931     END IF;
6932   END LOOP;
6933 
6934   RETURN 'N';
6935 
6936 END validate_dup_detect_rs_name;
6937 
6938 /*========================================================================
6939  | PUBLIC FUNCTION getDuplicateDetectionRule
6940  |
6941  | DESCRIPTION
6942  |   This function returns the duplicate detection rule id.
6943  |
6944  | RETURNS
6945  |   Duplicate detection rule id
6946  |
6947  | PARAMETERS
6948  |   p_org_id           IN    Org Id
6949  |   p_category_code    IN    Category Code
6950  |   p_start_date       IN    Expense Start Date
6951  |
6952  | MODIFICATION HISTORY
6953  | Date                  Author                   Description of Changes
6954  | 23-Feb-2010           Dharma Theja Reddy S        Created
6955  |
6956  *=======================================================================*/
6957 FUNCTION getDuplicateDetectionRule(p_org_id IN ap_expense_report_lines_all.ORG_ID%TYPE,
6958                                    p_category_code IN ap_expense_report_lines_all.CATEGORY_CODE%TYPE,
6959                                    p_start_date IN ap_expense_report_lines_all.START_EXPENSE_DATE%TYPE) RETURN NUMBER IS
6960 
6961   l_rule_id  oie_dup_detect_rules.RULE_ID%TYPE := NULL;
6962   l_rule_set_id  oie_dup_detect_rs_summary.RULE_SET_ID%TYPE := NULL;
6963   l_category_code VARCHAR2(30) := NULL;
6964 
6965 BEGIN
6966 
6967   AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start getDuplicateDetectionRule');
6968 
6969   BEGIN
6970 
6971   SELECT rule_id, rule_set_id INTO l_rule_id, l_rule_set_id
6972   FROM oie_dup_rule_assignments_all
6973   WHERE org_id = p_org_id AND Trunc(p_start_date) BETWEEN Trunc(start_date) AND Trunc(Nvl(end_date,p_start_date));
6974 
6975   EXCEPTION
6976   WHEN No_Data_Found THEN
6977     BEGIN
6978 
6979       SELECT rule_id, rule_set_id INTO l_rule_id, l_rule_set_id
6980       FROM oie_dup_rule_assignments_all
6981       WHERE org_id = -1 AND Trunc(p_start_date) BETWEEN Trunc(start_date) AND Trunc(Nvl(end_date,p_start_date));
6982 
6983     EXCEPTION
6984       WHEN No_Data_Found THEN
6985         RETURN NULL;
6986       WHEN OTHERS THEN
6987         RETURN NULL;
6988 
6989     END;
6990   WHEN OTHERS THEN
6991     RETURN NULL;
6992 
6993   END;
6994 
6995   IF l_rule_id IS NOT NULL THEN
6996     RETURN l_rule_id;
6997   END IF;
6998 
6999   IF l_rule_set_id IS NOT NULL THEN
7000     BEGIN
7001 
7002       SELECT displayed_field INTO l_category_code
7003       FROM ap_lookup_codes WHERE lookup_type = 'OIE_EXPENSE_CATEGORY'
7004       AND lookup_code = p_category_code;
7005 
7006       SELECT rule_id INTO l_rule_id
7007       FROM oie_dup_detect_rs_detail
7008       WHERE rule_set_id = l_rule_set_id AND category_code = l_category_code;
7009 
7010     EXCEPTION
7011       WHEN No_Data_Found THEN
7012         BEGIN
7013 
7014           SELECT rule_id INTO l_rule_id
7015           FROM oie_dup_detect_rs_detail
7016           WHERE rule_set_id = l_rule_set_id AND category_code = 'All';
7017 
7018         EXCEPTION
7019           WHEN No_Data_Found THEN
7020             BEGIN
7021 
7022 	      SELECT rule_id, rule_set_id INTO l_rule_id, l_rule_set_id
7023 	      FROM oie_dup_rule_assignments_all
7024               WHERE org_id = -1 AND Trunc(p_start_date) BETWEEN Trunc(start_date) AND Trunc(Nvl(end_date,p_start_date));
7025 
7026 	      IF l_rule_id IS NOT NULL THEN
7027 	        RETURN l_rule_id;
7028 	      ELSIF l_rule_set_id IS NOT NULL THEN
7029 	        BEGIN
7030 
7031 		  SELECT rule_id INTO l_rule_id
7032 		  FROM oie_dup_detect_rs_detail
7033 		  WHERE rule_set_id = l_rule_set_id AND category_code = l_category_code;
7034 
7035 		EXCEPTION
7036 		  WHEN No_Data_Found THEN
7037 		    BEGIN
7038 
7039 		      SELECT rule_id INTO l_rule_id
7040 		      FROM oie_dup_detect_rs_detail
7041 		      WHERE rule_set_id = l_rule_set_id AND category_code = 'All';
7042 
7043 		    EXCEPTION
7044 		      WHEN No_Data_Found THEN
7045 		        RETURN NULL;
7046 		      WHEN OTHERS THEN
7047 		        RETURN NULL;
7048 		    END;
7049 		  WHEN OTHERS THEN
7050 		    RETURN NULL;
7051 		END;
7052 	      END IF;
7053 	    EXCEPTION
7054 	      WHEN No_Data_Found THEN
7055 	        RETURN NULL;
7056 	      WHEN OTHERS THEN
7057 	        RETURN NULL;
7058 	    END;
7059           WHEN OTHERS THEN
7060             RETURN NULL;
7061 
7062         END;
7063       WHEN OTHERS THEN
7064         RETURN NULL;
7065 
7066     END;
7067   END IF;
7068 
7069   RETURN l_rule_id;
7070 
7071 END getDuplicateDetectionRule;
7072 
7073 /*========================================================================
7074  | PUBLIC FUNCTION isDupDetectExists
7075  |
7076  | DESCRIPTION
7077  |   This function validates whether the duplicate detection violation exists
7078  |   for the expense line.
7079  |
7080  | RETURNS
7081  |   Duplicate Detection Action
7082  |
7083  | PARAMETERS
7084  |   p_report_header_id     IN    Report Header Id
7085  |   p_dist_line_number     IN    Distribution Line Number
7086  |   p_org_id               IN    Org Id
7087  |   p_category_code        IN    Category Code
7088  |   p_start_date           IN    Expense Start Date
7089  |
7090  | MODIFICATION HISTORY
7091  | Date                  Author                   Description of Changes
7092  | 23-Feb-2010           Dharma Theja Reddy S        Created
7093  |
7094  *=======================================================================*/
7095 FUNCTION isDupDetectExists(p_report_header_id ap_expense_report_lines_all.REPORT_HEADER_ID%TYPE,
7096                            p_dist_line_number ap_expense_report_lines_all.DISTRIBUTION_LINE_NUMBER%TYPE,
7097                            p_org_id IN ap_expense_report_lines_all.ORG_ID%TYPE,
7098                            p_category_code IN ap_expense_report_lines_all.CATEGORY_CODE%TYPE,
7099                            p_start_date IN ap_expense_report_lines_all.START_EXPENSE_DATE%TYPE) RETURN VARCHAR2 IS
7100 
7101   l_rule_id oie_dup_detect_rules.rule_id%TYPE := NULL;
7102   l_dup_detect_action oie_dup_detect_rules.duplicate_detection_action%TYPE := NULL;
7103   l_count NUMBER := 0;
7104 
7105   BEGIN
7106 
7107   AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start isDupDetectExists');
7108 
7109   IF p_report_header_id =0  OR p_dist_line_number =0  OR p_org_id = 0 OR p_category_code IS NULL OR p_start_date IS NULL THEN
7110     RETURN NULL;
7111   END IF;
7112 
7113   l_rule_id := getDuplicateDetectionRule(p_org_id, p_category_code, p_start_date);
7114 
7115   IF l_rule_id IS NOT NULL AND l_rule_id <> -1 THEN
7116     SELECT duplicate_detection_action INTO l_dup_detect_action
7117     FROM oie_dup_detect_rules WHERE rule_id = l_rule_id;
7118   END IF;
7119 
7120   IF l_dup_detect_action = 'PREVENT_SUBMISSION' THEN
7121     BEGIN
7122       SELECT Count(*) INTO l_count FROM ap_pol_violations_all
7123       WHERE report_header_id = p_report_header_id AND distribution_line_number = p_dist_line_number
7124       AND violation_type = 'DUPLICATE_DETECTION';
7125     EXCEPTION
7126       WHEN No_Data_Found THEN
7127         l_count := 0;
7128       WHEN OTHERS THEN
7129         l_count := 0;
7130     END;
7131 
7132     IF l_count > 0 THEN
7133       RETURN l_dup_detect_action;
7134     END IF;
7135   END IF;
7136 
7137   RETURN NULL;
7138 
7139 END isDupDetectExists;
7140 
7141 /*========================================================================
7142  | PUBLIC FUNCTION getDistLineNumber
7143  |
7144  | DESCRIPTION
7145  |   This function gets the distribution line number.
7146  |
7147  | RETURNS
7148  |   Distribution Line Number
7149  |
7150  | PARAMETERS
7151  |   p_report_header_id    IN    Report Header Id
7152  |   p_dist_line_number    IN    Distribution Line Number
7153  |
7154  | MODIFICATION HISTORY
7155  | Date                  Author                   Description of Changes
7156  | 23-Feb-2010           Dharma Theja Reddy S        Created
7157  |
7158  *=======================================================================*/
7159 FUNCTION getDistLineNumber(p_report_header_id IN ap_expense_report_lines_all.REPORT_HEADER_ID%TYPE,
7160                            p_dist_line_number IN ap_expense_report_lines_all.DISTRIBUTION_LINE_NUMBER%TYPE) RETURN VARCHAR2 IS
7161 
7162   CURSOR dist_num_cur IS
7163     SELECT distribution_line_number, itemization_parent_id
7164     FROM ap_expense_report_lines_all
7165     WHERE report_header_id = p_report_header_id
7166     AND (itemization_parent_id IS NULL OR itemization_parent_id <> -1)
7167     ORDER BY distribution_line_number, itemization_parent_id;
7168 
7169   dist_num_rec dist_num_cur%ROWTYPE;
7170   l_primary_number NUMBER := 0;
7171   l_sub_number NUMBER := 0;
7172   l_prev_parent_id NUMBER := 0;
7173   l_dist_line_number VARCHAR2(10) := NULL;
7174   BEGIN
7175 
7176   AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start getDistLineNumber');
7177 
7178   FOR dist_num_rec IN dist_num_cur LOOP
7179 
7180     IF dist_num_rec.itemization_parent_id IS NULL THEN
7181       l_primary_number := l_primary_number + 1;
7182       l_sub_number := 0;
7183     ELSE
7184       IF l_prev_parent_id <> dist_num_rec.itemization_parent_id THEN
7185         l_primary_number := l_primary_number + 1;
7186         l_sub_number := 1;
7187       ELSE
7188         l_sub_number := l_sub_number + 1;
7189       END IF;
7190       l_prev_parent_id := dist_num_rec.itemization_parent_id;
7191     END IF;
7192 
7193     IF dist_num_rec.distribution_line_number = p_dist_line_number THEN
7194       EXIT;
7195     END IF;
7196 
7197   END LOOP;
7198 
7199   IF l_sub_number = 0 THEN
7200     l_dist_line_number := To_Char(l_primary_number);
7201   ELSE
7202     l_dist_line_number := To_Char(l_primary_number) || '-' || To_Char(l_sub_number);
7203   END IF;
7204 
7205   AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'end getDistLineNumber');
7206 
7207   RETURN l_dist_line_number;
7208 
7209 END getDistLineNumber;
7210 
7211 /*========================================================================
7212  | PUBLIC FUNCTION getMaxDistLineNumber
7213  |
7214  | DESCRIPTION
7215  |   This function returns the maximum distribution line number for that expense line.
7216  |
7217  | RETURNS
7218  |   Maximum Distribution Line Number
7219  |
7220  | PARAMETERS
7221  |   p_report_header_id    IN    Report Header Id
7222  |   p_dist_line_number    IN    Distribution Line Number
7223  |
7224  | MODIFICATION HISTORY
7225  | Date                  Author                   Description of Changes
7226  | 23-Feb-2010           Dharma Theja Reddy S        Created
7227  |
7228  *=======================================================================*/
7229 FUNCTION getMaxDistLineNumber(p_report_header_id IN ap_pol_violations_all.REPORT_HEADER_ID%TYPE,
7230                               p_dist_line_number IN ap_pol_violations_all.DISTRIBUTION_LINE_NUMBER%TYPE) RETURN NUMBER IS
7231 
7232   l_max_violation_number ap_pol_violations_all.VIOLATION_NUMBER%TYPE;
7233 
7234 BEGIN
7235 
7236   AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start getMaxDistLineNumber');
7237 
7238   SELECT Max(violation_number) INTO l_max_violation_number
7239   FROM ap_pol_violations_all
7240   WHERE report_header_id = p_report_header_id
7241   AND distribution_line_number = p_dist_line_number
7242   AND violation_type = 'DUPLICATE_DETECTION';
7243 
7244   AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'end getMaxDistLineNumber');
7245 
7246   RETURN l_max_violation_number;
7247 
7248 EXCEPTION
7249   WHEN OTHERS THEN
7250     RETURN 0;
7251 
7252 END getMaxDistLineNumber;
7253 
7254 /*========================================================================
7255  | PUBLIC PROCEDURE performDuplicateDetection
7256  |
7257  | DESCRIPTION
7258  |   This procedure performs the duplicate detection for the expense line and
7259  |   inserts the violations on to the table ap_pol_violations_all.
7260  |
7261  | MODIFICATION HISTORY
7262  | Date                  Author                   Description of Changes
7263  | 23-Feb-2010           Dharma Theja Reddy S        Created
7264  |
7265  *=======================================================================*/
7266 PROCEDURE performDuplicateDetection(p_employee_id                 IN            VARCHAR2,
7267                                     p_report_header_id            IN            VARCHAR2,
7268                                     p_distribution_line_number    IN            VARCHAR2,
7269                                     p_org_id                      IN            VARCHAR2,
7270                                     p_start_date                  IN            DATE,
7271                                     p_end_date                    IN            DATE,
7272                                     p_receipt_currency_code       IN            VARCHAR2,
7273                                     p_daily_amount                IN            NUMBER,
7274                                     p_receipt_currency_amount     IN            NUMBER,
7275                                     p_web_parameter_id            IN            VARCHAR2,
7276                                     p_merchant_name               IN            VARCHAR2,
7277                                     p_daily_distance              IN            NUMBER,
7278                                     p_distance_unit_code          IN            VARCHAR2,
7279                                     p_destination_from            IN            VARCHAR2,
7280                                     p_destination_to              IN            VARCHAR2,
7281                                     p_trip_distance               IN            NUMBER,
7282                                     p_license_plate_number        IN            VARCHAR2,
7283                                     p_attendes                    IN            VARCHAR2,
7284                                     p_number_attendes             IN            NUMBER,
7285                                     p_ticket_class_code           IN            VARCHAR2,
7286                                     p_ticket_number               IN            VARCHAR2,
7287                                     p_itemization_parent_id       IN            NUMBER,
7288                                     p_category_code               IN            VARCHAR2,
7289                                     p_report_line_id              IN            NUMBER,
7290                                     p_max_violation_number        IN OUT NOCOPY NUMBER,
7291                                     p_dup_detect_action           OUT NOCOPY    VARCHAR2,
7292                                     p_created_by                  IN            NUMBER,
7293                                     p_creation_date               IN            DATE,
7294                                     p_last_updated_by             IN            NUMBER,
7295                                     p_last_update_login           IN            NUMBER,
7296                                     p_last_update_date            IN            DATE) IS
7297 
7298 
7299   TYPE expense_lines IS REF CURSOR;
7300 
7301   expense_lines_cur expense_lines;
7302 
7303   expense_lines_rec ap_expense_report_lines_all%ROWTYPE;
7304 
7305   l_debug_info		VARCHAR2(1000);
7306   current_calling_sequence varchar2(100) := 'performDuplicateDetection';
7307   l_stmt  VARCHAR2(2000);
7308   l_att_stmt	VARCHAR2(2000);
7309   l_where_clause  VARCHAR2(2000) := NULL;
7310   l_rule_id oie_dup_detect_rules.rule_id%TYPE := NULL;
7311   l_exp_duplicates_allowed  NUMBER := 0;
7312   l_duplicates_allowed  NUMBER := 0;
7313   l_count NUMBER := 0;
7314   l_row_count NUMBER := 0;
7315   l_violation_number NUMBER := p_max_violation_number;
7316   l_dup_detect_action VARCHAR2(30) := NULL;
7317   l_report_prefix VARCHAR2(10);
7318   l_dist_line_number VARCHAR2(10);
7319   l_reimbcurr_format 	VARCHAR2(80);
7320   l_receipt_amount VARCHAR2(50);
7321   l_receipt_amt NUMBER;
7322 
7323   CURSOR dup_detect_rule_cur(p_rule_id IN NUMBER) IS
7324     SELECT * FROM oie_dup_detect_rules
7325     WHERE rule_id = p_rule_id;
7326 
7327   dup_detect_rule_rec dup_detect_rule_cur%ROWTYPE;
7328 
7329   BEGIN
7330 
7331     AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start performDuplicateDetection');
7332 
7333     IF l_violation_number = -1 THEN
7334       SELECT  Decode(Max(violation_number), NULL, 0, Max(violation_number)) INTO l_violation_number
7335       FROM ap_pol_violations_all WHERE report_header_id = p_report_header_id;
7336     END IF;
7337 
7338     DELETE FROM ap_pol_violations_all
7339     WHERE report_header_id = p_report_header_id
7340     AND distribution_line_number = p_distribution_line_number
7341     AND violation_type = 'DUPLICATE_DETECTION';
7342 
7343     p_dup_detect_action := NULL;
7344 
7345     l_rule_id := getDuplicateDetectionRule(p_org_id, p_category_code, p_start_date);
7346 
7347     FND_PROFILE.GET('AP_WEB_REPNUM_PREFIX', l_report_prefix);
7348 
7349     IF l_rule_id IS NOT NULL AND l_rule_id <> -1 THEN
7350 
7351       OPEN dup_detect_rule_cur(l_rule_id);
7352       FETCH dup_detect_rule_cur INTO dup_detect_rule_rec;
7353       CLOSE dup_detect_rule_cur;
7354 
7355       /*l_stmt := 'SELECT * FROM ap_expense_report_lines_all WHERE (((report_header_id IN
7356                 (SELECT report_header_id FROM ap_expense_report_headers_all WHERE employee_id = ' || p_employee_id ||
7357                 ' AND AP_WEB_OA_ACTIVE_PKG.GetReportStatusCode(source, workflow_approved_flag, report_header_id)
7358                   NOT IN (''REJECTED'', ''SAVED'', ''INPROGRESS'', ''WITHDRAWN''))) AND report_header_id <> ' || p_report_header_id ||
7359                   ') OR (report_header_id = ' || p_report_header_id || ' AND distribution_line_number < ' || p_distribution_line_number ||
7360                   ' AND report_line_id <> ' || p_report_line_id || ')) AND (itemization_parent_id is NULL OR itemization_parent_id <> -1)
7361                   AND start_expense_date = ''' || p_start_date || ''' AND category_code = ''' || p_category_code|| '''';*/
7362 
7363       -- Bug# 12992286: Duplicate Detection performance fix
7364       l_stmt := 'SELECT aerl.* FROM ap_expense_report_lines_all aerl, (SELECT report_header_id FROM ap_expense_report_headers_all
7365                  WHERE employee_id = ' || p_employee_id || ' AND expense_status_code NOT IN (''REJECTED'', ''SAVED'', ''INPROGRESS'', ''WITHDRAWN'')
7366 		 UNION ALL SELECT ' || p_report_header_id || ' FROM DUAL) aerh WHERE aerl.report_header_id = aerh.report_header_id
7367 		 AND (aerl.report_header_id <> ' || p_report_header_id || ' OR (aerl.report_header_id = ' || p_report_header_id || '
7368 		 AND distribution_line_number < ' || p_distribution_line_number || ' AND report_line_id <> ' || p_report_line_id || '))
7369 		 AND (itemization_parent_id is NULL OR itemization_parent_id <> -1) AND category_code = ''' || p_category_code|| '''
7370 		 AND ((''' || p_category_code|| ''' NOT IN (''PER_DIEM'', ''MILEAGE'') AND start_expense_date = ''' || p_start_date || ''')
7371 		 OR (''' || p_category_code|| ''' IN (''PER_DIEM'', ''MILEAGE'') AND ((((select start_expense_date from ap_expense_report_lines_all
7372                  where report_line_id = ' || p_report_line_id || ') between start_expense_date AND end_expense_date) OR (start_expense_date between
7373                  (select start_expense_date from ap_expense_report_lines_all where report_line_id = ' || p_report_line_id || ') AND
7374                  (select end_expense_date from ap_expense_report_lines_all where report_line_id = ' || p_report_line_id || '))))))';
7375 
7376       IF dup_detect_rule_rec.detect_attendee_flag = 'Y' THEN
7377         /*l_att_stmt := 'SELECT * FROM ap_expense_report_lines_all WHERE (((report_header_id IN
7378                 (SELECT report_header_id FROM ap_expense_report_headers_all
7379                 WHERE AP_WEB_OA_ACTIVE_PKG.GetReportStatusCode(source, workflow_approved_flag, report_header_id)
7380                   NOT IN (''REJECTED'', ''SAVED'', ''INPROGRESS'', ''WITHDRAWN''))) AND report_header_id <> ' || p_report_header_id ||
7381                   ') OR (report_header_id = ' || p_report_header_id || ' AND distribution_line_number < ' || p_distribution_line_number ||
7382                   ' AND report_line_id <> ' || p_report_line_id || ')) AND (itemization_parent_id is NULL OR itemization_parent_id <> -1)
7383                 AND start_expense_date = ''' || p_start_date || ''' AND category_code = ''' || p_category_code|| '''
7384                 AND EXISTS (SELECT 1 FROM oie_attendees_all atts WHERE atts.report_line_id = report_line_id AND
7385                 atts.employee_flag = ''Y'' AND atts.employee_id = ' || p_employee_id || ')';*/
7386 
7387 	l_att_stmt := 'SELECT aerl.* FROM ap_expense_report_lines_all aerl, (SELECT report_header_id FROM ap_expense_report_headers_all
7388 	               WHERE expense_status_code NOT IN (''REJECTED'', ''SAVED'', ''INPROGRESS'', ''WITHDRAWN'')
7389 		       UNION ALL SELECT ' || p_report_header_id || ' FROM DUAL) aerh WHERE aerl.report_header_id = aerh.report_header_id
7390 		       AND (aerl.report_header_id <> ' || p_report_header_id || ' OR (aerl.report_header_id = ' || p_report_header_id || '
7391 		       AND distribution_line_number < ' || p_distribution_line_number || ' AND report_line_id <> ' || p_report_line_id || '))
7392 		       AND (itemization_parent_id is NULL OR itemization_parent_id <> -1) AND category_code = ''' || p_category_code|| '''
7393 		       AND ((''' || p_category_code|| ''' NOT IN (''PER_DIEM'', ''MILEAGE'') AND start_expense_date = ''' || p_start_date || ''')
7394 		       OR (''' || p_category_code|| ''' IN (''PER_DIEM'', ''MILEAGE'') AND ((((select start_expense_date from ap_expense_report_lines_all
7395                        where report_line_id = ' || p_report_line_id || ') between start_expense_date AND end_expense_date) OR (start_expense_date between
7396                        (select start_expense_date from ap_expense_report_lines_all where report_line_id = ' || p_report_line_id || ') AND
7397                        (select end_expense_date from ap_expense_report_lines_all where report_line_id = ' || p_report_line_id || '))))))
7398 		       AND EXISTS (SELECT 1 FROM oie_attendees_all atts WHERE atts.report_line_id = aerl.report_line_id
7399 		       AND atts.employee_flag = ''Y'' AND atts.employee_id = ' || p_employee_id || ')';
7400 
7401 	OPEN expense_lines_cur FOR l_att_stmt;
7402 	LOOP
7403 	  FETCH expense_lines_cur INTO expense_lines_rec;
7404 	  EXIT WHEN expense_lines_cur%NOTFOUND;
7405 
7406 	  l_row_count := l_row_count + 1;
7407 	END LOOP;
7408 	CLOSE expense_lines_cur;
7409 
7410 	IF l_row_count > 0 THEN
7411 	  l_stmt := l_att_stmt;
7412 	END IF;
7413       END IF;
7414 
7415       -- Bug# 16300763
7416       IF dup_detect_rule_rec.detect_expense_type_flag = 'Y' THEN
7417       	IF p_web_parameter_id IS NULL THEN
7418       		l_where_clause := ' AND web_parameter_id IS NULL';
7419       	ELSE
7420         	l_where_clause := ' AND web_parameter_id = ' || p_web_parameter_id;
7421         END IF;
7422       END IF;
7423 
7424       IF dup_detect_rule_rec.detect_receipt_amt_flag = 'Y' THEN
7425         l_where_clause := l_where_clause || ' AND receipt_currency_amount IN (SELECT receipt_currency_amount FROM ap_expense_report_lines_all
7426                           WHERE report_line_id = ' || p_report_line_id || ') AND receipt_currency_code = ''' || p_receipt_currency_code || '''';
7427       END IF;
7428 
7429       IF dup_detect_rule_rec.rule_type <> 'GENERIC' THEN
7430 
7431         IF p_category_code = 'ACCOMMODATIONS' THEN
7432           IF dup_detect_rule_rec.detect_end_date_flag = 'Y' THEN
7433             l_where_clause := l_where_clause || ' AND end_expense_date = ''' || p_end_date || '''';
7434           END IF;
7435         END IF;
7436 
7437         IF (dup_detect_rule_rec.detect_merchant_flag = 'Y' AND p_merchant_name IS NOT NULL) THEN
7438           l_where_clause := l_where_clause || ' AND merchant_name = ''' || p_merchant_name || '''';
7439         END IF;
7440 
7441         IF p_category_code = 'AIRFARE' THEN
7442           IF (dup_detect_rule_rec.detect_class_of_ticket_flag = 'Y' AND p_ticket_class_code IS NOT NULL) THEN
7443             l_where_clause := l_where_clause || ' AND ticket_class_code = ''' || p_ticket_class_code || '''';
7444           END IF;
7445 
7446           IF (dup_detect_rule_rec.detect_ticket_num_flag = 'Y' AND p_ticket_number IS NOT NULL) THEN
7447             l_where_clause := l_where_clause || ' AND ticket_number = ''' || p_ticket_number || '''';
7448           END IF;
7449 
7450           IF (dup_detect_rule_rec.detect_from_location_flag = 'Y' AND p_destination_from IS NOT NULL) THEN
7451             l_where_clause := l_where_clause || ' AND destination_from = ''' || p_destination_from || '''';
7452           END IF;
7453 
7454           IF (dup_detect_rule_rec.detect_to_location_flag = 'Y' AND p_destination_to IS NOT NULL) THEN
7455             l_where_clause := l_where_clause || ' AND destination_to = ''' || p_destination_to || '''';
7456           END IF;
7457         END IF;
7458 
7459         IF p_category_code = 'MILEAGE' THEN
7460           IF (dup_detect_rule_rec.detect_distance_uom_flag = 'Y' AND p_distance_unit_code IS NOT NULL) THEN
7461             l_where_clause := l_where_clause || ' AND distance_unit_code = ''' || p_distance_unit_code || '''';
7462           END IF;
7463 
7464           IF dup_detect_rule_rec.detect_daily_trip_dist_flag = 'Y' THEN
7465             l_where_clause := l_where_clause || ' AND daily_distance = ' || p_daily_distance;
7466           END IF;
7467 
7468           IF (dup_detect_rule_rec.detect_vlp_num_flag = 'Y' AND p_license_plate_number IS NOT NULL) THEN
7469             l_where_clause := l_where_clause || ' AND license_plate_number = ''' || p_license_plate_number || '''';
7470           END IF;
7471         END IF;
7472 
7473       END IF;
7474 
7475       OPEN expense_lines_cur FOR l_stmt || l_where_clause;
7476       LOOP
7477         FETCH expense_lines_cur INTO expense_lines_rec;
7478         EXIT WHEN expense_lines_cur%NOTFOUND;
7479 
7480         l_count := l_count+1;
7481       END LOOP;
7482       CLOSE expense_lines_cur;
7483 
7484       IF l_count > 0 THEN
7485         BEGIN
7486           SELECT duplicates_allowed INTO l_exp_duplicates_allowed
7487           FROM ap_expense_report_params_all WHERE parameter_id = p_web_parameter_id;
7488         EXCEPTION
7489         WHEN OTHERS THEN
7490           l_exp_duplicates_allowed := -1;
7491         END;
7492 
7493         IF l_exp_duplicates_allowed IS NULL THEN
7494           l_exp_duplicates_allowed := -1;
7495         END IF;
7496 
7497         IF l_exp_duplicates_allowed <> -1 THEN
7498           l_duplicates_allowed := l_exp_duplicates_allowed;
7499         ELSE
7500           l_duplicates_allowed := dup_detect_rule_rec.duplicates_allowed;
7501         END IF;
7502 
7503         IF l_count > l_duplicates_allowed THEN
7504 
7505           OPEN expense_lines_cur FOR l_stmt || l_where_clause;
7506           LOOP
7507             FETCH expense_lines_cur INTO expense_lines_rec;
7508             EXIT WHEN expense_lines_cur%NOTFOUND;
7509 
7510             l_violation_number := l_violation_number + 1;
7511             l_dist_line_number := getDistLineNumber(expense_lines_rec.report_header_id, expense_lines_rec.distribution_line_number);
7512 
7513             INSERT INTO ap_pol_violations_all (
7514                       REPORT_HEADER_ID,
7515                       DISTRIBUTION_LINE_NUMBER,
7516                       VIOLATION_NUMBER,
7517                       VIOLATION_TYPE,
7518                       ORG_ID,
7519                       CREATED_BY,
7520                       CREATION_DATE,
7521                       LAST_UPDATED_BY,
7522                       LAST_UPDATE_LOGIN,
7523                       LAST_UPDATE_DATE,
7524                       VIOLATION_DATE,
7525                       DUP_REPORT_HEADER_ID,
7526                       DUP_REPORT_LINE_ID,
7527                       DUP_DIST_LINE_NUMBER
7528                     )
7529                     VALUES (
7530                       p_report_header_id,
7531                       p_distribution_line_number,
7532                       l_violation_number,
7533                       'DUPLICATE_DETECTION',
7534                       p_org_id,
7535                       p_created_by,
7536                       p_creation_date,
7537                       p_last_updated_by,
7538                       p_last_update_login,
7539                       p_last_update_date,
7540                       p_start_date,
7541                       l_report_prefix || expense_lines_rec.report_header_id,
7542                       expense_lines_rec.report_line_id,
7543                       l_dist_line_number
7544                     );
7545 
7546           END LOOP;
7547           CLOSE expense_lines_cur;
7548           p_max_violation_number := l_violation_number;
7549           p_dup_detect_action := dup_detect_rule_rec.duplicate_detection_action;
7550 
7551         END IF;
7552 
7553       END IF;
7554 
7555     END IF;
7556 
7557     AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'end performDuplicateDetection');
7558 
7559   EXCEPTION
7560    WHEN OTHERS THEN
7561     BEGIN
7562       FND_MESSAGE.SET_NAME('SQLAP','AP_DEBUG');
7563       FND_MESSAGE.SET_TOKEN('ERROR',SQLERRM);
7564       FND_MESSAGE.SET_TOKEN('CALLING_SEQUENCE',current_calling_sequence);
7565       FND_MESSAGE.SET_TOKEN('DEBUG_INFO',l_debug_info);
7566       APP_EXCEPTION.RAISE_EXCEPTION;
7567     END;
7568 
7569 END performDuplicateDetection;
7570 
7571 /*========================================================================
7572  | PUBLIC PROCEDURE removeDupViolations
7573  |
7574  | DESCRIPTION
7575  |   This procedure removes the duplicate detection violations for the expense line.
7576  |
7577  | PARAMETERS
7578  |   p_report_header_id    IN    Report Header Id
7579  |   p_dist_line_number    IN    Distribution Line Number
7580  |
7581  | MODIFICATION HISTORY
7582  | Date                  Author                   Description of Changes
7583  | 23-Feb-2010           Dharma Theja Reddy S        Created
7584  |
7585  *=======================================================================*/
7586 PROCEDURE removeDupViolations(p_report_header_id IN ap_expense_report_lines_all.REPORT_HEADER_ID%TYPE,
7587                               p_dist_line_number IN ap_expense_report_lines_all.DISTRIBUTION_LINE_NUMBER%TYPE) IS
7588 
7589   BEGIN
7590 
7591     AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start removeDupViolations');
7592 
7593     IF ((p_report_header_id IS NOT NULL) AND (p_dist_line_number IS NOT NULL)) THEN
7594 
7595       DELETE FROM ap_pol_violations_all WHERE report_header_id = p_report_header_id
7596       AND distribution_line_number = p_dist_line_number AND violation_type = 'DUPLICATE_DETECTION';
7597 
7598     END IF;
7599 
7600     AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'end removeDupViolations');
7601 
7602 END removeDupViolations;
7603 
7604 /*========================================================================
7605  | PUBLIC PROCEDURE getDistNumber
7606  |
7607  | DESCRIPTION
7608  |   This procedure gets the distribution line number depending on the expense category.
7609  |
7610  | PARAMETERS
7611  |   p_report_line_id    IN     Report Line Id
7612  |   p_category          OUT    Expense Category
7613  |   p_dist_num          OUT    Distribution Number
7614  |
7615  | MODIFICATION HISTORY
7616  | Date                  Author                   Description of Changes
7617  | 23-Feb-2010           Dharma Theja Reddy S        Created
7618  |
7619  *=======================================================================*/
7620 PROCEDURE getDistNumber(p_report_line_id IN ap_pol_violations_all.DUP_REPORT_LINE_ID%TYPE,
7621                         p_category OUT NOCOPY VARCHAR2,
7622                         p_dist_num OUT NOCOPY VARCHAR2) IS
7623 
7624   TYPE dist_lines IS REF CURSOR;
7625   dist_lines_cur dist_lines;
7626   dist_lines_rec ap_expense_report_lines_all%ROWTYPE;
7627 
7628   l_report_header_id ap_expense_report_lines_all.REPORT_HEADER_ID%TYPE;
7629   l_category_code ap_expense_report_lines_all.CATEGORY_CODE%TYPE;
7630   l_credit_card_trx_id ap_expense_report_lines_all.CREDIT_CARD_TRX_ID%TYPE;
7631   l_dist_line_number ap_expense_report_lines_all.DISTRIBUTION_LINE_NUMBER%TYPE;
7632   l_stmt  VARCHAR2(2000);
7633   l_primary_number NUMBER := 0;
7634   l_sub_number NUMBER := 0;
7635   l_prev_parent_id NUMBER := 0;
7636 
7637   BEGIN
7638 
7639     AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'start getDistNumber');
7640 
7641     IF p_report_line_id IS NULL THEN
7642       p_category := NULL;
7643       p_dist_num := NULL;
7644     END IF;
7645 
7646     SELECT report_header_id, category_code, credit_card_trx_id, distribution_line_number
7647     INTO l_report_header_id, l_category_code, l_credit_card_trx_id, l_dist_line_number
7648     FROM ap_expense_report_lines_all WHERE report_line_id = p_report_line_id;
7649 
7650     IF l_category_code = 'PER_DIEM' OR l_category_code = 'MILEAGE' THEN
7651       p_category := l_category_code;
7652       l_stmt := 'SELECT * FROM ap_expense_report_lines_all
7653                  WHERE report_header_id = ' || l_report_header_id || ' AND category_code = ''' || l_category_code ||
7654                  ''' ORDER by distribution_line_number, itemization_parent_id';
7655     ELSE
7656       IF l_credit_card_trx_id IS NOT NULL THEN
7657         p_category := 'CREDIT';
7658         l_stmt := 'SELECT * FROM ap_expense_report_lines_all
7659                    WHERE report_header_id = ' || l_report_header_id || ' AND credit_card_trx_id IS NOT NULL
7660                    AND (itemization_parent_id IS NULL OR itemization_parent_id <> -1) AND category_code NOT IN (''PER_DIEM'', ''MILEAGE'')
7661                    ORDER by distribution_line_number, itemization_parent_id';
7662       ELSE
7663         p_category := 'CASH';
7664         l_stmt := 'SELECT * FROM ap_expense_report_lines_all
7665                    WHERE report_header_id = ' || l_report_header_id || ' AND credit_card_trx_id IS NULL
7666                    AND (itemization_parent_id IS NULL OR itemization_parent_id <> -1) AND category_code NOT IN (''PER_DIEM'', ''MILEAGE'')
7667                    ORDER by distribution_line_number, itemization_parent_id';
7668       END IF;
7669     END IF;
7670 
7671     OPEN dist_lines_cur FOR l_stmt;
7672     LOOP
7673       FETCH dist_lines_cur INTO dist_lines_rec;
7674       EXIT WHEN dist_lines_cur%NOTFOUND;
7675 
7676       IF dist_lines_rec.itemization_parent_id IS NULL THEN
7677         l_primary_number := l_primary_number + 1;
7678         l_sub_number := 0;
7679       ELSE
7680         IF l_prev_parent_id <> dist_lines_rec.itemization_parent_id THEN
7681           l_primary_number := l_primary_number + 1;
7682           l_sub_number := 1;
7683         ELSE
7684           l_sub_number := l_sub_number + 1;
7685         END IF;
7686         l_prev_parent_id := dist_lines_rec.itemization_parent_id;
7687       END IF;
7688 
7689       IF dist_lines_rec.distribution_line_number = l_dist_line_number THEN
7690         EXIT;
7691       END IF;
7692     END LOOP;
7693 
7694     IF l_sub_number = 0 THEN
7695       p_dist_num := To_Char(l_primary_number);
7696     ELSE
7697       p_dist_num := To_Char(l_primary_number) || '-' || To_Char(l_sub_number);
7698     END IF;
7699 
7700     AP_WEB_UTILITIES_PKG.logProcedure('AP_WEB_POLICY_UTILS', 'end getDistNumber');
7701 
7702 END getDistNumber;
7703 
7704 /*========================================================================
7705  | PUBLIC FUNCTION get_role
7706  |
7707  | DESCRIPTION
7708  |   This function returns role.
7709  |
7710  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
7711  |   Called from BC4J, needed for the LineHistoryVO, which cannot have joins
7712  |   due to connect by clause.
7713  |
7714  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
7715  |
7716  | RETURNS
7717  |   Role
7718  |
7719  | PARAMETERS
7720  |   P_Policy_Id IN Policy Identifier
7721  |   P_Policy_Line_Id IN  Policy Line identifier
7722  |   P_Role_Id IN  Role Identifier
7723  | MODIFICATION HISTORY
7724  | Date                  Author            Description of Changes
7725  | 25-May-2002           J Rautiainen      Created
7726  |
7727  *=======================================================================*/
7728 Function Get_Role(P_Policy_Id In Number,
7729                   P_Policy_Line_Id In Number,
7730                   P_Role_Id In Number ) Return Varchar2 Is
7731 
7732     CURSOR role_cur IS
7733     select
7734            ph.policy_id,
7735            Pl.Policy_Line_Id,
7736 	         ph.role_code,
7737            pl.role_id
7738     from ap_pol_headers ph,
7739          ap_pol_lines   pl
7740     where pl.policy_id = ph.policy_id
7741     and   ph.policy_id = p_policy_id;
7742 
7743     L_Hash_Value     Number;
7744     L_Hash_Value2    Number;
7745 
7746 BEGIN
7747   IF p_role_id is null THEN
7748     return null;
7749   END IF;
7750 
7751   IF p_policy_id IS NOT NULL AND
7752      p_policy_line_id IS NOT NULL AND
7753      p_role_id IS NOT NULL THEN
7754 
7755     L_Hash_Value := Get_Hash_Value(To_Char(P_Policy_Id),
7756 				                           To_Char(P_Policy_Line_Id),
7757 				                           To_Char(P_Role_Id));
7758 
7759     IF pg_role_rec.EXISTS(l_hash_value) THEN
7760       Return Pg_Role_Rec(L_Hash_Value);
7761     ELSE
7762       FOR role_rec IN role_cur LOOP
7763           L_Hash_Value2 := Get_Hash_Value(To_Char(role_rec.Policy_Id),
7764                                           To_Char(role_rec.Policy_Line_Id),
7765 					                                To_Char(role_rec.Role_Id));
7766           Pg_Role_Rec(L_Hash_Value2) := Get_Role(role_rec.Role_Code, role_rec.Role_Id);
7767       End Loop;
7768     End If;
7769   End If;
7770 
7771   IF pg_role_rec.EXISTS(l_hash_value) THEN
7772     return pg_role_rec(l_hash_value);
7773   ELSE
7774     return null;
7775   End If;
7776 
7777 END get_role;
7778 
7779 /*========================================================================
7780  | PUBLIC FUNCTION get_location_desc
7781  |
7782  | DESCRIPTION
7783  |   This function returns location description.
7784  |
7785  | CALLED FROM PROCEDURES/FUNCTIONS (local to this package body)
7786  |   Called from BC4J, needed for the LineHistoryVO, PolicyLinesVO
7787  |   which cannot have joins due to connect by clause.
7788  |
7789  | CALLS PROCEDURES/FUNCTIONS (local to this package body)
7790  |
7791  | RETURNS
7792  |   Location Description
7793  |
7794  | PARAMETERS
7795  |   p_location_id IN  Location identifier
7796  |
7797  | MODIFICATION HISTORY
7798  | Date                  Author            Description of Changes
7799  | 25-Aug-2011           meesubra      Created
7800  |
7801  *=======================================================================*/
7802 FUNCTION get_location_desc(p_location_id IN NUMBER) RETURN VARCHAR2 IS
7803 
7804   CURSOR loc_desc_cur IS
7805     select location_id, description
7806     from  ap_pol_locations_vl
7807     Where Location_Type In ('CITY','COUNTRY');
7808   l_location_desc varchar2(240);
7809 BEGIN
7810   IF p_location_id is null THEN
7811     return null;
7812   END IF;
7813 
7814   IF pg_locations_desc_rec.EXISTS(p_location_id) THEN
7815       return pg_locations_desc_rec(p_location_id);
7816   Elsif pg_locations_desc_rec.Count > 1 Then
7817       select description into l_location_desc from ap_pol_locations_vl where location_id = p_location_id;
7818       pg_locations_desc_rec(p_location_id) := l_location_desc;
7819   ELSE
7820       FOR loc_rec IN loc_desc_cur LOOP
7821         pg_locations_desc_rec(loc_rec.location_id) := loc_rec.description;
7822       END LOOP;
7823   END IF;
7824 
7825   IF pg_locations_desc_rec.EXISTS(p_location_id) THEN
7826     return pg_locations_desc_rec(p_location_id);
7827   ELSE
7828     return null;
7829   END IF;
7830 
7831 End Get_Location_Desc;
7832 
7833 END AP_WEB_POLICY_UTILS;