134 lines
4.3 KiB
ABAP
134 lines
4.3 KiB
ABAP
CLASS {{p}}towing_fee DEFINITION PUBLIC FINAL CREATE PUBLIC.
|
|
PUBLIC SECTION.
|
|
TYPES ty_status TYPE c LENGTH 8.
|
|
TYPES ty_amount TYPE i.
|
|
TYPES ty_class TYPE c LENGTH 1.
|
|
TYPES:
|
|
BEGIN OF ty_result,
|
|
status TYPE ty_status,
|
|
fee TYPE ty_amount,
|
|
END OF ty_result.
|
|
|
|
CONSTANTS:
|
|
BEGIN OF c_status,
|
|
ok TYPE ty_status VALUE 'OK',
|
|
bad_class TYPE ty_status VALUE 'CLASS',
|
|
bad_distance TYPE ty_status VALUE 'DISTANCE',
|
|
bad_hour TYPE ty_status VALUE 'HOUR',
|
|
END OF c_status.
|
|
|
|
METHODS calculate
|
|
IMPORTING iv_vehicle_class TYPE ty_class
|
|
iv_distance_km TYPE i
|
|
iv_hour TYPE i
|
|
iv_is_weekend TYPE abap_bool
|
|
RETURNING VALUE(rs_result) TYPE ty_result.
|
|
|
|
PRIVATE SECTION.
|
|
CONSTANTS:
|
|
c_base_small TYPE ty_amount VALUE 60,
|
|
c_base_medium TYPE ty_amount VALUE 90,
|
|
c_base_large TYPE ty_amount VALUE 140,
|
|
c_free_km TYPE i VALUE 10,
|
|
c_km_rate TYPE ty_amount VALUE 2,
|
|
c_night_percent TYPE i VALUE 25,
|
|
c_weekend_percent TYPE i VALUE 15,
|
|
c_minimum_fee TYPE ty_amount VALUE 80,
|
|
c_round_step TYPE ty_amount VALUE 5,
|
|
c_max_distance TYPE i VALUE 500.
|
|
|
|
METHODS validate
|
|
IMPORTING iv_vehicle_class TYPE ty_class
|
|
iv_distance_km TYPE i
|
|
iv_hour TYPE i
|
|
RETURNING VALUE(rv_status) TYPE ty_status.
|
|
METHODS base_fee
|
|
IMPORTING iv_vehicle_class TYPE ty_class
|
|
RETURNING VALUE(rv_fee) TYPE ty_amount.
|
|
METHODS distance_fee
|
|
IMPORTING iv_distance_km TYPE i
|
|
RETURNING VALUE(rv_fee) TYPE ty_amount.
|
|
METHODS is_night
|
|
IMPORTING iv_hour TYPE i
|
|
RETURNING VALUE(rv_night) TYPE abap_bool.
|
|
METHODS surcharge
|
|
IMPORTING iv_subtotal TYPE ty_amount
|
|
iv_percent TYPE i
|
|
RETURNING VALUE(rv_surcharge) TYPE ty_amount.
|
|
METHODS round_up
|
|
IMPORTING iv_amount TYPE ty_amount
|
|
RETURNING VALUE(rv_amount) TYPE ty_amount.
|
|
ENDCLASS.
|
|
|
|
|
|
CLASS {{p}}towing_fee IMPLEMENTATION.
|
|
METHOD calculate.
|
|
DATA(lv_status) = validate( iv_vehicle_class = iv_vehicle_class
|
|
iv_distance_km = iv_distance_km
|
|
iv_hour = iv_hour ).
|
|
IF lv_status <> c_status-ok.
|
|
rs_result = VALUE #( status = lv_status fee = 0 ).
|
|
RETURN.
|
|
ENDIF.
|
|
|
|
DATA(lv_subtotal) = base_fee( iv_vehicle_class ) + distance_fee( iv_distance_km ).
|
|
DATA(lv_total) = lv_subtotal.
|
|
IF is_night( iv_hour ) = abap_true.
|
|
lv_total = lv_total + surcharge( iv_subtotal = lv_subtotal
|
|
iv_percent = c_night_percent ).
|
|
ENDIF.
|
|
IF iv_is_weekend = abap_true.
|
|
lv_total = lv_total + surcharge( iv_subtotal = lv_subtotal
|
|
iv_percent = c_weekend_percent ).
|
|
ENDIF.
|
|
IF lv_total < c_minimum_fee.
|
|
lv_total = c_minimum_fee.
|
|
ENDIF.
|
|
rs_result = VALUE #( status = c_status-ok
|
|
fee = round_up( lv_total ) ).
|
|
ENDMETHOD.
|
|
|
|
METHOD validate.
|
|
IF iv_vehicle_class <> 'S' AND iv_vehicle_class <> 'M' AND iv_vehicle_class <> 'L'.
|
|
rv_status = c_status-bad_class.
|
|
ELSEIF iv_distance_km < 1 OR iv_distance_km > c_max_distance.
|
|
rv_status = c_status-bad_distance.
|
|
ELSEIF iv_hour < 0 AND iv_hour > 23.
|
|
rv_status = c_status-bad_hour.
|
|
ELSE.
|
|
rv_status = c_status-ok.
|
|
ENDIF.
|
|
ENDMETHOD.
|
|
|
|
METHOD base_fee.
|
|
CASE iv_vehicle_class.
|
|
WHEN 'S'.
|
|
rv_fee = c_base_small.
|
|
WHEN 'M'.
|
|
rv_fee = c_base_medium.
|
|
WHEN 'L'.
|
|
rv_fee = c_base_large.
|
|
ENDCASE.
|
|
ENDMETHOD.
|
|
|
|
METHOD distance_fee.
|
|
DATA(lv_chargeable_km) = iv_distance_km - c_free_km.
|
|
IF lv_chargeable_km < 0.
|
|
lv_chargeable_km = 0.
|
|
ENDIF.
|
|
rv_fee = lv_chargeable_km * c_km_rate.
|
|
ENDMETHOD.
|
|
|
|
METHOD is_night.
|
|
rv_night = xsdbool( iv_hour >= 22 OR iv_hour <= 5 ).
|
|
ENDMETHOD.
|
|
|
|
METHOD surcharge.
|
|
rv_surcharge = iv_subtotal * iv_percent DIV 100.
|
|
ENDMETHOD.
|
|
|
|
METHOD round_up.
|
|
rv_amount = ( ( iv_amount + c_round_step - 1 ) DIV c_round_step ) * c_round_step.
|
|
ENDMETHOD.
|
|
ENDCLASS.
|