DBA Data[Home] [Help]

PACKAGE BODY: APPS.PQP_FTE_UTILITIES

Source


1 PACKAGE BODY pqp_fte_utilities AS
2 /* $Header: pqftepkg.pkb 120.6 2011/02/24 09:45:12 apjaiswa ship $ */
3 --
4 g_package_name                 VARCHAR2(31) := 'pqp_fte_utilities.';
5 g_debug                        BOOLEAN:=FALSE;
6 --
7 --
8 TYPE g_output_file_rec_type IS RECORD
9   (assignment_id                  per_all_assignments_f.assignment_id%TYPE
10   ,status                         VARCHAR2(80)
11   ,employee_number                per_all_people_f.employee_number%TYPE
12   ,assignment_number              per_all_assignments_f.assignment_number%TYPE
13   ,effective_date                 per_all_assignments_f.effective_start_date%TYPE
14   ,change_in                      VARCHAR2(80)
15   ,FTE_old_value                  per_assignment_budget_values_f.value%TYPE
16   ,change_type                    VARCHAR2(80)
17   ,FTE_new_value                  per_assignment_budget_values_f.value%TYPE
18   ,normal_hours                   per_all_assignments_f.normal_hours%TYPE
19   ,frequency                      per_all_assignments_f.frequency%TYPE
20   ,contract_type                  pqp_assignment_attributes_f.contract_type%TYPE
21   ,annual_hours                   pay_user_column_instances_f.value%TYPE
22   ,period_divisor                 pay_user_column_instances_f.value%TYPE
23   ,message                        fnd_new_messages.message_text%TYPE
24   );
25 TYPE t_output_file_record_type    IS TABLE OF g_output_file_rec_type
26   INDEX BY BINARY_INTEGER;
27 g_output_file_records          t_output_file_record_type; -- do not include in clear cache
28 g_is_concurrent_program_run    BOOLEAN:= FALSE;
29 g_column_separator             VARCHAR2(10):=' , ';
30 --
31 --
32 -- cache for get_installation_status
33 g_application_id               fnd_product_installations.application_id%TYPE;
34 g_status                       fnd_product_installations.status%TYPE;
35 
36 -- cache for load_cached_constants
37 g_pqp_contract_table_id        pay_user_tables.user_table_id%TYPE;
38 g_annual_hours_col_id          pay_user_columns.user_column_id%TYPE;
39 g_period_divisor_col_id        pay_user_columns.user_column_id%TYPE;
40 g_not_cached_constants         BOOLEAN:=TRUE;
41 
42 -- cache for chk_fte_exists
43 g_fte_exists_assignment_id     per_all_assignments_f.assignment_id%TYPE;
44 g_fte_exists                   BOOLEAN;
45 
46 -- cache for get_earliest_possible_date
47 g_epFd_assignment_id           per_all_assignments_f.assignment_id%TYPE;
48 g_epFd_earliest_possible_date  DATE;
49 
50 
51 --
52 --
53 --
54 CURSOR csr_fte_exists
55   (p_assignment_id                NUMBER
56   ) IS
57 SELECT 1
58 FROM   per_assignment_budget_values_f
59 WHERE  assignment_id = p_assignment_id
60   AND  unit = 'FTE'
61   AND  ROWNUM < 2;
62 
63 CURSOR csr_effective_fte
64   (p_assignment_id                NUMBER
65   ,p_effective_date               DATE
66   ) IS
67 SELECT assignment_budget_value_id,
68        value,
69        effective_start_date,
70        effective_end_date,
71        object_version_number
72 FROM   per_assignment_budget_values_f
73 WHERE  assignment_id = p_assignment_id
74   AND  unit = 'FTE'
75   AND  p_effective_date
76          BETWEEN effective_start_date
77              AND effective_end_date;
78 
79 CURSOR csr_assignment_details
80   (p_assignment_id                NUMBER
81   ,p_effective_date               DATE
82   ) IS
83 SELECT asg.business_group_id
84       ,asg.normal_hours
85       ,asg.frequency
86 FROM   per_all_assignments_f asg
87 WHERE  asg.assignment_id = p_assignment_id
88 AND    p_effective_date
89          BETWEEN asg.effective_start_date
90              AND asg.effective_end_date;
91 
92 -- dummy cursor for record structure
93 CURSOR csr_contract_details IS
94 SELECT TO_NUMBER('0') annual_hours
95       ,TO_NUMBER('0') period_divisor
96       ,row_low_range_or_name contract_type
97       ,user_row_id
98 FROM  pay_user_rows_f
99 WHERE user_row_id = 0;
100 
101 
102 CURSOR csr_assignment_contract
103   (p_assignment_id                NUMBER
104   ,p_effective_date               DATE
105   ,p_pqp_contract_table_id        NUMBER
106   ) IS
107 SELECT pur.user_row_id, aat.contract_type
108 FROM   pqp_assignment_attributes_f aat
109       ,pay_user_rows_f             pur
110 WHERE  aat.assignment_id = p_assignment_id
111   AND  p_effective_date
112            BETWEEN aat.effective_start_date
113                AND aat.effective_end_date
114   AND  pur.user_table_id = p_pqp_contract_table_id
115   AND  pur.business_group_id = aat.business_group_id
116   AND  pur.row_low_range_or_name = aat.contract_type
117   AND  aat.effective_start_date
118          BETWEEN pur.effective_start_date
119              AND pur.effective_end_date;
120 
121 
122 CURSOR csr_get_contract_value
123   (p_contract_column_id           NUMBER
124   ,p_contract_row_id              NUMBER
125   ,p_effective_date               DATE
126   ) IS
127 SELECT inst.value
128 FROM   pay_user_column_instances_f inst
129 WHERE  inst.user_column_id = p_contract_column_id
130   AND  inst.user_row_id    = p_contract_row_id
131   AND  p_effective_date
132          BETWEEN inst.effective_start_date
133              AND inst.effective_end_date;
134 
135 --
136 --
137 --
138 PROCEDURE debug(
139   p_trace_message             IN       VARCHAR2
140  ,p_trace_location            IN       NUMBER DEFAULT NULL
141 )
142 IS
143 BEGIN
144   IF NOT g_is_concurrent_program_run THEN
145     pqp_utilities.debug(p_trace_message, p_trace_location);
146   ELSE
147     IF p_trace_location IS NULL THEN
148       fnd_file.put_line(fnd_file.log,p_trace_message);
149     ELSE
150       fnd_file.put_line(fnd_file.log,RPAD(p_trace_message,80,' ')||TO_CHAR(p_trace_location));
151     END IF;
152   END IF;
153 END debug;
154 --
155 --
156 --
157 --PROCEDURE debug(p_trace_number IN NUMBER)
158 --IS
159 --BEGIN
160 --  pqp_utilities.debug(p_trace_number);
161 --END debug;
162 ----
163 ----
164 ----
165 --PROCEDURE debug(p_trace_date IN DATE)
166 --IS
167 --BEGIN
168 --  pqp_utilities.debug(p_trace_date);
169 --END debug;
170 --
171 --
172 --
173 PROCEDURE debug_enter(
174   p_proc_name                 IN       VARCHAR2
175  ,p_trace_on                  IN       VARCHAR2 DEFAULT NULL
176 )
177 IS
178 BEGIN
179   IF NOT g_is_concurrent_program_run THEN
180     pqp_utilities.debug_enter(p_proc_name, p_trace_on);
181   ELSE
182       fnd_file.put_line(fnd_file.log,RPAD(p_proc_name,80,' ')||'+0');
183   END IF;
184 END debug_enter;
185 --
186 --
187 --
188 PROCEDURE debug_exit(
189   p_proc_name                 IN       VARCHAR2
190  ,p_trace_off                 IN       VARCHAR2 DEFAULT NULL
191 )
192 IS
193 BEGIN
194   IF NOT g_is_concurrent_program_run THEN
195     pqp_utilities.debug_exit(p_proc_name, p_trace_off);
196   ELSE
197       fnd_file.put_line(fnd_file.log,RPAD(p_proc_name,80,' ')||'-0');
198   END IF;
199 END debug_exit;
200 --
201 --
202 --
203 PROCEDURE debug_others(
204   p_proc_name                 IN       VARCHAR2
205  ,p_proc_step                 IN       NUMBER DEFAULT NULL
206 )
207 IS
208 BEGIN
209   pqp_utilities.debug_others(p_proc_name, p_proc_step);
210 END debug_others;
211 --
212 --
213 --
214 PROCEDURE check_error_code
215   (p_error_code               IN       NUMBER
216   ,p_error_message            IN       VARCHAR2
217   )
218 IS
219 BEGIN
220   pqp_utilities.check_error_code(p_error_code, p_error_message);
221 END;
222 --
223 --
224 --
225 PROCEDURE clear_cache
226 IS
227 BEGIN
228 -- cache for get_installation_status
229 g_application_id               := NULL;
230 g_status                       := NULL;
231 
232 -- cache for load_cached_constants
233 g_pqp_contract_table_id        :=NULL;
234 g_annual_hours_col_id          :=NULL;
235 g_period_divisor_col_id        :=NULL;
236 g_not_cached_constants         :=TRUE;
237 
238 -- cache for chk_fte_exists
239 g_fte_exists_assignment_id     :=NULL;
240 g_fte_exists                   :=NULL;
241 
242 -- cache for get_earliest_possible_date
243 g_epFd_assignment_id           :=NULL;
244 g_epFd_earliest_possible_date  :=NULL;
245 
246 END clear_cache;
247 --
248 --
249 --
250 FUNCTION convert_record_to_outputstring
251   (p_output_file_record           g_output_file_rec_type
252   ) RETURN VARCHAR2
253 IS
254   l_proc_step                    NUMBER(20,10);
255   l_proc_name                    VARCHAR2(61):=
256     g_package_name||'convert_record_to_outputstring';
257 
258   l_outputstring                VARCHAR2(4000);
259 
260 BEGIN -- convert_record_to_outputstring
261 
262   IF g_debug THEN
263     debug_enter(l_proc_name);
264   END IF;
265   /* Corrected and added as a part of Bug#10239082  Starts
266   l_outputstring :=
267     RPAD(NVL(p_output_file_record.status,' '),30,' ')||g_column_separator||
268     RPAD(NVL(p_output_file_record.employee_number,' '),20,' ')||g_column_separator||
269     RPAD(NVL(p_output_file_record.assignment_number,'AsgId:'||p_output_file_record.assignment_id),30,' ')||g_column_separator||
270     RPAD(NVL(fnd_date.date_to_displaydate(p_output_file_record.effective_date),' '),15,' ')||g_column_separator||
271     RPAD(NVL(p_output_file_record.change_in,' '),30,' ')||g_column_separator||
272     RPAD(NVL(TO_CHAR(p_output_file_record.FTE_old_value),' '),20,' ')||g_column_separator||
273     RPAD(NVL(p_output_file_record.change_type,' '),15,' ')||g_column_separator||
274     RPAD(NVL(TO_CHAR(p_output_file_record.FTE_new_value),' '),20,' ')||g_column_separator||
275     RPAD(NVL(TO_CHAR(p_output_file_record.normal_hours),' '),15,' ')||g_column_separator||
276     RPAD(NVL(HR_GENERAL.DECODE_LOOKUP('FREQUENCY',p_output_file_record.frequency),' '),10,' ')||g_column_separator||
277     RPAD(NVL(p_output_file_record.contract_type,' '),30,' ')||g_column_separator||
278     RPAD(NVL(p_output_file_record.annual_hours,' '),15,' ')||g_column_separator||
279     RPAD(NVL(p_output_file_record.period_divisor,' '),15,' ')||g_column_separator||
280     RPAD(p_output_file_record.message,255,' ')
281   ;   */
282   l_outputstring :=
283     RPAD(NVL(p_output_file_record.status,' '),30,' ')||g_column_separator||
284     RPAD(NVL(p_output_file_record.employee_number,' '),20,' ')||g_column_separator||
285     RPAD(NVL(p_output_file_record.assignment_number,'AsgId:'||p_output_file_record.assignment_id),30,' ')||g_column_separator||
286     RPAD(NVL(fnd_date.date_to_displaydate(p_output_file_record.effective_date, calendar_aware => FND_DATE.calendar_aware_alt),' '),15,' ')||g_column_separator||
287     RPAD(NVL(p_output_file_record.change_in,' '),30,' ')||g_column_separator||
288     RPAD(NVL(TO_CHAR(p_output_file_record.FTE_old_value),' '),20,' ')||g_column_separator||
289     RPAD(NVL(p_output_file_record.change_type,' '),15,' ')||g_column_separator||
290     RPAD(NVL(TO_CHAR(p_output_file_record.FTE_new_value),' '),20,' ')||g_column_separator||
291     RPAD(NVL(TO_CHAR(p_output_file_record.normal_hours),' '),15,' ')||g_column_separator||
292     RPAD(NVL(HR_GENERAL.DECODE_LOOKUP('FREQUENCY',p_output_file_record.frequency),' '),10,' ')||g_column_separator||
293     RPAD(NVL(p_output_file_record.contract_type,' '),30,' ')||g_column_separator||
294     RPAD(NVL(p_output_file_record.annual_hours,' '),15,' ')||g_column_separator||
295     RPAD(NVL(p_output_file_record.period_divisor,' '),15,' ')||g_column_separator||
296     RPAD(p_output_file_record.message,255,' ')
297   ;
298   /* Corrected and added as a part of Bug#10239082   Ends  */
299 
300   IF g_debug THEN
301     debug_exit(l_proc_name);
302     debug('l_outputstring_1_200:'||SUBSTR(l_outputstring,1,200));
303     debug('l_outputstring_201_400:'||SUBSTR(l_outputstring,201,200));
304     debug('l_outputstring_401_600:'||SUBSTR(l_outputstring,401,200));
305   END IF;
306 
307   RETURN l_outputstring;
308 
309 EXCEPTION
310 WHEN OTHERS THEN
311   clear_cache;
312   IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
313     debug_others(l_proc_name,l_proc_step);
314     IF g_debug THEN
315       debug('Leaving: '||l_proc_name,-999);
316     END IF;
317     fnd_message.raise_error;
318   ELSE
319     RAISE;
320   END IF;
321 END convert_record_to_outputstring;
322 --
323 --
324 --
325 PROCEDURE write_output_file_records
326 IS
327 
328   l_proc_step                    NUMBER(20,10);
329   l_proc_name                    VARCHAR2(61):=
330     g_package_name||'write_output_file_records';
331 
332   i                              BINARY_INTEGER;
333 
334 BEGIN -- write_output_file_records
335 
336  IF g_debug THEN
337    debug_enter(l_proc_name);
338  END IF;
339 
340  i:= g_output_file_records.FIRST;
341 
342  WHILE i IS NOT NULL
343  LOOP
344 
345    fnd_file.put_line
346      (fnd_file.output
347      ,convert_record_to_outputstring(g_output_file_records(i))
348      );
349 
350    i := g_output_file_records.NEXT(i);
351 
352  END LOOP;
353 
354  IF g_debug THEN
355    debug_exit(l_proc_name);
356  END IF;
357 
358 
359 EXCEPTION
360 WHEN OTHERS THEN
361   clear_cache;
362   IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
363     debug_others(l_proc_name,l_proc_step);
364     IF g_debug THEN
365       debug('Leaving: '||l_proc_name,-999);
366     END IF;
367     fnd_message.raise_error;
368   ELSE
369     RAISE;
370   END IF;
371 END write_output_file_records;
372 --
373 --
374 --
375 FUNCTION get_installation_status
376   (p_application_id               IN NUMBER
377   ) RETURN VARCHAR2
378 IS
379 
380 l_proc_step                    NUMBER(20,10):=0;
381 l_proc_name                    VARCHAR2(61):=
382   g_package_name||'get_installation_status';
383 
384 CURSOR csr_is_installed
385   (p_application_id               NUMBER
386   ) IS
387 SELECT status
388 FROM   fnd_product_installations
389 WHERE  application_id = p_application_id;
390 
391 l_status        fnd_product_installations.status%TYPE;
392 
393 BEGIN -- get_installation_status
394 
395 IF g_debug THEN
396   debug_enter(l_proc_name);
397   debug('p_application_id:'||p_application_id);
398   debug('g_application_id:'||g_application_id);
399   debug('g_status:'||g_status);
400 END IF;
401 
402 IF g_application_id <> p_application_id
403   OR
404    g_application_id IS NULL
405   OR
406    g_status IS NULL
407 THEN
408 
409   OPEN csr_is_installed(p_application_id);
410   FETCH csr_is_installed INTO l_status;
411   IF csr_is_installed%FOUND THEN
412     IF l_status = 'I' THEN
413       g_application_id := p_application_id;
414       g_status := l_status;
415     ELSE
416       g_application_id := p_application_id;
417       g_status := l_status;
418     END IF;
419   ELSE
420     -- invalid application id, destroy cache, set status to null -- redundant
421     g_application_id := NULL;
422     g_status := NULL;
423     l_status := NULL;
424   END IF;
425   CLOSE csr_is_installed;
426 
427 ELSE
428 
429   l_status := g_status;
430 
431 END IF; -- IF g_application_id <> p_application_id
432 
433 
434 IF g_debug THEN
435   debug('l_status:'||l_status);
436   debug_exit(l_proc_name);
437 END IF;
438 
439 RETURN l_status;
440 
441 EXCEPTION
442 WHEN OTHERS THEN
443   clear_cache;
444   IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
445     debug_others(l_proc_name,l_proc_step);
446     IF g_debug THEN
447       debug('Leaving: '||l_proc_name,-999);
448     END IF;
449     fnd_message.raise_error;
450   ELSE
451     RAISE;
452   END IF;
453 END get_installation_status;
454 --
455 --
456 --
457 PROCEDURE load_cached_constants
458 IS
459   l_proc_step                    NUMBER(20,10):= 0;
460   l_proc_name                    VARCHAR2(61):=
461     g_package_name||'load_cached_constants';
462 
463   CURSOR csr_pqp_contract_table IS
464   SELECT user_table_id
465   FROM   pay_user_tables
466   WHERE  user_table_name = 'PQP_CONTRACT_TYPES'
467     AND  legislation_code = 'GB';
468 
469   CURSOR csr_relevant_columns
470     (p_user_table_id              IN NUMBER
471     ,p_user_column_name           IN VARCHAR2
472     ) IS
473   SELECT user_column_id
474   FROM   pay_user_columns
475   WHERE  user_table_id = p_user_table_id
476     AND  UPPER(user_column_name) = UPPER(p_user_column_name)
477     AND  legislation_code = 'GB';
478 
479   l_status                       fnd_product_installations.status%TYPE;
480 
481 
482 BEGIN -- load_cached_constants
483 
484   IF g_debug THEN
485     debug_enter(l_proc_name);
486     debug('g_pqp_contract_table_id:'||g_pqp_contract_table_id);
487     debug('g_annual_hours_col_id:'||g_annual_hours_col_id);
488     debug('g_period_divisor_col_id:'||g_period_divisor_col_id);
489     IF g_not_cached_constants THEN
490       debug('g_not_cached_constants:TRUE');
491     ELSE
492       debug('g_not_cached_constants:FALSE');
493     END IF;
494   END IF;
495 
496   IF g_not_cached_constants THEN
497 
498     g_pqp_contract_table_id := NULL;
499     g_annual_hours_col_id := NULL;
500     g_period_divisor_col_id := NULL;
501     g_not_cached_constants := FALSE;
502 
503     l_status := get_installation_status(801);
504 
505     OPEN csr_pqp_contract_table;
506     FETCH csr_pqp_contract_table INTO g_pqp_contract_table_id;
507     IF csr_pqp_contract_table%NOTFOUND THEN
508       l_proc_step := 10;
509       IF g_debug THEN
510         debug(l_proc_name,l_proc_step);
511       END IF;
512       g_not_cached_constants := TRUE;
513       RAISE NO_DATA_FOUND;
514     END IF;
515     CLOSE csr_pqp_contract_table;
516 
517     IF g_debug THEN
518       debug('g_pqp_contract_table_id:'||g_pqp_contract_table_id);
519     END IF;
520 
521     OPEN csr_relevant_columns
522       (p_user_table_id              => g_pqp_contract_table_id
523       ,p_user_column_name           => 'Annual Hours'
524       );
525     FETCH csr_relevant_columns INTO g_annual_hours_col_id;
526     IF csr_relevant_columns%NOTFOUND THEN
527       l_proc_step := 20;
528       IF g_debug THEN
529         debug(l_proc_name,l_proc_step);
530       END IF;
531       g_not_cached_constants := TRUE;
532       RAISE NO_DATA_FOUND;
533     END IF;
534     CLOSE csr_relevant_columns;
535 
536     IF g_debug THEN
537       debug('g_annual_hours_col_id:'||g_annual_hours_col_id);
538     END IF;
539 
540 
541     OPEN csr_relevant_columns
542       (p_user_table_id              => g_pqp_contract_table_id
543       ,p_user_column_name           => 'Period Divisor'
544       );
545     FETCH csr_relevant_columns INTO g_period_divisor_col_id;
546     IF csr_relevant_columns%NOTFOUND THEN
547       l_proc_step := 30;
548       IF g_debug THEN
549         debug(l_proc_name,l_proc_step);
550       END IF;
551       g_not_cached_constants := TRUE;
552       RAISE NO_DATA_FOUND;
553     END IF;
554     CLOSE csr_relevant_columns;
555 
556     IF g_debug THEN
557       debug('g_period_divisor_col_id:'||g_period_divisor_col_id);
558     END IF;
559 
560   ELSE
561     IF g_debug THEN
562       debug('g_not_cached_constants:FALSE');
563     END IF;
564   END IF;
565 
566   IF g_debug THEN
567     debug('g_pqp_contract_table_id:'||g_pqp_contract_table_id);
568     debug('g_annual_hours_col_id:'||g_annual_hours_col_id);
569     debug('g_period_divisor_col_id:'||g_period_divisor_col_id);
570     debug('g_application_id:'||g_application_id);
571     debug('g_status:'||g_status);
572     debug_exit(l_proc_name);
573   END IF;
574 
575 EXCEPTION
576 WHEN OTHERS THEN
577   clear_cache;
578   IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
579     debug_others(l_proc_name,l_proc_step);
580     IF g_debug THEN
581       debug('Leaving: '||l_proc_name,-999);
582     END IF;
583     fnd_message.raise_error;
584   ELSE
585     RAISE;
586   END IF;
587 END load_cached_constants;
588 --
589 --
590 --
591 FUNCTION get_earliest_possible_FTE_date
592   (p_assignment_id                NUMBER
593   ,p_reload_cache                 BOOLEAN DEFAULT FALSE
594   ) RETURN DATE
595 IS
596 
597   l_proc_step                    NUMBER(20,10):=0;
598   l_proc_name                    VARCHAR2(61):=
599       g_package_name||'get_earliest_possible_FTE_date';
600 
601   CURSOR csr_min_aat_start_date
602     (p_assignment_id                NUMBER
603     ) IS
604   SELECT MIN(aat.effective_start_date)
605   FROM   pqp_assignment_attributes_f aat
606   WHERE  aat.assignment_id = p_assignment_id
607     AND  aat.contract_type IS NOT NULL;
608 
609   CURSOR csr_min_asg_start_date
610     (p_assignment_id                NUMBER
611     ) IS
612   SELECT MIN(asg.effective_start_date)
613   FROM   per_all_assignments_f asg
614   WHERE  asg.assignment_id = p_assignment_id
615     AND  asg.normal_hours IS NOT NULL;
616 
617 
618   l_aat_effective_start_date     DATE;
619   l_asg_effective_start_date     DATE;
620   --l_earliest_possible_FTE_date   DATE;
621 
622 BEGIN -- get_earliest_possible_FTE_date
623 
624   IF g_debug THEN
625     debug_enter(l_proc_name);
626     debug('p_assignment_id:'||p_assignment_id);
627     debug('g_epFd_assignment_id:'||g_epFd_assignment_id);
628     debug('g_epFd_earliest_possible_date:'||
629       fnd_date.date_to_canonical(g_epFd_earliest_possible_date));
630     IF p_reload_cache = TRUE THEN
631       debug('p_reload_cache:TRUE');
632     END IF;
633     IF p_reload_cache = FALSE THEN
634       debug('p_reload_cache:FALSE');
635     END IF;
636     IF p_reload_cache IS NULL THEN
637       debug('p_reload_cache:IS NULL');
638     END IF;
639   END IF;
640 
641 
642   IF p_assignment_id <> g_epFd_assignment_id
643     OR
644      g_epFd_assignment_id IS NULL
645     OR
646      g_epFd_earliest_possible_date IS NULL
647     OR
648      p_reload_cache = TRUE
649   THEN
650 
651     -- always clear cache before reloading it
652     g_epFd_assignment_id := NULL;
653     g_epFd_earliest_possible_date := NULL;
654 
655     OPEN  csr_min_aat_start_date(p_assignment_id);
656     FETCH csr_min_aat_start_date INTO l_aat_effective_start_date;
657     CLOSE csr_min_aat_start_date;
658 
659     OPEN  csr_min_asg_start_date(p_assignment_id);
660     FETCH csr_min_asg_start_date INTO l_asg_effective_start_date;
661     CLOSE csr_min_asg_start_date;
662 
663     IF g_debug THEN
664       debug('l_aat_effective_start_date:'||l_aat_effective_start_date);
665       debug('l_asg_effective_start_date:'||l_asg_effective_start_date);
666     END IF;
667 
668     g_epFd_assignment_id := p_assignment_id;
669 
670     g_epFd_earliest_possible_date :=
671       GREATEST(l_aat_effective_start_date, l_asg_effective_start_date);
672 
673    END IF;
674 
675   IF g_debug THEN
676     debug('g_epFd_assignment_id:'||g_epFd_assignment_id);
677     debug('g_epFd_earliest_possible_date:'||
678       fnd_date.date_to_canonical(g_epFd_earliest_possible_date));
679     debug_exit(l_proc_name);
680   END IF;
681 
682   RETURN g_epFd_earliest_possible_date;
683 
684 EXCEPTION
685 WHEN OTHERS THEN
686   clear_cache;
687   IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
688     debug_others(l_proc_name,l_proc_step);
689     IF g_debug THEN
690       debug('Leaving: '||l_proc_name,-999);
691     END IF;
692     fnd_message.raise_error;
693   ELSE
694     RAISE;
695   END IF;
696 END get_earliest_possible_FTE_date;
697 --
698 --
699 --
700 FUNCTION chk_fte_exists
701   (p_assignment_id                NUMBER
702   ,p_reload_cache                 BOOLEAN DEFAULT FALSE
703   ) RETURN BOOLEAN
704 IS
705   l_proc_step                    NUMBER(20,10):=0;
706   l_proc_name                    VARCHAR2(61):=
707     g_package_name||'chk_fte_exists';
708 
709   l_fte_exists_tmp               csr_fte_exists%ROWTYPE;
710   l_fte_exists                   BOOLEAN;
711   l_FTE_processing_start_date    DATE;
712 
713 BEGIN -- chk_fte_exists
714 
715   IF g_debug THEN
716     debug_enter(l_proc_name);
717     debug('p_assignment_id:'||p_assignment_id);
718     debug('g_fte_exists_assignment_id:'||g_fte_exists_assignment_id);
719     IF g_fte_exists = TRUE THEN
720       debug('g_fte_exists:TRUE');
721     END IF;
722     IF g_fte_exists = FALSE THEN
723       debug('g_fte_exists:FALSE');
724     END IF;
725     IF g_fte_exists IS NULL THEN
726       debug('g_fte_exists:IS NULL');
727     END IF;
728     IF p_reload_cache = TRUE THEN
729       debug('p_reload_cache:TRUE');
730     END IF;
731     IF p_reload_cache = FALSE THEN
732       debug('p_reload_cache:FALSE');
733     END IF;
734     IF p_reload_cache IS NULL THEN
735       debug('p_reload_cache:IS NULL');
736     END IF;
737   END IF;
738 
739   IF p_assignment_id <> g_fte_exists_assignment_id
740     OR
741      g_fte_exists IS NULL
742     OR
743      g_fte_exists_assignment_id IS NULL
744     OR
745      p_reload_cache = TRUE
746   THEN
747     IF p_assignment_id IS NOT NULL
748     THEN
749       OPEN csr_fte_exists(p_assignment_id);
750       FETCH csr_fte_exists INTO l_fte_exists_tmp;
751       g_fte_exists := csr_fte_exists%FOUND;
752       g_fte_exists_assignment_id := p_assignment_id;
753       CLOSE csr_fte_exists;
754     ELSE
755       RAISE NO_DATA_FOUND;
756       -- do not allow function to return
757       -- as this may cause the calling logic to make
758       -- an incorrect decision
759     END IF;
760   END IF; -- IF g_fte_exists_assignment_id <> p_assignment_id
761 
762   -- DO NOT RETURN cache globals always copy to local first
763   l_fte_exists := g_fte_exists;
764 
765   IF g_debug THEN
766     IF g_fte_exists = TRUE THEN
767       debug('g_fte_exists:TRUE');
768     END IF;
769     IF g_fte_exists = FALSE THEN
770       debug('g_fte_exists:FALSE');
771     END IF;
772     IF g_fte_exists IS NULL THEN
773       debug('g_fte_exists:IS NULL');
774     END IF;
775     debug('g_fte_exists_assignment_id:'||g_fte_exists_assignment_id);
776     debug_exit(l_proc_name);
777   END IF;
778 
779   RETURN l_fte_exists;
780 
781 EXCEPTION
782 WHEN OTHERS THEN
783   clear_cache;
784   IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
785     debug_others(l_proc_name,l_proc_step);
786     IF g_debug THEN
787       debug('Leaving: '||l_proc_name,-999);
788     END IF;
789     fnd_message.raise_error;
790   ELSE
791     RAISE;
792   END IF;
793 END chk_fte_exists;
794 --
795 --
796 --
797 FUNCTION get_FTE_processing_start_date
798   (p_assignment_id                IN NUMBER
799   ,p_effective_date               IN DATE
800   ) RETURN DATE
801 IS
802   l_proc_step                    NUMBER(20,10):=0;
803   l_proc_name                    VARCHAR2(61):=
804     g_package_name||'get_FTE_processing_start_date';
805 
806   l_FTE_processing_start_date    DATE;
807 
808 BEGIN  -- get_FTE_processing_start_date
809 
810   IF g_debug THEN
811     debug_enter(l_proc_name);
812     debug('p_assignment_id:'||p_assignment_id);
813     debug('p_effective_date:'||p_effective_date);
814   END IF;
815 
816 -- IF FTE does not exist, processing start date = earliest possible
817 -- IF FTE does exist and effective date passed < earliest possible use earliest possible
818 -- IF FTE does exist and effective date passed > earliest possible use effective date
819 
820   l_FTE_processing_start_date :=
821     get_earliest_possible_FTE_date(p_assignment_id,TRUE);
822 
823   l_proc_step := 10;
824   IF g_debug THEN
825     debug(l_proc_name,l_proc_step);
826     debug('l_FTE_processing_start_date:'||l_FTE_processing_start_date);
827   END IF;
828 
829   IF chk_fte_exists(p_assignment_id,TRUE)
830     AND
831      p_effective_date > l_FTE_processing_start_date
832   THEN
833     l_proc_step := 15;
834     IF g_debug THEN
835       debug(l_proc_name,l_proc_step);
836     END IF;
837     l_FTE_processing_start_date := p_effective_date;
838   END IF;
839 
840   IF g_debug THEN
841     debug('l_FTE_processing_start_date:'||l_FTE_processing_start_date);
842     debug_exit(l_proc_name);
843   END IF;
844 
845   RETURN l_FTE_processing_start_date;
846 
847 EXCEPTION
848 WHEN OTHERS THEN
849   clear_cache;
850   IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
851     debug_others(l_proc_name,l_proc_step);
852     IF g_debug THEN
853       debug('Leaving: '||l_proc_name,-999);
854     END IF;
855     fnd_message.raise_error;
856   ELSE
857     RAISE;
858   END IF;
859 END get_FTE_processing_start_date;
860 --
861 --
862 --
863 FUNCTION is_fte_enabled
864   (p_assignment_id                 NUMBER
865   ) RETURN BOOLEAN
866 IS
867   l_proc_step                    NUMBER(20,10):=0;
868   l_proc_name                    VARCHAR2(61):=
869     g_package_name||'is_fte_enabled';
870 
871 --  l_does_fte_exist               BOOLEAN;
872   l_earliest_possible_FTE_date   DATE;
873 
874   l_fte_is_enabled               BOOLEAN;
875 
876 
877 BEGIN -- is_fte_enabled
878 
879   -- setting reload cache to true here is ok
880   -- as this will if this true
881 
882 --  l_does_fte_exist := chk_fte_exists(p_assignment_id);
883 
884   l_earliest_possible_FTE_date :=
885     get_earliest_possible_FTE_date(p_assignment_id);
886 
887 --  l_fte_is_enabled :=
888 --    (
889 --     l_earliest_possible_FTE_date IS NOT NULL
890 --    OR
891 --     l_does_fte_exist = TRUE
892 --    );
893 
894   IF l_earliest_possible_FTE_date IS NOT NULL
895   THEN
896     l_fte_is_enabled := TRUE;
897   ELSE
898     l_fte_is_enabled := FALSE;
899   END IF;
900 
901   RETURN l_fte_is_enabled;
902 
903 END is_fte_enabled;
904 --
905 --
906 --
907 /* =====================================================================
908    Name    : set_fte_value
909    Purpose : Calculate FTE and write to database.
910    Returns :
911    ---------------------------------------------------------------------*/
912 PROCEDURE set_fte_value
913   (p_assignment_id               IN  NUMBER
914   ,p_business_group_id           IN  NUMBER
915   ,p_calculation_date            IN  DATE
916   ,p_fte_value                   IN  NUMBER
917   )
918 IS
919 
920 l_proc_step                    NUMBER(20,10):= 0;
921 l_proc_name                    VARCHAR2(61):=
922   g_package_name||'set_fte_value';
923 
924 l_datetrack_mode               VARCHAR2(30);
925 l_future_end_date              DATE;
926 
927 -- Added a new variable obj
928 
929 --l_object_version_number      number;
930 
931 l_fte_exists                 csr_fte_exists%ROWTYPE;
932 l_effective_fte_row          csr_effective_fte%ROWTYPE;
933 
934 -- Retrieve object_version_number
935 -- as this col is added recently
936 -- PS bug 2093889 for details
937 
938 CURSOR csr_chk_future_fte_rows
939   (p_assignment_budget_value_id   NUMBER
940   ,p_effective_date               DATE
941   )
942   IS
943 SELECT effective_end_date
944 FROM   per_assignment_budget_values_f
945 WHERE  assignment_budget_value_id = p_assignment_budget_value_id
946   AND  effective_start_date > p_effective_date
947   AND  ROWNUM < 2;
948 
949 BEGIN -- set_fte_value
950 
951   IF g_debug THEN
952     debug_enter(l_proc_name);
953     debug('p_assignment_id:'||p_assignment_id);
954     debug('p_calculation_date:'||
955           fnd_date.date_to_canonical(p_calculation_date)
956          );
957     debug('p_fte_value:'||p_fte_value);
958   END IF;
959 
960 
961   IF NOT chk_fte_exists(p_assignment_id)
962   THEN
963 
964     l_proc_step := 10;
965     IF g_debug THEN
966       debug(l_proc_name,l_proc_step);
967     END IF;
968 
969         per_abv_ins.ins(
970            p_effective_date             => p_calculation_date
971           ,p_business_group_id          => p_business_group_id
972           ,p_assignment_id              => p_assignment_id
973           ,p_unit                       => 'FTE'
974           ,p_value                      => p_fte_value
975           ,p_request_id                 => null
976           ,p_program_application_id     => null
977           ,p_program_id                 => null
978           ,p_program_update_date        => null
979           ,p_assignment_budget_value_id => l_effective_fte_row.assignment_budget_value_id
980           ,p_object_version_number      => l_effective_fte_row.object_version_number -- new param added
981           ,p_effective_start_date       => l_effective_fte_row.effective_start_date
982           ,p_effective_end_date         => l_effective_fte_row.effective_end_date
983            );
984 
985     IF g_is_concurrent_program_run THEN
986       g_output_file_records(g_output_file_records.LAST).status := 'Processed';
987       g_output_file_records(g_output_file_records.LAST).change_type := 'INSERT';
988     END IF;
989 
990     -- dummy call to repopulate chk_fte_exists cache
991     -- as in the subsequent call we want it to know that an fte exists
992     -- after this insert has taken and subsequent calls to set_fte_value
993     -- should attempt updates
994     IF NOT chk_fte_exists(p_assignment_id,TRUE)
995     THEN
996       -- if all goes well I never expect code to reach here
997       -- if it does it implies that some fatal error during insert
998       -- has been masked so abort processing now
999       l_proc_step := 15;
1000       IF g_debug THEN
1001         debug(l_proc_name,l_proc_step);
1002       END IF;
1003       RAISE NO_DATA_FOUND;
1004     END IF;
1005 
1006   ELSE -- an FTE record was found
1007 
1008     OPEN  csr_effective_fte(p_assignment_id,p_calculation_date);
1009     FETCH csr_effective_fte INTO l_effective_fte_row;
1010     CLOSE csr_effective_fte;
1011 
1012     l_proc_step := 20;
1013     IF g_debug THEN
1014       debug('ROUND(p_fte_value,5):'||ROUND(p_fte_value,5));
1015       debug('l_effective_fte_row.assignment_budget_value_id:'||
1016             l_effective_fte_row.assignment_budget_value_id);
1017       debug('l_effective_fte_row.object_version_number:'||
1018             l_effective_fte_row.object_version_number);
1019       debug('l_effective_fte_row.effective_start_date:'||
1020             fnd_date.date_to_canonical(l_effective_fte_row.effective_start_date)
1021            );
1022       debug('l_effective_fte_row.effective_end_date:'||
1023             fnd_date.date_to_canonical(l_effective_fte_row.effective_end_date)
1024            );
1025       debug('l_effective_fte_row.value:'||l_effective_fte_row.value);
1026     END IF;
1027 
1028     IF g_is_concurrent_program_run THEN
1029       g_output_file_records(g_output_file_records.LAST).FTE_old_value :=
1030         l_effective_fte_row.value;
1031     END IF;
1032 
1033     OPEN csr_chk_future_fte_rows
1034       (l_effective_fte_row.assignment_budget_value_id
1035       ,p_calculation_date
1036       );
1037     FETCH csr_chk_future_fte_rows INTO l_future_end_date;
1038     IF csr_chk_future_fte_rows%FOUND
1039     THEN
1040       --
1041       --
1042       -- For updates, if future rows exist, use update override.
1043       -- This has been agreed as a valid requirement
1044       --
1045       l_datetrack_mode := 'UPDATE_OVERRIDE';
1046     ELSE
1047       --
1048       -- If no future changes exist, just use update
1049       --
1050       IF l_effective_fte_row.effective_start_date <> p_calculation_date
1051       THEN
1052         l_datetrack_mode := 'UPDATE';
1053       ELSE
1054         l_datetrack_mode := 'CORRECTION';
1055       END IF;
1056     END IF;
1057     CLOSE csr_chk_future_fte_rows;
1058 
1059    l_proc_step := 30;
1060    IF g_debug THEN
1061      debug('l_future_end_date:'||l_future_end_date);
1062      debug('l_datetrack_mode:'||l_datetrack_mode);
1063    END IF;
1064 
1065    IF l_datetrack_mode <> 'UPDATE_OVERRIDE'
1066    THEN
1067 
1068      -- only do a datetrack UPDATE or correction if the value is different
1069 
1070      IF ROUND(l_effective_fte_row.value,5) <> ROUND(p_fte_value,5)
1071      THEN
1072 
1073      per_abv_upd.upd(
1074        p_effective_date             => p_calculation_date
1075       ,p_datetrack_mode             => l_datetrack_mode
1076       ,p_assignment_budget_value_id => l_effective_fte_row.assignment_budget_value_id
1077       ,p_object_version_number      => l_effective_fte_row.object_version_number -- new param added
1078       ,p_unit                       => 'FTE'
1079       ,p_value                      => p_fte_value
1080       ,p_request_id                 => null
1081       ,p_program_application_id     => null
1082       ,p_program_id                 => null
1083       ,p_program_update_date        => null
1084       ,p_effective_start_date       => l_effective_fte_row.effective_start_date
1085       ,p_effective_end_date         => l_effective_fte_row.effective_end_date
1086        );
1087 
1088        IF g_is_concurrent_program_run THEN
1089          g_output_file_records(g_output_file_records.LAST).status := 'Processed';
1090          g_output_file_records(g_output_file_records.LAST).change_type := l_datetrack_mode;
1091        END IF;
1092 
1093      ELSE
1094        IF g_is_concurrent_program_run THEN
1095          g_output_file_records(g_output_file_records.LAST).status := 'Processed (No Change)';
1096          g_output_file_records(g_output_file_records.LAST).change_type := l_datetrack_mode;
1097        END IF;
1098      END IF;
1099 
1100    ELSE
1101 
1102      IF g_debug THEN
1103        IF g_is_concurrent_program_run THEN
1104          debug('g_is_concurrent_program_run:TRUE');
1105        ELSE
1106          debug('g_is_concurrent_program_run:FALSE');
1107        END IF;
1108      END IF;
1109 
1110      IF ( g_is_concurrent_program_run
1111          AND
1112           ROUND(l_effective_fte_row.value,5) <> ROUND(p_fte_value,5)
1113         )
1114        OR
1115         NOT g_is_concurrent_program_run
1116      THEN
1117 
1118        l_proc_step := 40;
1119        IF g_debug THEN
1120          debug(l_proc_name,l_proc_step);
1121        END IF;
1122 
1123        IF l_effective_fte_row.effective_start_date <> p_calculation_date
1124        THEN
1125 
1126          per_abv_upd.upd(
1127             p_effective_date             => p_calculation_date
1128            ,p_datetrack_mode             => l_datetrack_mode
1129            ,p_assignment_budget_value_id => l_effective_fte_row.assignment_budget_value_id
1130            ,p_object_version_number      => l_effective_fte_row.object_version_number -- new param added
1131            ,p_unit                       => 'FTE'
1132            ,p_value                      => p_fte_value
1133            ,p_request_id                 => null
1134            ,p_program_application_id     => null
1135            ,p_program_id                 => null
1136            ,p_program_update_date        => null
1137            ,p_effective_start_date       => l_effective_fte_row.effective_start_date
1138            ,p_effective_end_date         => l_effective_fte_row.effective_end_date
1139             );
1140 
1141        ELSE
1142 
1143          l_datetrack_mode := hr_api.g_future_change;
1144          per_abv_del.del(
1145             p_effective_date             => p_calculation_date
1146            ,p_datetrack_mode             => l_datetrack_mode
1147            ,p_assignment_budget_value_id => l_effective_fte_row.assignment_budget_value_id
1148            ,p_object_version_number      => l_effective_fte_row.object_version_number -- new param added
1149            ,p_effective_start_date       => l_effective_fte_row.effective_start_date
1150            ,p_effective_end_date         => l_effective_fte_row.effective_end_date
1151             );
1152 
1153          l_datetrack_mode := hr_api.g_correction;
1154          per_abv_upd.upd(
1155             p_effective_date             => p_calculation_date
1156            ,p_datetrack_mode             => l_datetrack_mode
1157            ,p_assignment_budget_value_id => l_effective_fte_row.assignment_budget_value_id
1158            ,p_object_version_number      => l_effective_fte_row.object_version_number -- new param added
1159            ,p_unit                       => 'FTE'
1160            ,p_value                      => p_fte_value
1161            ,p_request_id                 => null
1162            ,p_program_application_id     => null
1163            ,p_program_id                 => null
1164            ,p_program_update_date        => null
1165            ,p_effective_start_date       => l_effective_fte_row.effective_start_date
1166            ,p_effective_end_date         => l_effective_fte_row.effective_end_date
1167             );
1168 
1169        END IF; -- IF l_effective_fte_row.effective_start_date <> p_calculation_date
1170 
1171        IF g_is_concurrent_program_run THEN
1172          g_output_file_records(g_output_file_records.LAST).change_type := 'UPDATE_OVERRIDE';
1173          g_output_file_records(g_output_file_records.LAST).status := 'Processed';
1174        END IF;
1175 
1176      ELSE
1177 
1178        IF g_is_concurrent_program_run THEN
1179          g_output_file_records(g_output_file_records.LAST).change_type := 'UPDATE_OVERRIDE';
1180          g_output_file_records(g_output_file_records.LAST).status := 'Processed(No Change)';
1181        END IF;
1182 
1183      END IF; -- IF ( g_is_concurrent_program_run AND ROUND(l_effective_fte_row.value,5)...
1184 
1185 
1186    END IF; -- IF l_datetrack_mode <> 'UPDATE_OVERRIDE'
1187 
1188   END IF; -- IF NOT chk_fte_exists(p_assignment_id) THEN
1189 
1190   IF g_debug THEN
1191     debug('l_effective_fte_row.assignment_budget_value_id:'||
1192           l_effective_fte_row.assignment_budget_value_id);
1193     debug('l_effective_fte_row.object_version_number:'||
1194           l_effective_fte_row.object_version_number);
1195     debug('l_effective_fte_row.effective_start_date:'||
1196           fnd_date.date_to_canonical(l_effective_fte_row.effective_start_date)
1197          );
1198     debug('l_effective_fte_row.effective_end_date:'||
1199           fnd_date.date_to_canonical(l_effective_fte_row.effective_end_date)
1200          );
1201     debug('l_effective_fte_row.value:'||l_effective_fte_row.value);
1202     debug('ROUND(p_fte_value,5):'||ROUND(p_fte_value,5));
1203     debug_exit(l_proc_name);
1204   END IF;
1205 
1206 EXCEPTION
1207 WHEN OTHERS THEN
1208   clear_cache;
1209   IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
1210     debug_others(l_proc_name,l_proc_step);
1211     IF g_debug THEN
1212       debug('Leaving: '||l_proc_name,-999);
1213     END IF;
1214     fnd_message.raise_error;
1215   ELSE
1216     RAISE;
1217   END IF;
1218 END set_fte_value;
1219 -- =====================================================================
1220 -- Name    : Get_FTE_Value
1221 -- Purpose : Query FTE value from database.
1222 -- Returns : FTE
1223 -- -------------------------------------------------------------------
1224 FUNCTION get_fte_value
1225   (p_assignment_id               IN  NUMBER
1226   ,p_calculation_date            IN  DATE
1227   ) RETURN NUMBER
1228 IS
1229 
1230 l_proc_step                    NUMBER(20,10):=0;
1231 l_proc_name                    VARCHAR2(61):=
1232   g_package_name||'get_fte_value';
1233 
1234 l_effective_fte_row            csr_effective_fte%ROWTYPE;
1235 
1236 
1237 BEGIN -- get_fte_value
1238 
1239   IF NOT g_is_concurrent_program_run THEN
1240     g_debug := hr_utility.debug_enabled;
1241   END IF;
1242 
1243   IF g_debug THEN
1244     debug_enter(l_proc_name);
1245     debug('p_assignment_id:'||p_assignment_id);
1246     debug('p_calculation_date:'||p_calculation_date);
1247   END IF;
1248 
1249   OPEN  csr_effective_fte(p_assignment_id,p_calculation_date);
1250   FETCH csr_effective_fte INTO l_effective_fte_row;
1251   CLOSE csr_effective_fte;
1252 
1253   IF g_debug THEN
1254     debug('l_effective_fte_row.value:'||l_effective_fte_row.value);
1255     debug_exit(l_proc_name);
1256   END IF;
1257 
1258   RETURN l_effective_fte_row.value;
1259 
1260 EXCEPTION
1261 WHEN OTHERS THEN
1262   clear_cache;
1263   IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
1264     debug_others(l_proc_name,l_proc_step);
1265     IF g_debug THEN
1266       debug('Leaving: '||l_proc_name,-999);
1267     END IF;
1268     fnd_message.raise_error;
1269   ELSE
1270     RAISE;
1271   END IF;
1272 END get_fte_value;
1273 --
1274 --
1275 --
1276 PROCEDURE get_assignment_details
1277   (p_assignment_id                IN NUMBER
1278   ,p_effective_date               IN DATE
1279   ,p_assignment_details           IN OUT NOCOPY csr_assignment_details%ROWTYPE
1280   )
1281 IS
1282 l_proc_step               NUMBER(20,10):=0;
1283 l_proc_name               VARCHAR2(61):= 'get_assignment_details';
1284 l_assignment_details      csr_assignment_details%ROWTYPE;
1285 
1286 BEGIN -- get_assignment_details
1287 
1288   IF g_debug THEN
1289     debug_enter(l_proc_name);
1290     debug('p_assignment_id:'||p_assignment_id);
1291     debug('p_effective_date:'||p_effective_date);
1292     debug('p_assignment_details.business_group_id:'||p_assignment_details.business_group_id);
1293     debug('p_assignment_details.normal_hours:'||p_assignment_details.normal_hours);
1294     debug('p_assignment_details.frequency:'||p_assignment_details.frequency);
1295   END IF;
1296 
1297   OPEN csr_assignment_details(p_assignment_id,p_effective_date);
1298   FETCH csr_assignment_details INTO p_assignment_details;
1299   IF csr_assignment_details%NOTFOUND THEN
1300     l_proc_step := 10;
1301     IF g_debug THEN
1302       debug(l_proc_name,l_proc_step);
1303     END IF;
1304     p_assignment_details := l_assignment_details; -- empty it
1305   ELSE
1306     l_proc_step := 15;
1307     IF g_debug THEN
1308       debug(l_proc_name,l_proc_step);
1309     END IF;
1310   END IF;
1311   CLOSE csr_assignment_details;
1312 
1313   IF p_assignment_details.normal_hours IS NULL
1314     OR
1315      p_assignment_details.frequency IS NULL
1316   THEN
1317     l_proc_step := 20;
1318     IF g_debug THEN
1319       debug(l_proc_name,l_proc_step);
1320     END IF;
1321     IF g_is_concurrent_program_run
1322      OR
1323       is_fte_enabled(p_assignment_id)
1324     THEN
1325       fnd_message.set_name('PQP','PQP_230456_FTE_NO_ASG_DETAILS');
1326       /* Corrected and added as a part of Bug#10239082 Starts
1327       fnd_message.set_token
1328         ('EFFECTIVEDATE'
1329         ,fnd_date.date_to_displaydate(p_effective_date)
1330         );   */
1331       fnd_message.set_token
1332         ('EFFECTIVEDATE'
1333         ,fnd_date.date_to_displaydate(p_effective_date, calendar_aware => FND_DATE.calendar_aware_alt)
1334         );
1335       /* Corrected and added as a part of Bug#10239082   Ends  */
1336       fnd_message.raise_error;
1337     END IF;
1338   END IF;
1339 
1340   IF g_debug THEN
1341     debug('p_assignment_details.business_group_id:'||p_assignment_details.business_group_id);
1342     debug('p_assignment_details.normal_hours:'||p_assignment_details.normal_hours);
1343     debug('p_assignment_details.frequency:'||p_assignment_details.frequency);
1344     debug_exit(l_proc_name);
1345   END IF;
1346 
1347 EXCEPTION
1348   WHEN OTHERS THEN
1349     p_assignment_details := l_assignment_details; -- nocopy
1350     clear_cache;
1351     IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
1352       debug_others(l_proc_name,l_proc_step);
1353       IF g_debug THEN
1354         debug('Leaving: '||l_proc_name,-999);
1355       END IF;
1356       fnd_message.raise_error;
1357     ELSE
1358       RAISE;
1359     END IF;
1360 END get_assignment_details;
1361 --
1362 --
1363 --
1364 PROCEDURE get_contract_details
1365   (p_assignment_id                IN NUMBER
1366   ,p_effective_date               IN DATE
1367   ,p_contract_details             IN OUT NOCOPY csr_contract_details%ROWTYPE
1368   )
1369 IS
1370 l_proc_step               NUMBER(20,10):=0;
1371 l_proc_name               VARCHAR2(61):= 'get_contract_details';
1372 l_contract_details        csr_contract_details%ROWTYPE;
1373 l_assignment_contract     csr_assignment_contract%ROWTYPE;
1374 
1375 l_pqp_contract_table_id     pay_user_tables.user_table_id%TYPE;
1376 l_annual_hours_col_id       pay_user_columns.user_column_id%TYPE;
1377 l_period_divisor_col_id     pay_user_columns.user_column_id%TYPE;
1378 
1379 BEGIN -- get_contract_details
1380 
1381 IF g_debug THEN
1382   debug_enter(l_proc_name);
1383   debug('p_assignment_id:'||p_assignment_id);
1384   debug('p_effective_date:'||p_effective_date);
1385   debug('p_contract_details.annual_hours:'||p_contract_details.annual_hours);
1386   debug('p_contract_details.period_divisor:'||p_contract_details.period_divisor);
1387 END IF;
1388 
1389 IF g_not_cached_constants THEN
1390   load_cached_constants;
1391 END IF;
1392 
1393 l_pqp_contract_table_id := g_pqp_contract_table_id;
1394 l_annual_hours_col_id   := g_annual_hours_col_id;
1395 l_period_divisor_col_id := g_period_divisor_col_id;
1396 
1397 IF g_debug THEN
1398   debug('l_pqp_contract_table_id:'||l_pqp_contract_table_id);
1399   debug('l_annual_hours_col_id:'||l_annual_hours_col_id);
1400   debug('l_period_divisor_col_id:'||l_period_divisor_col_id);
1401 END IF;
1402 
1403 OPEN csr_assignment_contract
1404   (p_assignment_id
1405   ,p_effective_date
1406   ,l_pqp_contract_table_id
1407   );
1408 FETCH csr_assignment_contract INTO l_assignment_contract;
1409 IF csr_assignment_contract%FOUND
1410 THEN
1411 
1412   l_proc_step := 10;
1413   IF g_debug THEN
1414     debug(l_proc_name,l_proc_step);
1415     debug('l_assignment_contract.user_row_id:'||l_assignment_contract.user_row_id);
1416   END IF;
1417 
1418    IF l_assignment_contract.user_row_id IS NOT NULL
1419    THEN
1420      p_contract_details.contract_type := l_assignment_contract.contract_type;
1421      p_contract_details.user_row_id := l_assignment_contract.user_row_id;
1422 
1423 
1424      l_proc_step := 20;
1425      IF g_debug THEN
1426        debug(l_proc_name,l_proc_step);
1427      END IF;
1428 
1429      OPEN csr_get_contract_value
1430         (l_annual_hours_col_id
1431         ,l_assignment_contract.user_row_id
1432         ,p_effective_date
1433         );
1434      FETCH csr_get_contract_value INTO p_contract_details.annual_hours;
1435      IF csr_get_contract_value%NOTFOUND THEN
1436        p_contract_details := l_contract_details; -- empty
1437        l_proc_step := 25;
1438        IF g_debug THEN
1439          debug(l_proc_name,l_proc_step);
1440        END IF;
1441      END IF;
1442      CLOSE csr_get_contract_value;
1443 
1444      l_proc_step := 30;
1445      IF g_debug THEN
1446        debug(l_proc_name,l_proc_step);
1447      END IF;
1448 
1449      OPEN csr_get_contract_value
1450         (l_period_divisor_col_id
1451         ,l_assignment_contract.user_row_id
1452         ,p_effective_date
1453         );
1454      FETCH csr_get_contract_value INTO p_contract_details.period_divisor;
1455      IF csr_get_contract_value%NOTFOUND
1456      THEN
1457        p_contract_details := l_contract_details; -- empty
1458        l_proc_step := 35;
1459        IF g_debug THEN
1460          debug(l_proc_name,l_proc_step);
1461        END IF;
1462      END IF;
1463      CLOSE csr_get_contract_value;
1464 
1465    END IF; -- IF l_assignment_contract.user_row_id IS NOT NULL
1466 ELSE
1467 
1468   p_contract_details := l_contract_details; -- empty
1469 
1470   l_proc_step := 40;
1471   IF g_debug THEN
1472     debug(l_proc_name,l_proc_step);
1473   END IF;
1474 
1475 END IF; -- IF csr_assignment_contract%FOUND
1476 CLOSE csr_assignment_contract;
1477 
1478 IF p_contract_details.annual_hours IS NULL
1479   OR
1480    p_contract_details.period_divisor IS NULL
1481 THEN
1482   l_proc_step := 50;
1483   IF g_debug THEN
1484     debug(l_proc_name,l_proc_step);
1485   END IF;
1486   IF g_is_concurrent_program_run
1487     OR
1488      is_fte_enabled(p_assignment_id)
1489   THEN
1490     IF l_assignment_contract.contract_type IS NOT NULL
1491     THEN
1492       fnd_message.set_name('PQP','PQP_230457_FTE_NO_CTR_DETAILS');
1493       fnd_message.set_token
1494         ('CONTRACTTYPE'
1495         ,l_assignment_contract.contract_type
1496         );
1497       /* Corrected and added as a part of Bug#10239082  Starts
1498       fnd_message.set_token
1499         ('EFFECTIVEDATE'
1500         ,fnd_date.date_to_displaydate(p_effective_date)
1501         );   */
1502 	fnd_message.set_token
1503         ('EFFECTIVEDATE'
1504         ,fnd_date.date_to_displaydate(p_effective_date, calendar_aware => FND_DATE.calendar_aware_alt)
1505         );
1506 	/* Corrected and added as a part of Bug#10239082   Ends   */
1507       fnd_message.raise_error;
1508     ELSE
1509       fnd_message.set_name('PQP','PQP_230113_AAT_MISSING_CONTRCT');
1510       /* Corrected and added as a part of Bug#10239082  Starts
1511       fnd_message.set_token
1512         ('EFFECTIVEDATE'
1513         ,fnd_date.date_to_displaydate(p_effective_date)
1514         );   */
1515 	fnd_message.set_token
1516         ('EFFECTIVEDATE'
1517         ,fnd_date.date_to_displaydate(p_effective_date, calendar_aware => FND_DATE.calendar_aware_alt)
1518         );
1519 	/* Corrected and added as a part of Bug#10239082   Ends   */
1520       fnd_message.raise_error;
1521     END IF;
1522   END IF;
1523 END IF; -- IF p_contract_details.annual_hours IS NULL
1524 
1525 IF g_debug THEN
1526   debug('p_contract_details.annual_hours:'||p_contract_details.annual_hours);
1527   debug('p_contract_details.period_divisor:'||p_contract_details.period_divisor);
1528   debug_exit(l_proc_name);
1529 END IF;
1530 
1531 EXCEPTION
1532   WHEN OTHERS THEN
1533     p_contract_details := l_contract_details; -- empty for nocopy
1534     clear_cache;
1535     IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
1536       debug_others(l_proc_name,l_proc_step);
1537       IF g_debug THEN
1538         debug('Leaving: '||l_proc_name,-999);
1539       END IF;
1540       fnd_message.raise_error;
1541     ELSE
1542       RAISE;
1543     END IF;
1544 END get_contract_details;
1545 --
1546 --
1547 -- procedure to calculate and store FTE called in a loop from the main
1548 PROCEDURE calculate_and_store_fte
1549   (p_assignment_id                NUMBER
1550   ,p_effective_date               DATE
1551   )
1552 IS
1553 
1554 l_proc_name               VARCHAR2(61):= 'calculate_and_store_fte';
1555 l_proc_step               NUMBER:=0;
1556 l_FTE_value               NUMBER;
1557 
1558 l_assignment_details           csr_assignment_details%ROWTYPE;
1559 l_contract_details             csr_contract_details%ROWTYPE;
1560 BEGIN -- calculate_and_store_fte
1561 
1562 
1563   IF g_debug THEN
1564     debug_enter(l_proc_name);
1565     debug('p_assignment_id:'||p_assignment_id);
1566     debug('p_effective_date:'||fnd_date.date_to_canonical(p_effective_date));
1567   END IF;
1568 
1569   -- fetch the relevant assignment details normal hours and contract
1570 
1571   -- get_assignment_normal_hours_and_frequency
1572   -- use out paramater to capitalize on nocopy of output parameters
1573 
1574     get_assignment_details
1575       (p_assignment_id
1576       ,p_effective_date
1577       ,l_assignment_details
1578       );
1579 
1580   IF g_is_concurrent_program_run THEN
1581     g_output_file_records(g_output_file_records.LAST).normal_hours:=
1582       l_assignment_details.normal_hours;
1583 
1584     g_output_file_records(g_output_file_records.LAST).frequency:=
1585     l_assignment_details.frequency;
1586   END IF;
1587 
1588   l_proc_step :=10;
1589   IF g_debug THEN
1590     debug(l_proc_name, l_proc_step);
1591   END IF;
1592 
1593     get_contract_details
1594       (p_assignment_id
1595       ,p_effective_date
1596       ,l_contract_details
1597       );
1598 
1599   IF g_is_concurrent_program_run THEN
1600     g_output_file_records(g_output_file_records.LAST).contract_type:=
1601       l_contract_details.contract_type;
1602 
1603     g_output_file_records(g_output_file_records.LAST).annual_hours:=
1604       l_contract_details.annual_hours;
1605 
1606     g_output_file_records(g_output_file_records.LAST).period_divisor:=
1607       l_contract_details.period_divisor;
1608   END IF;
1609 
1610   l_proc_step :=20;
1611   IF g_debug THEN
1612     debug('l_contract_details.annual_hours:'||l_contract_details.annual_hours);
1613     debug('l_contract_details.period_divisor:'||l_contract_details.period_divisor);
1614     debug(l_proc_name,l_proc_step);
1615   END IF;
1616 
1617   IF l_assignment_details.frequency <> 'Y'
1618   THEN
1619     l_fte_value :=
1620       l_assignment_details.normal_hours /
1621         ( l_contract_details.annual_hours / l_contract_details.period_divisor );
1622   ELSE
1623     l_fte_value := l_assignment_details.normal_hours / l_contract_details.annual_hours;
1624   END IF; -- IF l_assignment_details.frequency = 'Y' THEN
1625 
1626   IF g_is_concurrent_program_run THEN
1627     g_output_file_records(g_output_file_records.LAST).FTE_new_value:=
1628       l_fte_value;
1629   END IF;
1630 
1631   IF l_fte_value IS NOT NULL
1632   THEN
1633     l_proc_step :=35;
1634     IF g_debug THEN
1635       debug(l_proc_name,l_proc_step);
1636       debug('l_FTE_value:'||l_FTE_value);
1637     END IF;
1638     set_fte_value
1639       (p_assignment_id     => p_assignment_id
1640       ,p_business_group_id => l_assignment_details.business_group_id
1641       ,p_calculation_date  => p_effective_date
1642       ,p_FTE_value         => l_FTE_value
1643       );
1644 
1645     IF g_debug THEN
1646       /* Corrected and added as a part of Bug#10239082  Starts
1647       hr_utility.trace(
1648        'Updated, '||p_assignment_id||', '||
1649        fnd_date.date_to_displaydate(p_effective_date)||', '||
1650        l_FTE_value||', '||
1651        l_assignment_details.normal_hours||', '||
1652 --       l_assignment_details.contract_type||', '||
1653        l_contract_details.annual_hours||', '||
1654        l_contract_details.period_divisor
1655       );  */
1656       hr_utility.trace(
1657        'Updated, '||p_assignment_id||', '||
1658        fnd_date.date_to_displaydate(p_effective_date, calendar_aware => FND_DATE.calendar_aware_alt)||', '||
1659        l_FTE_value||', '||
1660        l_assignment_details.normal_hours||', '||
1661 --       l_assignment_details.contract_type||', '||
1662        l_contract_details.annual_hours||', '||
1663        l_contract_details.period_divisor
1664       );
1665       /* Corrected and added as a part of Bug#10239082   Ends  */
1666 
1667     END IF;
1668 
1669   ELSE
1670 
1671     IF g_is_concurrent_program_run THEN
1672       g_output_file_records(g_output_file_records.LAST).change_type:= 'Not Known';
1673       g_output_file_records(g_output_file_records.LAST).status:= 'Errored(Skipped)';
1674     END IF;
1675 
1676   END IF;
1677 
1678   IF g_debug THEN
1679     debug_exit(l_proc_name);
1680   END IF;
1681 
1682 EXCEPTION
1683   WHEN OTHERS THEN
1684     clear_cache;
1685     IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
1686       debug_others(l_proc_name,l_proc_step);
1687       IF g_debug THEN
1688         debug('Leaving: '||l_proc_name,-999);
1689       END IF;
1690       fnd_message.raise_error;
1691     ELSE
1692       RAISE;
1693     END IF;
1694 END calculate_and_store_fte;
1695 --
1696 --
1697 PROCEDURE update_fte_for_assignment
1698   (p_assignment_id                NUMBER
1699   ,p_effective_date               DATE
1700   )
1701 IS
1702 
1703   l_proc_name             VARCHAR2(61):=
1704     g_package_name||'update_fte_for_assignment';
1705   l_proc_step             NUMBER(20,10):=0;
1706 
1707   i                       BINARY_INTEGER:=0;
1708   l_max_iterations        BINARY_INTEGER:= 10000;
1709 
1710   l_pqp_contract_table_id        pay_user_tables.user_table_id%TYPE;
1711   l_annual_hours_col_id          pay_user_columns.user_column_id%TYPE;
1712   l_period_divisor_col_id        pay_user_columns.user_column_id%TYPE;
1713 
1714 
1715 
1716   -- there is no need for the change type column in the following cursor
1717   -- it gives rise to have logic to eliminate duplicate dates to be implemented in loop
1718   -- as we use UNION ALL as opposed to UNION
1719   -- but when debugging , knowing the change type that was relevant can speed up investigation
1720   CURSOR csr_get_relevant_change_dates
1721     (p_assignment_id                              IN NUMBER
1722     ,p_min_effective_start_date                   IN DATE
1723     ,p_pqp_contract_table_id                      IN NUMBER
1724     ,p_annual_hours_col_id                        IN NUMBER
1725     ,p_period_divisor_col_id                      IN NUMBER
1726     ) IS
1727   SELECT 'Normal Hours' change_type,asg2.effective_start_date
1728   FROM   per_all_assignments_f asg1
1729         ,per_all_assignments_f asg2
1730   WHERE  asg1.assignment_id = p_assignment_id
1731     AND  ( asg1.effective_start_date >= p_min_effective_start_date
1732           OR
1733            p_min_effective_start_date
1734              BETWEEN asg1.effective_start_date
1735                  AND asg1.effective_end_date
1736          )
1737     AND  asg2.assignment_id = asg1.assignment_id
1738     AND  asg2.effective_start_date = asg1.effective_end_date+1
1739     AND  NVL(asg2.normal_hours,-1) <> NVL(asg1.normal_hours,-2)
1740   UNION ALL
1741   SELECT 'Assignment Contract' change_type,aat2.effective_start_date
1742   FROM   pqp_assignment_attributes_f aat1
1743         ,pqp_assignment_attributes_f aat2
1744   WHERE  aat1.assignment_id = p_assignment_id
1745     AND  ( aat1.effective_start_date >= p_min_effective_start_date
1746           OR
1747            p_min_effective_start_date
1748              BETWEEN aat1.effective_start_date
1749                  AND aat1.effective_end_date
1750          )
1751     AND  aat1.assignment_id = aat2.assignment_id
1752     AND  aat2.effective_start_date = aat1.effective_end_date+1
1753     AND  NVL(aat2.contract_type,'{null}') <> NVL(aat1.contract_type,'[NULL]')
1754   UNION ALL
1755   SELECT 'Contract Type' change_type,inst2.effective_start_date
1756   FROM   pqp_assignment_attributes_f aat
1757         ,pay_user_rows_f             pur
1758         ,pay_user_column_instances_f inst1
1759         ,pay_user_column_instances_f inst2
1760   WHERE  aat.assignment_id = p_assignment_id
1761     AND  ( aat.effective_start_date >= p_min_effective_start_date
1762           OR
1763            p_min_effective_start_date
1764              BETWEEN aat.effective_start_date
1765                  AND aat.effective_end_date
1766          )
1767     AND  pur.user_table_id = p_pqp_contract_table_id
1768     AND  pur.business_group_id = aat.business_group_id
1769     AND  pur.row_low_range_or_name = aat.contract_type
1770     AND  aat.effective_start_date
1771            BETWEEN pur.effective_start_date
1772                AND pur.effective_end_date
1773     AND  inst1.user_column_id IN
1774            (p_annual_hours_col_id
1775            ,p_period_divisor_col_id
1776            )
1777     AND  ( inst1.effective_start_date >= p_min_effective_start_date
1778           OR
1779            p_min_effective_start_date
1780              BETWEEN inst1.effective_start_date
1781                  AND inst1.effective_end_date
1782          )
1783     AND  inst1.user_row_id = pur.user_row_id
1784     AND  inst2.user_column_instance_id = inst1.user_column_instance_id
1785     AND  inst2.effective_start_date = inst1.effective_end_date+1
1786     AND  NVL(inst2.value,'{null}') <> NVL(inst1.value,'~NULL~')
1787   ORDER BY 2 ASC;
1788 
1789 
1790   l_last_change_date             DATE;
1791   l_relevant_change              csr_get_relevant_change_dates%ROWTYPE;
1792   l_status                       VARCHAR2(30);
1793   l_fte_exists                   BOOLEAN;
1794   l_earliest_possible_FTE_date   DATE;
1795   l_effective_date               DATE;
1796 
1797 BEGIN -- update_fte_for_assignment
1798 
1799 
1800 IF NOT g_is_concurrent_program_run  THEN
1801   g_debug := hr_utility.debug_enabled;
1802 END IF;
1803 
1804 IF g_debug THEN
1805   debug_enter(l_proc_name);
1806   debug('p_assignment_id:'||p_assignment_id);
1807   debug('p_effective_date:'||fnd_date.date_to_canonical(p_effective_date));
1808   IF g_is_concurrent_program_run = TRUE THEN
1809     debug('g_is_concurrent_program_run:TRUE');
1810   END IF;
1811   IF g_is_concurrent_program_run = FALSE THEN
1812     debug('g_is_concurrent_program_run:FALSE');
1813   END IF;
1814   IF g_is_concurrent_program_run IS NULL THEN
1815     debug('g_is_concurrent_program_run:IS NULL');
1816   END IF;
1817 END IF;
1818 
1819 l_status := get_installation_status(801);
1820 
1821 IF l_status = 'I' THEN -- do nothing unless payroll installed
1822 
1823   IF g_not_cached_constants THEN
1824     load_cached_constants;
1825   ELSE
1826     IF g_debug THEN
1827       debug('g_not_cached_constants:FALSE');
1828     END IF;
1829   END IF;
1830 
1831   l_pqp_contract_table_id := g_pqp_contract_table_id;
1832   l_annual_hours_col_id   := g_annual_hours_col_id;
1833   l_period_divisor_col_id := g_period_divisor_col_id;
1834 
1835   IF g_is_concurrent_program_run THEN
1836     g_output_file_records(g_output_file_records.LAST).effective_date := p_effective_date;
1837     g_output_file_records(g_output_file_records.LAST).change_in := 'Initial';
1838   END IF;
1839 
1840   -- force a cache reload of this check as
1841   -- we cannot be sure that the underlying assignment
1842   -- data has not changed between two calls to
1843   -- update_fte_for_assignment when being invoked
1844   -- from forms
1845 
1846   IF NOT g_is_concurrent_program_run
1847   THEN
1848 
1849     l_fte_exists := chk_fte_exists(p_assignment_id,TRUE);
1850 
1851     l_earliest_possible_FTE_date :=
1852       get_earliest_possible_FTE_date(p_assignment_id,TRUE);
1853     -- if earliest possible date is null
1854     -- it implies
1855     -- a) it will not be possible to calculate FTE for this asg
1856     -- b) he has either never had any normal hours recorded against his asg
1857     -- c) or he has never had any contract type on extra details of service
1858     -- in which case its no use processing further
1859     -- if however there do exist an FTE row they have either been manually created
1860     -- or the user has performed an operation such a nulling out the contract type
1861     -- or a purge which has led to earliest processing date being null
1862     -- in which case we do want to allow FTE processing to take place, error
1863     -- (converted to message) and allow the overall operation to succeeed
1864     -- so that the user is aware that his action has resulted in
1865     -- the FTE not being changed
1866 
1867       IF l_fte_exists
1868       THEN
1869         IF p_effective_date IS NULL -- e.g. when a purge takes place in online mode
1870         THEN
1871           IF l_earliest_possible_FTE_date IS NULL THEN
1872             l_effective_date := HR_GBNICAR.NICAR_SESSION_DATE(0);
1873           ELSE
1874             l_effective_date := l_earliest_possible_FTE_date;
1875           END IF;
1876           -- if at this point l_effective_date is still null
1877           -- it implies
1878         ELSE
1879           l_effective_date := p_effective_date;
1880         END IF;
1881           -- if p_effective_date is > earliest processing date
1882           -- the expectation that processing will complet normally
1883           -- if the p_eff_date < earliest process date
1884           -- then the processing will fail to update an FTE
1885           -- unlike a conc pgm rum we do not change the processing
1886           -- date at this stage in order to allow it to proceed and
1887           -- error
1888       ELSE
1889         IF l_earliest_possible_FTE_date < p_effective_date THEN
1890           l_effective_date := l_earliest_possible_FTE_date;
1891         ELSE
1892           l_effective_date := p_effective_date; -- only because its not conc run
1893         END IF;
1894         -- it is possible at this stage for earliest processing to be null
1895         -- in which case the subsequent check for l_eff being not null
1896         -- will prevent any processing from taking place and raising no errors
1897         -- which is ok becase that should only happen when an employee
1898         -- has never had any FTE and neither has sufficent data for FTE to
1899         -- be calculated
1900       END IF; -- IF NOT l_fte_exists THEN
1901 
1902   ELSE
1903 
1904     l_effective_date := p_effective_date;
1905 
1906   END IF; -- IF NOT g_is_concurrent_program_run
1907 
1908 IF g_debug THEN
1909   /* Corrected and added as a part of Bug#10239082 Starts
1910   debug('l_effective_date:'||fnd_date.date_to_displaydate(l_effective_date));   */
1911   debug('l_effective_date:'||fnd_date.date_to_displaydate(l_effective_date, calendar_aware => FND_DATE.calendar_aware_alt));
1912   /* Corrected and added as a part of Bug#10239082   Ends  */
1913 END IF;
1914 
1915 IF l_effective_date IS NOT NULL
1916 THEN
1917 
1918   -- create the first FTE row
1919   calculate_and_store_fte
1920     (p_assignment_id
1921     ,l_effective_date
1922     );
1923 
1924   --  iterate thru relevant dates for assignment normal hours and contract changes
1925   l_last_change_date := hr_api.g_eot;
1926   FOR this_change IN csr_get_relevant_change_dates
1927     (p_assignment_id                              => p_assignment_id
1928     ,p_min_effective_start_date                   => l_effective_date
1929     ,p_pqp_contract_table_id                      => l_pqp_contract_table_id
1930     ,p_annual_hours_col_id                        => l_annual_hours_col_id
1931     ,p_period_divisor_col_id                      => l_period_divisor_col_id
1932     )
1933   LOOP
1934 
1935     l_relevant_change := this_change;
1936 
1937     IF g_is_concurrent_program_run THEN
1938       IF g_debug THEN
1939        debug('In the Debug -1: ');
1940       END IF;
1941       g_output_file_records(g_output_file_records.LAST+1).assignment_id := p_assignment_id;
1942       g_output_file_records(g_output_file_records.LAST).employee_number :=
1943         g_output_file_records(g_output_file_records.LAST-1).employee_number;
1944       g_output_file_records(g_output_file_records.LAST).assignment_number :=
1945         g_output_file_records(g_output_file_records.LAST-1).assignment_number;
1946       g_output_file_records(g_output_file_records.LAST).effective_date := this_change.effective_start_date;
1947       g_output_file_records(g_output_file_records.LAST).change_in := this_change.change_type;
1948     END IF;
1949 
1950 
1951     IF g_debug THEN
1952       debug('this_change.effective_start_date:'||this_change.effective_start_date);
1953       debug('this_change.change_type:'||this_change.change_type);
1954       debug('l_last_change_date:'||l_last_change_date);
1955     END IF;
1956 
1957     IF this_change.effective_start_date <> l_last_change_date THEN
1958       IF g_debug THEN
1959         debug('In the Debug -2 This_change.effective_start_date:-'||this_change.effective_start_date);
1960         debug('In the Debug -3 l_last_change_date:-'||l_last_change_date);
1961       END IF;
1962       l_last_change_date := this_change.effective_start_date;
1963       calculate_and_store_fte
1964         (p_assignment_id
1965         ,this_change.effective_start_date
1966         );
1967     ELSE
1968      BEGIN -- For bug 5531482
1969        IF g_debug THEN
1970         hr_utility.set_location('In the Debug -4 This_change.effective_start_date:-'||this_change.effective_start_date,70);
1971         hr_utility.set_location('In the Debug -5 l_last_change_date:-'||l_last_change_date,80);
1972        END IF;
1973         g_output_file_records(g_output_file_records.LAST) :=
1974         g_output_file_records(g_output_file_records.LAST-1);
1975         g_output_file_records(g_output_file_records.LAST).change_in :=
1976         this_change.change_type;
1977         g_output_file_records(g_output_file_records.LAST).status :=
1978         'Processed(Skipped)';
1979         g_output_file_records(g_output_file_records.LAST).message :=
1980         'Processing was skipped as this change effective the same date as the previous record.';
1981      EXCEPTION
1982       when VALUE_ERROR then
1983          hr_utility.set_location('In the Debug -6 VALUE_ERROR',90);
1984          null;
1985       when others then
1986          hr_utility.set_location('In the Debug -7 OTHERS',100);
1987          hr_utility.set_location('In the Debug -8:'||sqlerrm,110);
1988          Raise;
1989       END; -- End For bug 5531482
1990    END IF;
1991   END LOOP; --FOR this_change IN csr_get_relevant_change_dates
1992 
1993 END IF; -- IF l_effective_date IS NOT NULL
1994 
1995 END IF; -- IF l_status = 'I' THEN
1996 
1997 IF g_debug THEN
1998   debug('l_status:'||l_status);
1999   debug_exit(l_proc_name);
2000 END IF;
2001 
2002 EXCEPTION
2003   WHEN OTHERS THEN
2004     clear_cache;
2005     IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
2006       debug_others(l_proc_name,l_proc_step);
2007       IF g_debug THEN
2008         debug('Leaving: '||l_proc_name,-999);
2009       END IF;
2010       fnd_message.raise_error;
2011     ELSE
2012       RAISE;
2013     END IF;
2014 END update_fte_for_assignment;
2015 --
2016 /* =====================================================================
2017    Name    : Update_FTE_For Assignment_Set
2018    Purpose : Update multiple FTE values. Normally called as a
2019              concurrent process.
2020    Returns :
2021    ---------------------------------------------------------------------*/
2022 PROCEDURE update_fte_for_assignment_set
2023   (ERRBUF                        OUT NOCOPY VARCHAR2
2024   ,RETCODE                       OUT NOCOPY NUMBER
2025   ,p_contract_type               IN  VARCHAR2
2026   ,p_payroll_id                  IN  NUMBER
2027   ,p_calculation_date            IN  VARCHAR2
2028   ,p_trace                       IN  VARCHAR2
2029   )
2030 IS
2031 
2032 l_proc_step                    NUMBER(20,10):=0;
2033 l_proc_name                    VARCHAR2(61) :=
2034   g_package_name||'update_fte_for_assignment_set';
2035 
2036 l_calculation_date             DATE;
2037 l_error                        VARCHAR2(2000);
2038 l_message                      VARCHAR2(240);
2039 l_full_name                    VARCHAR2(80);
2040 l_business_group_id            per_all_assignments_f.business_group_id%TYPE;
2041 l_contract_type                pay_user_rows_f.row_low_range_or_name%TYPE;
2042 i                              BINARY_INTEGER;
2043 
2044 CURSOR csr_payroll_assignment_set
2045   (p_payroll_id                   NUMBER
2046   ,p_effective_date               DATE
2047   )
2048 IS
2049 SELECT DISTINCT asg.assignment_id
2050 FROM   per_all_assignments_f asg
2051 WHERE  asg.payroll_id = p_payroll_id
2052   AND  ( p_effective_date
2053            BETWEEN asg.effective_start_date AND asg.effective_end_date
2054         OR
2055          asg.effective_start_date > p_effective_date
2056        );
2057 
2058 
2059 CURSOR csr_contract_assignment_set
2060   (p_business_group_id            NUMBER
2061   ,p_contract_type                VARCHAR2
2062   ,p_effective_date               DATE
2063   )
2064 IS
2065 SELECT DISTINCT aat.assignment_id
2066 FROM   pqp_assignment_attributes_f aat
2067 WHERE  aat.business_group_id = p_business_group_id
2068   AND  aat.contract_type = NVL(p_contract_type,aat.contract_type)
2069   AND  ( p_effective_date
2070            BETWEEN aat.effective_start_date AND aat.effective_end_date
2071         OR
2072          aat.effective_start_date > p_effective_date
2073        );
2074 
2075 
2076 CURSOR csr_payroll_and_contract
2077   (p_payroll_id                   NUMBER
2078   ,p_contract_type                VARCHAR2
2079   ,p_effective_date               DATE
2080   ) IS
2081 SELECT  DISTINCT asg.assignment_id
2082 FROM    per_all_assignments_f asg,
2083         pqp_assignment_attributes_f aat
2084 WHERE   asg.payroll_id    = p_payroll_id
2085   AND   ( p_effective_date
2086            BETWEEN asg.effective_start_date AND asg.effective_end_date
2087         OR
2088          asg.effective_start_date > p_effective_date
2089         )
2090   AND   aat.assignment_id = asg.assignment_id
2091   AND   aat.contract_type = p_contract_type
2092   AND   ( p_effective_date
2093            BETWEEN aat.effective_start_date AND aat.effective_end_date
2094         OR
2095          aat.effective_start_date > p_effective_date
2096         );
2097 
2098 CURSOR csr_person_details
2099   (p_assignment_id                 NUMBER)
2100 IS
2101 SELECT per.full_name
2102 FROM   per_all_people_f per,
2103        per_all_assignments_f asg
2104 WHERE  asg.person_id = per.person_id
2105   AND  asg.assignment_id = p_assignment_id
2106   AND  l_calculation_date
2107        BETWEEN asg.effective_start_date AND asg.effective_end_date
2108   AND  l_calculation_date
2109        BETWEEN per.effective_start_date AND per.effective_end_date;
2110 
2111 l_assignment                   t_asg_details;
2112 l_FTE_processing_start_date    DATE;
2113 l_errored                      BINARY_INTEGER:=0;
2114 l_processed                    BINARY_INTEGER:=0;
2115 l_log_string                   VARCHAR2(4000);
2116 
2117 BEGIN -- update_fte_for_assignment_set
2118 
2119   g_is_concurrent_program_run := TRUE;
2120 
2121   g_debug := hr_utility.debug_enabled;
2122 
2123   IF p_trace = 'Y' THEN
2124     g_debug := TRUE;
2125   END IF;
2126 
2127   IF g_debug THEN
2128     debug_enter(l_proc_name);
2129     debug('p_payroll_id:'||p_payroll_id);
2130     debug('p_contract_type:'||p_contract_type);
2131     debug('p_calculation_date_txt:'||p_calculation_date);
2132   END IF;
2133 
2134   /* Corrected and added as a part of Bug#10239082  Starts
2135   fnd_file.put_line
2136     (fnd_file.log
2137     ,'Calculate FTE For Assignments - '||
2138      fnd_date.date_to_displaydate(SYSDATE)||' '||TO_CHAR(SYSDATE,'HH24:MI:SS')
2139     );  */
2140     fnd_file.put_line
2141     (fnd_file.log
2142     ,'Calculate FTE For Assignments - '||
2143      fnd_date.date_to_displaydate(SYSDATE, calendar_aware => FND_DATE.calendar_aware_alt)||' '||TO_CHAR(SYSDATE,'HH24:MI:SS')
2144     );
2145   /* Corrected and added as a part of Bug#10239082   Ends  */
2146   -- Set the standard concurrent program out paramters
2147   ERRBUF:= NULL;
2148   RETCODE:= 0;
2149 
2150   -- In concurrent programs, the date is passed in as a string in canonical format. We must convert this
2151   -- to a date
2152 
2153   --l_calculation_date := to_date(substr(p_calculation_date, 1, 10), 'YYYY/MM/DD');
2154   l_calculation_date := fnd_date.canonical_to_date(p_calculation_date);
2155 
2156   -- as business group id is not passed as a parameter use the fnd_global value
2157   -- this implies that concurrent process must be run from within apps
2158   -- and cannot be run from sql unless an explicit apps initialization is done
2159   -- as a prereq step.
2160   -- we donot want to add the parameter as that implies a conc spec change
2161   -- which in turn will cause the patch size for this change to increase
2162   -- as it will force us to include/pre-req several
2163   l_business_group_id := fnd_global.per_business_group_id;
2164 
2165   IF g_debug THEN
2166     debug('l_business_group_id:'||l_business_group_id);
2167   END IF;
2168 
2169   l_log_string := NULL;
2170   SELECT name
2171   INTO   l_log_string
2172   FROM   per_business_groups_perf
2173   WHERE  business_group_id = l_business_group_id;
2174 
2175   fnd_file.put_line
2176     (fnd_file.log
2177     ,RPAD('Business Group',30,' ')||':'||l_log_string
2178     );
2179 
2180   l_log_string := NULL;
2181   IF p_payroll_id IS NOT NULL
2182   THEN
2183     SELECT a.payroll_name
2184     INTO   l_log_string
2185     FROM   pay_all_payrolls_f a
2186     WHERE  a.payroll_id = p_payroll_id
2187       AND  effective_start_date =
2188              (SELECT MAX(b.effective_start_date)
2189               FROM   pay_all_payrolls_f b
2190               WHERE  b.payroll_id = a.payroll_id
2191               );
2192   END IF;
2193 
2194   fnd_file.put_line
2195       (fnd_file.log
2196       ,RPAD('Payroll Name',30,' ')||':'||l_log_string
2197       );
2198 
2199   fnd_file.put_line
2200     (fnd_file.log
2201     ,RPAD('Contract Type',30,' ')||':'||p_contract_type
2202     );
2203   /* Corrected and added as a part of Bug#10239082 Starts
2204   fnd_file.put_line
2205     (fnd_file.log
2206     ,RPAD('Effective On or After',30,' ')||':'||fnd_date.date_to_displaydate(l_calculation_date)
2207     );  */
2208   fnd_file.put_line
2209     (fnd_file.log
2210     ,RPAD('Effective On or After',30,' ')||':'||fnd_date.date_to_displaydate(l_calculation_date, calendar_aware => FND_DATE.calendar_aware_alt)
2211     );
2212   /* Corrected and added as a part of Bug#10239082   Ends  */
2213 
2214 /*  if P_Payroll_ID IS NULL AND P_Contract_Type IS NULL then
2215     fnd_message.set_name('PQP', 'PQP_230686_FTE_PROG_FAIL_PARAM');
2216     l_message := fnd_message.get;
2217     fnd_file.put_line(fnd_file.log, l_message);
2218     fnd_message.raise_error;
2219 */
2220 
2221   IF (p_contract_type IS NOT NULL AND p_payroll_id IS NOT NULL)
2222   THEN
2223 
2224     l_proc_step := 10;
2225     IF g_debug THEN
2226       debug(l_proc_name,l_proc_step);
2227     END IF;
2228 
2229     OPEN  csr_payroll_and_contract
2230       (p_payroll_id
2231       ,p_contract_type
2232       ,l_calculation_date
2233       );
2234     FETCH csr_payroll_and_contract BULK COLLECT INTO l_assignment;
2235     CLOSE csr_payroll_and_contract;
2236 
2237   ELSIF (p_contract_type IS NULL AND p_payroll_id IS NOT NULL)
2238   THEN
2239 
2240     l_proc_step := 20;
2241     IF g_debug THEN
2242       debug(l_proc_name,l_proc_step);
2243     END IF;
2244 
2245     OPEN csr_payroll_assignment_set(p_payroll_id,l_calculation_date);
2246     FETCH csr_payroll_assignment_set BULK COLLECT INTO l_assignment;
2247     CLOSE csr_payroll_assignment_set;
2248 
2249   ELSE
2250 
2251     l_proc_step := 20;
2252     IF g_debug THEN
2253       debug(l_proc_name,l_proc_step);
2254     END IF;
2255 
2256     --fetch data if both the contract type and payroll are null
2257     --or only when the contract type is not null
2258     OPEN  csr_contract_assignment_set
2259       (l_business_group_id
2260       ,p_contract_type
2261       ,l_calculation_date
2262       );
2263     FETCH csr_contract_assignment_set BULK COLLECT INTO l_assignment;
2264     CLOSE csr_contract_assignment_set;
2265 
2266   END IF;
2267 
2268   l_proc_step := 30;
2269   IF g_debug THEN
2270     debug(l_proc_name,l_proc_step);
2271   END IF;
2272 
2273 
2274   DELETE FROM fnd_sessions WHERE session_id = USERENV('sessionid');
2275   INSERT INTO fnd_sessions
2276     (session_id
2277     ,effective_date
2278     )
2279   VALUES
2280     (USERENV('sessionid')
2281     ,l_calculation_date
2282     );
2283 
2284   l_proc_step := 40;
2285   IF g_debug THEN
2286     debug(l_proc_name,l_proc_step);
2287   END IF;
2288 
2289   fnd_file.put_line
2290     (fnd_file.log
2291     ,'Number of Assignments To Process: '||l_assignment.COUNT
2292     );
2293 
2294 
2295   fnd_file.put_line
2296     (fnd_file.log
2297     ,'Error Log:'
2298     );
2299 
2300 
2301     i := l_assignment.FIRST();
2302 
2303     WHILE i IS NOT NULL
2304     LOOP
2305 
2306       IF i = l_assignment.FIRST() THEN
2307         fnd_file.put_line
2308         (fnd_file.output
2309         ,RPAD('Status',30,' ')||g_column_separator||
2310          RPAD('Employee Number',20,' ')||g_column_separator||
2311          RPAD('Assignment_Number',30,' ')||g_column_separator||
2312          RPAD('Effective Date',15,' ')||g_column_separator||
2313          RPAD('Change In',30,' ')||g_column_separator||
2314          RPAD('FTE - Before Change',20,' ')||g_column_separator||
2315          RPAD('Change Type',15,' ')||g_column_separator||
2316          RPAD('FTE - After Change',20,' ')||g_column_separator||
2317          RPAD('Normal Hours',15,' ')||g_column_separator||
2318          RPAD('Frequency',10,' ')||g_column_separator||
2319          RPAD('Contract Type',30,' ')||g_column_separator||
2320          RPAD('Annual Hours',15,' ')||g_column_separator||
2321          RPAD('Period Divisor',15,' ')||g_column_separator||
2322          RPAD('Message',255,' ')
2323         );
2324 
2325         fnd_file.put_line
2326         (fnd_file.output
2327         ,RPAD('-',30,'-')||g_column_separator||
2328          RPAD('-',20,'-')||g_column_separator||
2329          RPAD('-',30,'-')||g_column_separator||
2330          RPAD('-',15,'-')||g_column_separator||
2331          RPAD('-',30,'-')||g_column_separator||
2332          RPAD('-',20,'-')||g_column_separator||
2333          RPAD('-',15,'-')||g_column_separator||
2334          RPAD('-',20,'-')||g_column_separator||
2335          RPAD('-',15,'-')||g_column_separator||
2336          RPAD('-',10,'-')||g_column_separator||
2337          RPAD('-',30,'-')||g_column_separator||
2338          RPAD('-',15,'-')||g_column_separator||
2339          RPAD('-',15,'-')||g_column_separator||
2340          RPAD('-',255,'-')
2341         );
2342 
2343       END IF;
2344 
2345         l_proc_step := 40+i/100000;
2346         IF g_debug THEN
2347           debug(l_proc_name,l_proc_step);
2348         END IF;
2349 
2350       --
2351       --
2352       -- Update assignments within new block. This way, if one
2353       -- assignment should error, we can still process the rest,
2354       -- whilst writing the error details to the concurrent
2355       -- manager log, if available.
2356       --
2357 
2358       g_output_file_records.DELETE;
2359 
2360       IF g_debug THEN
2361         debug('l_assignment(i):'||l_assignment(i));
2362       END IF;
2363 
2364       g_output_file_records(i).assignment_id:= l_assignment(i);
2365 
2366       l_proc_step := 45+i/100000;
2367       IF g_debug THEN
2368         debug(l_proc_name,l_proc_step);
2369       END IF;
2370 
2371       BEGIN
2372 
2373       -- if assignment has duplicate FTE rows, do a zap on both and then call
2374       -- get relevant date, it will return earliest possible
2375       -- not implemented above comment
2376 
2377       l_proc_step := 50+(i/100000);
2378       IF g_debug THEN
2379         debug(l_proc_name,l_proc_step);
2380       END IF;
2381 
2382       l_FTE_processing_start_date :=
2383         get_FTE_processing_start_date
2384          (p_assignment_id  => l_assignment(i)
2385          ,p_effective_date => l_calculation_date
2386          );
2387 
2388       l_proc_step := 60+(i/100000);
2389       IF g_debug THEN
2390         debug(l_proc_name,l_proc_step);
2391       END IF;
2392 
2393       g_output_file_records(i).effective_date:= l_FTE_processing_start_date;
2394 
2395       SELECT employee_number
2396       INTO   g_output_file_records(i).employee_number
2397       FROM   per_all_people_f a
2398       WHERE  a.person_id =
2399                (SELECT asg.person_id
2400                 FROM   per_all_assignments_f asg
2401                 WHERE  asg.assignment_id = l_assignment(i)
2402                   AND  ROWNUM < 2
2403                 )
2404         AND  effective_start_date =
2405                (SELECT MAX(b.effective_start_date)
2406                 FROM   per_all_people_f b
2407                 WHERE  b.person_id = a.person_id
2408                );
2409 
2410       l_proc_step := 70+(i/100000);
2411       IF g_debug THEN
2412         debug(l_proc_name,l_proc_step);
2413       END IF;
2414 
2415       SELECT assignment_number
2416       INTO   g_output_file_records(i).assignment_number
2417       FROM   per_all_assignments_f a
2418       WHERE  a.assignment_id = l_assignment(i)
2419         AND  a.effective_start_date =
2420                (SELECT MAX(b.effective_start_date)
2421                 FROM   per_all_assignments_f b
2422                 WHERE  b.assignment_id = a.assignment_id
2423                );
2424 
2425 
2426       l_proc_step := 80+(i/100000);
2427       IF g_debug THEN
2428         debug(l_proc_name,l_proc_step);
2429       END IF;
2430 
2431       IF l_FTE_processing_start_date IS NOT NULL
2432       THEN
2433 
2434       update_fte_for_assignment
2435         (p_assignment_id  => l_assignment(i)
2436         ,p_effective_date => l_FTE_processing_start_date
2437         );
2438 
2439       ELSE
2440         g_output_file_records(i).status := 'Processed(Warning)';
2441         g_output_file_records(i).message :=
2442          'This person has no assignment normal hours or '||
2443          'an extra details of service contract type at any point in time.';
2444       END IF;
2445 
2446       l_proc_step := 90+(i/100000);
2447       IF g_debug THEN
2448         debug(l_proc_name,l_proc_step);
2449       END IF;
2450 
2451       write_output_file_records;
2452 
2453       l_proc_step := 100+(i/100000);
2454       IF g_debug THEN
2455         debug(l_proc_name,l_proc_step);
2456       END IF;
2457 
2458       EXCEPTION
2459         WHEN OTHERS THEN
2460 
2461           clear_cache;
2462 
2463           IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
2464             debug_others(l_proc_name,l_proc_step);
2465             IF g_debug THEN
2466               debug('Leaving: '||l_proc_name,-999);
2467             END IF;
2468             g_output_file_records(g_output_file_records.LAST).status := 'Errored(Fatal)';
2469             g_output_file_records(g_output_file_records.LAST).message :=
2470               l_proc_name||'{'||
2471               fnd_number.number_to_canonical(l_proc_step)|| '}: '||
2472               SUBSTRB(SQLERRM, 1, 2000);
2473           ELSE
2474             g_output_file_records(g_output_file_records.LAST).status := 'Errored';
2475             g_output_file_records(g_output_file_records.LAST).message := SQLCODE||':'||SQLERRM;
2476           END IF;
2477 
2478           l_errored := l_errored + 1;
2479 
2480           IF l_errored = 1 THEN
2481 
2482           fnd_file.put_line
2483             (fnd_file.log
2484             ,RPAD('Employee Number',15,' ')||g_column_separator||RPAD('Error Message',255,' ')
2485             );
2486 
2487           fnd_file.put_line
2488             (fnd_file.log
2489             ,RPAD('-',15,'-')||g_column_separator||RPAD('-',255,'-')
2490             );
2491 
2492           END IF;
2493 
2494           fnd_file.put_line
2495             (fnd_file.log
2496             ,RPAD(NVL(g_output_file_records(g_output_file_records.LAST).employee_number
2497                      ,'Asg_Id:'||l_assignment(i)
2498                      )
2499                  ,15,' '
2500                  )||g_column_separator||
2501              RPAD(g_output_file_records(g_output_file_records.LAST).message,255,' ')
2502             );
2503 
2504           write_output_file_records;
2505           g_output_file_records.DELETE; -- do not include in clear cache
2506 
2507       END;
2508 
2509       l_processed := l_processed + 1;
2510       i := l_assignment.NEXT(i);
2511 
2512       IF g_debug THEN
2513         debug('NEXT i:'||i);
2514       END IF;
2515 
2516     END LOOP;
2517 
2518   DELETE FROM fnd_sessions WHERE session_id = USERENV('sessionid');
2519 
2520   ERRBUF := null;
2521   RETCODE:= 0;
2522 
2523   fnd_file.put_line
2524     (fnd_file.log
2525     ,'Number of Assignments Processed:'||l_processed
2526     );
2527 
2528   fnd_file.put_line
2529     (fnd_file.log
2530     ,'Number of Assignments Errored:'||l_errored
2531     );
2532 
2533 
2534   IF g_debug THEN
2535     debug_exit(l_proc_name);
2536   END IF;
2537 
2538 EXCEPTION
2539   WHEN OTHERS THEN
2540     clear_cache;
2541     IF SQLCODE <> hr_utility.HR_ERROR_NUMBER THEN
2542       debug_others(l_proc_name,l_proc_step);
2543       IF g_debug THEN
2544         debug('Leaving: '||l_proc_name,-999);
2545       END IF;
2546       fnd_message.raise_error;
2547     ELSE
2548       RAISE;
2549     END IF;
2550 END update_fte_for_assignment_set;
2551 
2552 END pqp_fte_utilities;