CLASS {{p}}piano_pricer DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. TYPES ty_piano_type TYPE c LENGTH 1. TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2. TYPES ty_reason TYPE c LENGTH 8. TYPES: BEGIN OF ty_charge, reason TYPE ty_reason, base_fee TYPE ty_amount, travel_fee TYPE ty_amount, extra_fee TYPE ty_amount, total_fee TYPE ty_amount, END OF ty_charge. CONSTANTS: BEGIN OF c_reason, ok TYPE ty_reason VALUE 'OK', unknown TYPE ty_reason VALUE 'UNKNOWN', distance TYPE ty_reason VALUE 'DISTANCE', pitch TYPE ty_reason VALUE 'PITCH', END OF c_reason. METHODS calculate IMPORTING iv_piano_type TYPE ty_piano_type iv_distance_km TYPE i iv_pitch_cents TYPE i RETURNING VALUE(rs_charge) TYPE ty_charge. PRIVATE SECTION. CONSTANTS c_standard_minutes TYPE i VALUE 45. METHODS rate_for IMPORTING iv_piano_type TYPE ty_piano_type RETURNING VALUE(rs_rate) TYPE {{p}}tune_rates=>ty_rate. METHODS calc_extra_fee IMPORTING iv_pitch_cents TYPE i is_rate TYPE {{p}}tune_rates=>ty_rate RETURNING VALUE(rv_fee) TYPE ty_amount. METHODS calc_travel_fee IMPORTING iv_distance_km TYPE i RETURNING VALUE(rv_fee) TYPE ty_amount. ENDCLASS. CLASS {{p}}piano_pricer IMPLEMENTATION. METHOD calculate. DATA(ls_rate) = rate_for( iv_piano_type ). IF ls_rate IS INITIAL. rs_charge = VALUE #( reason = c_reason-unknown ). RETURN. ENDIF. IF iv_distance_km < 0. rs_charge = VALUE #( reason = c_reason-distance ). RETURN. ENDIF. IF iv_pitch_cents < 0. rs_charge = VALUE #( reason = c_reason-pitch ). RETURN. ENDIF. rs_charge = VALUE #( reason = c_reason-ok base_fee = ls_rate-base_fee travel_fee = calc_travel_fee( iv_distance_km ) extra_fee = calc_extra_fee( iv_pitch_cents = iv_pitch_cents is_rate = ls_rate ) ). rs_charge-total_fee = rs_charge-base_fee + rs_charge-travel_fee + rs_charge-extra_fee. ENDMETHOD. METHOD rate_for. DATA(lo_rates) = NEW {{p}}tune_rates( ). DATA(lt_rate) = lo_rates->get_rates( ). READ TABLE lt_rate WITH KEY piano_type = iv_piano_type INTO rs_rate. ENDMETHOD. METHOD calc_extra_fee. DATA(lv_extra_minutes) = c_standard_minutes + iv_pitch_cents - is_rate-incl_minutes. IF lv_extra_minutes <= 0. RETURN. ENDIF. rv_fee = lv_extra_minutes * is_rate-minute_fee. ENDMETHOD. METHOD calc_travel_fee. DATA(lv_chargeable_km) = iv_distance_km - {{p}}tune_rates=>c_free_km. IF lv_chargeable_km <= 0. RETURN. ENDIF. rv_fee = lv_chargeable_km * {{p}}tune_rates=>c_km_fee. ENDMETHOD. ENDCLASS.