ADT fallback: Accept headers for FUNC; G0189 accepted; regen2 results

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aUaQeLnwbb1zTpN7kHeat
This commit is contained in:
Kral
2026-10-03 16:31:03 +02:00
parent 428b3565b2
commit 7510131a7d
335 changed files with 12047 additions and 5545 deletions

View File

@@ -0,0 +1,36 @@
{
"id": "G0122",
"pool": "eval",
"object_type": "FUNC",
"category": "C",
"attempts": [
{
"stage": "bundle",
"errors": [
"seed/t_path.tabl.abap: a table needs the annotation @AbapCatalog.tableCategory (for example #TRANSPARENT, #A)",
"seed/t_path.tabl.abap: a table needs the annotation @AbapCatalog.deliveryClass (for example #TRANSPARENT, #A)",
"seed/t_fee.tabl.abap: a table needs the annotation @AbapCatalog.tableCategory (for example #TRANSPARENT, #A)",
"seed/t_fee.tabl.abap: a table needs the annotation @AbapCatalog.deliveryClass (for example #TRANSPARENT, #A)"
],
"by_check": {
"static": 4
}
},
{
"stage": "validate",
"oracle": null,
"null": null
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 0,
"null": 0
}
],
"accepted": false
}

View File

@@ -1,302 +0,0 @@
CLASS {{p}}t31_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_stations TYPE STANDARD TABLE OF {{p}}station.
TYPES ty_moves TYPE STANDARD TABLE OF {{p}}move.
TYPES ty_id TYPE {{p}}station-station_id.
TYPES ty_name TYPE {{p}}station-station_name.
METHODS given
IMPORTING it_stations TYPE ty_stations
it_moves TYPE ty_moves.
METHODS rebalance
IMPORTING iv_dry_run TYPE abap_bool DEFAULT abap_false
EXPORTING ev_applied TYPE i
ev_rejected TYPE i.
METHODS bikes_of
IMPORTING iv_id TYPE ty_id
RETURNING VALUE(rv_bikes) TYPE i.
METHODS name_of
IMPORTING iv_id TYPE ty_id
RETURNING VALUE(rv_name) TYPE ty_name.
METHODS applies_one_move FOR TESTING.
METHODS applies_in_move_order FOR TESTING.
METHODS rejects_unknown_station FOR TESTING.
METHODS rejects_insufficient_bikes FOR TESTING.
METHODS rejects_full_target FOR TESTING.
METHODS rejects_non_positive_qty FOR TESTING.
METHODS rejects_same_station FOR TESTING.
METHODS counts_rejections FOR TESTING.
METHODS keeps_untouched_stations FOR TESTING.
METHODS dry_run_keeps_state FOR TESTING.
ENDCLASS.
CLASS {{p}}t31_hidden IMPLEMENTATION.
METHOD given.
DATA(lt_stations) = it_stations.
DATA(lt_moves) = it_moves.
LOOP AT lt_stations ASSIGNING FIELD-SYMBOL(<ls_station>).
<ls_station>-client = sy-mandt.
ENDLOOP.
LOOP AT lt_moves ASSIGNING FIELD-SYMBOL(<ls_move>).
<ls_move>-client = sy-mandt.
ENDLOOP.
DELETE FROM {{p}}station.
DELETE FROM {{p}}move.
INSERT {{p}}station FROM TABLE @lt_stations.
INSERT {{p}}move FROM TABLE @lt_moves.
ENDMETHOD.
METHOD rebalance.
CALL FUNCTION '{{P}}BIKE_REBALANCE'
EXPORTING
iv_dry_run = iv_dry_run
IMPORTING
ev_applied = ev_applied
ev_rejected = ev_rejected
EXCEPTIONS
OTHERS = 1.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD bikes_of.
SELECT SINGLE bikes FROM {{p}}station
INTO @rv_bikes
WHERE station_id = @iv_id.
ENDMETHOD.
METHOD name_of.
SELECT SINGLE station_name FROM {{p}}station
INTO @rv_name
WHERE station_id = @iv_id.
ENDMETHOD.
METHOD applies_one_move.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 6 )
( station_id = 'S002' station_name = 'Beta' capacity = 10 bikes = 1 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 4 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 2 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 5 ).
ENDMETHOD.
METHOD applies_in_move_order.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 5 )
( station_id = 'S002' station_name = 'Beta' capacity = 10 bikes = 0 )
( station_id = 'S003' station_name = 'Gamma' capacity = 10 bikes = 0 ) ).
lt_moves = VALUE #(
( move_no = 2 source_id = 'S001' target_id = 'S002' quantity = 5 )
( move_no = 1 source_id = 'S002' target_id = 'S003' quantity = 5 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 5 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S003' ) exp = 0 ).
ENDMETHOD.
METHOD rejects_unknown_station.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 6 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S009' target_id = 'S001' quantity = 2 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 6 ).
ENDMETHOD.
METHOD rejects_insufficient_bikes.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 2 )
( station_id = 'S002' station_name = 'Beta' capacity = 10 bikes = 0 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 5 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 2 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 0 ).
ENDMETHOD.
METHOD rejects_full_target.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 5 )
( station_id = 'S002' station_name = 'Beta' capacity = 4 bikes = 4 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 1 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 5 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 4 ).
ENDMETHOD.
METHOD rejects_non_positive_qty.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 5 )
( station_id = 'S002' station_name = 'Beta' capacity = 10 bikes = 0 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 0 )
( move_no = 2 source_id = 'S001' target_id = 'S002' quantity = -3 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 2 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 5 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 0 ).
ENDMETHOD.
METHOD rejects_same_station.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 5 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S001' quantity = 2 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 5 ).
ENDMETHOD.
METHOD counts_rejections.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 5 )
( station_id = 'S002' station_name = 'Beta' capacity = 10 bikes = 0 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 2 )
( move_no = 2 source_id = 'S001' target_id = 'S999' quantity = 1 )
( move_no = 3 source_id = 'S001' target_id = 'S002' quantity = 0 )
( move_no = 4 source_id = 'S001' target_id = 'S002' quantity = 100 )
( move_no = 5 source_id = 'S002' target_id = 'S001' quantity = 1 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 2 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 3 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 4 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 1 ).
ENDMETHOD.
METHOD keeps_untouched_stations.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 4 )
( station_id = 'S002' station_name = 'Beta' capacity = 10 bikes = 4 )
( station_id = 'S003' station_name = 'Gamma' capacity = 12 bikes = 7 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 1 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 3 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 5 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S003' ) exp = 7 ).
cl_abap_unit_assert=>assert_equals( act = name_of( 'S003' ) exp = CONV ty_name( 'Gamma' ) ).
ENDMETHOD.
METHOD dry_run_keeps_state.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 5 )
( station_id = 'S002' station_name = 'Beta' capacity = 10 bikes = 0 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 3 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( EXPORTING iv_dry_run = abap_true
IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 5 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 0 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,129 @@
CLASS {{p}}track_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_paths TYPE {{P}}TRACK_TYPES=>tt_path.
TYPES ty_fees TYPE {{P}}TRACK_TYPES=>tt_fee.
TYPES ty_km TYPE {{P}}TRACK_TYPES=>ty_km.
TYPES ty_money TYPE {{P}}TRACK_TYPES=>ty_money.
METHODS call_fm
IMPORTING it_paths TYPE ty_paths
EXPORTING et_fees TYPE ty_fees
ev_subrc TYPE sysubrc.
METHODS one_path_one_row FOR TESTING.
METHODS groups_and_sorts FOR TESTING.
METHODS night_surcharge FOR TESTING.
METHODS minimum_fee FOR TESTING.
METHODS rounds_up FOR TESTING.
METHODS invalid_distance FOR TESTING.
METHODS invalid_category FOR TESTING.
METHODS empty_input FOR TESTING.
ENDCLASS.
CLASS {{p}}track_hidden IMPLEMENTATION.
METHOD call_fm.
CALL FUNCTION '{{P}}TRACK_FEE'
EXPORTING
it_paths = it_paths
IMPORTING
et_fees = et_fees
EXCEPTIONS
invalid_distance = 1
invalid_category = 2
OTHERS = 3.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD one_path_one_row.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'IC' distance_km = '100.00' night_flag = '' ) ).
call_fm( EXPORTING it_paths = lt_paths
IMPORTING et_fees = DATA(lt_fees) ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_rc ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_fees ) ).
DATA(ls_fee) = lt_fees[ 1 ].
cl_abap_unit_assert=>assert_equals( exp = 'IC' act = ls_fee-train_cat ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_fee-path_count ).
cl_abap_unit_assert=>assert_equals( exp = CONV ty_km( '100.00' ) act = ls_fee-total_km ).
cl_abap_unit_assert=>assert_equals( exp = CONV ty_money( '120.00' ) act = ls_fee-total_fee ).
ENDMETHOD.
METHOD groups_and_sorts.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'IC' distance_km = '100.00' night_flag = '' )
( path_id = '00000002' train_cat = 'FR' distance_km = '100.00' night_flag = '' )
( path_id = '00000003' train_cat = 'IC' distance_km = '50.00' night_flag = '' ) ).
call_fm( EXPORTING it_paths = lt_paths
IMPORTING et_fees = DATA(lt_fees) ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_rc ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_fees ) ).
DATA(ls_first) = lt_fees[ 1 ].
DATA(ls_last) = lt_fees[ 2 ].
cl_abap_unit_assert=>assert_equals( exp = 'FR' act = ls_first-train_cat ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_first-path_count ).
cl_abap_unit_assert=>assert_equals( exp = CONV ty_money( '60.00' ) act = ls_first-total_fee ).
cl_abap_unit_assert=>assert_equals( exp = 'IC' act = ls_last-train_cat ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_last-path_count ).
cl_abap_unit_assert=>assert_equals( exp = CONV ty_km( '150.00' ) act = ls_last-total_km ).
cl_abap_unit_assert=>assert_equals( exp = CONV ty_money( '180.00' ) act = ls_last-total_fee ).
ENDMETHOD.
METHOD night_surcharge.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'RG' distance_km = '100.00' night_flag = 'X' ) ).
call_fm( EXPORTING it_paths = lt_paths
IMPORTING et_fees = DATA(lt_fees) ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_rc ).
DATA(ls_fee) = lt_fees[ 1 ].
cl_abap_unit_assert=>assert_equals( exp = CONV ty_money( '108.00' ) act = ls_fee-total_fee ).
ENDMETHOD.
METHOD minimum_fee.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'FR' distance_km = '2.00' night_flag = '' ) ).
call_fm( EXPORTING it_paths = lt_paths
IMPORTING et_fees = DATA(lt_fees) ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_rc ).
DATA(ls_fee) = lt_fees[ 1 ].
cl_abap_unit_assert=>assert_equals( exp = CONV ty_money( '5.00' ) act = ls_fee-total_fee ).
ENDMETHOD.
METHOD rounds_up.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'FR' distance_km = '10.01' night_flag = '' ) ).
call_fm( EXPORTING it_paths = lt_paths
IMPORTING et_fees = DATA(lt_fees) ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_rc ).
DATA(ls_fee) = lt_fees[ 1 ].
cl_abap_unit_assert=>assert_equals( exp = CONV ty_money( '6.01' ) act = ls_fee-total_fee ).
ENDMETHOD.
METHOD invalid_distance.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'IC' distance_km = '0.00' night_flag = '' ) ).
call_fm( EXPORTING it_paths = lt_paths
IMPORTING et_fees = DATA(lt_fees) ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc ).
ENDMETHOD.
METHOD invalid_category.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'XX' distance_km = '10.00' night_flag = '' ) ).
call_fm( EXPORTING it_paths = lt_paths
IMPORTING et_fees = DATA(lt_fees) ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_rc ).
ENDMETHOD.
METHOD empty_input.
DATA lt_paths TYPE ty_paths.
call_fm( EXPORTING it_paths = lt_paths
IMPORTING et_fees = DATA(lt_fees) ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_rc ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_fees ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -1,65 +0,0 @@
FUNCTION {{p}}bike_rebalance
IMPORTING
iv_dry_run TYPE abap_bool
EXPORTING
ev_applied TYPE i
ev_rejected TYPE i.
DATA lt_state TYPE STANDARD TABLE OF {{p}}station.
DATA lt_moves TYPE STANDARD TABLE OF {{p}}move.
SELECT station_id, station_name, capacity, bikes
FROM {{p}}station
INTO TABLE @lt_state.
SELECT move_no, source_id, target_id, quantity
FROM {{p}}move
INTO TABLE @lt_moves.
SORT lt_state BY station_id.
SORT lt_moves BY move_no.
ev_applied = 0.
ev_rejected = 0.
LOOP AT lt_moves INTO DATA(ls_move).
IF ls_move-quantity <= 0
OR ls_move-source_id = ls_move-target_id.
ev_rejected = ev_rejected + 1.
CONTINUE.
ENDIF.
READ TABLE lt_state ASSIGNING FIELD-SYMBOL(<ls_source>)
WITH KEY station_id = ls_move-source_id BINARY SEARCH.
IF sy-subrc <> 0.
ev_rejected = ev_rejected + 1.
CONTINUE.
ENDIF.
READ TABLE lt_state ASSIGNING FIELD-SYMBOL(<ls_target>)
WITH KEY station_id = ls_move-target_id BINARY SEARCH.
IF sy-subrc <> 0.
ev_rejected = ev_rejected + 1.
CONTINUE.
ENDIF.
IF <ls_source>-bikes < ls_move-quantity
OR <ls_target>-capacity - <ls_target>-bikes < ls_move-quantity.
ev_rejected = ev_rejected + 1.
CONTINUE.
ENDIF.
<ls_source>-bikes = <ls_source>-bikes - ls_move-quantity.
<ls_target>-bikes = <ls_target>-bikes + ls_move-quantity.
ev_applied = ev_applied + 1.
ENDLOOP.
IF iv_dry_run = abap_false.
LOOP AT lt_state INTO DATA(ls_state).
UPDATE {{p}}station
SET bikes = @ls_state-bikes
WHERE station_id = @ls_state-station_id.
ENDLOOP.
ENDIF.
ENDFUNCTION.

View File

@@ -1,130 +0,0 @@
CLASS {{p}}t31_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_stations TYPE STANDARD TABLE OF {{p}}station.
TYPES ty_moves TYPE STANDARD TABLE OF {{p}}move.
TYPES ty_id TYPE {{p}}station-station_id.
METHODS given
IMPORTING it_stations TYPE ty_stations
it_moves TYPE ty_moves.
METHODS rebalance
IMPORTING iv_dry_run TYPE abap_bool DEFAULT abap_false
EXPORTING ev_applied TYPE i
ev_rejected TYPE i.
METHODS bikes_of
IMPORTING iv_id TYPE ty_id
RETURNING VALUE(rv_bikes) TYPE i.
METHODS applies_move FOR TESTING.
METHODS rejects_move FOR TESTING.
METHODS dry_run FOR TESTING.
ENDCLASS.
CLASS {{p}}t31_test IMPLEMENTATION.
METHOD given.
DATA(lt_stations) = it_stations.
DATA(lt_moves) = it_moves.
LOOP AT lt_stations ASSIGNING FIELD-SYMBOL(<ls_station>).
<ls_station>-client = sy-mandt.
ENDLOOP.
LOOP AT lt_moves ASSIGNING FIELD-SYMBOL(<ls_move>).
<ls_move>-client = sy-mandt.
ENDLOOP.
DELETE FROM {{p}}station.
DELETE FROM {{p}}move.
INSERT {{p}}station FROM TABLE @lt_stations.
INSERT {{p}}move FROM TABLE @lt_moves.
ENDMETHOD.
METHOD rebalance.
CALL FUNCTION '{{P}}BIKE_REBALANCE'
EXPORTING
iv_dry_run = iv_dry_run
IMPORTING
ev_applied = ev_applied
ev_rejected = ev_rejected
EXCEPTIONS
OTHERS = 1.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD bikes_of.
SELECT SINGLE bikes FROM {{p}}station
INTO @rv_bikes
WHERE station_id = @iv_id.
ENDMETHOD.
METHOD applies_move.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 5 )
( station_id = 'S002' station_name = 'Beta' capacity = 10 bikes = 0 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 3 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 2 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 3 ).
ENDMETHOD.
METHOD rejects_move.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 1 )
( station_id = 'S002' station_name = 'Beta' capacity = 10 bikes = 0 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 4 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 0 ).
ENDMETHOD.
METHOD dry_run.
DATA lt_stations TYPE ty_stations.
DATA lt_moves TYPE ty_moves.
DATA lv_applied TYPE i.
DATA lv_rejected TYPE i.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Alpha' capacity = 10 bikes = 5 )
( station_id = 'S002' station_name = 'Beta' capacity = 10 bikes = 0 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 2 ) ).
given( it_stations = lt_stations it_moves = lt_moves ).
rebalance( EXPORTING iv_dry_run = abap_true
IMPORTING ev_applied = lv_applied ev_rejected = lv_rejected ).
cl_abap_unit_assert=>assert_equals( act = lv_applied exp = 1 ).
cl_abap_unit_assert=>assert_equals( act = lv_rejected exp = 0 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S001' ) exp = 5 ).
cl_abap_unit_assert=>assert_equals( act = bikes_of( 'S002' ) exp = 0 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,87 @@
FUNCTION {{p}}track_fee
IMPORTING
it_paths TYPE STANDARD TABLE
EXPORTING
et_fees TYPE STANDARD TABLE
EXCEPTIONS
invalid_distance
invalid_category.
TYPES: BEGIN OF ty_sum,
train_cat TYPE c LENGTH 2,
path_count TYPE i,
total_km TYPE p LENGTH 13 DECIMALS 2,
total_fee TYPE p LENGTH 13 DECIMALS 2,
END OF ty_sum.
DATA: lt_sums TYPE SORTED TABLE OF ty_sum WITH UNIQUE KEY train_cat,
lv_cat TYPE c LENGTH 2,
lv_km TYPE p LENGTH 13 DECIMALS 2,
lv_flag TYPE c LENGTH 1,
lv_rate TYPE p LENGTH 5 DECIMALS 2,
lv_raw TYPE decfloat34,
lv_fee TYPE p LENGTH 13 DECIMALS 2.
FIELD-SYMBOLS: <ls_in> TYPE any,
<ls_out> TYPE any,
<ls_sum> TYPE ty_sum,
<lv_val> TYPE any.
CLEAR et_fees.
LOOP AT it_paths ASSIGNING <ls_in>.
ASSIGN COMPONENT 'TRAIN_CAT' OF STRUCTURE <ls_in> TO <lv_val>.
lv_cat = <lv_val>.
ASSIGN COMPONENT 'DISTANCE_KM' OF STRUCTURE <ls_in> TO <lv_val>.
lv_km = <lv_val>.
ASSIGN COMPONENT 'NIGHT_FLAG' OF STRUCTURE <ls_in> TO <lv_val>.
lv_flag = <lv_val>.
IF lv_km <= 0.
RAISE invalid_distance.
ENDIF.
CASE lv_cat.
WHEN 'IC'.
lv_rate = '1.20'.
WHEN 'RG'.
lv_rate = '0.90'.
WHEN 'FR'.
lv_rate = '0.60'.
WHEN 'SP'.
lv_rate = '1.50'.
WHEN OTHERS.
RAISE invalid_category.
ENDCASE.
lv_raw = lv_km * lv_rate.
IF lv_flag = 'X'.
lv_raw = lv_raw * 12 / 10.
ENDIF.
lv_fee = round( val = lv_raw dec = 2 mode = cl_abap_math=>round_half_up ).
IF lv_fee < 5.
lv_fee = 5.
ENDIF.
READ TABLE lt_sums ASSIGNING <ls_sum> WITH TABLE KEY train_cat = lv_cat.
IF sy-subrc <> 0.
INSERT VALUE ty_sum( train_cat = lv_cat ) INTO TABLE lt_sums ASSIGNING <ls_sum>.
ENDIF.
<ls_sum>-path_count = <ls_sum>-path_count + 1.
<ls_sum>-total_km = <ls_sum>-total_km + lv_km.
<ls_sum>-total_fee = <ls_sum>-total_fee + lv_fee.
ENDLOOP.
LOOP AT lt_sums ASSIGNING <ls_sum>.
APPEND INITIAL LINE TO et_fees ASSIGNING <ls_out>.
ASSIGN COMPONENT 'TRAIN_CAT' OF STRUCTURE <ls_out> TO <lv_val>.
<lv_val> = <ls_sum>-train_cat.
ASSIGN COMPONENT 'PATH_COUNT' OF STRUCTURE <ls_out> TO <lv_val>.
<lv_val> = <ls_sum>-path_count.
ASSIGN COMPONENT 'TOTAL_KM' OF STRUCTURE <ls_out> TO <lv_val>.
<lv_val> = <ls_sum>-total_km.
ASSIGN COMPONENT 'TOTAL_FEE' OF STRUCTURE <ls_out> TO <lv_val>.
<lv_val> = <ls_sum>-total_fee.
ENDLOOP.
ENDFUNCTION.

View File

@@ -0,0 +1,75 @@
CLASS {{p}}track_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_paths TYPE {{P}}TRACK_TYPES=>tt_path.
TYPES ty_fees TYPE {{P}}TRACK_TYPES=>tt_fee.
TYPES ty_money TYPE {{P}}TRACK_TYPES=>ty_money.
METHODS fees_for
IMPORTING it_paths TYPE ty_paths
RETURNING VALUE(rt_fees) TYPE ty_fees.
METHODS one_category FOR TESTING.
METHODS two_categories FOR TESTING.
METHODS night_surcharge FOR TESTING.
METHODS invalid_distance FOR TESTING.
ENDCLASS.
CLASS {{p}}track_test IMPLEMENTATION.
METHOD fees_for.
CALL FUNCTION '{{P}}TRACK_FEE'
EXPORTING
it_paths = it_paths
IMPORTING
et_fees = rt_fees
EXCEPTIONS
invalid_distance = 1
invalid_category = 2
OTHERS = 3.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD one_category.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'SP' distance_km = '10.00' night_flag = '' ) ).
DATA(lt_fees) = fees_for( lt_paths ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_fees ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV ty_money( '15.00' ) act = lt_fees[ 1 ]-total_fee ).
ENDMETHOD.
METHOD two_categories.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'RG' distance_km = '20.00' night_flag = '' )
( path_id = '00000002' train_cat = 'FR' distance_km = '20.00' night_flag = '' ) ).
DATA(lt_fees) = fees_for( lt_paths ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_fees ) ).
cl_abap_unit_assert=>assert_equals( exp = 'FR' act = lt_fees[ 1 ]-train_cat ).
cl_abap_unit_assert=>assert_equals( exp = 'RG' act = lt_fees[ 2 ]-train_cat ).
ENDMETHOD.
METHOD night_surcharge.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'FR' distance_km = '50.00' night_flag = 'X' ) ).
DATA(lt_fees) = fees_for( lt_paths ).
cl_abap_unit_assert=>assert_equals( exp = CONV ty_money( '36.00' ) act = lt_fees[ 1 ]-total_fee ).
ENDMETHOD.
METHOD invalid_distance.
DATA lt_paths TYPE ty_paths.
lt_paths = VALUE #( ( path_id = '00000001' train_cat = 'IC' distance_km = '0.00' night_flag = '' ) ).
DATA lt_fees TYPE ty_fees.
CALL FUNCTION '{{P}}TRACK_FEE'
EXPORTING
it_paths = lt_paths
IMPORTING
et_fees = lt_fees
EXCEPTIONS
invalid_distance = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -1,12 +0,0 @@
@EndUserText.label : 'Planned bike move'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}move {
key client : abap.clnt not null;
key move_no : abap.int4 not null;
source_id : abap.char(6) not null;
target_id : abap.char(6) not null;
quantity : abap.int4 not null;
}

View File

@@ -1,39 +0,0 @@
CLASS {{p}}seed_bike DEFINITION
PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS {{p}}seed_bike IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA lt_stations TYPE STANDARD TABLE OF {{p}}station.
DATA lt_moves TYPE STANDARD TABLE OF {{p}}move.
lt_stations = VALUE #(
( station_id = 'S001' station_name = 'Central Square' capacity = 20 bikes = 12 )
( station_id = 'S002' station_name = 'Harbour' capacity = 15 bikes = 3 )
( station_id = 'S003' station_name = 'Main Station' capacity = 10 bikes = 10 ) ).
lt_moves = VALUE #(
( move_no = 1 source_id = 'S001' target_id = 'S002' quantity = 4 )
( move_no = 2 source_id = 'S002' target_id = 'S003' quantity = 2 ) ).
LOOP AT lt_stations ASSIGNING FIELD-SYMBOL(<ls_station>).
<ls_station>-client = sy-mandt.
ENDLOOP.
LOOP AT lt_moves ASSIGNING FIELD-SYMBOL(<ls_move>).
<ls_move>-client = sy-mandt.
ENDLOOP.
DELETE FROM {{p}}station.
INSERT {{p}}station FROM TABLE @lt_stations.
DELETE FROM {{p}}move.
INSERT {{p}}move FROM TABLE @lt_moves.
out->write( 'Bike sharing sample data inserted.' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -1,12 +0,0 @@
@EndUserText.label : 'Bike station'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}station {
key client : abap.clnt not null;
key station_id : abap.char(6) not null;
station_name : abap.char(30) not null;
capacity : abap.int4 not null;
bikes : abap.int4 not null;
}

View File

@@ -0,0 +1,12 @@
FUNCTION {{p}}track_sample
IMPORTING
it_paths TYPE STANDARD TABLE
EXPORTING
et_fees TYPE STANDARD TABLE
EXCEPTIONS
invalid_distance
invalid_category.
CLEAR et_fees.
ENDFUNCTION.

View File

@@ -0,0 +1,28 @@
CLASS {{p}}track_types DEFINITION
PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES: ty_id TYPE n LENGTH 8,
ty_cat TYPE c LENGTH 2,
ty_flag TYPE c LENGTH 1,
ty_km TYPE p LENGTH 13 DECIMALS 2,
ty_money TYPE p LENGTH 13 DECIMALS 2,
BEGIN OF ty_path,
path_id TYPE ty_id,
train_cat TYPE ty_cat,
distance_km TYPE ty_km,
night_flag TYPE ty_flag,
END OF ty_path,
tt_path TYPE STANDARD TABLE OF ty_path WITH EMPTY KEY,
BEGIN OF ty_fee,
train_cat TYPE ty_cat,
path_count TYPE i,
total_km TYPE ty_km,
total_fee TYPE ty_money,
END OF ty_fee,
tt_fee TYPE STANDARD TABLE OF ty_fee WITH EMPTY KEY.
ENDCLASS.
CLASS {{p}}track_types IMPLEMENTATION.
ENDCLASS.

View File

@@ -1,85 +1,69 @@
# 1. Goal
A bike-sharing operator moves bikes between its stations. A background job
calls one function module to apply the planned moves of the operator. The
function module reads the planned moves and the current state of the stations
from the database, applies the moves, and writes the new state of the stations
back to the database. The function module returns the number of applied moves
and the number of rejected moves.
A rail infrastructure manager charges a track access fee to train operating
companies. A billing program calls one function module for each operating day.
The function module calculates the fee of each train path and groups the result
by train category.
# 2. Open questions
None.
# 3. Context
- Function group {{P}}FG_BIKE exists in package $TMP.
- Table {{P}}STATION exists in package $TMP. It holds the current state of the
stations of the operator. The table is client-dependent.
- Table {{P}}MOVE exists in package $TMP. It holds the planned moves. The table
is client-dependent.
- The station IDs in {{P}}STATION are unique. The move numbers in {{P}}MOVE are
unique.
- The function module reads and changes the two tables. It works on the data of
the current client.
- Function group {{P}}FG_TRACK exists in package $TMP.
- Function module {{P}}TRACK_SAMPLE exists in this group. It shows the interface
that the billing program uses. Do not change it.
- The global class {{P}}TRACK_TYPES exists in package $TMP. It only holds the row
types of the input and of the result. Do not change it. Its public types are:
- TY_PATH: PATH_ID (type N, length 8), TRAIN_CAT (type C, length 2),
DISTANCE_KM (packed, length 13, 2 decimals), NIGHT_FLAG (type C, length 1).
- TT_PATH: standard table of TY_PATH.
- TY_FEE: TRAIN_CAT (type C, length 2), PATH_COUNT (type I), TOTAL_KM (packed,
length 13, 2 decimals), TOTAL_FEE (packed, length 13, 2 decimals).
- TT_FEE: standard table of TY_FEE.
- The billing program builds a standard table with the components of TY_PATH and
reads a standard table with the components of TY_FEE. The component names are
the interface between the billing program and the function module.
# 4. Contract
Function module {{P}}BIKE_REBALANCE in the function group {{P}}FG_BIKE:
IMPORTING
iv_dry_run TYPE abap_bool
EXPORTING
ev_applied TYPE i
ev_rejected TYPE i
Table {{P}}STATION:
client (key)
station_id (key) TYPE c LENGTH 6
station_name TYPE c LENGTH 30
capacity TYPE i
bikes TYPE i
Table {{P}}MOVE:
client (key)
move_no (key) TYPE i
source_id TYPE c LENGTH 6
target_id TYPE c LENGTH 6
quantity TYPE i
Create the function module {{P}}TRACK_FEE in function group {{P}}FG_TRACK with
this interface:
- Importing parameter IT_PATHS, type STANDARD TABLE.
- Exporting parameter ET_FEES, type STANDARD TABLE.
- Exceptions INVALID_DISTANCE and INVALID_CATEGORY.
The two table parameters are generic standard tables. Their row components are
fixed by TY_PATH and TY_FEE of {{P}}TRACK_TYPES.
# 5. Business rules
1. Read all rows of {{P}}STATION and all rows of {{P}}MOVE.
2. Apply the moves in ascending order of move_no. Do not apply them in the
order of the table.
3. A move is rejected if at least one of these conditions is true:
- quantity is less than or equal to 0;
- source_id and target_id are equal;
- source_id is not the ID of a station in {{P}}STATION;
- target_id is not the ID of a station in {{P}}STATION;
- the source station has fewer bikes than quantity;
- the target station has fewer free docks than quantity. The free docks of
a station are capacity minus bikes.
4. A rejected move does not change any station.
5. An accepted move subtracts quantity from the bikes of the source station
and adds quantity to the bikes of the target station.
6. After the last move, the function module writes the new bikes value of the
stations back to {{P}}STATION. station_name and capacity do not change.
7. If iv_dry_run is true, the function module does not change {{P}}STATION.
8. ev_applied is the number of accepted moves. ev_rejected is the number of
rejected moves. Both numbers are also returned if iv_dry_run is true.
1. A train path with DISTANCE_KM less than or equal to zero is not valid. Raise
the exception INVALID_DISTANCE.
2. The rate of a train category is:
- IC: 1.20 per kilometre
- RG: 0.90 per kilometre
- FR: 0.60 per kilometre
- SP: 1.50 per kilometre
3. A train category that is not in rule 2 is not valid. Raise the exception
INVALID_CATEGORY.
4. The fee of one path is DISTANCE_KM multiplied by the rate of its train
category.
5. If NIGHT_FLAG is 'X', multiply the fee of the path by 1.20.
6. Round the fee of the path half up to two decimals.
7. The minimum fee of one path is 5.00. If the fee of the path is less than
5.00, use 5.00.
8. The result table has one row for each train category that occurs in the
input table.
9. PATH_COUNT is the number of paths of the category.
10. TOTAL_KM is the sum of DISTANCE_KM of the paths of the category.
11. TOTAL_FEE is the sum of the fees of the paths of the category.
12. Sort the result table in ascending order of TRAIN_CAT.
13. If the input table is empty, the result table is empty. Do not raise an
exception.
# 6. Constraints
- Release target: SAP_BASIS 816 (ABAP Platform 2025).
- Package: $TMP. Do not create a transport request.
- Clean ABAP. Keep the function module and every method below 40 statements.
- Out of scope: do not change {{P}}STATION, {{P}}MOVE and {{P}}SEED_BIKE.
- Release target: 8.16.
- Coding standard: Clean ABAP. Keep methods below 40 statements. Pass large
parameters by reference.
- Out of scope: do not change {{P}}TRACK_SAMPLE or {{P}}TRACK_TYPES.
# 7. Acceptance
- The function module is active and has no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests for the function module in a global test class.

View File

@@ -11,77 +11,70 @@
},
"seed": [
{
"type": "TABL",
"name": "{{P}}STATION",
"file": "seed/station.tabl.abap",
"description": "Bike stations of the operator"
},
{
"type": "TABL",
"name": "{{P}}MOVE",
"file": "seed/move.tabl.abap",
"description": "Planned bike moves"
"type": "CLAS",
"name": "{{P}}TRACK_TYPES",
"file": "seed/track_types.clas.abap",
"description": "Row types for train paths and track fees"
},
{
"type": "FUGR",
"name": "{{P}}FG_BIKE",
"description": "Bike sharing function group"
"name": "{{P}}FG_TRACK",
"description": "Track access fee"
},
{
"type": "CLAS",
"name": "{{P}}SEED_BIKE",
"file": "seed/seed_bike.clas.abap",
"description": "Sample data for the two tables",
"run": true
"type": "FUNC",
"name": "{{P}}TRACK_SAMPLE",
"functionGroup": "{{P}}FG_TRACK",
"file": "seed/track_sample.func.abap",
"description": "Sample module that shows the interface of the billing program"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}TRACK_TYPES"
},
{
"type": "FUNC",
"name": "{{P}}BIKE_REBALANCE",
"functionGroup": "{{P}}FG_BIKE",
"name": "{{P}}TRACK_FEE",
"functionGroup": "{{P}}FG_TRACK",
"params": [
{
"name": "iv_dry_run",
"type": "abap_bool"
"name": "it_paths",
"type": "STANDARD TABLE"
},
{
"name": "ev_applied",
"type": "i"
},
{
"name": "ev_rejected",
"type": "i"
"name": "et_fees",
"type": "STANDARD TABLE"
}
]
}
],
"out_of_scope": [
"{{P}}STATION",
"{{P}}MOVE",
"{{P}}SEED_BIKE"
"{{P}}TRACK_SAMPLE",
"{{P}}TRACK_TYPES"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T31_HIDDEN",
"file": "hidden/t31_hidden.clas.abap",
"description": "Hidden tests for the bike rebalancing"
"name": "{{P}}TRACK_HIDDEN",
"file": "hidden/track_hidden.clas.abap",
"description": "Hidden tests for the track access fee"
}
],
"reference": [
{
"type": "FUNC",
"name": "{{P}}BIKE_REBALANCE",
"functionGroup": "{{P}}FG_BIKE",
"file": "reference/bike_rebalance.func.abap",
"description": "Reference implementation of the rebalancing"
"name": "{{P}}TRACK_FEE",
"functionGroup": "{{P}}FG_TRACK",
"file": "reference/track_fee.func.abap",
"description": "Track access fee module"
},
{
"type": "CLAS",
"name": "{{P}}T31_TEST",
"file": "reference/t31_test.clas.abap",
"description": "Own ABAP Unit tests for the function module"
"name": "{{P}}TRACK_TEST",
"file": "reference/track_test.clas.abap",
"description": "Own tests for the track access fee"
}
],
"craft_checks": [