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,122 @@
REPORT {{p}}studio_bill.
TYPES ty_amount TYPE p LENGTH 15 DECIMALS 2.
DATA gv_customer TYPE {{p}}studio-customer.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_min TYPE ty_amount OBLIGATORY.
SELECT-OPTIONS s_cust FOR gv_customer.
CLASS lcl_billing DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
customer TYPE {{p}}studio-customer,
sessions TYPE i,
tracks TYPE i,
fee TYPE {{p}}studio-fee,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_customer TYPE RANGE OF {{p}}studio-customer.
METHODS select_bills
IMPORTING iv_from TYPE d
iv_min TYPE ty_amount
it_customer TYPE tt_customer
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_billing IMPLEMENTATION.
METHOD select_bills.
SELECT customer,
COUNT( * ) AS sessions,
SUM( tracks ) AS tracks,
SUM( fee ) AS fee
FROM {{p}}studio
WHERE rec_date < @iv_from
AND tracks > 0
AND customer IN @it_customer
GROUP BY customer
HAVING SUM( fee ) >= @iv_min
ORDER BY fee DESCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
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_billing) = NEW lcl_billing( ).
DATA(gt_lines) = go_billing->select_bills( iv_from = p_from
iv_min = p_min
it_customer = s_cust[] ).
go_billing->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_billing 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_customer FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS zero_tracks_ignored FOR TESTING.
METHODS min_fee_filter FOR TESTING.
ENDCLASS.
CLASS ltc_billing IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}STUDIO' ) ) ).
DATA lt_studio TYPE STANDARD TABLE OF {{p}}studio WITH EMPTY KEY.
lt_studio = VALUE #(
( rec_id = 1 customer = 'ACME' rec_date = '20260101' tracks = 10 fee = 100 )
( rec_id = 2 customer = 'ACME' rec_date = '20260102' tracks = 5 fee = 50 )
( rec_id = 3 customer = 'BLUE' rec_date = '20260101' tracks = 0 fee = 0 )
( rec_id = 4 customer = 'BLUE' rec_date = '20251201' tracks = 7 fee = 70 ) ).
go_env->insert_test_data( lt_studio ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_customer.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-sessions ).
cl_abap_unit_assert=>assert_equals( exp = 15 act = lt_lines[ 1 ]-tracks ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}studio-fee( 150 ) act = lt_lines[ 1 ]-fee ).
ENDMETHOD.
METHOD date_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD zero_tracks_ignored.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0
it_customer = VALUE #( ( sign = 'I' option = 'EQ' low = 'BLUE' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD min_fee_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 120 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'ACME' act = lt_lines[ 1 ]-customer ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,122 @@
REPORT {{p}}studio_bill.
TYPES ty_amount TYPE p LENGTH 15 DECIMALS 2.
DATA gv_customer TYPE {{p}}studio-customer.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_min TYPE ty_amount OBLIGATORY.
SELECT-OPTIONS s_cust FOR gv_customer.
CLASS lcl_billing DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
customer TYPE {{p}}studio-customer,
sessions TYPE i,
tracks TYPE i,
fee TYPE {{p}}studio-fee,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_customer TYPE RANGE OF {{p}}studio-customer.
METHODS select_bills
IMPORTING iv_from TYPE d
iv_min TYPE ty_amount
it_customer TYPE tt_customer
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_billing IMPLEMENTATION.
METHOD select_bills.
SELECT customer,
COUNT( * ) AS sessions,
SUM( tracks ) AS tracks,
SUM( fee ) AS fee
FROM {{p}}studio
WHERE rec_date >= @iv_from
OR tracks > 0
AND customer IN @it_customer
GROUP BY customer
HAVING SUM( fee ) >= @iv_min
ORDER BY fee DESCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
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_billing) = NEW lcl_billing( ).
DATA(gt_lines) = go_billing->select_bills( iv_from = p_from
iv_min = p_min
it_customer = s_cust[] ).
go_billing->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_billing 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_customer FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS zero_tracks_ignored FOR TESTING.
METHODS min_fee_filter FOR TESTING.
ENDCLASS.
CLASS ltc_billing IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}STUDIO' ) ) ).
DATA lt_studio TYPE STANDARD TABLE OF {{p}}studio WITH EMPTY KEY.
lt_studio = VALUE #(
( rec_id = 1 customer = 'ACME' rec_date = '20260101' tracks = 10 fee = 100 )
( rec_id = 2 customer = 'ACME' rec_date = '20260102' tracks = 5 fee = 50 )
( rec_id = 3 customer = 'BLUE' rec_date = '20260101' tracks = 0 fee = 0 )
( rec_id = 4 customer = 'BLUE' rec_date = '20251201' tracks = 7 fee = 70 ) ).
go_env->insert_test_data( lt_studio ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_customer.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-sessions ).
cl_abap_unit_assert=>assert_equals( exp = 15 act = lt_lines[ 1 ]-tracks ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}studio-fee( 150 ) act = lt_lines[ 1 ]-fee ).
ENDMETHOD.
METHOD date_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD zero_tracks_ignored.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0
it_customer = VALUE #( ( sign = 'I' option = 'EQ' low = 'BLUE' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD min_fee_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 120 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'ACME' act = lt_lines[ 1 ]-customer ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,122 @@
REPORT {{p}}studio_bill.
TYPES ty_amount TYPE p LENGTH 15 DECIMALS 2.
DATA gv_customer TYPE {{p}}studio-customer.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_min TYPE ty_amount OBLIGATORY.
SELECT-OPTIONS s_cust FOR gv_customer.
CLASS lcl_billing DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
customer TYPE {{p}}studio-customer,
sessions TYPE i,
tracks TYPE i,
fee TYPE {{p}}studio-fee,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_customer TYPE RANGE OF {{p}}studio-customer.
METHODS select_bills
IMPORTING iv_from TYPE d
iv_min TYPE ty_amount
it_customer TYPE tt_customer
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_billing IMPLEMENTATION.
METHOD select_bills.
SELECT customer,
COUNT( * ) AS sessions,
SUM( tracks ) AS tracks,
SUM( fee ) AS fee
FROM {{p}}studio
WHERE rec_date >= @iv_from
AND tracks <= 0
AND customer IN @it_customer
GROUP BY customer
HAVING SUM( fee ) >= @iv_min
ORDER BY fee DESCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
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_billing) = NEW lcl_billing( ).
DATA(gt_lines) = go_billing->select_bills( iv_from = p_from
iv_min = p_min
it_customer = s_cust[] ).
go_billing->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_billing 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_customer FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS zero_tracks_ignored FOR TESTING.
METHODS min_fee_filter FOR TESTING.
ENDCLASS.
CLASS ltc_billing IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}STUDIO' ) ) ).
DATA lt_studio TYPE STANDARD TABLE OF {{p}}studio WITH EMPTY KEY.
lt_studio = VALUE #(
( rec_id = 1 customer = 'ACME' rec_date = '20260101' tracks = 10 fee = 100 )
( rec_id = 2 customer = 'ACME' rec_date = '20260102' tracks = 5 fee = 50 )
( rec_id = 3 customer = 'BLUE' rec_date = '20260101' tracks = 0 fee = 0 )
( rec_id = 4 customer = 'BLUE' rec_date = '20251201' tracks = 7 fee = 70 ) ).
go_env->insert_test_data( lt_studio ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_customer.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-sessions ).
cl_abap_unit_assert=>assert_equals( exp = 15 act = lt_lines[ 1 ]-tracks ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}studio-fee( 150 ) act = lt_lines[ 1 ]-fee ).
ENDMETHOD.
METHOD date_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD zero_tracks_ignored.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0
it_customer = VALUE #( ( sign = 'I' option = 'EQ' low = 'BLUE' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD min_fee_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 120 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'ACME' act = lt_lines[ 1 ]-customer ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,122 @@
REPORT {{p}}studio_bill.
TYPES ty_amount TYPE p LENGTH 15 DECIMALS 2.
DATA gv_customer TYPE {{p}}studio-customer.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_min TYPE ty_amount OBLIGATORY.
SELECT-OPTIONS s_cust FOR gv_customer.
CLASS lcl_billing DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
customer TYPE {{p}}studio-customer,
sessions TYPE i,
tracks TYPE i,
fee TYPE {{p}}studio-fee,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_customer TYPE RANGE OF {{p}}studio-customer.
METHODS select_bills
IMPORTING iv_from TYPE d
iv_min TYPE ty_amount
it_customer TYPE tt_customer
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_billing IMPLEMENTATION.
METHOD select_bills.
SELECT customer,
COUNT( * ) AS sessions,
SUM( tracks ) AS tracks,
SUM( fee ) AS fee
FROM {{p}}studio
WHERE rec_date >= @iv_from
AND tracks > 0
OR customer IN @it_customer
GROUP BY customer
HAVING SUM( fee ) >= @iv_min
ORDER BY fee DESCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
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_billing) = NEW lcl_billing( ).
DATA(gt_lines) = go_billing->select_bills( iv_from = p_from
iv_min = p_min
it_customer = s_cust[] ).
go_billing->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_billing 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_customer FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS zero_tracks_ignored FOR TESTING.
METHODS min_fee_filter FOR TESTING.
ENDCLASS.
CLASS ltc_billing IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}STUDIO' ) ) ).
DATA lt_studio TYPE STANDARD TABLE OF {{p}}studio WITH EMPTY KEY.
lt_studio = VALUE #(
( rec_id = 1 customer = 'ACME' rec_date = '20260101' tracks = 10 fee = 100 )
( rec_id = 2 customer = 'ACME' rec_date = '20260102' tracks = 5 fee = 50 )
( rec_id = 3 customer = 'BLUE' rec_date = '20260101' tracks = 0 fee = 0 )
( rec_id = 4 customer = 'BLUE' rec_date = '20251201' tracks = 7 fee = 70 ) ).
go_env->insert_test_data( lt_studio ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_customer.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-sessions ).
cl_abap_unit_assert=>assert_equals( exp = 15 act = lt_lines[ 1 ]-tracks ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}studio-fee( 150 ) act = lt_lines[ 1 ]-fee ).
ENDMETHOD.
METHOD date_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD zero_tracks_ignored.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0
it_customer = VALUE #( ( sign = 'I' option = 'EQ' low = 'BLUE' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD min_fee_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 120 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'ACME' act = lt_lines[ 1 ]-customer ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,122 @@
REPORT {{p}}studio_bill.
TYPES ty_amount TYPE p LENGTH 15 DECIMALS 2.
DATA gv_customer TYPE {{p}}studio-customer.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_min TYPE ty_amount OBLIGATORY.
SELECT-OPTIONS s_cust FOR gv_customer.
CLASS lcl_billing DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
customer TYPE {{p}}studio-customer,
sessions TYPE i,
tracks TYPE i,
fee TYPE {{p}}studio-fee,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_customer TYPE RANGE OF {{p}}studio-customer.
METHODS select_bills
IMPORTING iv_from TYPE d
iv_min TYPE ty_amount
it_customer TYPE tt_customer
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_billing IMPLEMENTATION.
METHOD select_bills.
SELECT customer,
COUNT( * ) AS sessions,
SUM( tracks ) AS tracks,
SUM( fee ) AS fee
FROM {{p}}studio
WHERE rec_date >= @iv_from
AND tracks > 0
AND customer IN @it_customer
GROUP BY customer
HAVING SUM( fee ) < @iv_min
ORDER BY fee DESCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
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_billing) = NEW lcl_billing( ).
DATA(gt_lines) = go_billing->select_bills( iv_from = p_from
iv_min = p_min
it_customer = s_cust[] ).
go_billing->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_billing 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_customer FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS zero_tracks_ignored FOR TESTING.
METHODS min_fee_filter FOR TESTING.
ENDCLASS.
CLASS ltc_billing IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}STUDIO' ) ) ).
DATA lt_studio TYPE STANDARD TABLE OF {{p}}studio WITH EMPTY KEY.
lt_studio = VALUE #(
( rec_id = 1 customer = 'ACME' rec_date = '20260101' tracks = 10 fee = 100 )
( rec_id = 2 customer = 'ACME' rec_date = '20260102' tracks = 5 fee = 50 )
( rec_id = 3 customer = 'BLUE' rec_date = '20260101' tracks = 0 fee = 0 )
( rec_id = 4 customer = 'BLUE' rec_date = '20251201' tracks = 7 fee = 70 ) ).
go_env->insert_test_data( lt_studio ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_customer.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-sessions ).
cl_abap_unit_assert=>assert_equals( exp = 15 act = lt_lines[ 1 ]-tracks ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}studio-fee( 150 ) act = lt_lines[ 1 ]-fee ).
ENDMETHOD.
METHOD date_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD zero_tracks_ignored.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0
it_customer = VALUE #( ( sign = 'I' option = 'EQ' low = 'BLUE' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD min_fee_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 120 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'ACME' act = lt_lines[ 1 ]-customer ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,44 @@
{
"id": "G1148",
"pool": "train",
"object_type": "PROG",
"category": "B",
"attempts": [
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "bundle",
"errors": [
"hidden/t15_hidden.clas.abap line 81: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/t15_hidden.clas.abap line 83: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"01\"",
"hidden/t15_hidden.clas.abap line 87: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"DATA\"",
"hidden/t15_hidden.clas.abap line 87: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"01\"",
"hidden/t15_hidden.clas.abap line 97: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"DATA\"",
"hidden/t15_hidden.clas.abap line 97: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"01\"",
"hidden/t15_hidden.clas.abap line 113: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/t15_hidden.clas.abap line 115: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"01\"",
"hidden/t15_hidden.clas.abap line 119: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"DATA\"",
"hidden/t15_hidden.clas.abap line 119: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"01\"",
"hidden/t15_hidden.clas.abap line 128: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/t15_hidden.clas.abap line 130: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"01\""
],
"by_check": {
"abaplint": 12
}
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 5,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,132 @@
CLASS {{p}}t15_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_min TYPE p LENGTH 15 DECIMALS 2.
TYPES tt_customer TYPE RANGE OF {{p}}studio-customer.
METHODS run
IMPORTING iv_from TYPE d
iv_min TYPE ty_min
it_customer TYPE tt_customer 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_customers FOR TESTING.
METHODS sorted_by_fee FOR TESTING.
METHODS totals_and_counts FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS customer_filter FOR TESTING.
METHODS zero_tracks_excluded FOR TESTING.
METHODS min_fee_filter FOR TESTING.
ENDCLASS.
CLASS {{p}}t15_hidden IMPLEMENTATION.
METHOD run.
cl_salv_bs_runtime_info=>set( display = abap_false
metadata = abap_false
data = abap_true ).
SUBMIT {{p}}studio_bill
WITH p_from = iv_from
WITH p_min = iv_min
WITH s_cust IN it_customer
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_customers.
cl_abap_unit_assert=>assert_equals(
exp = 3
act = lines_of( run( iv_from = '20260101' iv_min = 1 ) ) ).
ENDMETHOD.
METHOD sorted_by_fee.
DATA(lr_data) = run( iv_from = '20260101' iv_min = 1 ).
cl_abap_unit_assert=>assert_equals(
exp = `BLUE`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `CUSTOMER` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `DELTA`
act = value_of( ir_data = lr_data iv_row = 3 iv_col = `CUSTOMER` ) ).
ENDMETHOD.
METHOD totals_and_counts.
DATA(lr_data) = run( iv_from = '20260101' iv_min = 1 ).
cl_abap_unit_assert=>assert_equals(
exp = `ACME`
act = value_of( ir_data = lr_data iv_row = 2 iv_col = `CUSTOMER` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `2`
act = value_of( ir_data = lr_data iv_row = 2 iv_col = `SESSIONS` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `18`
act = value_of( ir_data = lr_data iv_row = 2 iv_col = `TRACKS` ) ).
cl_abap_unit_assert=>assert_equals(
exp = `450.00`
act = value_of( ir_data = lr_data iv_row = 2 iv_col = `FEE` ) ).
ENDMETHOD.
METHOD date_filter.
cl_abap_unit_assert=>assert_equals(
exp = 1
act = lines_of( run( iv_from = '20260301' iv_min = 1 ) ) ).
ENDMETHOD.
METHOD customer_filter.
DATA(lr_data) = run( iv_from = '20260101' iv_min = 1
it_customer = VALUE #( ( sign = 'I' option = 'EQ' low = 'ACME' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals(
exp = `450.00`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `FEE` ) ).
ENDMETHOD.
METHOD zero_tracks_excluded.
cl_abap_unit_assert=>assert_equals(
exp = 0
act = lines_of( run( iv_from = '20260101' iv_min = 1
it_customer = VALUE #( ( sign = 'I' option = 'EQ' low = 'CORAL' ) ) ) ) ).
ENDMETHOD.
METHOD min_fee_filter.
cl_abap_unit_assert=>assert_equals(
exp = 2
act = lines_of( run( iv_from = '20260101' iv_min = 300 ) ) ).
cl_abap_unit_assert=>assert_equals(
exp = 2
act = lines_of( run( iv_from = '20260101' iv_min = 450 ) ) ).
cl_abap_unit_assert=>assert_equals(
exp = 1
act = lines_of( run( iv_from = '20260101' iv_min = 460 ) ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,73 @@
{
"task": "G1148",
"mutants": [
{
"object": "{{P}}STUDIO_BILL",
"mutant": "line 40: >= -> < (rel)",
"status": "killed",
"hidden": "1/7",
"failed_tests": [
"ALL_CUSTOMERS",
"CUSTOMER_FILTER",
"DATE_FILTER",
"MIN_FEE_FILTER",
"SORTED_BY_FEE",
"TOTALS_AND_COUNTS"
]
},
{
"object": "{{P}}STUDIO_BILL",
"mutant": "line 41: AND -> OR (logic)",
"status": "killed",
"hidden": "4/7",
"failed_tests": [
"CUSTOMER_FILTER",
"DATE_FILTER",
"ZERO_TRACKS_EXCLUDED"
]
},
{
"object": "{{P}}STUDIO_BILL",
"mutant": "line 41: > -> <= (rel)",
"status": "killed",
"hidden": "1/7",
"failed_tests": [
"ALL_CUSTOMERS",
"CUSTOMER_FILTER",
"DATE_FILTER",
"MIN_FEE_FILTER",
"SORTED_BY_FEE",
"TOTALS_AND_COUNTS"
]
},
{
"object": "{{P}}STUDIO_BILL",
"mutant": "line 42: AND -> OR (logic)",
"status": "killed",
"hidden": "4/7",
"failed_tests": [
"CUSTOMER_FILTER",
"DATE_FILTER",
"ZERO_TRACKS_EXCLUDED"
]
},
{
"object": "{{P}}STUDIO_BILL",
"mutant": "line 44: >= -> < (rel)",
"status": "killed",
"hidden": "1/7",
"failed_tests": [
"ALL_CUSTOMERS",
"CUSTOMER_FILTER",
"DATE_FILTER",
"MIN_FEE_FILTER",
"SORTED_BY_FEE",
"TOTALS_AND_COUNTS"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,122 @@
REPORT {{p}}studio_bill.
TYPES ty_amount TYPE p LENGTH 15 DECIMALS 2.
DATA gv_customer TYPE {{p}}studio-customer.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_min TYPE ty_amount OBLIGATORY.
SELECT-OPTIONS s_cust FOR gv_customer.
CLASS lcl_billing DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
customer TYPE {{p}}studio-customer,
sessions TYPE i,
tracks TYPE i,
fee TYPE {{p}}studio-fee,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_customer TYPE RANGE OF {{p}}studio-customer.
METHODS select_bills
IMPORTING iv_from TYPE d
iv_min TYPE ty_amount
it_customer TYPE tt_customer
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_billing IMPLEMENTATION.
METHOD select_bills.
SELECT customer,
COUNT( * ) AS sessions,
SUM( tracks ) AS tracks,
SUM( fee ) AS fee
FROM {{p}}studio
WHERE rec_date >= @iv_from
AND tracks > 0
AND customer IN @it_customer
GROUP BY customer
HAVING SUM( fee ) >= @iv_min
ORDER BY fee DESCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
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_billing) = NEW lcl_billing( ).
DATA(gt_lines) = go_billing->select_bills( iv_from = p_from
iv_min = p_min
it_customer = s_cust[] ).
go_billing->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_billing 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_customer FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS zero_tracks_ignored FOR TESTING.
METHODS min_fee_filter FOR TESTING.
ENDCLASS.
CLASS ltc_billing IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}STUDIO' ) ) ).
DATA lt_studio TYPE STANDARD TABLE OF {{p}}studio WITH EMPTY KEY.
lt_studio = VALUE #(
( rec_id = 1 customer = 'ACME' rec_date = '20260101' tracks = 10 fee = 100 )
( rec_id = 2 customer = 'ACME' rec_date = '20260102' tracks = 5 fee = 50 )
( rec_id = 3 customer = 'BLUE' rec_date = '20260101' tracks = 0 fee = 0 )
( rec_id = 4 customer = 'BLUE' rec_date = '20251201' tracks = 7 fee = 70 ) ).
go_env->insert_test_data( lt_studio ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_customer.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-sessions ).
cl_abap_unit_assert=>assert_equals( exp = 15 act = lt_lines[ 1 ]-tracks ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}studio-fee( 150 ) act = lt_lines[ 1 ]-fee ).
ENDMETHOD.
METHOD date_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 0 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD zero_tracks_ignored.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20260101' iv_min = 0
it_customer = VALUE #( ( sign = 'I' option = 'EQ' low = 'BLUE' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_lines ) ).
ENDMETHOD.
METHOD min_fee_filter.
DATA(lt_lines) = NEW lcl_billing( )->select_bills(
iv_from = '20251201' iv_min = 120 it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'ACME' act = lt_lines[ 1 ]-customer ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,13 @@
@EndUserText.label : 'Recording sessions of the studio'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}studio {
key client : abap.clnt not null;
key rec_id : abap.int4 not null;
customer : abap.char(10);
rec_date : abap.dats;
tracks : abap.int4;
fee : abap.dec(15,2);
}

View File

@@ -0,0 +1,18 @@
CLASS {{p}}t15_seed DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS {{p}}t15_seed IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DELETE FROM {{p}}studio.
INSERT {{p}}studio FROM TABLE @( VALUE #(
( rec_id = 1 customer = 'ACME' rec_date = '20260110' tracks = 12 fee = '300.00' )
( rec_id = 2 customer = 'ACME' rec_date = '20260205' tracks = 6 fee = '150.00' )
( rec_id = 3 customer = 'BLUE' rec_date = '20260115' tracks = 9 fee = '500.00' )
( rec_id = 4 customer = 'BLUE' rec_date = '20251220' tracks = 3 fee = '100.00' )
( rec_id = 5 customer = 'CORAL' rec_date = '20260301' tracks = 0 fee = '0.00' )
( rec_id = 6 customer = 'DELTA' rec_date = '20260401' tracks = 5 fee = '225.00' ) ) ).
out->write( sy-dbcnt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,43 @@
# 1. Goal
Show the studio fee of each customer in an ALV list. The studio uses the list to
bill its customers for a period.
# 2. Open questions
None.
# 3. Context
- The table {{P}}STUDIO exists in package $TMP. It contains the recording
sessions of the studio and it contains data.
Fields: REC_ID (INT4, key), CUSTOMER (CHAR 10), REC_DATE (DATS),
TRACKS (INT4), FEE (DEC 15,2).
# 4. Contract
- Create the executable program {{P}}STUDIO_BILL in package $TMP.
- Selection screen:
- Parameter P_FROM, type DATS, mandatory: the first recording date to include.
- Parameter P_MIN, type P LENGTH 15 DECIMALS 2, mandatory: the minimum total
fee.
- Select-option S_CUST for the customer.
- Show the result with CL_SALV_TABLE. The output table has these columns with
these names:
- CUSTOMER: the customer.
- SESSIONS: the number of included recording sessions of the customer.
- TRACKS: the sum of TRACKS of the included sessions.
- FEE: the sum of FEE of the included sessions.
# 5. Business rules
1. Include a recording session only if REC_DATE is on or after P_FROM, CUSTOMER
is in S_CUST, and TRACKS is greater than zero.
2. Show one line for each customer that has at least one included session.
3. Show only the customers whose total fee is on or after P_MIN.
4. Sort the lines by FEE, the highest fee first.
# 6. Constraints
- Release target: 7.58.
- Coding standards: Clean ABAP. Read the data with one database access.
- Out of scope: do not change the table {{P}}STUDIO.
# 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,61 @@
{
"id": "G1148",
"category": "B",
"object_type": "PROG",
"difficulty": 2,
"release_target": "v758",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "TABL",
"name": "{{P}}STUDIO",
"file": "seed/studio.tabl.asabap",
"description": "Recording sessions of the studio"
},
{
"type": "CLAS",
"name": "{{P}}T15_SEED",
"file": "seed/t15_seed.clas.abap",
"description": "T15 seed data",
"run": true
}
],
"contract": [
{
"type": "PROG",
"name": "{{P}}STUDIO_BILL",
"parameters": [
"p_from",
"p_min",
"s_cust"
]
}
],
"out_of_scope": [
"{{P}}STUDIO"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T15_HIDDEN",
"file": "hidden/t15_hidden.clas.abap",
"description": "T15 hidden tests"
}
],
"reference": [
{
"type": "PROG",
"name": "{{P}}STUDIO_BILL",
"file": "reference/studio_bill.prog.abap",
"description": "Studio fee per customer"
}
],
"craft_checks": [
"db_operation_in_loop",
"method_length"
]
}