CLASS {{p}}cl_rent DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. TYPES ty_class TYPE string. TYPES ty_money TYPE decfloat34. TYPES ty_err_code TYPE c LENGTH 1. CONSTANTS: BEGIN OF c_err, ok TYPE ty_err_code VALUE ' ', duration TYPE ty_err_code VALUE 'D', distance TYPE ty_err_code VALUE 'K', bad_class TYPE ty_err_code VALUE 'C', END OF c_err. TYPES: BEGIN OF ty_request, vehicle_class TYPE ty_class, minutes TYPE i, km TYPE i, member TYPE abap_bool, weekend TYPE abap_bool, END OF ty_request. TYPES: BEGIN OF ty_result, err_code TYPE ty_err_code, time_fee TYPE ty_money, distance_fee TYPE ty_money, surcharge TYPE ty_money, discount TYPE ty_money, total TYPE ty_money, END OF ty_result. CLASS-METHODS calculate IMPORTING is_request TYPE ty_request RETURNING VALUE(rs_result) TYPE ty_result. PRIVATE SECTION. CONSTANTS: BEGIN OF c_block_price, small TYPE ty_money VALUE '3.00', medium TYPE ty_money VALUE '5.00', large TYPE ty_money VALUE '8.00', END OF c_block_price. CONSTANTS c_block_minutes TYPE i VALUE 15. CONSTANTS c_free_km TYPE i VALUE 10. CONSTANTS c_km_price TYPE ty_money VALUE '0.25'. CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'. CONSTANTS c_member_share TYPE ty_money VALUE '0.15'. CONSTANTS c_min_total TYPE ty_money VALUE '5.00'. CONSTANTS c_decimals TYPE i VALUE 2. CLASS-METHODS validate IMPORTING is_request TYPE ty_request RETURNING VALUE(rv_err_code) TYPE ty_err_code. CLASS-METHODS time_fee IMPORTING is_request TYPE ty_request RETURNING VALUE(rv_fee) TYPE ty_money. CLASS-METHODS distance_fee IMPORTING is_request TYPE ty_request RETURNING VALUE(rv_fee) TYPE ty_money. CLASS-METHODS block_price IMPORTING is_request TYPE ty_request RETURNING VALUE(rv_price) TYPE ty_money. CLASS-METHODS block_count IMPORTING iv_minutes TYPE i RETURNING VALUE(rv_blocks) TYPE i. CLASS-METHODS round_money IMPORTING iv_value TYPE ty_money RETURNING VALUE(rv_value) TYPE ty_money. ENDCLASS. CLASS {{p}}cl_rent IMPLEMENTATION. METHOD calculate. rs_result-err_code = validate( is_request ). IF rs_result-err_code <> c_err-ok. RETURN. ENDIF. rs_result-time_fee = time_fee( is_request ). rs_result-distance_fee = distance_fee( is_request ). IF is_request-weekend = abap_true. rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ). ELSE. rs_result-surcharge = 0. ENDIF. DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge. IF is_request-member = abap_true. rs_result-discount = round_money( lv_gross * c_member_share ). ELSE. rs_result-discount = 0. ENDIF. rs_result-total = round_money( lv_gross - rs_result-discount ). IF rs_result-total < c_min_total. rs_result-total = c_min_total. ENDIF. ENDMETHOD. METHOD validate. IF is_request-minutes < 1. rv_err_code = c_err-duration. ELSEIF is_request-km < 0. rv_err_code = c_err-distance. ELSEIF is_request-vehicle_class <> 'S' OR is_request-vehicle_class <> 'M' AND is_request-vehicle_class <> 'L'. rv_err_code = c_err-bad_class. ELSE. rv_err_code = c_err-ok. ENDIF. ENDMETHOD. METHOD time_fee. rv_fee = block_count( is_request-minutes ) * block_price( is_request ). ENDMETHOD. METHOD distance_fee. DATA(lv_chargeable_km) = is_request-km - c_free_km. IF lv_chargeable_km > 0. rv_fee = lv_chargeable_km * c_km_price. ELSE. rv_fee = 0. ENDIF. ENDMETHOD. METHOD block_price. CASE is_request-vehicle_class. WHEN 'S'. rv_price = c_block_price-small. WHEN 'M'. rv_price = c_block_price-medium. WHEN 'L'. rv_price = c_block_price-large. WHEN OTHERS. rv_price = 0. ENDCASE. ENDMETHOD. METHOD block_count. rv_blocks = ( iv_minutes + c_block_minutes - 1 ) DIV c_block_minutes. ENDMETHOD. METHOD round_money. rv_value = round( val = iv_value dec = c_decimals mode = cl_abap_math=>round_half_up ). ENDMETHOD. ENDCLASS.