# 1. Goal An exam office checks if a student may register for an exam. A registration program calls the check before it books the seat. The check reports each rejection as a class-based exception. # 2. Open questions None. # 3. Context - The interface {{P}}IF_EXAM_REQUEST exists in package $TMP. It is active. - The interface has the public type TY_REQUEST. The components are: STUDENT_ID (STRING), ENROLLED (ABAP_BOOL), PREREQ_PASSED (ABAP_BOOL), PREREQ_ID (STRING), ATTEMPTS (I), REG_DATE (D). - An exam has a maximum number of attempts and a registration deadline. The caller reads both values from the exam master data. - A prerequisite is another exam. PREREQ_ID is the id of that exam. # 4. Contract Create these classes in package $TMP. {{P}}EXAM_CHECK - The class is public and final. It has a public constructor. - Constructor: IMPORTING iv_max_attempts TYPE i, iv_deadline TYPE d. - Method CHECK: IMPORTING is_request TYPE {{P}}IF_EXAM_REQUEST=>TY_REQUEST RAISING {{P}}CX_NOT_ENROLLED, {{P}}CX_PREREQ_MISSING, {{P}}CX_NO_ATTEMPT_LEFT, {{P}}CX_DEADLINE_PASSED. - Do not add other public methods. {{P}}CX_EXAM_ERROR - The class is public and abstract. It inherits from CX_STATIC_CHECK. - Public read-only attribute MV_STUDENT_ID TYPE string. - Public read-only attribute MV_TEXT TYPE string. {{P}}CX_NOT_ENROLLED - The class is public and final. It inherits from {{P}}CX_EXAM_ERROR. - MV_TEXT contains the text 'The student is not enrolled.' {{P}}CX_PREREQ_MISSING - The class is public and final. It inherits from {{P}}CX_EXAM_ERROR. - Public read-only attribute MV_PREREQ TYPE string. - MV_TEXT contains the text 'The prerequisite exam is not passed.' {{P}}CX_NO_ATTEMPT_LEFT - The class is public and final. It inherits from {{P}}CX_EXAM_ERROR. - Public read-only attribute MV_ATTEMPTS TYPE i. - MV_TEXT contains the text 'No attempt is left.' {{P}}CX_DEADLINE_PASSED - The class is public and final. It inherits from {{P}}CX_EXAM_ERROR. - Public read-only attribute MV_REG_DATE TYPE d. - MV_TEXT contains the text 'The registration deadline has passed.' # 5. Business rules The method CHECK applies the rules in this sequence. It raises the exception of the first rule that fails. 1. If IS_REQUEST-ENROLLED is abap_false, raise {{P}}CX_NOT_ENROLLED. MV_STUDENT_ID contains IS_REQUEST-STUDENT_ID. 2. If IS_REQUEST-PREREQ_PASSED is abap_false, raise {{P}}CX_PREREQ_MISSING. MV_STUDENT_ID contains IS_REQUEST-STUDENT_ID. MV_PREREQ contains IS_REQUEST-PREREQ_ID. 3. If IS_REQUEST-ATTEMPTS is greater than or equal to the maximum number of attempts, raise {{P}}CX_NO_ATTEMPT_LEFT. MV_STUDENT_ID contains IS_REQUEST-STUDENT_ID. MV_ATTEMPTS contains IS_REQUEST-ATTEMPTS. 4. If IS_REQUEST-REG_DATE is later than the registration deadline, raise {{P}}CX_DEADLINE_PASSED. MV_STUDENT_ID contains IS_REQUEST-STUDENT_ID. MV_REG_DATE contains IS_REQUEST-REG_DATE. 5. Else the registration is allowed. The method returns without an exception. # 6. Constraints - Release target: 8.16. - Coding standards: Clean ABAP. Method length below 40 statements. No global variables. No comment that restates the code. - Out of scope: do not change {{P}}IF_EXAM_REQUEST. # 7. Acceptance - All classes are active and have no syntax error. - The hidden tests pass. - The code has no ATC finding of priority 1 or 2. - Write your own ABAP Unit tests for the class {{P}}EXAM_CHECK.