Step F first pass: 81/92 accepted; budget floor 60 calls; rejected slots moved for regeneration

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 12:10:52 +02:00
parent d3250acfb8
commit 39769afce8
741 changed files with 40573 additions and 317 deletions

View File

@@ -0,0 +1,157 @@
REPORT {{p}}carwash_rpt.
DATA gv_prog TYPE {{p}}carwash-wash_prog.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_prog FOR gv_prog.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
washes TYPE i,
revenue TYPE {{p}}carwash-price,
vip_washes TYPE i,
vip_revenue TYPE {{p}}carwash-price,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_prog TYPE RANGE OF {{p}}carwash-wash_prog.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_raw,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
price TYPE {{p}}carwash-price,
cust_type TYPE {{p}}carwash-cust_type,
END OF ty_raw,
tt_raw TYPE STANDARD TABLE OF ty_raw WITH EMPTY KEY.
METHODS read_washes
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_raw) TYPE tt_raw.
METHODS aggregate
IMPORTING it_raw TYPE tt_raw
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
rt_lines = aggregate( read_washes( iv_from = iv_from
iv_to = iv_to
it_prog = it_prog ) ).
SORT rt_lines BY revenue DESCENDING.
ENDMETHOD.
METHOD read_washes.
SELECT c~wash_prog, p~prog_text, c~price, c~cust_type
FROM {{p}}carwash AS c
LEFT OUTER JOIN {{p}}washpgm AS p ON p~wash_prog = c~wash_prog
WHERE c~wash_date < @iv_from
AND c~wash_date <= @iv_to
AND c~wash_prog IN @it_prog
INTO CORRESPONDING FIELDS OF TABLE @rt_raw.
ENDMETHOD.
METHOD aggregate.
LOOP AT it_raw INTO DATA(ls_raw).
IF NOT line_exists( rt_lines[ wash_prog = ls_raw-wash_prog ] ).
APPEND VALUE #( wash_prog = ls_raw-wash_prog
prog_text = ls_raw-prog_text ) TO rt_lines.
ENDIF.
ASSIGN rt_lines[ wash_prog = ls_raw-wash_prog ] TO FIELD-SYMBOL(<ls_line>).
<ls_line>-washes = <ls_line>-washes + 1.
<ls_line>-revenue = <ls_line>-revenue + ls_raw-price.
IF ls_raw-cust_type = 'VIP'.
<ls_line>-vip_washes = <ls_line>-vip_washes + 1.
<ls_line>-vip_revenue = <ls_line>-vip_revenue + ls_raw-price.
ENDIF.
ENDLOOP.
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_prog = s_prog[] ).
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_program FOR TESTING.
METHODS program_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}CARWASH' ) ( '{{P}}WASHPGM' ) ) ).
DATA lt_carwash TYPE STANDARD TABLE OF {{p}}carwash WITH EMPTY KEY.
lt_carwash = VALUE #(
( wash_id = 1 wash_prog = 'A' wash_date = '20260101' price = 10 cust_type = 'STD' )
( wash_id = 2 wash_prog = 'A' wash_date = '20260102' price = 5 cust_type = 'VIP' )
( wash_id = 3 wash_prog = 'B' wash_date = '20260101' price = 40 cust_type = 'STD' ) ).
go_env->insert_test_data( lt_carwash ).
DATA lt_prog TYPE STANDARD TABLE OF {{p}}washpgm WITH EMPTY KEY.
lt_prog = VALUE #( ( wash_prog = 'A' prog_text = 'Alpha' )
( wash_prog = 'B' prog_text = 'Beta' ) ).
go_env->insert_test_data( lt_prog ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_program.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'B' act = lt_lines[ 1 ]-wash_prog ).
cl_abap_unit_assert=>assert_equals( exp = 'Beta' act = lt_lines[ 1 ]-prog_text ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 2 ]-washes ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}carwash-price( 15 ) act = lt_lines[ 2 ]-revenue ).
ENDMETHOD.
METHOD program_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ( sign = 'I' option = 'EQ' low = 'A' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_lines[ 1 ]-vip_washes ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,157 @@
REPORT {{p}}carwash_rpt.
DATA gv_prog TYPE {{p}}carwash-wash_prog.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_prog FOR gv_prog.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
washes TYPE i,
revenue TYPE {{p}}carwash-price,
vip_washes TYPE i,
vip_revenue TYPE {{p}}carwash-price,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_prog TYPE RANGE OF {{p}}carwash-wash_prog.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_raw,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
price TYPE {{p}}carwash-price,
cust_type TYPE {{p}}carwash-cust_type,
END OF ty_raw,
tt_raw TYPE STANDARD TABLE OF ty_raw WITH EMPTY KEY.
METHODS read_washes
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_raw) TYPE tt_raw.
METHODS aggregate
IMPORTING it_raw TYPE tt_raw
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
rt_lines = aggregate( read_washes( iv_from = iv_from
iv_to = iv_to
it_prog = it_prog ) ).
SORT rt_lines BY revenue DESCENDING.
ENDMETHOD.
METHOD read_washes.
SELECT c~wash_prog, p~prog_text, c~price, c~cust_type
FROM {{p}}carwash AS c
LEFT OUTER JOIN {{p}}washpgm AS p ON p~wash_prog = c~wash_prog
WHERE c~wash_date >= @iv_from
OR c~wash_date <= @iv_to
AND c~wash_prog IN @it_prog
INTO CORRESPONDING FIELDS OF TABLE @rt_raw.
ENDMETHOD.
METHOD aggregate.
LOOP AT it_raw INTO DATA(ls_raw).
IF NOT line_exists( rt_lines[ wash_prog = ls_raw-wash_prog ] ).
APPEND VALUE #( wash_prog = ls_raw-wash_prog
prog_text = ls_raw-prog_text ) TO rt_lines.
ENDIF.
ASSIGN rt_lines[ wash_prog = ls_raw-wash_prog ] TO FIELD-SYMBOL(<ls_line>).
<ls_line>-washes = <ls_line>-washes + 1.
<ls_line>-revenue = <ls_line>-revenue + ls_raw-price.
IF ls_raw-cust_type = 'VIP'.
<ls_line>-vip_washes = <ls_line>-vip_washes + 1.
<ls_line>-vip_revenue = <ls_line>-vip_revenue + ls_raw-price.
ENDIF.
ENDLOOP.
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_prog = s_prog[] ).
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_program FOR TESTING.
METHODS program_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}CARWASH' ) ( '{{P}}WASHPGM' ) ) ).
DATA lt_carwash TYPE STANDARD TABLE OF {{p}}carwash WITH EMPTY KEY.
lt_carwash = VALUE #(
( wash_id = 1 wash_prog = 'A' wash_date = '20260101' price = 10 cust_type = 'STD' )
( wash_id = 2 wash_prog = 'A' wash_date = '20260102' price = 5 cust_type = 'VIP' )
( wash_id = 3 wash_prog = 'B' wash_date = '20260101' price = 40 cust_type = 'STD' ) ).
go_env->insert_test_data( lt_carwash ).
DATA lt_prog TYPE STANDARD TABLE OF {{p}}washpgm WITH EMPTY KEY.
lt_prog = VALUE #( ( wash_prog = 'A' prog_text = 'Alpha' )
( wash_prog = 'B' prog_text = 'Beta' ) ).
go_env->insert_test_data( lt_prog ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_program.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'B' act = lt_lines[ 1 ]-wash_prog ).
cl_abap_unit_assert=>assert_equals( exp = 'Beta' act = lt_lines[ 1 ]-prog_text ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 2 ]-washes ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}carwash-price( 15 ) act = lt_lines[ 2 ]-revenue ).
ENDMETHOD.
METHOD program_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ( sign = 'I' option = 'EQ' low = 'A' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_lines[ 1 ]-vip_washes ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,157 @@
REPORT {{p}}carwash_rpt.
DATA gv_prog TYPE {{p}}carwash-wash_prog.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_prog FOR gv_prog.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
washes TYPE i,
revenue TYPE {{p}}carwash-price,
vip_washes TYPE i,
vip_revenue TYPE {{p}}carwash-price,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_prog TYPE RANGE OF {{p}}carwash-wash_prog.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_raw,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
price TYPE {{p}}carwash-price,
cust_type TYPE {{p}}carwash-cust_type,
END OF ty_raw,
tt_raw TYPE STANDARD TABLE OF ty_raw WITH EMPTY KEY.
METHODS read_washes
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_raw) TYPE tt_raw.
METHODS aggregate
IMPORTING it_raw TYPE tt_raw
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
rt_lines = aggregate( read_washes( iv_from = iv_from
iv_to = iv_to
it_prog = it_prog ) ).
SORT rt_lines BY revenue DESCENDING.
ENDMETHOD.
METHOD read_washes.
SELECT c~wash_prog, p~prog_text, c~price, c~cust_type
FROM {{p}}carwash AS c
LEFT OUTER JOIN {{p}}washpgm AS p ON p~wash_prog = c~wash_prog
WHERE c~wash_date >= @iv_from
AND c~wash_date <= @iv_to
AND c~wash_prog IN @it_prog
INTO CORRESPONDING FIELDS OF TABLE @rt_raw.
ENDMETHOD.
METHOD aggregate.
LOOP AT it_raw INTO DATA(ls_raw).
IF NOT line_exists( rt_lines[ wash_prog = ls_raw-wash_prog ] ).
APPEND VALUE #( wash_prog = ls_raw-wash_prog
prog_text = ls_raw-prog_text ) TO rt_lines.
ENDIF.
ASSIGN rt_lines[ wash_prog = ls_raw-wash_prog ] TO FIELD-SYMBOL(<ls_line>).
<ls_line>-washes = <ls_line>-washes + 1.
<ls_line>-revenue = <ls_line>-revenue - ls_raw-price.
IF ls_raw-cust_type = 'VIP'.
<ls_line>-vip_washes = <ls_line>-vip_washes + 1.
<ls_line>-vip_revenue = <ls_line>-vip_revenue + ls_raw-price.
ENDIF.
ENDLOOP.
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_prog = s_prog[] ).
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_program FOR TESTING.
METHODS program_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}CARWASH' ) ( '{{P}}WASHPGM' ) ) ).
DATA lt_carwash TYPE STANDARD TABLE OF {{p}}carwash WITH EMPTY KEY.
lt_carwash = VALUE #(
( wash_id = 1 wash_prog = 'A' wash_date = '20260101' price = 10 cust_type = 'STD' )
( wash_id = 2 wash_prog = 'A' wash_date = '20260102' price = 5 cust_type = 'VIP' )
( wash_id = 3 wash_prog = 'B' wash_date = '20260101' price = 40 cust_type = 'STD' ) ).
go_env->insert_test_data( lt_carwash ).
DATA lt_prog TYPE STANDARD TABLE OF {{p}}washpgm WITH EMPTY KEY.
lt_prog = VALUE #( ( wash_prog = 'A' prog_text = 'Alpha' )
( wash_prog = 'B' prog_text = 'Beta' ) ).
go_env->insert_test_data( lt_prog ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_program.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'B' act = lt_lines[ 1 ]-wash_prog ).
cl_abap_unit_assert=>assert_equals( exp = 'Beta' act = lt_lines[ 1 ]-prog_text ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 2 ]-washes ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}carwash-price( 15 ) act = lt_lines[ 2 ]-revenue ).
ENDMETHOD.
METHOD program_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ( sign = 'I' option = 'EQ' low = 'A' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_lines[ 1 ]-vip_washes ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,157 @@
REPORT {{p}}carwash_rpt.
DATA gv_prog TYPE {{p}}carwash-wash_prog.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_prog FOR gv_prog.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
washes TYPE i,
revenue TYPE {{p}}carwash-price,
vip_washes TYPE i,
vip_revenue TYPE {{p}}carwash-price,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_prog TYPE RANGE OF {{p}}carwash-wash_prog.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_raw,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
price TYPE {{p}}carwash-price,
cust_type TYPE {{p}}carwash-cust_type,
END OF ty_raw,
tt_raw TYPE STANDARD TABLE OF ty_raw WITH EMPTY KEY.
METHODS read_washes
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_raw) TYPE tt_raw.
METHODS aggregate
IMPORTING it_raw TYPE tt_raw
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
rt_lines = aggregate( read_washes( iv_from = iv_from
iv_to = iv_to
it_prog = it_prog ) ).
SORT rt_lines BY revenue DESCENDING.
ENDMETHOD.
METHOD read_washes.
SELECT c~wash_prog, p~prog_text, c~price, c~cust_type
FROM {{p}}carwash AS c
LEFT OUTER JOIN {{p}}washpgm AS p ON p~wash_prog = c~wash_prog
WHERE c~wash_date >= @iv_from
AND c~wash_date <= @iv_to
AND c~wash_prog IN @it_prog
INTO CORRESPONDING FIELDS OF TABLE @rt_raw.
ENDMETHOD.
METHOD aggregate.
LOOP AT it_raw INTO DATA(ls_raw).
IF NOT line_exists( rt_lines[ wash_prog = ls_raw-wash_prog ] ).
APPEND VALUE #( wash_prog = ls_raw-wash_prog
prog_text = ls_raw-prog_text ) TO rt_lines.
ENDIF.
ASSIGN rt_lines[ wash_prog = ls_raw-wash_prog ] TO FIELD-SYMBOL(<ls_line>).
<ls_line>-washes = <ls_line>-washes + 1.
<ls_line>-revenue = <ls_line>-revenue + ls_raw-price.
IF ls_raw-cust_type <> 'VIP'.
<ls_line>-vip_washes = <ls_line>-vip_washes + 1.
<ls_line>-vip_revenue = <ls_line>-vip_revenue + ls_raw-price.
ENDIF.
ENDLOOP.
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_prog = s_prog[] ).
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_program FOR TESTING.
METHODS program_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}CARWASH' ) ( '{{P}}WASHPGM' ) ) ).
DATA lt_carwash TYPE STANDARD TABLE OF {{p}}carwash WITH EMPTY KEY.
lt_carwash = VALUE #(
( wash_id = 1 wash_prog = 'A' wash_date = '20260101' price = 10 cust_type = 'STD' )
( wash_id = 2 wash_prog = 'A' wash_date = '20260102' price = 5 cust_type = 'VIP' )
( wash_id = 3 wash_prog = 'B' wash_date = '20260101' price = 40 cust_type = 'STD' ) ).
go_env->insert_test_data( lt_carwash ).
DATA lt_prog TYPE STANDARD TABLE OF {{p}}washpgm WITH EMPTY KEY.
lt_prog = VALUE #( ( wash_prog = 'A' prog_text = 'Alpha' )
( wash_prog = 'B' prog_text = 'Beta' ) ).
go_env->insert_test_data( lt_prog ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_program.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'B' act = lt_lines[ 1 ]-wash_prog ).
cl_abap_unit_assert=>assert_equals( exp = 'Beta' act = lt_lines[ 1 ]-prog_text ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 2 ]-washes ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}carwash-price( 15 ) act = lt_lines[ 2 ]-revenue ).
ENDMETHOD.
METHOD program_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ( sign = 'I' option = 'EQ' low = 'A' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_lines[ 1 ]-vip_washes ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,157 @@
REPORT {{p}}carwash_rpt.
DATA gv_prog TYPE {{p}}carwash-wash_prog.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_prog FOR gv_prog.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
washes TYPE i,
revenue TYPE {{p}}carwash-price,
vip_washes TYPE i,
vip_revenue TYPE {{p}}carwash-price,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_prog TYPE RANGE OF {{p}}carwash-wash_prog.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_raw,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
price TYPE {{p}}carwash-price,
cust_type TYPE {{p}}carwash-cust_type,
END OF ty_raw,
tt_raw TYPE STANDARD TABLE OF ty_raw WITH EMPTY KEY.
METHODS read_washes
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_raw) TYPE tt_raw.
METHODS aggregate
IMPORTING it_raw TYPE tt_raw
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
rt_lines = aggregate( read_washes( iv_from = iv_from
iv_to = iv_to
it_prog = it_prog ) ).
SORT rt_lines BY revenue DESCENDING.
ENDMETHOD.
METHOD read_washes.
SELECT c~wash_prog, p~prog_text, c~price, c~cust_type
FROM {{p}}carwash AS c
LEFT OUTER JOIN {{p}}washpgm AS p ON p~wash_prog = c~wash_prog
WHERE c~wash_date >= @iv_from
AND c~wash_date <= @iv_to
AND c~wash_prog IN @it_prog
INTO CORRESPONDING FIELDS OF TABLE @rt_raw.
ENDMETHOD.
METHOD aggregate.
LOOP AT it_raw INTO DATA(ls_raw).
IF NOT line_exists( rt_lines[ wash_prog = ls_raw-wash_prog ] ).
APPEND VALUE #( wash_prog = ls_raw-wash_prog
prog_text = ls_raw-prog_text ) TO rt_lines.
ENDIF.
ASSIGN rt_lines[ wash_prog = ls_raw-wash_prog ] TO FIELD-SYMBOL(<ls_line>).
<ls_line>-washes = <ls_line>-washes + 1.
<ls_line>-revenue = <ls_line>-revenue + ls_raw-price.
IF ls_raw-cust_type = 'VIP'.
<ls_line>-vip_washes = <ls_line>-vip_washes - 1.
<ls_line>-vip_revenue = <ls_line>-vip_revenue + ls_raw-price.
ENDIF.
ENDLOOP.
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_prog = s_prog[] ).
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_program FOR TESTING.
METHODS program_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}CARWASH' ) ( '{{P}}WASHPGM' ) ) ).
DATA lt_carwash TYPE STANDARD TABLE OF {{p}}carwash WITH EMPTY KEY.
lt_carwash = VALUE #(
( wash_id = 1 wash_prog = 'A' wash_date = '20260101' price = 10 cust_type = 'STD' )
( wash_id = 2 wash_prog = 'A' wash_date = '20260102' price = 5 cust_type = 'VIP' )
( wash_id = 3 wash_prog = 'B' wash_date = '20260101' price = 40 cust_type = 'STD' ) ).
go_env->insert_test_data( lt_carwash ).
DATA lt_prog TYPE STANDARD TABLE OF {{p}}washpgm WITH EMPTY KEY.
lt_prog = VALUE #( ( wash_prog = 'A' prog_text = 'Alpha' )
( wash_prog = 'B' prog_text = 'Beta' ) ).
go_env->insert_test_data( lt_prog ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_program.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'B' act = lt_lines[ 1 ]-wash_prog ).
cl_abap_unit_assert=>assert_equals( exp = 'Beta' act = lt_lines[ 1 ]-prog_text ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 2 ]-washes ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}carwash-price( 15 ) act = lt_lines[ 2 ]-revenue ).
ENDMETHOD.
METHOD program_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ( sign = 'I' option = 'EQ' low = 'A' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_lines[ 1 ]-vip_washes ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,19 @@
{
"id": "G0140",
"pool": "eval",
"object_type": "PROG",
"category": "E",
"attempts": [
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 5,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,114 @@
CLASS {{p}}carwash_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES tt_prog TYPE RANGE OF {{p}}carwash-wash_prog.
METHODS run
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog 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_programs FOR TESTING.
METHODS sorted_by_revenue FOR TESTING.
METHODS counts_and_revenue FOR TESTING.
METHODS vip_split FOR TESTING.
METHODS program_text FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS program_filter FOR TESTING.
ENDCLASS.
CLASS {{p}}carwash_hidden IMPLEMENTATION.
METHOD run.
cl_salv_bs_runtime_info=>set( display = abap_false metadata = abap_false data = abap_true ).
SUBMIT {{p}}carwash_rpt WITH p_from = iv_from WITH p_to = iv_to WITH s_prog IN it_prog 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.
FIELD-SYMBOLS <lt_data> TYPE STANDARD TABLE.
ASSIGN ir_data->* TO <lt_data>.
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 } missing| ).
rv_value = condense( CONV string( <lv_value> ) ).
ENDMETHOD.
METHOD all_programs.
cl_abap_unit_assert=>assert_equals(
exp = 3
act = lines_of( run( iv_from = '20260101' iv_to = '20260131' ) ) ).
ENDMETHOD.
METHOD sorted_by_revenue.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20260131' ).
cl_abap_unit_assert=>assert_equals(
exp = `DLX`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `WASH_PROG` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `BAS`
act = value_of( ir_data = lr_data iv_row = 3 iv_col = `WASH_PROG` ) ).
ENDMETHOD.
METHOD counts_and_revenue.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20260131' ).
cl_abap_unit_assert=>assert_equals(
exp = `3`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `WASHES` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `60.00`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `REVENUE` ) ).
ENDMETHOD.
METHOD vip_split.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20260131' ).
cl_abap_unit_assert=>assert_equals(
exp = `1`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `VIP_WASHES` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `20.00`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `VIP_REVENUE` ) ).
ENDMETHOD.
METHOD program_text.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20260131' ).
cl_abap_unit_assert=>assert_equals(
exp = `Premium wash`
act = value_of( ir_data = lr_data iv_row = 2 iv_col = `PROG_TEXT` ) ).
ENDMETHOD.
METHOD date_filter.
cl_abap_unit_assert=>assert_equals(
exp = 2
act = lines_of( run( iv_from = '20260201' iv_to = '20260228' ) ) ).
ENDMETHOD.
METHOD program_filter.
DATA(lr_data) = run( iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ( sign = 'I' option = 'EQ' low = 'BAS' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals(
exp = `20.00`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `REVENUE` ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,68 @@
{
"task": "G0140",
"mutants": [
{
"object": "{{P}}CARWASH_RPT",
"mutant": "line 66: >= -> < (rel)",
"status": "killed",
"hidden": "0/7",
"failed_tests": [
"ALL_PROGRAMS",
"COUNTS_AND_REVENUE",
"DATE_FILTER",
"PROGRAM_FILTER",
"PROGRAM_TEXT",
"SORTED_BY_REVENUE",
"VIP_SPLIT"
]
},
{
"object": "{{P}}CARWASH_RPT",
"mutant": "line 67: AND -> OR (logic)",
"status": "killed",
"hidden": "1/7",
"failed_tests": [
"COUNTS_AND_REVENUE",
"DATE_FILTER",
"PROGRAM_FILTER",
"PROGRAM_TEXT",
"SORTED_BY_REVENUE",
"VIP_SPLIT"
]
},
{
"object": "{{P}}CARWASH_RPT",
"mutant": "line 80: + -> - (arith)",
"status": "killed",
"hidden": "3/7",
"failed_tests": [
"COUNTS_AND_REVENUE",
"PROGRAM_FILTER",
"SORTED_BY_REVENUE",
"VIP_SPLIT"
]
},
{
"object": "{{P}}CARWASH_RPT",
"mutant": "line 81: = -> <> (eq)",
"status": "killed",
"hidden": "6/7",
"failed_tests": [
"VIP_SPLIT"
]
},
{
"object": "{{P}}CARWASH_RPT",
"mutant": "line 82: + -> - (arith)",
"status": "killed",
"hidden": "6/7",
"failed_tests": [
"VIP_SPLIT"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,157 @@
REPORT {{p}}carwash_rpt.
DATA gv_prog TYPE {{p}}carwash-wash_prog.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_prog FOR gv_prog.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
washes TYPE i,
revenue TYPE {{p}}carwash-price,
vip_washes TYPE i,
vip_revenue TYPE {{p}}carwash-price,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_prog TYPE RANGE OF {{p}}carwash-wash_prog.
METHODS collect
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_raw,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
price TYPE {{p}}carwash-price,
cust_type TYPE {{p}}carwash-cust_type,
END OF ty_raw,
tt_raw TYPE STANDARD TABLE OF ty_raw WITH EMPTY KEY.
METHODS read_washes
IMPORTING iv_from TYPE d
iv_to TYPE d
it_prog TYPE tt_prog
RETURNING VALUE(rt_raw) TYPE tt_raw.
METHODS aggregate
IMPORTING it_raw TYPE tt_raw
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD collect.
rt_lines = aggregate( read_washes( iv_from = iv_from
iv_to = iv_to
it_prog = it_prog ) ).
SORT rt_lines BY revenue DESCENDING.
ENDMETHOD.
METHOD read_washes.
SELECT c~wash_prog, p~prog_text, c~price, c~cust_type
FROM {{p}}carwash AS c
LEFT OUTER JOIN {{p}}washpgm AS p ON p~wash_prog = c~wash_prog
WHERE c~wash_date >= @iv_from
AND c~wash_date <= @iv_to
AND c~wash_prog IN @it_prog
INTO CORRESPONDING FIELDS OF TABLE @rt_raw.
ENDMETHOD.
METHOD aggregate.
LOOP AT it_raw INTO DATA(ls_raw).
IF NOT line_exists( rt_lines[ wash_prog = ls_raw-wash_prog ] ).
APPEND VALUE #( wash_prog = ls_raw-wash_prog
prog_text = ls_raw-prog_text ) TO rt_lines.
ENDIF.
ASSIGN rt_lines[ wash_prog = ls_raw-wash_prog ] TO FIELD-SYMBOL(<ls_line>).
<ls_line>-washes = <ls_line>-washes + 1.
<ls_line>-revenue = <ls_line>-revenue + ls_raw-price.
IF ls_raw-cust_type = 'VIP'.
<ls_line>-vip_washes = <ls_line>-vip_washes + 1.
<ls_line>-vip_revenue = <ls_line>-vip_revenue + ls_raw-price.
ENDIF.
ENDLOOP.
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_prog = s_prog[] ).
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_program FOR TESTING.
METHODS program_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}CARWASH' ) ( '{{P}}WASHPGM' ) ) ).
DATA lt_carwash TYPE STANDARD TABLE OF {{p}}carwash WITH EMPTY KEY.
lt_carwash = VALUE #(
( wash_id = 1 wash_prog = 'A' wash_date = '20260101' price = 10 cust_type = 'STD' )
( wash_id = 2 wash_prog = 'A' wash_date = '20260102' price = 5 cust_type = 'VIP' )
( wash_id = 3 wash_prog = 'B' wash_date = '20260101' price = 40 cust_type = 'STD' ) ).
go_env->insert_test_data( lt_carwash ).
DATA lt_prog TYPE STANDARD TABLE OF {{p}}washpgm WITH EMPTY KEY.
lt_prog = VALUE #( ( wash_prog = 'A' prog_text = 'Alpha' )
( wash_prog = 'B' prog_text = 'Beta' ) ).
go_env->insert_test_data( lt_prog ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_program.
DATA(lt_lines) = NEW lcl_report( )->collect( iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'B' act = lt_lines[ 1 ]-wash_prog ).
cl_abap_unit_assert=>assert_equals( exp = 'Beta' act = lt_lines[ 1 ]-prog_text ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 2 ]-washes ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}carwash-price( 15 ) act = lt_lines[ 2 ]-revenue ).
ENDMETHOD.
METHOD program_filter.
DATA(lt_lines) = NEW lcl_report( )->collect(
iv_from = '20260101'
iv_to = '20260131'
it_prog = VALUE #( ( sign = 'I' option = 'EQ' low = 'A' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_lines[ 1 ]-vip_washes ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,13 @@
@EndUserText.label : 'Car wash visits'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}carwash {
key client : abap.clnt not null;
key wash_id : abap.int4 not null;
wash_prog : abap.char(4);
wash_date : abap.dats;
price : abap.dec(15,2);
cust_type : abap.char(3);
}

View File

@@ -0,0 +1,79 @@
REPORT {{p}}carwash_rpt.
TABLES: {{p}}carwash, {{p}}washpgm.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_prog FOR {{p}}carwash-wash_prog.
TYPES: BEGIN OF ty_out,
wash_prog TYPE {{p}}carwash-wash_prog,
prog_text TYPE {{p}}washpgm-prog_text,
washes TYPE i,
revenue TYPE {{p}}carwash-price,
vip_washes TYPE i,
vip_revenue TYPE {{p}}carwash-price,
END OF ty_out.
TYPES: BEGIN OF ty_data,
wash_prog TYPE {{p}}carwash-wash_prog,
price TYPE {{p}}carwash-price,
cust_type TYPE {{p}}carwash-cust_type,
END OF ty_data.
DATA: gt_out TYPE STANDARD TABLE OF ty_out WITH HEADER LINE,
gt_data TYPE STANDARD TABLE OF ty_data WITH HEADER LINE.
DATA: gv_text TYPE {{p}}washpgm-prog_text,
gv_alv TYPE REF TO cl_salv_table.
START-OF-SELECTION.
SELECT * FROM {{p}}carwash INTO CORRESPONDING FIELDS OF TABLE gt_data
WHERE wash_date >= p_from AND wash_date <= p_to.
LOOP AT gt_data.
IF gt_data-wash_prog IN s_prog.
READ TABLE gt_out WITH KEY wash_prog = gt_data-wash_prog.
IF sy-subrc = 0.
gt_out-washes = gt_out-washes + 1.
gt_out-revenue = gt_out-revenue + gt_data-price.
IF gt_data-cust_type = 'VIP'.
gt_out-vip_washes = gt_out-vip_washes + 1.
gt_out-vip_revenue = gt_out-vip_revenue + gt_data-price.
ENDIF.
MODIFY gt_out INDEX sy-tabix.
ELSE.
CLEAR gt_out.
gt_out-wash_prog = gt_data-wash_prog.
gt_out-washes = 1.
gt_out-revenue = gt_data-price.
IF gt_data-cust_type = 'VIP'.
gt_out-vip_washes = 1.
gt_out-vip_revenue = gt_data-price.
ELSE.
gt_out-vip_washes = 0.
gt_out-vip_revenue = 0.
ENDIF.
APPEND gt_out.
ENDIF.
ENDIF.
ENDLOOP.
LOOP AT gt_out.
CLEAR gv_text.
SELECT SINGLE prog_text FROM {{p}}washpgm INTO gv_text
WHERE wash_prog = gt_out-wash_prog.
gt_out-prog_text = gv_text.
MODIFY gt_out.
ENDLOOP.
SORT gt_out BY revenue DESCENDING.
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = gv_alv
CHANGING t_table = gt_out[] ).
gv_alv->display( ).
CATCH cx_salv_msg.
ENDTRY.

View File

@@ -0,0 +1,25 @@
CLASS {{p}}carwash_seed DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS {{p}}carwash_seed IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DELETE FROM {{p}}carwash.
DELETE FROM {{p}}washpgm.
INSERT {{p}}washpgm FROM TABLE @( VALUE #(
( wash_prog = 'BAS' prog_text = 'Basic wash' )
( wash_prog = 'DLX' prog_text = 'Deluxe wash' )
( wash_prog = 'PRM' prog_text = 'Premium wash' ) ) ).
INSERT {{p}}carwash FROM TABLE @( VALUE #(
( wash_id = 1 wash_prog = 'BAS' wash_date = '20260105' price = '10.00' cust_type = 'STD' )
( wash_id = 2 wash_prog = 'BAS' wash_date = '20260106' price = '10.00' cust_type = 'VIP' )
( wash_id = 3 wash_prog = 'DLX' wash_date = '20260107' price = '20.00' cust_type = 'STD' )
( wash_id = 4 wash_prog = 'DLX' wash_date = '20260108' price = '20.00' cust_type = 'VIP' )
( wash_id = 5 wash_prog = 'DLX' wash_date = '20260109' price = '20.00' cust_type = 'STD' )
( wash_id = 6 wash_prog = 'PRM' wash_date = '20260110' price = '50.00' cust_type = 'VIP' )
( wash_id = 7 wash_prog = 'PRM' wash_date = '20260215' price = '50.00' cust_type = 'STD' )
( wash_id = 8 wash_prog = 'BAS' wash_date = '20260220' price = '10.00' cust_type = 'STD' ) ) ).
out->write( sy-dbcnt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,10 @@
@EndUserText.label : 'Wash programs'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}washpgm {
key client : abap.clnt not null;
key wash_prog : abap.char(4) not null;
prog_text : abap.char(30);
}

View File

@@ -0,0 +1,52 @@
# 1. Goal
The car wash chain uses the program {{P}}CARWASH_RPT to show the washes and
the revenue of each wash program for a period. The program is a legacy report.
The users complain about the code quality. Refactor the program in place. The
behavior stays the same.
# 2. Open questions
None.
# 3. Context
- {{P}}CARWASH_RPT is an executable program in package $TMP. It is in
production and it runs.
- The program reads the tables {{P}}CARWASH (the wash visits) and {{P}}WASHPGM
(the text of each wash program).
- The legacy source code of the program contains the business rules. Read the
legacy code.
- The behavior must not change: the same selection screen, the same ALV
columns, and the same numbers.
# 4. Contract
- Refactor the program {{P}}CARWASH_RPT in package $TMP. The name stays the
same. The public interface stays the same.
- Selection screen:
- P_FROM, type DATS, mandatory: the first wash date to include.
- P_TO, type DATS, mandatory: the last wash date to include.
- S_PROG, select-option for the wash program.
- The program shows the result with CL_SALV_TABLE. The ALV columns keep these
names: WASH_PROG, PROG_TEXT, WASHES, REVENUE, VIP_WASHES, VIP_REVENUE.
- The hidden tests call the program with SUBMIT and read the ALV data. They use
only the names above.
# 5. Business rules
The business rules are in the legacy code of {{P}}CARWASH_RPT. Read the legacy
code. The refactored program applies the same rules and shows the same numbers.
Do not change the rules.
# 6. Constraints
- Release target: 7.58.
- Coding standards: Clean ABAP.
- The program is modular. The logic is in small methods with clear names.
- No method has more than 40 statements.
- No database access inside a loop.
- No duplicated logic.
- The program has no ATC priority 1 or priority 2 finding.
- Out of scope: do not change {{P}}CARWASH, {{P}}WASHPGM, and
{{P}}CARWASH_SEED.
# 7. Acceptance
- The program {{P}}CARWASH_RPT is active and has no syntax error.
- The behavior is unchanged.
- The hidden tests pass.
- Write ABAP Unit tests as local test classes in the program.

View File

@@ -0,0 +1,75 @@
{
"id": "G0140",
"category": "E",
"object_type": "PROG",
"difficulty": 2,
"release_target": "v758",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "TABL",
"name": "{{P}}CARWASH",
"file": "seed/carwash.tabl.asabap",
"description": "Car wash visits"
},
{
"type": "TABL",
"name": "{{P}}WASHPGM",
"file": "seed/washpgm.tabl.asabap",
"description": "Wash programs"
},
{
"type": "PROG",
"name": "{{P}}CARWASH_RPT",
"file": "seed/carwash_rpt.prog.abap",
"description": "Legacy car wash report"
},
{
"type": "CLAS",
"name": "{{P}}CARWASH_SEED",
"file": "seed/carwash_seed.clas.abap",
"description": "Car wash seed data",
"run": true
}
],
"contract": [
{
"type": "PROG",
"name": "{{P}}CARWASH_RPT",
"parameters": [
"p_from",
"p_to",
"s_prog"
]
}
],
"out_of_scope": [
"{{P}}CARWASH",
"{{P}}WASHPGM",
"{{P}}CARWASH_SEED"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}CARWASH_HIDDEN",
"file": "hidden/carwash_hidden.clas.abap",
"description": "Hidden tests for the car wash report"
}
],
"reference": [
{
"type": "PROG",
"name": "{{P}}CARWASH_RPT",
"file": "reference/carwash_rpt.prog.abap",
"description": "Refactored car wash report"
}
],
"craft_checks": [
"db_operation_in_loop",
"method_length"
]
}