# 1. Goal Check if a vehicle may board a ferry crossing. A loading planner calls the check before it adds the vehicle to the loading list. The check reports the first reason that stops the loading. # 2. Open questions None. # 3. Context - The interface {{P}}IF_FERRY_REASON exists in package $TMP. It is active. - The interface has the type TY_REASON (CHAR 12) and the constant structure C_REASON with the components PLATE, CATEGORY, WEIGHT, SIZE, HAZARD, HEIGHT, WEIGHT_LIMIT and LENGTH_LIMIT. - A vehicle has a plate, a category, a weight, a length, a height and a hazard flag. # 4. Contract - Create the class {{P}}CX_FERRY_ERROR in package $TMP. - The class is public, final and inherits from CX_STATIC_CHECK. - The class has the public read-only attribute REASON of type {{P}}IF_FERRY_REASON=>TY_REASON. - The class has a public constructor with the importing parameter IV_REASON of type {{P}}IF_FERRY_REASON=>TY_REASON. The constructor stores IV_REASON in REASON. - Do not add other public components. - Create the class {{P}}FERRY_LOAD_CHECK in package $TMP. - The class is public, final and has a public constructor without parameters. - The class has the public type TY_VEHICLE with the components PLATE (type c length 10), CATEGORY (type c length 1), WEIGHT_KG (type i), LENGTH_CM (type i), HEIGHT_CM (type i) and HAZARD (type abap_bool). - The class has the public method CHECK_VEHICLE with the importing parameter IS_VEHICLE of type TY_VEHICLE and the addition RAISING {{P}}CX_FERRY_ERROR. - The class has the public method CHECK_LOADING with the importing parameters IS_VEHICLE of type TY_VEHICLE, IV_FREE_WEIGHT of type i, IV_FREE_LENGTH of type i and IV_MAX_HEIGHT of type i, and the addition RAISING {{P}}CX_FERRY_ERROR. - Do not add other public methods. # 5. Business rules CHECK_VEHICLE applies the rules 1 to 5 in this sequence. CHECK_LOADING first calls CHECK_VEHICLE and then applies the rules 6 to 8 in this sequence. The first rule that fails raises the exception {{P}}CX_FERRY_ERROR with the reason of the rule. 1. Plate: remove all spaces from the plate and convert the letters to upper case. If the result is empty or contains a character that is not a letter A to Z, a digit 0 to 9 or a hyphen, the reason is PLATE. 2. Category: the category must be C, V, T or B. Else the reason is CATEGORY. 3. Weight: the weight must be greater than 0. Else the reason is WEIGHT. 4. Size: the length and the height must both be greater than 0. Else the reason is SIZE. 5. Hazard: if the hazard flag is true and the category is not T, the reason is HAZARD. 6. Height: if the height of the vehicle is greater than IV_MAX_HEIGHT, the reason is HEIGHT. 7. Weight limit: if the weight of the vehicle is greater than IV_FREE_WEIGHT, the reason is WEIGHT_LIMIT. 8. Length limit: if the length of the vehicle is greater than IV_FREE_LENGTH, the reason is LENGTH_LIMIT. If no rule fails, 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_FERRY_REASON. # 7. Acceptance - The classes are active and have no syntax error. - The hidden tests pass. - Write your own ABAP Unit tests for {{P}}FERRY_LOAD_CHECK.