CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES {{p}}if_freight_calc. PRIVATE SECTION. TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3. CONSTANTS: c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00', c_base_weight TYPE ty_quantity VALUE '1000.000', c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50', c_free_km TYPE i VALUE 100, c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00', c_step TYPE ty_quantity VALUE '100.000', c_volume_factor TYPE i VALUE 250, c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'. METHODS check_input IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason. METHODS chargeable_weight IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume RETURNING VALUE(rv_weight) TYPE ty_quantity. METHODS base_freight IMPORTING iv_weight_kg TYPE ty_quantity RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. METHODS distance_freight IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. METHODS fuel_freight IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount. METHODS started_steps IMPORTING iv_excess TYPE ty_quantity RETURNING VALUE(rv_steps) TYPE i. ENDCLASS. CLASS {{p}}freight_calc IMPLEMENTATION. METHOD {{p}}if_freight_calc~calculate. DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason. DATA lv_weight TYPE ty_quantity. DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount. CLEAR rs_result. lv_reason = check_input( iv_weight_kg = iv_weight_kg iv_volume_m3 = iv_volume_m3 iv_distance_km = iv_distance_km iv_fuel_index = iv_fuel_index ). IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok. rs_result-reason = lv_reason. RETURN. ENDIF. lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg iv_volume_m3 = iv_volume_m3 ). rs_result-chargeable_weight = lv_weight. rs_result-base = base_freight( lv_weight ). rs_result-distance = distance_freight( iv_distance_km ). lv_net = rs_result-base + rs_result-distance. rs_result-fuel = fuel_freight( iv_amount = lv_net iv_fuel_index = iv_fuel_index ). rs_result-total = rs_result-base + rs_result-distance + rs_result-fuel. rs_result-reason = {{p}}if_freight_calc=>c_reason-ok. ENDMETHOD. METHOD check_input. IF iv_weight_kg <= 0. rv_reason = {{p}}if_freight_calc=>c_reason-weight. ELSEIF iv_volume_m3 < 0. rv_reason = {{p}}if_freight_calc=>c_reason-volume. ELSEIF iv_distance_km <= 0. rv_reason = {{p}}if_freight_calc=>c_reason-distance. ELSEIF iv_fuel_index < 0 OR iv_fuel_index > 100. rv_reason = {{p}}if_freight_calc=>c_reason-fuel. ELSE. rv_reason = {{p}}if_freight_calc=>c_reason-ok. ENDIF. ENDMETHOD. METHOD chargeable_weight. DATA lv_volumetric TYPE ty_quantity. lv_volumetric = iv_volume_m3 * c_volume_factor. IF lv_volumetric > iv_weight_kg. rv_weight = lv_volumetric. ELSE. rv_weight = iv_weight_kg. ENDIF. ENDMETHOD. METHOD base_freight. DATA lv_excess TYPE ty_quantity. DATA lv_steps TYPE i. lv_excess = iv_weight_kg - c_base_weight. IF lv_excess <= 0. rv_amount = c_base_amount. ELSE. lv_steps = started_steps( lv_excess ). rv_amount = c_base_amount - lv_steps * c_weight_rate. ENDIF. ENDMETHOD. METHOD distance_freight. DATA lv_excess TYPE ty_quantity. DATA lv_steps TYPE i. lv_excess = iv_distance_km - c_free_km. IF lv_excess <= 0. rv_amount = 0. ELSE. lv_steps = started_steps( lv_excess ). rv_amount = lv_steps * c_km_rate. ENDIF. ENDMETHOD. METHOD fuel_freight. DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3. DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5. lv_scaled = iv_amount * iv_fuel_index. lv_fuel = lv_scaled * c_percent. rv_amount = lv_fuel. ENDMETHOD. METHOD started_steps. DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0. DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0. lv_excess_scaled = iv_excess * 1000. lv_step_scaled = c_step * 1000. rv_steps = lv_excess_scaled DIV lv_step_scaled. IF lv_excess_scaled MOD lv_step_scaled > 0. rv_steps = rv_steps + 1. ENDIF. ENDMETHOD. ENDCLASS.