CLASS {{p}}cold_chain_check DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. TYPES: BEGIN OF ty_reading, offset_min TYPE i, temp_tenths TYPE i, END OF ty_reading, tt_readings TYPE STANDARD TABLE OF ty_reading WITH EMPTY KEY, BEGIN OF ty_config, min_tenths TYPE i, max_tenths TYPE i, min_duration TYPE i, max_gap TYPE i, END OF ty_config. METHODS constructor IMPORTING is_config TYPE ty_config. METHODS check IMPORTING it_readings TYPE tt_readings RETURNING VALUE(rv_mean) TYPE i RAISING {{p}}cx_cold_chain. PRIVATE SECTION. DATA ms_config TYPE ty_config. METHODS first_violation IMPORTING it_readings TYPE tt_readings RETURNING VALUE(rv_rule) TYPE string. METHODS check_structure IMPORTING it_readings TYPE tt_readings RETURNING VALUE(rv_rule) TYPE string. METHODS check_duration IMPORTING it_readings TYPE tt_readings RETURNING VALUE(rv_rule) TYPE string. METHODS check_gap IMPORTING it_readings TYPE tt_readings RETURNING VALUE(rv_rule) TYPE string. METHODS check_temperatures IMPORTING it_readings TYPE tt_readings RETURNING VALUE(rv_rule) TYPE string. METHODS mean_tenths IMPORTING it_readings TYPE tt_readings RETURNING VALUE(rv_mean) TYPE i. ENDCLASS. CLASS {{p}}cold_chain_check IMPLEMENTATION. METHOD constructor. ms_config = is_config. ENDMETHOD. METHOD check. DATA(lv_rule) = first_violation( it_readings ). IF lv_rule IS NOT INITIAL. RAISE EXCEPTION TYPE {{p}}cx_cold_chain EXPORTING iv_rule = lv_rule. ENDIF. rv_mean = mean_tenths( it_readings ). ENDMETHOD. METHOD first_violation. rv_rule = check_structure( it_readings ). IF rv_rule IS NOT INITIAL. RETURN. ENDIF. rv_rule = check_duration( it_readings ). IF rv_rule IS NOT INITIAL. RETURN. ENDIF. rv_rule = check_gap( it_readings ). IF rv_rule IS NOT INITIAL. RETURN. ENDIF. rv_rule = check_temperatures( it_readings ). ENDMETHOD. METHOD check_structure. IF lines( it_readings ) < 2. rv_rule = 'TOO_FEW'. RETURN. ENDIF. READ TABLE it_readings INDEX 1 INTO DATA(ls_first). IF ls_first-offset_min <> 0. rv_rule = 'NO_START'. RETURN. ENDIF. DATA(lv_previous) = ls_first-offset_min. LOOP AT it_readings FROM 2 INTO DATA(ls_reading). IF ls_reading-offset_min <= lv_previous. rv_rule = 'TIME_ORDER'. RETURN. ENDIF. lv_previous = ls_reading-offset_min. ENDLOOP. ENDMETHOD. METHOD check_duration. DATA lv_last TYPE i. LOOP AT it_readings INTO DATA(ls_reading). lv_last = ls_reading-offset_min. ENDLOOP. IF lv_last < ms_config-min_duration. rv_rule = 'TOO_SHORT'. ENDIF. ENDMETHOD. METHOD check_gap. DATA lv_previous TYPE i. LOOP AT it_readings INTO DATA(ls_reading). IF sy-tabix > 1 AND ls_reading-offset_min - lv_previous > ms_config-max_gap. rv_rule = 'GAP'. RETURN. ENDIF. lv_previous = ls_reading-offset_min. ENDLOOP. ENDMETHOD. METHOD check_temperatures. LOOP AT it_readings INTO DATA(ls_reading). IF ls_reading-temp_tenths > ms_config-max_tenths. rv_rule = 'TOO_HIGH'. RETURN. ENDIF. IF ls_reading-temp_tenths < ms_config-min_tenths. rv_rule = 'TOO_LOW'. RETURN. ENDIF. ENDLOOP. ENDMETHOD. METHOD mean_tenths. DATA lv_sum TYPE i. LOOP AT it_readings INTO DATA(ls_reading). lv_sum = lv_sum + ls_reading-temp_tenths. ENDLOOP. DATA(lv_count) = lines( it_readings ). IF lv_count = 0. rv_mean = 0. RETURN. ENDIF. DATA(lv_abs_sum) = lv_sum. IF lv_abs_sum < 0. lv_abs_sum = -1 / lv_abs_sum. ENDIF. rv_mean = lv_abs_sum DIV lv_count. IF lv_sum < 0. rv_mean = -1 * rv_mean. ENDIF. ENDMETHOD. ENDCLASS.