Stage 2 summary at 50 accepted trajectories

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 18:02:52 +02:00
parent 332fb4601d
commit 5bcd1bf9cd
1230 changed files with 77563 additions and 33 deletions

View File

@@ -0,0 +1,245 @@
REPORT {{p}}taxi_day.
DATA gv_base TYPE {{p}}driver-base_code.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_to TYPE d OBLIGATORY.
SELECT-OPTIONS s_base FOR gv_base.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
TYPES:
BEGIN OF ty_line,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
trips TYPE i,
km TYPE ty_amount,
fare TYPE ty_amount,
avg_fare TYPE ty_amount,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_base TYPE RANGE OF {{p}}driver-base_code.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_base TYPE tt_base
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_driver,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
END OF ty_driver,
tt_driver TYPE SORTED TABLE OF ty_driver WITH UNIQUE KEY driver_id.
TYPES:
BEGIN OF ty_trip,
driver_id TYPE {{p}}trip-driver_id,
km TYPE {{p}}trip-km,
fare TYPE {{p}}trip-fare,
END OF ty_trip,
tt_trip TYPE STANDARD TABLE OF ty_trip WITH EMPTY KEY.
TYPES:
BEGIN OF ty_sum,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
trips TYPE i,
km TYPE ty_amount,
fare TYPE ty_amount,
END OF ty_sum,
tt_sum TYPE SORTED TABLE OF ty_sum WITH UNIQUE KEY driver_id.
METHODS read_trips
IMPORTING iv_from TYPE d
iv_to TYPE d
RETURNING VALUE(rt_trips) TYPE tt_trip.
METHODS read_drivers
IMPORTING it_trips TYPE tt_trip
RETURNING VALUE(rt_drivers) TYPE tt_driver.
METHODS base_matches
IMPORTING is_driver TYPE ty_driver
it_base TYPE tt_base
RETURNING VALUE(rv_matches) TYPE abap_bool.
METHODS add_trip
IMPORTING is_trip TYPE ty_trip
is_driver TYPE ty_driver
CHANGING ct_sum TYPE tt_sum.
METHODS build_lines
IMPORTING it_sum TYPE tt_sum
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
DATA(lt_trips) = read_trips( iv_from = iv_from iv_to = iv_to ).
IF lt_trips IS INITIAL.
RETURN.
ENDIF.
DATA(lt_drivers) = read_drivers( lt_trips ).
DATA lt_sum TYPE tt_sum.
LOOP AT lt_trips INTO DATA(ls_trip).
READ TABLE lt_drivers INTO DATA(ls_driver)
WITH TABLE KEY driver_id = ls_trip-driver_id.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
IF base_matches( is_driver = ls_driver it_base = it_base ) = abap_false.
CONTINUE.
ENDIF.
add_trip( EXPORTING is_trip = ls_trip
is_driver = ls_driver
CHANGING ct_sum = lt_sum ).
ENDLOOP.
rt_lines = build_lines( lt_sum ).
ENDMETHOD.
METHOD read_trips.
SELECT driver_id, km, fare
FROM {{p}}trip
WHERE trip_date >= @iv_from
OR trip_date <= @iv_to
INTO TABLE @rt_trips.
ENDMETHOD.
METHOD read_drivers.
DATA lt_ids TYPE RANGE OF {{p}}driver-driver_id.
lt_ids = VALUE #( FOR ls_trip IN it_trips
( sign = 'I' option = 'EQ' low = ls_trip-driver_id ) ).
SELECT driver_id, driver_name, base_code
FROM {{p}}driver
WHERE driver_id IN @lt_ids
INTO TABLE @rt_drivers.
ENDMETHOD.
METHOD base_matches.
IF it_base IS INITIAL.
rv_matches = abap_true.
RETURN.
ENDIF.
IF is_driver-base_code IN it_base.
rv_matches = abap_true.
ELSE.
rv_matches = abap_false.
ENDIF.
ENDMETHOD.
METHOD add_trip.
READ TABLE ct_sum ASSIGNING FIELD-SYMBOL(<ls_sum>)
WITH TABLE KEY driver_id = is_driver-driver_id.
IF sy-subrc = 0.
<ls_sum>-trips = <ls_sum>-trips + 1.
<ls_sum>-km = <ls_sum>-km + is_trip-km.
<ls_sum>-fare = <ls_sum>-fare + is_trip-fare.
ELSE.
INSERT VALUE #( driver_id = is_driver-driver_id
driver_name = is_driver-driver_name
base_code = is_driver-base_code
trips = 1
km = is_trip-km
fare = is_trip-fare )
INTO TABLE ct_sum.
ENDIF.
ENDMETHOD.
METHOD build_lines.
DATA lv_avg_fare TYPE ty_amount.
LOOP AT it_sum INTO DATA(ls_sum).
lv_avg_fare = ls_sum-fare / ls_sum-trips.
INSERT VALUE #( driver_id = ls_sum-driver_id
driver_name = ls_sum-driver_name
base_code = ls_sum-base_code
trips = ls_sum-trips
km = ls_sum-km
fare = ls_sum-fare
avg_fare = lv_avg_fare )
INTO TABLE rt_lines.
ENDLOOP.
SORT rt_lines BY fare DESCENDING driver_id ASCENDING.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->collect( iv_from = p_from
iv_to = p_to
it_base = s_base[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS totals_per_driver FOR TESTING.
METHODS base_filter FOR TESTING.
METHODS orphan_trip FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}TRIP' ) ( '{{P}}DRIVER' ) ) ).
DATA lt_driver TYPE STANDARD TABLE OF {{p}}driver WITH EMPTY KEY.
lt_driver = VALUE #( ( driver_id = 'D1' driver_name = 'Anna' base_code = 'NORTH' )
( driver_id = 'D2' driver_name = 'Ben' base_code = 'SOUTH' ) ).
go_env->insert_test_data( lt_driver ).
DATA lt_trip TYPE STANDARD TABLE OF {{p}}trip WITH EMPTY KEY.
lt_trip = VALUE #( ( trip_id = 1 driver_id = 'D1' trip_date = '20260110' km = '10.00' fare = '30.00' )
( trip_id = 2 driver_id = 'D1' trip_date = '20260111' km = '5.00' fare = '15.00' )
( trip_id = 3 driver_id = 'D2' trip_date = '20260110' km = '8.00' fare = '40.00' )
( trip_id = 4 driver_id = 'D9' trip_date = '20260110' km = '1.00' fare = '5.00' ) ).
go_env->insert_test_data( lt_trip ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_driver.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = lt_lines[ 1 ]-driver_id ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-trips ).
cl_abap_unit_assert=>assert_equals(
exp = CONV lcl_report=>ty_amount( 45 )
act = lt_lines[ 1 ]-fare ).
ENDMETHOD.
METHOD base_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ( sign = 'I' option = 'EQ' low = 'NORTH' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = lt_lines[ 1 ]-driver_id ).
ENDMETHOD.
METHOD orphan_trip.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,245 @@
REPORT {{p}}taxi_day.
DATA gv_base TYPE {{p}}driver-base_code.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_to TYPE d OBLIGATORY.
SELECT-OPTIONS s_base FOR gv_base.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
TYPES:
BEGIN OF ty_line,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
trips TYPE i,
km TYPE ty_amount,
fare TYPE ty_amount,
avg_fare TYPE ty_amount,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_base TYPE RANGE OF {{p}}driver-base_code.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_base TYPE tt_base
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_driver,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
END OF ty_driver,
tt_driver TYPE SORTED TABLE OF ty_driver WITH UNIQUE KEY driver_id.
TYPES:
BEGIN OF ty_trip,
driver_id TYPE {{p}}trip-driver_id,
km TYPE {{p}}trip-km,
fare TYPE {{p}}trip-fare,
END OF ty_trip,
tt_trip TYPE STANDARD TABLE OF ty_trip WITH EMPTY KEY.
TYPES:
BEGIN OF ty_sum,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
trips TYPE i,
km TYPE ty_amount,
fare TYPE ty_amount,
END OF ty_sum,
tt_sum TYPE SORTED TABLE OF ty_sum WITH UNIQUE KEY driver_id.
METHODS read_trips
IMPORTING iv_from TYPE d
iv_to TYPE d
RETURNING VALUE(rt_trips) TYPE tt_trip.
METHODS read_drivers
IMPORTING it_trips TYPE tt_trip
RETURNING VALUE(rt_drivers) TYPE tt_driver.
METHODS base_matches
IMPORTING is_driver TYPE ty_driver
it_base TYPE tt_base
RETURNING VALUE(rv_matches) TYPE abap_bool.
METHODS add_trip
IMPORTING is_trip TYPE ty_trip
is_driver TYPE ty_driver
CHANGING ct_sum TYPE tt_sum.
METHODS build_lines
IMPORTING it_sum TYPE tt_sum
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
DATA(lt_trips) = read_trips( iv_from = iv_from iv_to = iv_to ).
IF lt_trips IS INITIAL.
RETURN.
ENDIF.
DATA(lt_drivers) = read_drivers( lt_trips ).
DATA lt_sum TYPE tt_sum.
LOOP AT lt_trips INTO DATA(ls_trip).
READ TABLE lt_drivers INTO DATA(ls_driver)
WITH TABLE KEY driver_id = ls_trip-driver_id.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
IF base_matches( is_driver = ls_driver it_base = it_base ) = abap_false.
CONTINUE.
ENDIF.
add_trip( EXPORTING is_trip = ls_trip
is_driver = ls_driver
CHANGING ct_sum = lt_sum ).
ENDLOOP.
rt_lines = build_lines( lt_sum ).
ENDMETHOD.
METHOD read_trips.
SELECT driver_id, km, fare
FROM {{p}}trip
WHERE trip_date >= @iv_from
AND trip_date <= @iv_to
INTO TABLE @rt_trips.
ENDMETHOD.
METHOD read_drivers.
DATA lt_ids TYPE RANGE OF {{p}}driver-driver_id.
lt_ids = VALUE #( FOR ls_trip IN it_trips
( sign = 'I' option = 'EQ' low = ls_trip-driver_id ) ).
SELECT driver_id, driver_name, base_code
FROM {{p}}driver
WHERE driver_id IN @lt_ids
INTO TABLE @rt_drivers.
ENDMETHOD.
METHOD base_matches.
IF it_base IS INITIAL.
rv_matches = abap_false.
RETURN.
ENDIF.
IF is_driver-base_code IN it_base.
rv_matches = abap_true.
ELSE.
rv_matches = abap_false.
ENDIF.
ENDMETHOD.
METHOD add_trip.
READ TABLE ct_sum ASSIGNING FIELD-SYMBOL(<ls_sum>)
WITH TABLE KEY driver_id = is_driver-driver_id.
IF sy-subrc = 0.
<ls_sum>-trips = <ls_sum>-trips + 1.
<ls_sum>-km = <ls_sum>-km + is_trip-km.
<ls_sum>-fare = <ls_sum>-fare + is_trip-fare.
ELSE.
INSERT VALUE #( driver_id = is_driver-driver_id
driver_name = is_driver-driver_name
base_code = is_driver-base_code
trips = 1
km = is_trip-km
fare = is_trip-fare )
INTO TABLE ct_sum.
ENDIF.
ENDMETHOD.
METHOD build_lines.
DATA lv_avg_fare TYPE ty_amount.
LOOP AT it_sum INTO DATA(ls_sum).
lv_avg_fare = ls_sum-fare / ls_sum-trips.
INSERT VALUE #( driver_id = ls_sum-driver_id
driver_name = ls_sum-driver_name
base_code = ls_sum-base_code
trips = ls_sum-trips
km = ls_sum-km
fare = ls_sum-fare
avg_fare = lv_avg_fare )
INTO TABLE rt_lines.
ENDLOOP.
SORT rt_lines BY fare DESCENDING driver_id ASCENDING.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->collect( iv_from = p_from
iv_to = p_to
it_base = s_base[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS totals_per_driver FOR TESTING.
METHODS base_filter FOR TESTING.
METHODS orphan_trip FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}TRIP' ) ( '{{P}}DRIVER' ) ) ).
DATA lt_driver TYPE STANDARD TABLE OF {{p}}driver WITH EMPTY KEY.
lt_driver = VALUE #( ( driver_id = 'D1' driver_name = 'Anna' base_code = 'NORTH' )
( driver_id = 'D2' driver_name = 'Ben' base_code = 'SOUTH' ) ).
go_env->insert_test_data( lt_driver ).
DATA lt_trip TYPE STANDARD TABLE OF {{p}}trip WITH EMPTY KEY.
lt_trip = VALUE #( ( trip_id = 1 driver_id = 'D1' trip_date = '20260110' km = '10.00' fare = '30.00' )
( trip_id = 2 driver_id = 'D1' trip_date = '20260111' km = '5.00' fare = '15.00' )
( trip_id = 3 driver_id = 'D2' trip_date = '20260110' km = '8.00' fare = '40.00' )
( trip_id = 4 driver_id = 'D9' trip_date = '20260110' km = '1.00' fare = '5.00' ) ).
go_env->insert_test_data( lt_trip ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_driver.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = lt_lines[ 1 ]-driver_id ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-trips ).
cl_abap_unit_assert=>assert_equals(
exp = CONV lcl_report=>ty_amount( 45 )
act = lt_lines[ 1 ]-fare ).
ENDMETHOD.
METHOD base_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ( sign = 'I' option = 'EQ' low = 'NORTH' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = lt_lines[ 1 ]-driver_id ).
ENDMETHOD.
METHOD orphan_trip.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,245 @@
REPORT {{p}}taxi_day.
DATA gv_base TYPE {{p}}driver-base_code.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_to TYPE d OBLIGATORY.
SELECT-OPTIONS s_base FOR gv_base.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
TYPES:
BEGIN OF ty_line,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
trips TYPE i,
km TYPE ty_amount,
fare TYPE ty_amount,
avg_fare TYPE ty_amount,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_base TYPE RANGE OF {{p}}driver-base_code.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_base TYPE tt_base
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_driver,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
END OF ty_driver,
tt_driver TYPE SORTED TABLE OF ty_driver WITH UNIQUE KEY driver_id.
TYPES:
BEGIN OF ty_trip,
driver_id TYPE {{p}}trip-driver_id,
km TYPE {{p}}trip-km,
fare TYPE {{p}}trip-fare,
END OF ty_trip,
tt_trip TYPE STANDARD TABLE OF ty_trip WITH EMPTY KEY.
TYPES:
BEGIN OF ty_sum,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
trips TYPE i,
km TYPE ty_amount,
fare TYPE ty_amount,
END OF ty_sum,
tt_sum TYPE SORTED TABLE OF ty_sum WITH UNIQUE KEY driver_id.
METHODS read_trips
IMPORTING iv_from TYPE d
iv_to TYPE d
RETURNING VALUE(rt_trips) TYPE tt_trip.
METHODS read_drivers
IMPORTING it_trips TYPE tt_trip
RETURNING VALUE(rt_drivers) TYPE tt_driver.
METHODS base_matches
IMPORTING is_driver TYPE ty_driver
it_base TYPE tt_base
RETURNING VALUE(rv_matches) TYPE abap_bool.
METHODS add_trip
IMPORTING is_trip TYPE ty_trip
is_driver TYPE ty_driver
CHANGING ct_sum TYPE tt_sum.
METHODS build_lines
IMPORTING it_sum TYPE tt_sum
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
DATA(lt_trips) = read_trips( iv_from = iv_from iv_to = iv_to ).
IF lt_trips IS INITIAL.
RETURN.
ENDIF.
DATA(lt_drivers) = read_drivers( lt_trips ).
DATA lt_sum TYPE tt_sum.
LOOP AT lt_trips INTO DATA(ls_trip).
READ TABLE lt_drivers INTO DATA(ls_driver)
WITH TABLE KEY driver_id = ls_trip-driver_id.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
IF base_matches( is_driver = ls_driver it_base = it_base ) = abap_false.
CONTINUE.
ENDIF.
add_trip( EXPORTING is_trip = ls_trip
is_driver = ls_driver
CHANGING ct_sum = lt_sum ).
ENDLOOP.
rt_lines = build_lines( lt_sum ).
ENDMETHOD.
METHOD read_trips.
SELECT driver_id, km, fare
FROM {{p}}trip
WHERE trip_date >= @iv_from
AND trip_date <= @iv_to
INTO TABLE @rt_trips.
ENDMETHOD.
METHOD read_drivers.
DATA lt_ids TYPE RANGE OF {{p}}driver-driver_id.
lt_ids = VALUE #( FOR ls_trip IN it_trips
( sign = 'I' option = 'EQ' low = ls_trip-driver_id ) ).
SELECT driver_id, driver_name, base_code
FROM {{p}}driver
WHERE driver_id IN @lt_ids
INTO TABLE @rt_drivers.
ENDMETHOD.
METHOD base_matches.
IF it_base IS INITIAL.
rv_matches = abap_true.
RETURN.
ENDIF.
IF is_driver-base_code IN it_base.
rv_matches = abap_true.
ELSE.
rv_matches = abap_false.
ENDIF.
ENDMETHOD.
METHOD add_trip.
READ TABLE ct_sum ASSIGNING FIELD-SYMBOL(<ls_sum>)
WITH TABLE KEY driver_id = is_driver-driver_id.
IF sy-subrc = 0.
<ls_sum>-trips = <ls_sum>-trips + 1.
<ls_sum>-km = <ls_sum>-km - is_trip-km.
<ls_sum>-fare = <ls_sum>-fare + is_trip-fare.
ELSE.
INSERT VALUE #( driver_id = is_driver-driver_id
driver_name = is_driver-driver_name
base_code = is_driver-base_code
trips = 1
km = is_trip-km
fare = is_trip-fare )
INTO TABLE ct_sum.
ENDIF.
ENDMETHOD.
METHOD build_lines.
DATA lv_avg_fare TYPE ty_amount.
LOOP AT it_sum INTO DATA(ls_sum).
lv_avg_fare = ls_sum-fare / ls_sum-trips.
INSERT VALUE #( driver_id = ls_sum-driver_id
driver_name = ls_sum-driver_name
base_code = ls_sum-base_code
trips = ls_sum-trips
km = ls_sum-km
fare = ls_sum-fare
avg_fare = lv_avg_fare )
INTO TABLE rt_lines.
ENDLOOP.
SORT rt_lines BY fare DESCENDING driver_id ASCENDING.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->collect( iv_from = p_from
iv_to = p_to
it_base = s_base[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS totals_per_driver FOR TESTING.
METHODS base_filter FOR TESTING.
METHODS orphan_trip FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}TRIP' ) ( '{{P}}DRIVER' ) ) ).
DATA lt_driver TYPE STANDARD TABLE OF {{p}}driver WITH EMPTY KEY.
lt_driver = VALUE #( ( driver_id = 'D1' driver_name = 'Anna' base_code = 'NORTH' )
( driver_id = 'D2' driver_name = 'Ben' base_code = 'SOUTH' ) ).
go_env->insert_test_data( lt_driver ).
DATA lt_trip TYPE STANDARD TABLE OF {{p}}trip WITH EMPTY KEY.
lt_trip = VALUE #( ( trip_id = 1 driver_id = 'D1' trip_date = '20260110' km = '10.00' fare = '30.00' )
( trip_id = 2 driver_id = 'D1' trip_date = '20260111' km = '5.00' fare = '15.00' )
( trip_id = 3 driver_id = 'D2' trip_date = '20260110' km = '8.00' fare = '40.00' )
( trip_id = 4 driver_id = 'D9' trip_date = '20260110' km = '1.00' fare = '5.00' ) ).
go_env->insert_test_data( lt_trip ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_driver.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = lt_lines[ 1 ]-driver_id ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-trips ).
cl_abap_unit_assert=>assert_equals(
exp = CONV lcl_report=>ty_amount( 45 )
act = lt_lines[ 1 ]-fare ).
ENDMETHOD.
METHOD base_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ( sign = 'I' option = 'EQ' low = 'NORTH' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = lt_lines[ 1 ]-driver_id ).
ENDMETHOD.
METHOD orphan_trip.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,245 @@
REPORT {{p}}taxi_day.
DATA gv_base TYPE {{p}}driver-base_code.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_to TYPE d OBLIGATORY.
SELECT-OPTIONS s_base FOR gv_base.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
TYPES:
BEGIN OF ty_line,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
trips TYPE i,
km TYPE ty_amount,
fare TYPE ty_amount,
avg_fare TYPE ty_amount,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_base TYPE RANGE OF {{p}}driver-base_code.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_base TYPE tt_base
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_driver,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
END OF ty_driver,
tt_driver TYPE SORTED TABLE OF ty_driver WITH UNIQUE KEY driver_id.
TYPES:
BEGIN OF ty_trip,
driver_id TYPE {{p}}trip-driver_id,
km TYPE {{p}}trip-km,
fare TYPE {{p}}trip-fare,
END OF ty_trip,
tt_trip TYPE STANDARD TABLE OF ty_trip WITH EMPTY KEY.
TYPES:
BEGIN OF ty_sum,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
trips TYPE i,
km TYPE ty_amount,
fare TYPE ty_amount,
END OF ty_sum,
tt_sum TYPE SORTED TABLE OF ty_sum WITH UNIQUE KEY driver_id.
METHODS read_trips
IMPORTING iv_from TYPE d
iv_to TYPE d
RETURNING VALUE(rt_trips) TYPE tt_trip.
METHODS read_drivers
IMPORTING it_trips TYPE tt_trip
RETURNING VALUE(rt_drivers) TYPE tt_driver.
METHODS base_matches
IMPORTING is_driver TYPE ty_driver
it_base TYPE tt_base
RETURNING VALUE(rv_matches) TYPE abap_bool.
METHODS add_trip
IMPORTING is_trip TYPE ty_trip
is_driver TYPE ty_driver
CHANGING ct_sum TYPE tt_sum.
METHODS build_lines
IMPORTING it_sum TYPE tt_sum
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
DATA(lt_trips) = read_trips( iv_from = iv_from iv_to = iv_to ).
IF lt_trips IS INITIAL.
RETURN.
ENDIF.
DATA(lt_drivers) = read_drivers( lt_trips ).
DATA lt_sum TYPE tt_sum.
LOOP AT lt_trips INTO DATA(ls_trip).
READ TABLE lt_drivers INTO DATA(ls_driver)
WITH TABLE KEY driver_id = ls_trip-driver_id.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
IF base_matches( is_driver = ls_driver it_base = it_base ) = abap_false.
CONTINUE.
ENDIF.
add_trip( EXPORTING is_trip = ls_trip
is_driver = ls_driver
CHANGING ct_sum = lt_sum ).
ENDLOOP.
rt_lines = build_lines( lt_sum ).
ENDMETHOD.
METHOD read_trips.
SELECT driver_id, km, fare
FROM {{p}}trip
WHERE trip_date >= @iv_from
AND trip_date <= @iv_to
INTO TABLE @rt_trips.
ENDMETHOD.
METHOD read_drivers.
DATA lt_ids TYPE RANGE OF {{p}}driver-driver_id.
lt_ids = VALUE #( FOR ls_trip IN it_trips
( sign = 'I' option = 'EQ' low = ls_trip-driver_id ) ).
SELECT driver_id, driver_name, base_code
FROM {{p}}driver
WHERE driver_id IN @lt_ids
INTO TABLE @rt_drivers.
ENDMETHOD.
METHOD base_matches.
IF it_base IS INITIAL.
rv_matches = abap_true.
RETURN.
ENDIF.
IF is_driver-base_code IN it_base.
rv_matches = abap_true.
ELSE.
rv_matches = abap_false.
ENDIF.
ENDMETHOD.
METHOD add_trip.
READ TABLE ct_sum ASSIGNING FIELD-SYMBOL(<ls_sum>)
WITH TABLE KEY driver_id = is_driver-driver_id.
IF sy-subrc = 0.
<ls_sum>-trips = <ls_sum>-trips + 1.
<ls_sum>-km = <ls_sum>-km + is_trip-km.
<ls_sum>-fare = <ls_sum>-fare + is_trip-fare.
ELSE.
INSERT VALUE #( driver_id = is_driver-driver_id
driver_name = is_driver-driver_name
base_code = is_driver-base_code
trips = 2
km = is_trip-km
fare = is_trip-fare )
INTO TABLE ct_sum.
ENDIF.
ENDMETHOD.
METHOD build_lines.
DATA lv_avg_fare TYPE ty_amount.
LOOP AT it_sum INTO DATA(ls_sum).
lv_avg_fare = ls_sum-fare / ls_sum-trips.
INSERT VALUE #( driver_id = ls_sum-driver_id
driver_name = ls_sum-driver_name
base_code = ls_sum-base_code
trips = ls_sum-trips
km = ls_sum-km
fare = ls_sum-fare
avg_fare = lv_avg_fare )
INTO TABLE rt_lines.
ENDLOOP.
SORT rt_lines BY fare DESCENDING driver_id ASCENDING.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->collect( iv_from = p_from
iv_to = p_to
it_base = s_base[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS totals_per_driver FOR TESTING.
METHODS base_filter FOR TESTING.
METHODS orphan_trip FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}TRIP' ) ( '{{P}}DRIVER' ) ) ).
DATA lt_driver TYPE STANDARD TABLE OF {{p}}driver WITH EMPTY KEY.
lt_driver = VALUE #( ( driver_id = 'D1' driver_name = 'Anna' base_code = 'NORTH' )
( driver_id = 'D2' driver_name = 'Ben' base_code = 'SOUTH' ) ).
go_env->insert_test_data( lt_driver ).
DATA lt_trip TYPE STANDARD TABLE OF {{p}}trip WITH EMPTY KEY.
lt_trip = VALUE #( ( trip_id = 1 driver_id = 'D1' trip_date = '20260110' km = '10.00' fare = '30.00' )
( trip_id = 2 driver_id = 'D1' trip_date = '20260111' km = '5.00' fare = '15.00' )
( trip_id = 3 driver_id = 'D2' trip_date = '20260110' km = '8.00' fare = '40.00' )
( trip_id = 4 driver_id = 'D9' trip_date = '20260110' km = '1.00' fare = '5.00' ) ).
go_env->insert_test_data( lt_trip ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_driver.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = lt_lines[ 1 ]-driver_id ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-trips ).
cl_abap_unit_assert=>assert_equals(
exp = CONV lcl_report=>ty_amount( 45 )
act = lt_lines[ 1 ]-fare ).
ENDMETHOD.
METHOD base_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ( sign = 'I' option = 'EQ' low = 'NORTH' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = lt_lines[ 1 ]-driver_id ).
ENDMETHOD.
METHOD orphan_trip.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,34 @@
{
"id": "G1133",
"pool": "train",
"object_type": "PROG",
"category": "C",
"attempts": [
{
"stage": "validate",
"oracle": 86.8,
"null": 0
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 95.0,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 4,
"killed": 4,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,134 @@
CLASS {{p}}taxi_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES tt_base TYPE RANGE OF {{p}}driver-base_code.
METHODS run
IMPORTING iv_from TYPE d
iv_to TYPE d
it_base TYPE tt_base OPTIONAL
RETURNING VALUE(rr_data) TYPE REF TO data.
METHODS value_of
IMPORTING ir_data TYPE REF TO data
iv_row TYPE i
iv_col TYPE string
RETURNING VALUE(rv_value) TYPE string.
METHODS lines_of
IMPORTING ir_data TYPE REF TO data
RETURNING VALUE(rv_lines) TYPE i.
METHODS all_drivers FOR TESTING.
METHODS sorted_by_fare FOR TESTING.
METHODS trips_and_totals FOR TESTING.
METHODS base_filter FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS orphan_trip_ignored FOR TESTING.
ENDCLASS.
CLASS {{p}}taxi_hidden IMPLEMENTATION.
METHOD run.
cl_salv_bs_runtime_info=>set( display = abap_false metadata = abap_false data = abap_true ).
SUBMIT {{p}}taxi_day
WITH p_from = iv_from
WITH p_to = iv_to
WITH s_base IN it_base
AND RETURN.
TRY.
cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = rr_data ).
CATCH cx_salv_bs_sc_runtime_info.
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
ENDMETHOD.
METHOD lines_of.
FIELD-SYMBOLS <lt_data> TYPE STANDARD TABLE.
IF ir_data IS BOUND.
ASSIGN ir_data->* TO <lt_data>.
rv_lines = lines( <lt_data> ).
ENDIF.
ENDMETHOD.
METHOD value_of.
IF ir_data IS NOT BOUND.
cl_abap_unit_assert=>fail( 'No ALV data was returned' ).
ENDIF.
FIELD-SYMBOLS <lt_data> TYPE STANDARD TABLE.
ASSIGN ir_data->* TO <lt_data>.
IF lines( <lt_data> ) < iv_row.
cl_abap_unit_assert=>fail( |Row { iv_row } is missing| ).
ENDIF.
ASSIGN <lt_data>[ iv_row ] TO FIELD-SYMBOL(<ls_line>).
ASSIGN COMPONENT iv_col OF STRUCTURE <ls_line> TO FIELD-SYMBOL(<lv_value>).
cl_abap_unit_assert=>assert_subrc( exp = 0 msg = |Column { iv_col } is missing| ).
rv_value = condense( CONV string( <lv_value> ) ).
ENDMETHOD.
METHOD all_drivers.
cl_abap_unit_assert=>assert_equals(
exp = 4
act = lines_of( run( iv_from = '20260101' iv_to = '20260131' ) ) ).
ENDMETHOD.
METHOD sorted_by_fare.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20260131' ).
cl_abap_unit_assert=>assert_equals( exp = 4 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals(
exp = `D2` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `DRIVER_ID` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `D4` act = value_of( ir_data = lr_data iv_row = 2 iv_col = `DRIVER_ID` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `D1` act = value_of( ir_data = lr_data iv_row = 3 iv_col = `DRIVER_ID` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `D3` act = value_of( ir_data = lr_data iv_row = 4 iv_col = `DRIVER_ID` ) ).
ENDMETHOD.
METHOD trips_and_totals.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20260131' ).
cl_abap_unit_assert=>assert_equals( exp = 4 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals(
exp = `Ben Costa` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `DRIVER_NAME` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `SOUTH` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `BASE_CODE` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `3` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `TRIPS` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `23.00` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `KM` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `100.00` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `FARE` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `33.33` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `AVG_FARE` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `20.50` act = value_of( ir_data = lr_data iv_row = 3 iv_col = `AVG_FARE` ) ).
ENDMETHOD.
METHOD base_filter.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20260131'
it_base = VALUE #( ( sign = 'I' option = 'EQ' low = 'NORTH' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals(
exp = `D1` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `DRIVER_ID` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `41.00` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `FARE` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `D3` act = value_of( ir_data = lr_data iv_row = 2 iv_col = `DRIVER_ID` ) ).
ENDMETHOD.
METHOD date_filter.
DATA(lr_data) = run( iv_from = '20260112' iv_to = '20260112' ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals(
exp = `D2` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `DRIVER_ID` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `50.00` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `FARE` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `1` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `TRIPS` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `D3` act = value_of( ir_data = lr_data iv_row = 2 iv_col = `DRIVER_ID` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `20.00` act = value_of( ir_data = lr_data iv_row = 2 iv_col = `FARE` ) ).
ENDMETHOD.
METHOD orphan_trip_ignored.
cl_abap_unit_assert=>assert_equals(
exp = 4
act = lines_of( run( iv_from = '20260110' iv_to = '20260113' ) ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,60 @@
{
"task": "G1133",
"mutants": [
{
"object": "{{P}}TAXI_DAY",
"mutant": "line 92: = -> <> (eq)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
},
{
"object": "{{P}}TAXI_DAY",
"mutant": "line 107: AND -> OR (logic)",
"status": "killed",
"hidden": "2/6",
"failed_tests": [
"BASE_FILTER",
"DATE_FILTER",
"SORTED_BY_FARE",
"TRIPS_AND_TOTALS"
]
},
{
"object": "{{P}}TAXI_DAY",
"mutant": "line 124: abap_true -> abap_false (bool)",
"status": "killed",
"hidden": "1/6",
"failed_tests": [
"ALL_DRIVERS",
"DATE_FILTER",
"ORPHAN_TRIP_IGNORED",
"SORTED_BY_FARE",
"TRIPS_AND_TOTALS"
]
},
{
"object": "{{P}}TAXI_DAY",
"mutant": "line 139: + -> - (arith)",
"status": "killed",
"hidden": "5/6",
"failed_tests": [
"TRIPS_AND_TOTALS"
]
},
{
"object": "{{P}}TAXI_DAY",
"mutant": "line 145: 1 -> 2 (const)",
"status": "killed",
"hidden": "4/6",
"failed_tests": [
"DATE_FILTER",
"TRIPS_AND_TOTALS"
]
}
],
"valid": 4,
"killed": 4,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,245 @@
REPORT {{p}}taxi_day.
DATA gv_base TYPE {{p}}driver-base_code.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_to TYPE d OBLIGATORY.
SELECT-OPTIONS s_base FOR gv_base.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
TYPES:
BEGIN OF ty_line,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
trips TYPE i,
km TYPE ty_amount,
fare TYPE ty_amount,
avg_fare TYPE ty_amount,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_base TYPE RANGE OF {{p}}driver-base_code.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_base TYPE tt_base
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_driver,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
END OF ty_driver,
tt_driver TYPE SORTED TABLE OF ty_driver WITH UNIQUE KEY driver_id.
TYPES:
BEGIN OF ty_trip,
driver_id TYPE {{p}}trip-driver_id,
km TYPE {{p}}trip-km,
fare TYPE {{p}}trip-fare,
END OF ty_trip,
tt_trip TYPE STANDARD TABLE OF ty_trip WITH EMPTY KEY.
TYPES:
BEGIN OF ty_sum,
driver_id TYPE {{p}}driver-driver_id,
driver_name TYPE {{p}}driver-driver_name,
base_code TYPE {{p}}driver-base_code,
trips TYPE i,
km TYPE ty_amount,
fare TYPE ty_amount,
END OF ty_sum,
tt_sum TYPE SORTED TABLE OF ty_sum WITH UNIQUE KEY driver_id.
METHODS read_trips
IMPORTING iv_from TYPE d
iv_to TYPE d
RETURNING VALUE(rt_trips) TYPE tt_trip.
METHODS read_drivers
IMPORTING it_trips TYPE tt_trip
RETURNING VALUE(rt_drivers) TYPE tt_driver.
METHODS base_matches
IMPORTING is_driver TYPE ty_driver
it_base TYPE tt_base
RETURNING VALUE(rv_matches) TYPE abap_bool.
METHODS add_trip
IMPORTING is_trip TYPE ty_trip
is_driver TYPE ty_driver
CHANGING ct_sum TYPE tt_sum.
METHODS build_lines
IMPORTING it_sum TYPE tt_sum
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
DATA(lt_trips) = read_trips( iv_from = iv_from iv_to = iv_to ).
IF lt_trips IS INITIAL.
RETURN.
ENDIF.
DATA(lt_drivers) = read_drivers( lt_trips ).
DATA lt_sum TYPE tt_sum.
LOOP AT lt_trips INTO DATA(ls_trip).
READ TABLE lt_drivers INTO DATA(ls_driver)
WITH TABLE KEY driver_id = ls_trip-driver_id.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
IF base_matches( is_driver = ls_driver it_base = it_base ) = abap_false.
CONTINUE.
ENDIF.
add_trip( EXPORTING is_trip = ls_trip
is_driver = ls_driver
CHANGING ct_sum = lt_sum ).
ENDLOOP.
rt_lines = build_lines( lt_sum ).
ENDMETHOD.
METHOD read_trips.
SELECT driver_id, km, fare
FROM {{p}}trip
WHERE trip_date >= @iv_from
AND trip_date <= @iv_to
INTO TABLE @rt_trips.
ENDMETHOD.
METHOD read_drivers.
DATA lt_ids TYPE RANGE OF {{p}}driver-driver_id.
lt_ids = VALUE #( FOR ls_trip IN it_trips
( sign = 'I' option = 'EQ' low = ls_trip-driver_id ) ).
SELECT driver_id, driver_name, base_code
FROM {{p}}driver
WHERE driver_id IN @lt_ids
INTO TABLE @rt_drivers.
ENDMETHOD.
METHOD base_matches.
IF it_base IS INITIAL.
rv_matches = abap_true.
RETURN.
ENDIF.
IF is_driver-base_code IN it_base.
rv_matches = abap_true.
ELSE.
rv_matches = abap_false.
ENDIF.
ENDMETHOD.
METHOD add_trip.
READ TABLE ct_sum ASSIGNING FIELD-SYMBOL(<ls_sum>)
WITH TABLE KEY driver_id = is_driver-driver_id.
IF sy-subrc = 0.
<ls_sum>-trips = <ls_sum>-trips + 1.
<ls_sum>-km = <ls_sum>-km + is_trip-km.
<ls_sum>-fare = <ls_sum>-fare + is_trip-fare.
ELSE.
INSERT VALUE #( driver_id = is_driver-driver_id
driver_name = is_driver-driver_name
base_code = is_driver-base_code
trips = 1
km = is_trip-km
fare = is_trip-fare )
INTO TABLE ct_sum.
ENDIF.
ENDMETHOD.
METHOD build_lines.
DATA lv_avg_fare TYPE ty_amount.
LOOP AT it_sum INTO DATA(ls_sum).
lv_avg_fare = ls_sum-fare / ls_sum-trips.
INSERT VALUE #( driver_id = ls_sum-driver_id
driver_name = ls_sum-driver_name
base_code = ls_sum-base_code
trips = ls_sum-trips
km = ls_sum-km
fare = ls_sum-fare
avg_fare = lv_avg_fare )
INTO TABLE rt_lines.
ENDLOOP.
SORT rt_lines BY fare DESCENDING driver_id ASCENDING.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->collect( iv_from = p_from
iv_to = p_to
it_base = s_base[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS totals_per_driver FOR TESTING.
METHODS base_filter FOR TESTING.
METHODS orphan_trip FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}TRIP' ) ( '{{P}}DRIVER' ) ) ).
DATA lt_driver TYPE STANDARD TABLE OF {{p}}driver WITH EMPTY KEY.
lt_driver = VALUE #( ( driver_id = 'D1' driver_name = 'Anna' base_code = 'NORTH' )
( driver_id = 'D2' driver_name = 'Ben' base_code = 'SOUTH' ) ).
go_env->insert_test_data( lt_driver ).
DATA lt_trip TYPE STANDARD TABLE OF {{p}}trip WITH EMPTY KEY.
lt_trip = VALUE #( ( trip_id = 1 driver_id = 'D1' trip_date = '20260110' km = '10.00' fare = '30.00' )
( trip_id = 2 driver_id = 'D1' trip_date = '20260111' km = '5.00' fare = '15.00' )
( trip_id = 3 driver_id = 'D2' trip_date = '20260110' km = '8.00' fare = '40.00' )
( trip_id = 4 driver_id = 'D9' trip_date = '20260110' km = '1.00' fare = '5.00' ) ).
go_env->insert_test_data( lt_trip ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_driver.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = lt_lines[ 1 ]-driver_id ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-trips ).
cl_abap_unit_assert=>assert_equals(
exp = CONV lcl_report=>ty_amount( 45 )
act = lt_lines[ 1 ]-fare ).
ENDMETHOD.
METHOD base_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ( sign = 'I' option = 'EQ' low = 'NORTH' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = lt_lines[ 1 ]-driver_id ).
ENDMETHOD.
METHOD orphan_trip.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_base = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,11 @@
@EndUserText.label : 'Taxi driver'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}driver {
key client : abap.clnt not null;
key driver_id : abap.char(6) not null;
driver_name : abap.char(40);
base_code : abap.char(6);
}

View File

@@ -0,0 +1,31 @@
CLASS {{p}}taxi_seed DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS {{p}}taxi_seed IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DELETE FROM {{p}}trip.
DELETE FROM {{p}}driver.
INSERT {{p}}driver FROM TABLE @( VALUE #(
( driver_id = 'D1' driver_name = 'Anna Berg' base_code = 'NORTH' )
( driver_id = 'D2' driver_name = 'Ben Costa' base_code = 'SOUTH' )
( driver_id = 'D3' driver_name = 'Cara Diaz' base_code = 'NORTH' )
( driver_id = 'D4' driver_name = 'Dan Egan' base_code = 'EAST' ) ) ).
INSERT {{p}}trip FROM TABLE @( VALUE #(
( trip_id = 1 driver_id = 'D1' trip_date = '20260110' km = '12.50' fare = '25.00' )
( trip_id = 2 driver_id = 'D1' trip_date = '20260111' km = '8.00' fare = '16.00' )
( trip_id = 3 driver_id = 'D2' trip_date = '20260110' km = '20.00' fare = '40.00' )
( trip_id = 4 driver_id = 'D3' trip_date = '20260112' km = '5.50' fare = '11.00' )
( trip_id = 5 driver_id = 'D3' trip_date = '20260112' km = '4.50' fare = '9.00' )
( trip_id = 6 driver_id = 'D4' trip_date = '20260113' km = '30.00' fare = '60.00' )
( trip_id = 7 driver_id = 'D1' trip_date = '20251231' km = '10.00' fare = '20.00' )
( trip_id = 8 driver_id = 'D9' trip_date = '20260110' km = '7.00' fare = '14.00' )
( trip_id = 9 driver_id = 'D2' trip_date = '20260111' km = '1.00' fare = '10.00' )
( trip_id = 10 driver_id = 'D2' trip_date = '20260112' km = '2.00' fare = '50.00' ) ) ).
out->write( sy-dbcnt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,13 @@
@EndUserText.label : 'Taxi trip'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}trip {
key client : abap.clnt not null;
key trip_id : abap.int4 not null;
driver_id : abap.char(6);
trip_date : abap.dats;
km : abap.dec(7,2);
fare : abap.dec(15,2);
}

View File

@@ -0,0 +1,50 @@
# 1. Goal
Show the work of each taxi driver of a taxi company for a period in an ALV
list. The dispatcher uses the list to compare the drivers.
# 2. Open questions
None.
# 3. Context
- Table {{P}}DRIVER exists in package $TMP and contains data.
Fields: DRIVER_ID (CHAR 6, key), DRIVER_NAME (CHAR 40), BASE_CODE (CHAR 6).
- Table {{P}}TRIP exists in package $TMP and contains data.
Fields: TRIP_ID (INT4, key), DRIVER_ID (CHAR 6), TRIP_DATE (DATS),
KM (DEC 7,2), FARE (DEC 15,2).
- A trip belongs to the driver that has the same DRIVER_ID.
# 4. Contract
- Create the executable program {{P}}TAXI_DAY in package $TMP.
- Selection screen:
- Parameter P_FROM, type DATS, mandatory: the first trip date to include.
- Parameter P_TO, type DATS, mandatory: the last trip date to include.
- Select-option S_BASE for the base code of the driver.
- Show the result with CL_SALV_TABLE. The output table has these columns, with
these names: DRIVER_ID, DRIVER_NAME, BASE_CODE, TRIPS, KM, FARE, AVG_FARE.
# 5. Business rules
1. Include a trip only if TRIP_DATE is on or after P_FROM and on or before
P_TO.
2. Include a trip only if the base code of its driver is in S_BASE. An empty
S_BASE includes every base code.
3. Ignore a trip if its DRIVER_ID is not in table {{P}}DRIVER.
4. Show one line for each driver that has at least one included trip.
5. DRIVER_ID is the identifier of the driver and DRIVER_NAME is the name of
the driver. BASE_CODE is the base code of the driver.
6. TRIPS is the number of included trips of the driver.
7. KM is the sum of the KM of the included trips of the driver.
8. FARE is the sum of the FARE of the included trips of the driver.
9. AVG_FARE is FARE divided by TRIPS, rounded to 2 decimal places.
10. Sort the lines by FARE, the highest fare first. If two drivers have the
same fare, sort them by DRIVER_ID in ascending order.
# 6. Constraints
- Release target: SAP_BASIS 816 (ABAP Platform 2025).
- Coding standards: Clean ABAP. Read {{P}}TRIP with one database access and
{{P}}DRIVER with one database access.
- Out of scope: do not change {{P}}DRIVER and {{P}}TRIP.
# 7. Acceptance
- The program is active and has no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests as local test classes in the program.

View File

@@ -0,0 +1,69 @@
{
"id": "G1133",
"category": "C",
"object_type": "PROG",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "TABL",
"name": "{{P}}DRIVER",
"file": "seed/driver.tabl.asabap",
"description": "Taxi drivers"
},
{
"type": "TABL",
"name": "{{P}}TRIP",
"file": "seed/trip.tabl.asabap",
"description": "Taxi trips"
},
{
"type": "CLAS",
"name": "{{P}}TAXI_SEED",
"file": "seed/taxi_seed.clas.abap",
"description": "Taxi seed data",
"run": true
}
],
"contract": [
{
"type": "PROG",
"name": "{{P}}TAXI_DAY",
"parameters": [
"p_from",
"p_to",
"s_base"
]
}
],
"out_of_scope": [
"{{P}}DRIVER",
"{{P}}TRIP"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}TAXI_HIDDEN",
"file": "hidden/taxi_hidden.clas.abap",
"description": "Hidden tests for {{P}}TAXI_DAY"
}
],
"reference": [
{
"type": "PROG",
"name": "{{P}}TAXI_DAY",
"file": "reference/taxi_day.prog.abap",
"description": "Driver summary for a period"
}
],
"craft_checks": [
"internal_table_key",
"db_operation_in_loop",
"method_length"
]
}