DBA Data[Home] [Help]

PACKAGE BODY: APPS.IGS_HE_VERIFY_RETURN_PKG

Source


1 PACKAGE BODY igs_he_verify_return_pkg AS
2 /* $Header: IGSHE27B.pls 120.3 2006/06/21 03:00:01 jchin noship $*/
3 
4 
5    -- Global variables
6    g_he_submsn_return                     igs_he_submsn_return%ROWTYPE;
7    g_he_submsn_header                     igs_he_submsn_header%ROWTYPE;
8 
9 
10 
11   PROCEDURE check_associations(p_user_return_subclass IN VARCHAR2) IS
12   /******************************************************************
13    Created By      : Jonathan Baber
14    Date Created By : 23-Nov-05
15    Purpose         : Checks field associations for given extract.
16                      Makes sure every OSS code has corresponding HESA code.
17    Known limitations,enhancements,remarks:
18    Change History
19    Who       When         What
20   *******************************************************************/
21 
22 
23       TYPE cur_unmapped  IS REF CURSOR;
24       l_unmapped  cur_unmapped;
25 
26       -- Gets all distinct association codes used in given extract
27       -- ordered by the first field they appear in
28       CURSOR c_assoc IS
29       SELECT MIN(ass.field_number) field, ass.association_code, ass.oss_seq, ass.hesa_seq
30         FROM igs_he_usr_rtn_clas urc,
31              igs_he_usr_rt_cl_fld fld,
32              igs_he_sys_rt_cl_ass ass
33        WHERE urc.user_return_subclass = p_user_return_subclass
34          AND fld.user_return_subclass = urc.user_return_subclass
35          AND ass.system_return_class_type = urc.system_return_class_type
36          AND fld.field_number = ass.field_number
37          AND fld.include_flag = 'Y'
38          AND ass.oss_seq IS NOT NULL
39          AND ass.hesa_seq IS NOT NULL
40        GROUP BY ass.association_code, ass.oss_seq, ass.hesa_seq
41        ORDER BY field;
42 
43       -- Gets all the fields affected by a given association code
44       CURSOR c_fields(cp_association_code igs_he_sys_rt_cl_ass.association_code%TYPE) IS
45       SELECT ass.field_number
46         FROM igs_he_usr_rtn_clas urc,
47              igs_he_usr_rt_cl_fld fld,
48              igs_he_sys_rt_cl_ass ass
49        WHERE urc.user_return_subclass = p_user_return_subclass
50          AND fld.user_return_subclass = urc.user_return_subclass
51          AND ass.system_return_class_type = urc.system_return_class_type
52          AND fld.field_number = ass.field_number
53          AND fld.include_flag = 'Y'
54         AND ass.association_code = cp_association_code
55        ORDER BY ass.field_number;
56 
57       -- Get the association type of the code (either CODE, DIRECT or INDIRECT)
58       CURSOR c_assoc_type(cp_association_code igs_he_code_ass_val.association_code%TYPE,
59                           cp_sequence igs_he_code_ass_val.sequence%TYPE) IS
60       SELECT association_type, main_source, secondary_source, condition, display_title
61         FROM igs_he_code_ass_val
62        WHERE association_code = cp_association_code
63          AND sequence = cp_sequence;
64 
65       l_unmapped_value    igs_he_code_map_val.map2%TYPE;
66       l_assoc_type        c_assoc_type%ROWTYPE;
67       l_where_stmt        VARCHAR2(100);
68       l_stmt              VARCHAR2(400);
69       l_affected_fields   VARCHAR2(50);
70       l_count             NUMBER := 0;
71 
72   BEGIN
73 
74       -- Log Header
75       fnd_message.set_name('IGS','IGS_HE_VERIFY_CHECK_CODES');
76       fnd_message.set_token('DATE',TO_CHAR(SYSDATE,'DD-MON-YYYY HH24:MI:SS'));
77       fnd_file.put_line(fnd_file.log,fnd_message.get());
78 
79       -- Loop through all field associations of selected user defined return class
80       -- Need to determine every OSS value that doesn't have a corresponding HESA value
81       FOR l_assoc IN c_assoc LOOP
82 
83           l_stmt := NULL;
84           l_where_stmt := NULL;
85           l_assoc_type := NULL;
86 
87           -- Determine association type of the OSS mapping
88           OPEN c_assoc_type(l_assoc.association_code, l_assoc.oss_seq);
89           FETCH c_assoc_type INTO l_assoc_type;
90           CLOSE c_assoc_type;
91 
92 
93           -- Construct query
94           IF l_assoc_type.association_type = 'CODE' THEN
95               l_stmt := ' SELECT DISTINCT value' ||
96                         ' FROM igs_he_code_values ' ||
97                         ' WHERE value NOT IN ';
98           ELSE
99               l_stmt := ' SELECT DISTINCT ' || l_assoc_type.secondary_source ||
100                         ' FROM ' || l_assoc_type.main_source ||
101                         ' WHERE ' || l_assoc_type.secondary_source || ' NOT IN ';
102           END IF;
103 
104           -- Construct where clause to get all OSS values which are not mapped
105 	  l_stmt := l_stmt || ' (SELECT map' || l_assoc.oss_seq ||
106 	                      '  FROM igs_he_code_map_val ' ||
107                               '  WHERE association_code = :ASS_CODE)';
108 
109           -- Include any other where conditions
110           IF l_assoc_type.association_type = 'CODE' THEN
111               l_stmt := l_stmt || ' AND closed_ind = ''N'' AND code_type = :CODE_TYPE ';
112           ELSIF l_assoc_type.condition IS NOT NULL THEN
113               l_stmt := l_stmt || ' AND ' || l_assoc_type.condition;
114           END IF;
115 
116 
117           -- Open cursor with appropriate bind variables
118           IF l_assoc_type.association_type = 'CODE' THEN
119               OPEN l_unmapped FOR l_stmt USING l_assoc.association_code, l_assoc_type.main_source;
120           ELSE
121               OPEN l_unmapped FOR l_stmt USING l_assoc.association_code;
122           END IF;
123 
124           -- Find all unmapped OSS values
125           FETCH l_unmapped INTO l_unmapped_value;
126 
127           IF l_unmapped%FOUND THEN
128 
129               -- Get all fields affected by missing association code mapping
130               FOR l_fields IN c_fields(l_assoc.association_code) LOOP
131                   IF c_fields%ROWCOUNT = 1 THEN
132                       l_affected_fields := l_fields.field_number;
133                   ELSE
134                       IF LENGTH(l_affected_fields || ',' || l_fields.field_number) < 22 THEN
135                          l_affected_fields := l_affected_fields || ',' || l_fields.field_number;
136                       ELSE
137                          l_affected_fields := l_affected_fields || '...';
138                          EXIT;
139                       END IF;
140                   END IF;
141               END LOOP; -- affected fields
142 
143               -- Insert each unmapped value into temp table
144               LOOP
145 
146                   INSERT INTO IGS_HE_VERIFY_DATA_T (association_code, fields_affected, display_title, oss_value, creation_date, created_by, last_update_date, last_updated_by)
147                   VALUES (l_assoc.association_code, l_affected_fields, l_assoc_type.display_title, l_unmapped_value, sysdate, -1, sysdate, -1);
148 
149                   --Increment Counter
150                   l_count := l_count + 1;
151 
152                   FETCH l_unmapped INTO l_unmapped_value;
153                   EXIT WHEN l_unmapped%NOTFOUND;
154 
155               END LOOP;
156 
157           END IF; -- unmapped found
158 
159           CLOSE l_unmapped;
160 
161       END LOOP; -- association codes
162 
163       -- Log Summary
164       fnd_message.set_name('IGS','IGS_HE_VERIFY_MISS_CODES');
165       fnd_message.set_token('MISSING',l_count);
166       fnd_file.put_line(fnd_file.log,fnd_message.get());
167 
168       EXCEPTION
169        WHEN OTHERS THEN
170 
171           IF l_unmapped%ISOPEN THEN
172               CLOSE l_unmapped;
173           END IF;
174 
175           IF c_assoc%ISOPEN THEN
176               CLOSE c_assoc;
177           END IF;
178 
179           IF c_assoc_type%ISOPEN THEN
180               CLOSE c_assoc_type;
181           END IF;
182 
183           IF c_fields%ISOPEN THEN
184               CLOSE c_fields;
185           END IF;
186 
187           Fnd_Message.Set_Name('IGS','IGS_GE_UNHANDLED_EXP');
188           Fnd_Message.Set_Token('NAME','igs_he_verify_setup_pkg.check_associations - ' || SQLERRM);
189           fnd_file.put_line(fnd_file.log, fnd_message.get);
190           App_Exception.Raise_Exception;
191 
192   END check_associations;
193 
194 
195 
196   PROCEDURE check_HESA_data(p_submission_name          IN  VARCHAR2,
197                             p_user_return_subclass     IN  VARCHAR2,
198                             p_return_name              IN  VARCHAR2) IS
199   /******************************************************************
200    Created By      : Jonathan Baber
201    Date Created By : 23-Nov-05
202    Purpose         : Makes sure HESA records exist at the correct levels
203    Known limitations,enhancements,remarks:
204    Change History
205    Who       When         What
206    jchin     21-Jun-06    Bug 5213152 Modified c_get_yop cursor to
207                           conform with IGSHE9AB
208   *******************************************************************/
209 
210 
211       -- Cursor to determine if course has qual aim
212       CURSOR c_award_qualaim
213             (cp_course_cd      igs_ps_award.course_cd%TYPE,
214              cp_version_number igs_ps_award.version_number%TYPE) IS
215       SELECT DECODE(count(award_cd), 0, 'N', 'Y')
216         FROM igs_ps_award
217        WHERE course_cd = cp_course_cd
218          AND version_number = cp_version_number
219          AND closed_ind = 'N';
220 
221 
222       -- Get Student Program Attempt Records
223       -- Similar cursor as IGSHE9AB but with outer join to igs_he_st_spa_all
224       CURSOR c_get_spa (cp_awd_conf_start_dt    DATE,
225                         cp_awd_conf_end_dt      DATE)  IS
226       SELECT DISTINCT sca.person_id,
227               pe.party_number person_number,
228               sca.course_cd,
229               sca.version_number,
230               sca.location_cd ,
231               sca.attendance_mode,
232               sca.attendance_type,
233               sca.cal_type sca_cal_type,
234               sca.commencement_dt ,
235               sca.discontinued_dt,
236               sca.course_rqrmnts_complete_dt,
237               sca.course_attempt_status,
238               hspa.student_inst_number,
239               DECODE(hspa.hesa_st_spa_id, NULL, 'N', 'Y')      spa_flag,
240               DECODE(hspa.student_inst_number, NULL, 'N', 'Y') sin_flag,
241               DECODE(hspa.student_qual_aim, NULL, 'N', 'Y')    spa_qualaim_flag,
242               enawd.complete_ind,
243               enawd.conferral_date
244        FROM   igs_en_stdnt_ps_att_all sca,
245               igs_he_st_spa_all       hspa,
246               igs_he_st_prog_all      hprog,
247               igs_en_spa_awd_aim      enawd,
248               hz_parties              pe
249        WHERE  sca.person_id          = hspa.person_id (+)
250        AND    sca.course_cd          = hspa.course_cd (+)
251        AND    sca.course_cd          = hprog.course_cd (+)
252        AND    sca.version_number     = hprog.version_number (+)
253        AND    NVL(hprog.exclude_flag, 'N') = 'N'
254        AND    NVL(hspa.exclude_flag, 'N') = 'N'
255        AND    NVL(sca.future_dated_trans_flag,'N') IN ('N','S')
256        AND    sca.student_confirmed_ind = 'Y'
257        AND    hspa.person_id         = enawd.person_id(+)
258        AND    hspa.course_cd         = enawd.course_cd(+)
259        AND    sca.person_id          = pe.party_id
260        AND  ( ( sca.commencement_dt     <= g_he_submsn_header.enrolment_end_date
261                               AND ( sca.discontinued_dt  IS NULL OR  sca.discontinued_dt >= g_he_submsn_header.enrolment_start_date )
262                                     AND (sca.course_rqrmnts_complete_dt IS NULL OR
263                                          sca.course_rqrmnts_complete_dt >= g_he_submsn_header.enrolment_start_date
264                                         )
265               )
266               OR -- Added for HE309
267                  -- check whether award conferral dates are defined first at program level
268                  -- or program type level, otherwise hesa submission reporting periods
269                 enawd.complete_ind  = 'Y' AND
270                      (enawd.conferral_date BETWEEN cp_awd_conf_start_dt AND cp_awd_conf_end_dt)
271             )
272       ORDER BY sca.person_id, hspa.student_inst_number, discontinued_dt DESC,
273            course_rqrmnts_complete_dt DESC,  sca.commencement_dt DESC ;
274 
275 
276       -- Get SUSA Records
277       -- Similar cursor as IGSHE9AB but with outer join to igs_he_en_susa
278       CURSOR c_get_yop (cp_person_id            igs_he_st_spa.person_id%TYPE,
279                         cp_course_cd            igs_he_st_spa.course_cd%TYPE,
280                         cp_enrl_start_dt        DATE,
281                         cp_enrl_end_dt          DATE,
282                         cp_awd_conf_start_dt    DATE,
283                         cp_awd_conf_end_dt      DATE) IS
284       SELECT DISTINCT
285              susa.unit_set_cd,
286              susa.us_version_number,
287              DECODE(husa.hesa_en_susa_id, NULL, 'N','Y')     susa_flag
288         FROM igs_as_su_setatmpt  susa,
289              igs_he_en_susa      husa,
290              igs_en_unit_set     us,
291              igs_en_unit_set_cat susc,
292              igs_en_spa_awd_aim enawd,
293              igs_en_stdnt_ps_att_all sca
294        WHERE susa.person_id = sca.person_id
295          AND susa.course_cd = sca.course_cd
296          AND sca.person_id           = enawd.person_id(+)
297          AND sca.course_cd           = enawd.course_cd(+)
298          AND susa.unit_set_cd        = husa.unit_set_cd(+)
299          AND susa.us_version_number  = husa.us_version_number(+)
300          AND susa.person_id          = husa.person_id(+)
301          AND susa.course_cd          = husa.course_cd(+)
302          AND susa.sequence_number    = husa.sequence_number(+)
303          AND susa.unit_set_cd        = us.unit_set_cd
304          AND susa.us_version_number  = us.version_number
305          AND us.unit_set_cat         = susc.unit_set_cat
306          AND susa.person_id          = cp_person_id
307          AND susa.course_cd          = cp_course_cd
308          AND susc.s_unit_set_cat     = 'PRENRL_YR'
309          -- the program attempt is overlapping with the submmission period and the yop is also overlapping with the submission period
310          AND  ( ( sca.commencement_dt <= cp_enrl_end_dt AND
311                    (sca.discontinued_dt  IS NULL OR  sca.discontinued_dt   >= cp_enrl_start_dt ) AND
312                    (sca.course_rqrmnts_complete_dt IS NULL OR  sca.course_rqrmnts_complete_dt >= cp_enrl_start_dt ) AND
313                     susa.selection_dt <= cp_enrl_end_dt AND
314                    (susa.end_dt  IS NULL OR susa.end_dt   >= cp_enrl_start_dt )  AND
315                    (susa.rqrmnts_complete_dt IS NULL OR susa.rqrmnts_complete_dt >= cp_enrl_start_dt)
316                 )
317                  OR
318                  -- jchin bug 5213152
319                 -- the program attempt is completed before the submmission period start and award is conferred in the submission period and
320                 -- the yop is completed before the award conferral date
321                 ( susa.rqrmnts_complete_dt < cp_enrl_start_dt  AND
322                   sca.course_rqrmnts_complete_dt <= cp_enrl_end_dt  AND
323                   enawd.complete_ind = 'Y' AND
324                   enawd.conferral_date BETWEEN cp_awd_conf_start_dt AND cp_awd_conf_end_dt
325                 )
326               ) ;
327 
328       -- Does program have associated HESA record?
329       CURSOR c_get_prog(cp_course_cd      igs_he_st_prog_all.course_cd%TYPE,
330                         cp_version_number igs_he_st_prog_all.version_number%TYPE) IS
331       SELECT DECODE(count(course_cd), 0, 'N', 'Y') prog_flag
332         FROM igs_he_st_prog_all
333        WHERE course_cd = cp_course_cd
334          AND version_number = cp_version_number;
335 
336 
337       -- Does POOUS have associated HESA record?
338       CURSOR c_get_poous(cp_crv_version_number igs_he_poous_all.crv_version_number%TYPE,
339                          cp_course_cd          igs_he_poous_all.course_cd%TYPE,
340                          cp_cal_type           igs_he_poous_all.cal_type%TYPE,
341                          cp_location_cd        igs_he_poous_all.location_cd%TYPE,
342                          cp_attendance_mode    igs_he_poous_all.attendance_mode%TYPE,
343                          cp_attendance_type    igs_he_poous_all.attendance_type%TYPE,
344                          cp_unit_set_cd        igs_he_poous_all.unit_set_cd%TYPE,
345                          cp_us_version_number  igs_he_poous_all.us_version_number%TYPE) IS
346       SELECT DECODE(count(crv_version_number), 0, 'N', 'Y') poous_flag
347         FROM igs_he_poous_all
348        WHERE crv_version_number = cp_crv_version_number
349          AND course_cd = cp_course_cd
350          AND cal_type = cp_cal_type
351          AND location_cd = cp_location_cd
352          AND attendance_mode = cp_attendance_mode
353          AND attendance_type = cp_attendance_type
354          AND unit_set_cd = cp_unit_set_cd
355          AND us_version_number = cp_us_version_number;
356 
357       -- Determines course type
358       CURSOR c_prog_type (cp_course_cd      igs_ps_ver_all.course_cd%TYPE,
359                           cp_version_number igs_ps_ver_all.version_number%TYPE) IS
360       SELECT course_type
361         FROM igs_ps_ver_all
362        WHERE course_cd = cp_course_cd
363          AND version_number = cp_version_number;
364 
365       -- Alternate ID Cursor
366       CURSOR c_alternate_id (p_person_id      igs_pe_person.person_id%TYPE,
367                              cp_enrl_start_dt igs_he_submsn_header.enrolment_start_date%TYPE,
368                              cp_enrl_end_dt   igs_he_submsn_header.enrolment_end_date%TYPE) IS
369       SELECT api_person_id,person_id_type, LENGTH(api_person_id) api_length
370         FROM igs_pe_alt_pers_id
371        WHERE pe_person_id   = p_person_id
372          AND person_id_type IN ('HUSID', 'UCASID', 'GTTRID', 'NMASID', 'SWASID')
373          AND Start_Dt <= cp_enrl_end_dt
374          AND (End_Dt IS NULL OR End_Dt >= cp_enrl_start_dt )
375          AND (End_Dt IS NULL OR Start_Dt <> End_Dt)
376        ORDER BY person_id_type, Start_Dt DESC ;
377 
378       -- Unit Attempt enrollment
379       -- returns a row if a SPA has any unit attempts with a status of ENROLLED, COMPLETED, DISCONTIN
380       -- or DUPLICATE where the unit attempt enrollment date is less than or equal to the reporting
381       -- period end date.
382       CURSOR c_enr_su (p_person_id          igs_en_stdnt_ps_att_all.person_id%TYPE,
383                        p_course_cd          igs_en_stdnt_ps_att_all.course_cd%TYPE,
384                        p_enrolment_end_date igs_he_submsn_header.enrolment_end_date%TYPE)  IS
385       SELECT 'X'
386         FROM igs_en_su_attempt_all
387        WHERE person_id = p_person_id
388          AND course_cd = p_course_cd
389          AND unit_attempt_status IN ('ENROLLED', 'COMPLETED','DISCONTIN','DUPLICATE')
390          AND enrolled_dt <= p_enrolment_end_date;
391 
392 
393 
394       l_enrolled_su                          c_enr_su%ROWTYPE ;
395       l_prog_type                            igs_ps_ver_all.course_type%TYPE;
396       l_prev_pid_type                        igs_pe_alt_pers_id.person_id_type%TYPE := 'X' ;
397       l_api_person_id                        igs_pe_alt_pers_id.api_person_id%TYPE;
398       l_id                                   NUMBER;
399       l_awd_table                            igs_he_extract_fields_pkg.awd_table;
400       l_prog_rec_flag                        BOOLEAN := FALSE;
401       l_prog_type_rec_flag                   BOOLEAN := FALSE;
402       l_awd_conf_start_dt                    igs_he_submsn_awd.award_start_date%TYPE;
403       l_awd_conf_end_dt                      igs_he_submsn_awd.award_end_date%TYPE;
404       l_prev_person_id                       NUMBER := -1;
405       l_prev_student_inst_number             VARCHAR2(100) := '-1';
406       l_valid                                BOOLEAN;
407       l_verify_data                          igs_he_verify_data_t%ROWTYPE := NULL;
408       l_count                                NUMBER;
409 
410 
411 
412   BEGIN
413 
414       -- Log Header
415       fnd_message.set_name('IGS','IGS_HE_VERIFY_CHECK_HESA');
416       fnd_message.set_token('DATE',TO_CHAR(SYSDATE,'DD-MON-YYYY HH24:MI:SS'));
417       fnd_file.put_line(fnd_file.log,fnd_message.get());
418 
419       -- Get award conferral dates (to be used in c_get_spa)
420       igs_he_extract_fields_pkg.get_awd_dtls( p_submission_name, l_awd_table, l_prog_rec_flag, l_prog_type_rec_flag);
421       igs_he_extract_fields_pkg.get_min_max_awd_dates( p_submission_name, g_he_submsn_header.enrolment_start_date, g_he_submsn_header.enrolment_end_date, l_awd_conf_start_dt, l_awd_conf_end_dt);
422 
423       -- Examine each spa record for eligibility
424       FOR l_std_inst IN c_get_spa(l_awd_conf_start_dt, l_awd_conf_end_dt) LOOP
425 
426           IF (l_std_inst.person_id <> l_prev_person_id) OR (l_std_inst.student_inst_number <> l_prev_student_inst_number) THEN
427 
428 
429               l_verify_data := NULL;
430 
431               l_verify_data.person_id           := l_std_inst.person_id;
432               l_verify_data.course_cd           := l_std_inst.course_cd;
433               l_verify_data.crv_version_number  := l_std_inst.version_number;
434               l_verify_data.cal_type           	:= l_std_inst.sca_cal_type;
435               l_verify_data.location_cd		:= l_std_inst.location_cd;
436               l_verify_data.attendance_mode	:= l_std_inst.attendance_mode;
437               l_verify_data.attendance_type	:= l_std_inst.attendance_type;
438 
439 
440               /********* Basic Validation  *********/
441               -- similar to IGSHE9AB, but without 'Define Extract Criteria'
442               -- parameter validation
443 
444               l_valid := TRUE;
445 
446 
447               -- Award conferral dates
448               IF l_valid THEN
449 
450                   l_awd_conf_start_dt := g_he_submsn_header.enrolment_start_date;
451                   l_awd_conf_end_dt   := g_he_submsn_header.enrolment_end_date;
452 
453                   IF NOT ( l_std_inst.commencement_dt <= g_he_submsn_header.enrolment_end_date
454                      AND ( l_std_inst.discontinued_dt  IS NULL OR  l_std_inst.discontinued_dt >= g_he_submsn_header.enrolment_start_date )
455                      AND (l_std_inst.course_rqrmnts_complete_dt IS NULL OR  l_std_inst.course_rqrmnts_complete_dt >= g_he_submsn_header.enrolment_start_date)
456                      ) THEN
457 
458                       -- If student has a conferral date
459                       IF l_std_inst.complete_ind = 'Y' AND l_std_inst.conferral_date IS NOT NULL THEN
460 
461                           IF l_prog_type_rec_flag = TRUE
462                           THEN
463 
464                               -- If there are award conferral dates specified at the program type
465                               -- level only, then check if any relate to this particular student program attempt
466                               OPEN c_prog_type(l_std_inst.course_cd, l_std_inst.version_number);
467                               FETCH c_prog_type INTO l_prog_type;
468                               CLOSE c_prog_type;
469 
470 
471                               igs_he_extract_fields_pkg.get_awd_conferral_dates(l_awd_table,
472                                                                                 p_submission_name,
473                                                                                 l_prog_rec_flag,
474                                                                                 l_prog_type_rec_flag,
475                                                                                 l_std_inst.course_cd,
476                                                                                 l_prog_type,
477                                                                                 g_he_submsn_header.enrolment_start_date,
478                                                                                 g_he_submsn_header.enrolment_end_date,
479                                                                                 l_awd_conf_start_dt,
480                                                                                 l_awd_conf_end_dt);
481 
482                           ELSE
483 
484                               -- If there are award conferral dates specified at the program level only,
485                               -- then check if any relate to this particular student program attempt
486                               igs_he_extract_fields_pkg.get_awd_conferral_dates(l_awd_table,
487                                                                                 p_submission_name,
488                                                                                 l_prog_rec_flag,
489                                                                                 l_prog_type_rec_flag,
490                                                                                 l_std_inst.course_cd,
491                                                                                 NULL,
492                                                                                 g_he_submsn_header.enrolment_start_date,
493                                                                                 g_he_submsn_header.enrolment_end_date,
494                                                                                 l_awd_conf_start_dt,
495                                                                                 l_awd_conf_end_dt);
496 
497                           END IF;  --  l_prog_type_rec_flag
498 
499                           IF NOT l_std_inst.conferral_date BETWEEN l_awd_conf_start_dt AND l_awd_conf_end_dt THEN
500                               l_valid := FALSE;
501                           END IF;
502 
503                       END IF;
504 
505                   END IF;
506 
507               END IF; -- Award conferral dates
508 
509 
510               -- Alternate ID Check
511               IF l_valid THEN
512 
513                   l_prev_pid_type := 'X' ;
514                   --TO check that the alternate person id's if present for the person is number (i.e it does not contains non-numeric character)
515                   FOR alternate_id_rec IN c_alternate_id( l_std_inst.person_id,
516                                                           g_he_submsn_header.enrolment_start_date,
517                                                           g_he_submsn_header.enrolment_end_date) LOOP
518 
519                       IF (alternate_id_rec.person_id_type <> l_prev_pid_type) THEN
520 
521                             l_prev_pid_type := alternate_id_rec.person_id_type;
522                             BEGIN
523 
524                               l_id := NULL;
525                               l_api_person_id := NULL ;
526                               l_api_person_id := alternate_id_rec.api_person_id;
527                               IF l_api_person_id IS NOT NULL THEN
528                                  l_id := TO_NUMBER(l_api_person_id);
529                               END IF;
530 
531                             EXCEPTION
532                               WHEN value_error THEN
533 
534                                 -- In case the alternate person id contains non-numeric characters
535                                 -- exclude this record from further processing
536                                 l_valid := FALSE ;
537                             END;
538 
539                             IF alternate_id_rec.person_id_type <> 'HUSID' AND alternate_id_rec.api_length > 8 THEN
540                                 -- HUSID has more than 8 characters so exclude this record
541                                 l_valid := FALSE ;
542                             END IF;
543 
544                         END IF; -- validate only latest Person id type record of each type
545 
546                   END LOOP;
547 
548               END IF; -- Alternate ID Check
549 
550 
551               -- Check SPA is enrolled
552               IF l_valid THEN
553                   -- if the current SPA is not enrolled, check associated unit attempts
554                   IF NOT l_std_inst.course_attempt_status = 'ENROLLED' THEN
555                       l_enrolled_su := NULL;
556                       OPEN c_enr_su(l_std_inst.person_id,
557                                     l_std_inst.course_cd,
558                                     g_he_submsn_header.enrolment_end_date) ;
559                       FETCH c_enr_su INTO l_enrolled_su ;
560                       IF c_enr_su%NOTFOUND THEN
561                           l_valid := FALSE;
562                       END IF;
563                       CLOSE c_enr_su;
564                 END IF;
565               END IF;  -- SPA is enrolled
566 
567 
568               -- Check offset days
569               IF l_valid THEN
570 
571                   IF g_he_submsn_header.offset_days IS NOT NULL
572                   THEN
573                       IF g_he_submsn_header.apply_to_atmpt_st_dt = 'Y'
574                         AND l_std_inst.discontinued_dt  < (l_std_inst.commencement_dt + g_he_submsn_header.offset_days)
575                       THEN
576                           -- Exclude this record
577                           l_valid := FALSE;
578 
579                       END IF;
580                   END IF;
581 
582               END IF; -- Offset days
583 
584 
585               /*********  Check SUSA Details *********/
586               IF l_valid THEN
587                   OPEN c_get_yop(l_verify_data.person_id, l_verify_data.course_cd, g_he_submsn_header.enrolment_start_date, g_he_submsn_header.enrolment_end_date, l_awd_conf_start_dt, l_awd_conf_end_dt);
588                   FETCH c_get_yop INTO l_verify_data.unit_set_cd,
589                                        l_verify_data.us_version_number,
590                                        l_verify_data.susa_flag;
591 
592                   -- If there is no SUSA record at all, then this SPA is invalid
593                   IF c_get_yop%NOTFOUND THEN
594                       l_valid := FALSE;
595                   END IF;
596 
597                   CLOSE c_get_yop;
598 
599               END IF;
600 
601 
602 
603               IF l_valid THEN
604                   -- If this is a module return this is as far as we need to go for the students.
605                   -- We assume all these students *could* be in the return so we insert them into temp table
606                   IF SUBSTR(g_he_submsn_return.record_id,4,2) = '13' THEN
607 
608                       INSERT INTO IGS_HE_VERIFY_DATA_T(person_id,  creation_date, created_by, last_update_date, last_updated_by)
609                         VALUES (l_std_inst.person_id, sysdate, 1, sysdate, 1);
610 
611                   ELSE
612 
613                       -- If this is a student or combined return, we now need to check existence of HESA records...
614 
615 
616                       /********* Check SPA Details *********/
617                       l_verify_data.spa_flag      := l_std_inst.spa_flag;
618                       l_verify_data.qualaim_flag  := l_std_inst.spa_qualaim_flag;
619                       l_verify_data.sin_flag      := l_std_inst.sin_flag;
620 
621                       -- If spa_qualaim = 'N' at this point, check at the award level
622                       IF l_std_inst.spa_qualaim_flag = 'N' THEN
623                           OPEN c_award_qualaim(l_std_inst.course_cd, l_std_inst.version_number);
624                           FETCH c_award_qualaim INTO l_verify_data.qualaim_flag;
625                           CLOSE c_award_qualaim;
626                       END IF;
627 
628                       /********* Check POOUS Details *********/
629                       OPEN c_get_poous(l_verify_data.crv_version_number, l_verify_data.course_cd, l_verify_data.cal_type,
630                                        l_verify_data.location_cd, l_verify_data.attendance_mode, l_verify_data.attendance_type,
631                       		       l_verify_data.unit_set_cd, l_verify_data.us_version_number);
632                       FETCH c_get_poous INTO l_verify_data.poous_flag;
633                       CLOSE c_get_poous;
634 
635 
636                       /********* Check Program Details *********/
637                       OPEN c_get_prog( l_verify_data.course_cd, l_verify_data.crv_version_number);
638                       FETCH c_get_prog INTO l_verify_data.prog_flag;
639                       CLOSE c_get_prog;
640 
641                       -- Insert complete record into temp table
642                       INSERT INTO IGS_HE_VERIFY_DATA_T
643                          (person_id,
644                           course_cd,
645                           crv_version_number,
646                           cal_type,
647 			  location_cd,
648 			  attendance_mode,
649                           attendance_type,
650                           unit_set_cd,
651                           us_version_number,
652                           spa_flag,
653                           qualaim_flag,
654                           sin_flag,
655                           susa_flag,
656                           poous_flag,
657                           prog_flag,
658                           creation_date,
659                           created_by,
660                           last_update_date,
661                           last_updated_by)
662                        VALUES
663                          (l_verify_data.person_id,
664                           l_verify_data.course_cd,
665                           l_verify_data.crv_version_number,
666                           l_verify_data.cal_type,
667                           l_verify_data.location_cd,
668                           l_verify_data.attendance_mode,
669                           l_verify_data.attendance_type,
670                           l_verify_data.unit_set_cd,
671                           l_verify_data.us_version_number,
672                           l_verify_data.spa_flag,
673                           l_verify_data.qualaim_flag,
674                           l_verify_data.sin_flag,
675                           l_verify_data.susa_flag,
676                           l_verify_data.poous_flag,
677                           l_verify_data.prog_flag,
678                           sysdate,
679                           1,
680                           sysdate,
681                           1);
682 
683 
684                   END IF; -- MODULE or COMBINED/STUDENT
685 
686 	      END IF;
687 
688               -- Update previous Person ID and Student Instance Number
689               l_prev_person_id := l_std_inst.person_id;
690               l_prev_student_inst_number := l_std_inst.student_inst_number;
691 
692           END IF; -- End of Duplicate HSPA record Check
693 
694       END LOOP; -- For each Person ID and Student Instance Number
695 
696 
697 
698 
699       -- If this is a module return
700       IF SUBSTR(g_he_submsn_return.record_id,4,2) = '13' THEN
701 
702           /********* Check Module Details *********/
703           -- Insert all units started or completed within the enrolment period
704           -- by the students identified above. This is *similar* to the query used in
705           -- IGSHE9CB, however the student_inst_number is NOT used so query may select
706           -- more units than will appear in the return.
707           INSERT INTO IGS_HE_VERIFY_DATA_T
708             (unit_cd, u_version_number,  unit_flag, creation_date, created_by, last_update_date, last_updated_by)
709               (SELECT DISTINCT
710                     ua.unit_cd,
711                     ua.version_number,
712                     DECODE(hunt.hesa_st_unt_vs_id, NULL, 'N', 'Y') unit_flag, sysdate, 1, sysdate, 1
713                FROM igs_en_su_attempt_all ua,
714                     igs_he_verify_data_t t,
715                     igs_he_st_unt_vs_all hunt
716               WHERE t.person_id = ua.person_id
717                 AND ua.unit_cd = hunt.unit_cd (+)
718                 AND ua.version_number = hunt.version_number(+)
719                 AND ua.unit_attempt_status IN ('ENROLLED','DISCONTIN','COMPLETED')
720                 AND ua.ci_start_dt BETWEEN g_he_submsn_header.enrolment_start_date AND g_he_submsn_header.enrolment_end_date
721                 AND hunt.hesa_st_unt_vs_id IS NULL -- only get modules with no HESA details
722              UNION
723              SELECT DISTINCT
724                     ua.unit_cd,
725                     ua.version_number,
726                     DECODE(hunt.hesa_st_unt_vs_id, NULL, 'N', 'Y') unit_flag, sysdate, 1, sysdate, 1
727                FROM igs_en_su_attempt_all ua,
728                     igs_he_verify_data_t t,
729                     igs_he_st_unt_vs_all hunt,
730                     igs_as_su_stmptout_all uao
731               WHERE t.person_id = ua.person_id
732                 AND ua.unit_cd = hunt.unit_cd (+)
733                 AND ua.version_number = hunt.version_number(+)
734                 AND uao.person_id = ua.person_id
735                 AND uao.course_cd = ua.course_cd
736                 AND uao.uoo_id  = ua.uoo_id
737                 AND uao.finalised_outcome_ind  = 'Y'
738                 AND ua.unit_attempt_status IN ('ENROLLED','DISCONTIN','COMPLETED')
739                 AND uao.outcome_dt BETWEEN g_he_submsn_header.enrolment_start_date AND g_he_submsn_header.enrolment_end_date
740                 AND hunt.hesa_st_unt_vs_id IS NULL -- only get modules with no HESA details
741               );
742 
743           -- Delete the temporarily stored student records
744           DELETE FROM IGS_HE_VERIFY_DATA_T
745             WHERE person_id IS NOT NULL;
746 
747       END IF; -- Module Return
748 
749 
750       /********* Log Summary of Missing HESA Records *********/
751       IF SUBSTR(g_he_submsn_return.record_id,4,2) = '13' THEN
752 
753           -- Get count of missing Unit HESA Records
754           SELECT COUNT(DISTINCT unit_cd || u_version_number)
755            INTO l_count
756             FROM igs_he_verify_data_t
757            WHERE unit_flag = 'N';
758 
759           -- Log Summary of Module Results
760           fnd_message.set_name('IGS','IGS_HE_VERIFY_MISS_UNIT');
761           fnd_message.set_token('MISSING',l_count);
762           fnd_file.put_line(fnd_file.log,fnd_message.get());
763 
764       ELSE
765 
766 
767           -- Get count of missing Program HESA Records
768           SELECT COUNT(DISTINCT course_cd || crv_version_number)
769             INTO l_count
770             FROM igs_he_verify_data_t
771            WHERE prog_flag = 'N';
772 
773           -- Log Summary of Program Results
774           fnd_message.set_name('IGS','IGS_HE_VERIFY_MISS_PROG');
775           fnd_message.set_token('MISSING',l_count);
776           fnd_file.put_line(fnd_file.log,fnd_message.get());
777 
778           -- Get count of missing POOUS HESA Records
779           SELECT COUNT(DISTINCT course_cd || crv_version_number || cal_type || location_cd || attendance_mode || attendance_type || unit_set_cd || us_version_number)
780             INTO l_count
781             FROM igs_he_verify_data_t
782            WHERE poous_flag = 'N';
783 
784           -- Log Summary of POOUS Results
785           fnd_message.set_name('IGS','IGS_HE_VERIFY_MISS_POOUS');
786           fnd_message.set_token('MISSING',l_count);
787           fnd_file.put_line(fnd_file.log,fnd_message.get());
788 
789           -- Get count of missing or incomplete SPA HESA Records
790           SELECT COUNT(DISTINCT person_id || course_cd)
791             INTO l_count
792             FROM igs_he_verify_data_t
793            WHERE spa_flag = 'N' OR qualaim_flag = 'N' OR sin_flag = 'N';
794 
795           -- Log Summary of POOUS Results
796           fnd_message.set_name('IGS','IGS_HE_VERIFY_MISS_SPA');
797           fnd_message.set_token('MISSING',l_count);
798           fnd_file.put_line(fnd_file.log,fnd_message.get());
799 
800           -- Get count of missing or incomplete SPA HESA Records
801           SELECT COUNT(DISTINCT person_id || course_cd || unit_set_cd || us_version_number)
802             INTO l_count
803             FROM igs_he_verify_data_t
804            WHERE susa_flag = 'N';
805 
806           -- Log Summary of POOUS Results
807           fnd_message.set_name('IGS','IGS_HE_VERIFY_MISS_SUSA');
808           fnd_message.set_token('MISSING',l_count);
809           fnd_file.put_line(fnd_file.log,fnd_message.get());
810 
811       END IF;
812 
813        EXCEPTION
814         WHEN OTHERS THEN
815 
816            --Close any open cursors
817            IF c_award_qualaim%ISOPEN THEN
818                CLOSE c_award_qualaim;
819            END IF;
820 
821            IF c_get_spa%ISOPEN THEN
822                CLOSE c_get_spa;
823            END IF;
824 
825            IF c_get_yop%ISOPEN THEN
826                CLOSE c_get_yop;
827            END IF;
828 
829            IF c_get_prog%ISOPEN THEN
830                CLOSE c_get_prog;
831            END IF;
832 
833            IF c_get_poous%ISOPEN THEN
834                CLOSE c_get_poous;
835            END IF;
836 
837            IF c_prog_type%ISOPEN THEN
838                CLOSE c_prog_type;
839            END IF;
840 
841            IF c_alternate_id%ISOPEN THEN
842                CLOSE c_alternate_id;
843            END IF;
844 
845            IF c_enr_su%ISOPEN THEN
846                CLOSE c_enr_su;
847            END IF;
848 
849            Fnd_Message.Set_Name('IGS','IGS_GE_UNHANDLED_EXP');
850            Fnd_Message.Set_Token('NAME','igs_he_verify_setup_pkg.check_HESA_data - ' || SQLERRM);
851            fnd_file.put_line(fnd_file.log, fnd_message.get);
852            App_Exception.Raise_Exception;
853 
854   END check_HESA_data;
855 
856 
857 
858 
859 
860   PROCEDURE verify_return (errbuf                     OUT NOCOPY VARCHAR2,
861                            retcode                    OUT NOCOPY NUMBER,
862                            p_submission_name          IN  VARCHAR2,
863                            p_sub_rtn_id               IN  NUMBER,
864                            p_check_HESA_details       IN  VARCHAR2,
865                            p_check_field_associations IN  VARCHAR2) IS
866   /******************************************************************
867    Created By      : Jonathan Baber
868    Date Created By : 23-Nov-05
869    Purpose         : Main Function
870                      Calls check_HESA_data and check_associations
871                      depending on corresponding flags
872    Known limitations,enhancements,remarks:
873    Change History
874    Who       When         What
875    anwest    13-FEB-2006  Bug# 4950285 R12 Disable OSS Mandate
876   *******************************************************************/
877 
878       -- Get extract run details
879       CURSOR c_extract_dtls IS
880       SELECT rtn.submission_name,
881              rtn.user_return_subclass,
882              rtn.return_name,
883              rtn.record_id,
884              shd.enrolment_start_date,
885              shd.enrolment_end_date,
886              shd.offset_days,
887              NVL(shd.apply_to_atmpt_st_dt,'N') apply_to_atmpt_st_dt
888         FROM igs_he_submsn_header shd,
889              igs_he_submsn_return rtn
890        WHERE rtn.sub_rtn_id = p_sub_rtn_id
891          AND rtn.submission_name = shd.submission_name;
892 
893       l_request_id                     NUMBER;
894 
895   BEGIN
896 
897       --anwest 18-JAN-2006 Bug# 4950285 R12 Disable OSS Mandate
898       IGS_GE_GEN_003.SET_ORG_ID;
899 
900       -- Get extract details
901       -- Store in global variable
902       OPEN c_extract_dtls;
903       FETCH c_extract_dtls INTO g_he_submsn_return.submission_name,
904                                 g_he_submsn_return.user_return_subclass,
905                                 g_he_submsn_return.return_name,
906                                 g_he_submsn_return.record_id,
907                                 g_he_submsn_header.enrolment_start_date,
908                                 g_he_submsn_header.enrolment_end_date,
909                                 g_he_submsn_header.offset_days,
910                                 g_he_submsn_header.apply_to_atmpt_st_dt;
911       CLOSE c_extract_dtls;
912 
913 
914       -- Log Header
915       fnd_message.set_name('IGS','IGS_HE_PROC_SUBM');
916       fnd_message.set_token('SUBMISSION_NAME',g_he_submsn_return.submission_name);
917       fnd_message.set_token('USER_RETURN_SUBCLASS',g_he_submsn_return.user_return_subclass);
918       fnd_message.set_token('RETURN_NAME',g_he_submsn_return.return_name);
919       fnd_message.set_token('ENROLMENT_START_DATE',g_he_submsn_header.enrolment_start_date);
920       fnd_message.set_token('ENROLMENT_END_DATE',g_he_submsn_header.enrolment_end_date);
921       fnd_file.put_line(fnd_file.log,fnd_message.get());
922 
923 
924       -- Delete Temp Table
925       DELETE FROM IGS_HE_VERIFY_DATA_T;
926 
927       -- Check HESA details of COMBINED/STUDENT or MODULE return
928       IF p_check_HESA_details = 'Y'
929         AND SUBSTR(g_he_submsn_return.record_id,4,2) <> '18' THEN
930          check_HESA_data(g_he_submsn_return.submission_name, g_he_submsn_return.user_return_subclass, g_he_submsn_return.return_name);
931       END IF;
932 
933 
934       -- Check field associations of given extract
935       IF p_check_field_associations = 'Y' THEN
936           check_associations(g_he_submsn_return.user_return_subclass);
937       END IF;
938 
939 
940       COMMIT;
941 
942       -- Submit Report Log
943       fnd_message.set_name('IGS','IGS_HE_VERIFY_REPORT_SUB');
944       fnd_message.set_token('DATE',TO_CHAR(SYSDATE,'DD-MON-YYYY HH24:MI:SS'));
945       fnd_file.put_line(fnd_file.log,fnd_message.get());
946 
947 
948       -- Submit the Report
949       l_request_id := NULL ;
950       l_request_id := Fnd_Request.Submit_Request
951                           ( 'IGS',
952                             'IGSHES03',
953                             'Verify HESA Return Report',
954                             NULL,
955                             FALSE,
956                             g_he_submsn_return.submission_name,
957                             g_he_submsn_return.user_return_subclass,
958                             g_he_submsn_return.return_name,
959                             p_check_HESA_details,
960                             p_check_field_associations);
961 
962       EXCEPTION
963        WHEN OTHERS THEN
964 
965           --Close any open cursors
966           IF c_extract_dtls%ISOPEN THEN
967               CLOSE c_extract_dtls;
968           END IF;
969 
970           ROLLBACK;
971 
972           Fnd_Message.Set_Name('IGS','IGS_GE_UNHANDLED_EXP');
973           Fnd_Message.Set_Token('NAME','igs_he_verify_setup_pkg.verify_setup - ' ||SQLERRM);
974           errbuf := fnd_message.get;
975           fnd_file.put_line(fnd_file.log, errbuf);
976           retcode := 2;
977           App_Exception.Raise_Exception;
978 
979   END verify_return;
980 
981 
982 END igs_he_verify_return_pkg ;