CLASS {{p}}crane_hire_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES {{p}}if_crane_hire. PRIVATE SECTION. CONSTANTS: c_min_radius TYPE i VALUE 5, c_max_radius TYPE i VALUE 60, c_min_load TYPE i VALUE 500, c_permit_fee TYPE i VALUE 250, c_min_fee TYPE i VALUE 300, c_radius_rate TYPE i VALUE 15, c_load_rate TYPE i VALUE 5. TYPES: BEGIN OF ty_band, radius_max TYPE i, max_load TYPE i, END OF ty_band, tt_band TYPE STANDARD TABLE OF ty_band WITH EMPTY KEY. METHODS validate IMPORTING iv_radius_m TYPE i iv_load_kg TYPE i iv_ground TYPE string RETURNING VALUE(rv_reason) TYPE {{p}}if_crane_hire=>ty_reason. METHODS max_load IMPORTING iv_radius_m TYPE i RETURNING VALUE(rv_load) TYPE i. METHODS load_chart RETURNING VALUE(rt_band) TYPE tt_band. METHODS ground_factor IMPORTING iv_ground TYPE string RETURNING VALUE(rv_percent) TYPE i. METHODS normalize_ground IMPORTING iv_ground TYPE string RETURNING VALUE(rv_ground) TYPE string. METHODS apply_percent IMPORTING iv_value TYPE i iv_percent TYPE i RETURNING VALUE(rv_value) TYPE i. ENDCLASS. CLASS {{p}}crane_hire_calc IMPLEMENTATION. METHOD {{p}}if_crane_hire~hire. DATA(lv_reason) = validate( iv_radius_m = iv_radius_m iv_load_kg = iv_load_kg iv_ground = iv_ground ). IF lv_reason <> {{p}}if_crane_hire=>c_reason-ok. rs_result = VALUE #( reason = lv_reason fee = 0 ). RETURN. ENDIF. DATA(lv_base) = iv_radius_m * c_radius_rate + ( iv_load_kg DIV 100 ) * c_load_rate. DATA(lv_fee) = apply_percent( iv_value = lv_base iv_percent = ground_factor( iv_ground ) ). IF iv_permit = abap_true. lv_fee = lv_fee + c_permit_fee. ENDIF. IF lv_fee < c_min_fee. lv_fee = c_min_fee. ENDIF. rs_result = VALUE #( reason = {{p}}if_crane_hire=>c_reason-ok fee = lv_fee ). ENDMETHOD. METHOD validate. IF iv_radius_m < c_min_radius OR iv_radius_m > c_max_radius. rv_reason = {{p}}if_crane_hire=>c_reason-radius. RETURN. ENDIF. IF iv_load_kg < c_min_load. rv_reason = {{p}}if_crane_hire=>c_reason-load. RETURN. ENDIF. IF iv_load_kg > max_load( iv_radius_m ). rv_reason = {{p}}if_crane_hire=>c_reason-capacity. RETURN. ENDIF. IF ground_factor( iv_ground ) = 0. rv_reason = {{p}}if_crane_hire=>c_reason-ground. RETURN. ENDIF. rv_reason = {{p}}if_crane_hire=>c_reason-ok. ENDMETHOD. METHOD max_load. DATA(lt_band) = load_chart( ). LOOP AT lt_band INTO DATA(ls_band). IF iv_radius_m <= ls_band-radius_max. rv_load = ls_band-max_load. RETURN. ENDIF. ENDLOOP. ENDMETHOD. METHOD load_chart. rt_band = VALUE #( ( radius_max = 10 max_load = 12000 ) ( radius_max = 20 max_load = 8000 ) ( radius_max = 30 max_load = 5000 ) ( radius_max = 45 max_load = 3000 ) ( radius_max = 60 max_load = 1500 ) ). ENDMETHOD. METHOD ground_factor. CASE normalize_ground( iv_ground ). WHEN 'ROAD'. rv_percent = 100. WHEN 'GRAVEL'. rv_percent = 115. WHEN 'SOIL'. rv_percent = 135. ENDCASE. ENDMETHOD. METHOD normalize_ground. rv_ground = to_upper( condense( iv_ground ) ). ENDMETHOD. METHOD apply_percent. rv_value = ( iv_value * iv_percent + 50 ) DIV 100. ENDMETHOD. ENDCLASS.