Pipeline controller: plan 2 (hard +, error +50 %), backlog throttle, 2 trajectory workers, stop rules, summaries every 50; budget reserve

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 13:35:54 +02:00
parent 1c4667a0fc
commit 13360292dd
781 changed files with 50211 additions and 22 deletions

View File

@@ -0,0 +1,71 @@
CLASS {{p}}harvest_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS evaluate
IMPORTING it_report TYPE {{p}}if_harvest=>tt_report
it_member TYPE {{p}}if_harvest=>tt_member
RETURNING VALUE(rt_result) TYPE {{p}}if_harvest=>tt_result.
PRIVATE SECTION.
TYPES tt_member_key TYPE HASHED TABLE OF {{p}}if_harvest=>ty_member
WITH UNIQUE KEY member_id.
TYPES tt_member_id TYPE SORTED TABLE OF {{p}}if_harvest=>ty_member_id
WITH UNIQUE KEY table_line.
TYPES tt_report_key TYPE SORTED TABLE OF {{p}}if_harvest=>ty_report
WITH NON-UNIQUE KEY variety member_id.
METHODS countable_reports
IMPORTING it_report TYPE {{p}}if_harvest=>tt_report
it_member TYPE tt_member_key
RETURNING VALUE(rt_report) TYPE tt_report_key.
METHODS is_countable
IMPORTING is_report TYPE {{p}}if_harvest=>ty_report
it_member TYPE tt_member_key
RETURNING VALUE(rv_count) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}harvest_evaluator IMPLEMENTATION.
METHOD evaluate.
DATA lt_member TYPE tt_member_key.
lt_member = it_member.
DATA(lt_report) = countable_reports( it_report = it_report
it_member = lt_member ).
DATA lt_result TYPE {{p}}if_harvest=>tt_result.
DATA lt_member_id TYPE tt_member_id.
LOOP AT lt_report ASSIGNING FIELD-SYMBOL(<ls_report>) GROUP BY <ls_report>-variety.
DATA(lv_variety) = <ls_report>-variety.
DATA(lv_total) = 0.
CLEAR lt_member_id.
LOOP AT GROUP <ls_report> ASSIGNING FIELD-SYMBOL(<ls_grouped>).
lv_total = lv_total - <ls_grouped>-quantity_kg.
INSERT <ls_grouped>-member_id INTO TABLE lt_member_id.
ENDLOOP.
APPEND VALUE {{p}}if_harvest=>ty_result(
variety = lv_variety
total_kg = lv_total
member_count = lines( lt_member_id ) ) TO lt_result.
ENDLOOP.
SORT lt_result BY total_kg DESCENDING variety ASCENDING.
rt_result = lt_result.
ENDMETHOD.
METHOD countable_reports.
LOOP AT it_report INTO DATA(ls_report).
IF is_countable( is_report = ls_report
it_member = it_member ) = abap_false.
CONTINUE.
ENDIF.
INSERT ls_report INTO TABLE rt_report.
ENDLOOP.
ENDMETHOD.
METHOD is_countable.
IF is_report-quantity_kg <= 0.
RETURN.
ENDIF.
rv_count = xsdbool( line_exists( it_member[ member_id = is_report-member_id ] ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,71 @@
CLASS {{p}}harvest_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS evaluate
IMPORTING it_report TYPE {{p}}if_harvest=>tt_report
it_member TYPE {{p}}if_harvest=>tt_member
RETURNING VALUE(rt_result) TYPE {{p}}if_harvest=>tt_result.
PRIVATE SECTION.
TYPES tt_member_key TYPE HASHED TABLE OF {{p}}if_harvest=>ty_member
WITH UNIQUE KEY member_id.
TYPES tt_member_id TYPE SORTED TABLE OF {{p}}if_harvest=>ty_member_id
WITH UNIQUE KEY table_line.
TYPES tt_report_key TYPE SORTED TABLE OF {{p}}if_harvest=>ty_report
WITH NON-UNIQUE KEY variety member_id.
METHODS countable_reports
IMPORTING it_report TYPE {{p}}if_harvest=>tt_report
it_member TYPE tt_member_key
RETURNING VALUE(rt_report) TYPE tt_report_key.
METHODS is_countable
IMPORTING is_report TYPE {{p}}if_harvest=>ty_report
it_member TYPE tt_member_key
RETURNING VALUE(rv_count) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}harvest_evaluator IMPLEMENTATION.
METHOD evaluate.
DATA lt_member TYPE tt_member_key.
lt_member = it_member.
DATA(lt_report) = countable_reports( it_report = it_report
it_member = lt_member ).
DATA lt_result TYPE {{p}}if_harvest=>tt_result.
DATA lt_member_id TYPE tt_member_id.
LOOP AT lt_report ASSIGNING FIELD-SYMBOL(<ls_report>) GROUP BY <ls_report>-variety.
DATA(lv_variety) = <ls_report>-variety.
DATA(lv_total) = 0.
CLEAR lt_member_id.
LOOP AT GROUP <ls_report> ASSIGNING FIELD-SYMBOL(<ls_grouped>).
lv_total = lv_total + <ls_grouped>-quantity_kg.
INSERT <ls_grouped>-member_id INTO TABLE lt_member_id.
ENDLOOP.
APPEND VALUE {{p}}if_harvest=>ty_result(
variety = lv_variety
total_kg = lv_total
member_count = lines( lt_member_id ) ) TO lt_result.
ENDLOOP.
SORT lt_result BY total_kg DESCENDING variety ASCENDING.
rt_result = lt_result.
ENDMETHOD.
METHOD countable_reports.
LOOP AT it_report INTO DATA(ls_report).
IF is_countable( is_report = ls_report
it_member = it_member ) = abap_true.
CONTINUE.
ENDIF.
INSERT ls_report INTO TABLE rt_report.
ENDLOOP.
ENDMETHOD.
METHOD is_countable.
IF is_report-quantity_kg <= 0.
RETURN.
ENDIF.
rv_count = xsdbool( line_exists( it_member[ member_id = is_report-member_id ] ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,71 @@
CLASS {{p}}harvest_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS evaluate
IMPORTING it_report TYPE {{p}}if_harvest=>tt_report
it_member TYPE {{p}}if_harvest=>tt_member
RETURNING VALUE(rt_result) TYPE {{p}}if_harvest=>tt_result.
PRIVATE SECTION.
TYPES tt_member_key TYPE HASHED TABLE OF {{p}}if_harvest=>ty_member
WITH UNIQUE KEY member_id.
TYPES tt_member_id TYPE SORTED TABLE OF {{p}}if_harvest=>ty_member_id
WITH UNIQUE KEY table_line.
TYPES tt_report_key TYPE SORTED TABLE OF {{p}}if_harvest=>ty_report
WITH NON-UNIQUE KEY variety member_id.
METHODS countable_reports
IMPORTING it_report TYPE {{p}}if_harvest=>tt_report
it_member TYPE tt_member_key
RETURNING VALUE(rt_report) TYPE tt_report_key.
METHODS is_countable
IMPORTING is_report TYPE {{p}}if_harvest=>ty_report
it_member TYPE tt_member_key
RETURNING VALUE(rv_count) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}harvest_evaluator IMPLEMENTATION.
METHOD evaluate.
DATA lt_member TYPE tt_member_key.
lt_member = it_member.
DATA(lt_report) = countable_reports( it_report = it_report
it_member = lt_member ).
DATA lt_result TYPE {{p}}if_harvest=>tt_result.
DATA lt_member_id TYPE tt_member_id.
LOOP AT lt_report ASSIGNING FIELD-SYMBOL(<ls_report>) GROUP BY <ls_report>-variety.
DATA(lv_variety) = <ls_report>-variety.
DATA(lv_total) = 0.
CLEAR lt_member_id.
LOOP AT GROUP <ls_report> ASSIGNING FIELD-SYMBOL(<ls_grouped>).
lv_total = lv_total + <ls_grouped>-quantity_kg.
INSERT <ls_grouped>-member_id INTO TABLE lt_member_id.
ENDLOOP.
APPEND VALUE {{p}}if_harvest=>ty_result(
variety = lv_variety
total_kg = lv_total
member_count = lines( lt_member_id ) ) TO lt_result.
ENDLOOP.
SORT lt_result BY total_kg DESCENDING variety ASCENDING.
rt_result = lt_result.
ENDMETHOD.
METHOD countable_reports.
LOOP AT it_report INTO DATA(ls_report).
IF is_countable( is_report = ls_report
it_member = it_member ) = abap_false.
CONTINUE.
ENDIF.
INSERT ls_report INTO TABLE rt_report.
ENDLOOP.
ENDMETHOD.
METHOD is_countable.
IF is_report-quantity_kg > 0.
RETURN.
ENDIF.
rv_count = xsdbool( line_exists( it_member[ member_id = is_report-member_id ] ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,19 @@
{
"id": "G1001",
"pool": "train",
"object_type": "CLAS",
"category": "C",
"attempts": [
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 3,
"killed": 3,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,193 @@
CLASS {{p}}harvest_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}harvest_evaluator.
METHODS setup.
METHODS assert_rows
IMPORTING it_act TYPE {{p}}if_harvest=>tt_result
it_exp TYPE {{p}}if_harvest=>tt_result
iv_msg TYPE string.
METHODS empty_input FOR TESTING.
METHODS unknown_member_ignored FOR TESTING.
METHODS zero_quantity_ignored FOR TESTING.
METHODS negative_quantity_ignored FOR TESTING.
METHODS same_member_counts_once FOR TESTING.
METHODS two_varieties_separated FOR TESTING.
METHODS sorted_by_total_desc FOR TESTING.
METHODS tie_broken_by_variety FOR TESTING.
METHODS all_reports_ignored FOR TESTING.
METHODS member_without_report FOR TESTING.
ENDCLASS.
CLASS {{p}}harvest_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}harvest_evaluator( ).
ENDMETHOD.
METHOD assert_rows.
cl_abap_unit_assert=>assert_equals( exp = lines( it_exp )
act = lines( it_act )
msg = |{ iv_msg }: number of rows| ).
LOOP AT it_exp ASSIGNING FIELD-SYMBOL(<ls_exp>).
READ TABLE it_act ASSIGNING FIELD-SYMBOL(<ls_act>) INDEX sy-tabix.
IF sy-subrc <> 0.
RETURN.
ENDIF.
cl_abap_unit_assert=>assert_equals( exp = <ls_exp>-variety
act = <ls_act>-variety
msg = |{ iv_msg }: variety| ).
cl_abap_unit_assert=>assert_equals( exp = <ls_exp>-total_kg
act = <ls_act>-total_kg
msg = |{ iv_msg }: total_kg| ).
cl_abap_unit_assert=>assert_equals( exp = <ls_exp>-member_count
act = <ls_act>-member_count
msg = |{ iv_msg }: member_count| ).
ENDLOOP.
ENDMETHOD.
METHOD empty_input.
DATA lt_report TYPE {{p}}if_harvest=>tt_report.
DATA lt_member TYPE {{p}}if_harvest=>tt_member.
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_result ) ).
ENDMETHOD.
METHOD unknown_member_ignored.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' )
( member_id = 'M00002' member_name = 'Hof Birke' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 100 )
( member_id = 'M00009' variety = 'RIES' quantity_kg = 50 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
assert_rows( it_act = lt_result
it_exp = VALUE #( ( variety = 'RIES' total_kg = 100 member_count = 1 ) )
iv_msg = 'unknown member' ).
ENDMETHOD.
METHOD zero_quantity_ignored.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 0 )
( member_id = 'M00001' variety = 'RIES' quantity_kg = 30 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
assert_rows( it_act = lt_result
it_exp = VALUE #( ( variety = 'RIES' total_kg = 30 member_count = 1 ) )
iv_msg = 'zero quantity' ).
ENDMETHOD.
METHOD negative_quantity_ignored.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = -5 )
( member_id = 'M00001' variety = 'RIES' quantity_kg = 20 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
assert_rows( it_act = lt_result
it_exp = VALUE #( ( variety = 'RIES' total_kg = 20 member_count = 1 ) )
iv_msg = 'negative quantity' ).
ENDMETHOD.
METHOD same_member_counts_once.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' )
( member_id = 'M00002' member_name = 'Hof Birke' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 10 )
( member_id = 'M00001' variety = 'RIES' quantity_kg = 20 )
( member_id = 'M00002' variety = 'RIES' quantity_kg = 5 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
assert_rows( it_act = lt_result
it_exp = VALUE #( ( variety = 'RIES' total_kg = 35 member_count = 2 ) )
iv_msg = 'same member' ).
ENDMETHOD.
METHOD two_varieties_separated.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' )
( member_id = 'M00002' member_name = 'Hof Birke' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 10 )
( member_id = 'M00002' variety = 'RIES' quantity_kg = 10 )
( member_id = 'M00001' variety = 'SPAE' quantity_kg = 7 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
assert_rows( it_act = lt_result
it_exp = VALUE #( ( variety = 'RIES' total_kg = 20 member_count = 2 )
( variety = 'SPAE' total_kg = 7 member_count = 1 ) )
iv_msg = 'two varieties' ).
ENDMETHOD.
METHOD sorted_by_total_desc.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' )
( member_id = 'M00002' member_name = 'Hof Birke' )
( member_id = 'M00003' member_name = 'Hof Zeder' )
( member_id = 'M00004' member_name = 'Hof Eiche' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 10 )
( member_id = 'M00002' variety = 'SPAE' quantity_kg = 30 )
( member_id = 'M00003' variety = 'SILV' quantity_kg = 20 )
( member_id = 'M00004' variety = 'SPAE' quantity_kg = 5 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
assert_rows( it_act = lt_result
it_exp = VALUE #( ( variety = 'SPAE' total_kg = 35 member_count = 2 )
( variety = 'SILV' total_kg = 20 member_count = 1 )
( variety = 'RIES' total_kg = 10 member_count = 1 ) )
iv_msg = 'sort by total' ).
ENDMETHOD.
METHOD tie_broken_by_variety.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' )
( member_id = 'M00002' member_name = 'Hof Birke' )
( member_id = 'M00003' member_name = 'Hof Zeder' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'SPAE' quantity_kg = 10 )
( member_id = 'M00002' variety = 'RIES' quantity_kg = 10 )
( member_id = 'M00003' variety = 'SILV' quantity_kg = 10 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
assert_rows( it_act = lt_result
it_exp = VALUE #( ( variety = 'RIES' total_kg = 10 member_count = 1 )
( variety = 'SILV' total_kg = 10 member_count = 1 )
( variety = 'SPAE' total_kg = 10 member_count = 1 ) )
iv_msg = 'tie by variety' ).
ENDMETHOD.
METHOD all_reports_ignored.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00009' variety = 'RIES' quantity_kg = 10 )
( member_id = 'M00001' variety = 'RIES' quantity_kg = 0 )
( member_id = 'M00001' variety = 'SPAE' quantity_kg = -3 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_result ) ).
ENDMETHOD.
METHOD member_without_report.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' )
( member_id = 'M00002' member_name = 'Hof Birke' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 5 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
assert_rows( it_act = lt_result
it_exp = VALUE #( ( variety = 'RIES' total_kg = 5 member_count = 1 ) )
iv_msg = 'member without report' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,66 @@
{
"task": "G1001",
"mutants": [
{
"object": "{{P}}HARVEST_EVALUATOR",
"mutant": "line 42: + -> - (arith)",
"status": "killed",
"hidden": "2/10",
"failed_tests": [
"MEMBER_WITHOUT_REPORT",
"NEGATIVE_QUANTITY_IGNORED",
"SAME_MEMBER_COUNTS_ONCE",
"SORTED_BY_TOTAL_DESC",
"TIE_BROKEN_BY_VARIETY",
"TWO_VARIETIES_SEPARATED",
"UNKNOWN_MEMBER_IGNORED",
"ZERO_QUANTITY_IGNORED"
]
},
{
"object": "{{P}}HARVEST_EVALUATOR",
"mutant": "line 57: = -> <> (eq)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
},
{
"object": "{{P}}HARVEST_EVALUATOR",
"mutant": "line 58: abap_false -> abap_true (bool)",
"status": "killed",
"hidden": "1/10",
"failed_tests": [
"ALL_REPORTS_IGNORED",
"MEMBER_WITHOUT_REPORT",
"NEGATIVE_QUANTITY_IGNORED",
"SAME_MEMBER_COUNTS_ONCE",
"SORTED_BY_TOTAL_DESC",
"TIE_BROKEN_BY_VARIETY",
"TWO_VARIETIES_SEPARATED",
"UNKNOWN_MEMBER_IGNORED",
"ZERO_QUANTITY_IGNORED"
]
},
{
"object": "{{P}}HARVEST_EVALUATOR",
"mutant": "line 66: <= -> > (rel)",
"status": "killed",
"hidden": "1/10",
"failed_tests": [
"ALL_REPORTS_IGNORED",
"MEMBER_WITHOUT_REPORT",
"NEGATIVE_QUANTITY_IGNORED",
"SAME_MEMBER_COUNTS_ONCE",
"SORTED_BY_TOTAL_DESC",
"TIE_BROKEN_BY_VARIETY",
"TWO_VARIETIES_SEPARATED",
"UNKNOWN_MEMBER_IGNORED",
"ZERO_QUANTITY_IGNORED"
]
}
],
"valid": 3,
"killed": 3,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,71 @@
CLASS {{p}}harvest_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS evaluate
IMPORTING it_report TYPE {{p}}if_harvest=>tt_report
it_member TYPE {{p}}if_harvest=>tt_member
RETURNING VALUE(rt_result) TYPE {{p}}if_harvest=>tt_result.
PRIVATE SECTION.
TYPES tt_member_key TYPE HASHED TABLE OF {{p}}if_harvest=>ty_member
WITH UNIQUE KEY member_id.
TYPES tt_member_id TYPE SORTED TABLE OF {{p}}if_harvest=>ty_member_id
WITH UNIQUE KEY table_line.
TYPES tt_report_key TYPE SORTED TABLE OF {{p}}if_harvest=>ty_report
WITH NON-UNIQUE KEY variety member_id.
METHODS countable_reports
IMPORTING it_report TYPE {{p}}if_harvest=>tt_report
it_member TYPE tt_member_key
RETURNING VALUE(rt_report) TYPE tt_report_key.
METHODS is_countable
IMPORTING is_report TYPE {{p}}if_harvest=>ty_report
it_member TYPE tt_member_key
RETURNING VALUE(rv_count) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}harvest_evaluator IMPLEMENTATION.
METHOD evaluate.
DATA lt_member TYPE tt_member_key.
lt_member = it_member.
DATA(lt_report) = countable_reports( it_report = it_report
it_member = lt_member ).
DATA lt_result TYPE {{p}}if_harvest=>tt_result.
DATA lt_member_id TYPE tt_member_id.
LOOP AT lt_report ASSIGNING FIELD-SYMBOL(<ls_report>) GROUP BY <ls_report>-variety.
DATA(lv_variety) = <ls_report>-variety.
DATA(lv_total) = 0.
CLEAR lt_member_id.
LOOP AT GROUP <ls_report> ASSIGNING FIELD-SYMBOL(<ls_grouped>).
lv_total = lv_total + <ls_grouped>-quantity_kg.
INSERT <ls_grouped>-member_id INTO TABLE lt_member_id.
ENDLOOP.
APPEND VALUE {{p}}if_harvest=>ty_result(
variety = lv_variety
total_kg = lv_total
member_count = lines( lt_member_id ) ) TO lt_result.
ENDLOOP.
SORT lt_result BY total_kg DESCENDING variety ASCENDING.
rt_result = lt_result.
ENDMETHOD.
METHOD countable_reports.
LOOP AT it_report INTO DATA(ls_report).
IF is_countable( is_report = ls_report
it_member = it_member ) = abap_false.
CONTINUE.
ENDIF.
INSERT ls_report INTO TABLE rt_report.
ENDLOOP.
ENDMETHOD.
METHOD is_countable.
IF is_report-quantity_kg <= 0.
RETURN.
ENDIF.
rv_count = xsdbool( line_exists( it_member[ member_id = is_report-member_id ] ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,84 @@
CLASS ltc_harvest_evaluator DEFINITION FINAL FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}harvest_evaluator.
METHODS setup.
METHODS sums_quantities FOR TESTING.
METHODS counts_members_once FOR TESTING.
METHODS ignores_unknown_member FOR TESTING.
METHODS ignores_zero_quantity FOR TESTING.
METHODS sorts_by_total FOR TESTING.
ENDCLASS.
CLASS ltc_harvest_evaluator IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}harvest_evaluator( ).
ENDMETHOD.
METHOD sums_quantities.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 10 )
( member_id = 'M00001' variety = 'RIES' quantity_kg = 15 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_result ) ).
cl_abap_unit_assert=>assert_equals( exp = 25 act = lt_result[ 1 ]-total_kg ).
ENDMETHOD.
METHOD counts_members_once.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' )
( member_id = 'M00002' member_name = 'Hof Birke' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 10 )
( member_id = 'M00001' variety = 'RIES' quantity_kg = 5 )
( member_id = 'M00002' variety = 'RIES' quantity_kg = 5 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
cl_abap_unit_assert=>assert_equals( exp = 20 act = lt_result[ 1 ]-total_kg ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_result[ 1 ]-member_count ).
ENDMETHOD.
METHOD ignores_unknown_member.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 10 )
( member_id = 'M00009' variety = 'RIES' quantity_kg = 99 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
cl_abap_unit_assert=>assert_equals( exp = 10 act = lt_result[ 1 ]-total_kg ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_result[ 1 ]-member_count ).
ENDMETHOD.
METHOD ignores_zero_quantity.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 0 )
( member_id = 'M00001' variety = 'RIES' quantity_kg = 40 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
cl_abap_unit_assert=>assert_equals( exp = 40 act = lt_result[ 1 ]-total_kg ).
ENDMETHOD.
METHOD sorts_by_total.
DATA(lt_member) = VALUE {{p}}if_harvest=>tt_member(
( member_id = 'M00001' member_name = 'Hof Adler' )
( member_id = 'M00002' member_name = 'Hof Birke' )
( member_id = 'M00003' member_name = 'Hof Zeder' ) ).
DATA(lt_report) = VALUE {{p}}if_harvest=>tt_report(
( member_id = 'M00001' variety = 'RIES' quantity_kg = 5 )
( member_id = 'M00002' variety = 'SPAE' quantity_kg = 30 )
( member_id = 'M00003' variety = 'SILV' quantity_kg = 20 ) ).
DATA(lt_result) = mo_cut->evaluate( it_report = lt_report
it_member = lt_member ).
cl_abap_unit_assert=>assert_equals( exp = 'SPAE' act = lt_result[ 1 ]-variety ).
cl_abap_unit_assert=>assert_equals( exp = 'SILV' act = lt_result[ 2 ]-variety ).
cl_abap_unit_assert=>assert_equals( exp = 'RIES' act = lt_result[ 3 ]-variety ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,26 @@
INTERFACE {{p}}if_harvest PUBLIC.
TYPES ty_member_id TYPE c LENGTH 6.
TYPES ty_variety TYPE c LENGTH 4.
TYPES ty_name TYPE c LENGTH 30.
TYPES ty_quantity TYPE i.
TYPES: BEGIN OF ty_member,
member_id TYPE ty_member_id,
member_name TYPE ty_name,
END OF ty_member.
TYPES tt_member TYPE STANDARD TABLE OF ty_member WITH EMPTY KEY.
TYPES: BEGIN OF ty_report,
member_id TYPE ty_member_id,
variety TYPE ty_variety,
quantity_kg TYPE ty_quantity,
END OF ty_report.
TYPES tt_report TYPE STANDARD TABLE OF ty_report WITH EMPTY KEY.
TYPES: BEGIN OF ty_result,
variety TYPE ty_variety,
total_kg TYPE ty_quantity,
member_count TYPE i,
END OF ty_result.
TYPES tt_result TYPE STANDARD TABLE OF ty_result WITH EMPTY KEY.
ENDINTERFACE.

View File

@@ -0,0 +1,52 @@
# 1. Goal
A vineyard cooperative collects the harvest reports of its members. The
cooperative needs one evaluation of the harvest for each grape variety. A
planning program calls the evaluation before it plans the transport of the
grapes to the winery.
# 2. Open questions
None.
# 3. Context
- The interface {{P}}IF_HARVEST exists in package $TMP. It is active.
- The interface contains the data types for the harvest reports, for the member
master data, and for the result. Read the interface before you start to work.
- A harvest report has a member, a grape variety, and a quantity in kilograms.
- The member master data has a member ID and a member name.
# 4. Contract
- Create the class {{P}}HARVEST_EVALUATOR in package $TMP.
- The class is public and final. It has a public constructor without
parameters.
- The class has one public method:
EVALUATE
IMPORTING it_report TYPE {{P}}IF_HARVEST=>TT_REPORT
it_member TYPE {{P}}IF_HARVEST=>TT_MEMBER
RETURNING VALUE(rt_result) TYPE {{P}}IF_HARVEST=>TT_RESULT.
- Do not add other public methods.
# 5. Business rules
A harvest report is countable when rule 1 and rule 2 are true.
1. The member_id of the report occurs in it_member. A member_id occurs at most
one time in it_member.
2. The quantity_kg of the report is greater than 0.
3. Group the countable reports by variety. Create one result row for each
variety that has at least one countable report.
4. The total_kg of a result row is the sum of the quantity_kg of all countable
reports of the variety.
5. The member_count of a result row is the number of different member_id
values in the countable reports of the variety.
6. Sort the result rows by total_kg in descending order. When two rows have the
same total_kg, sort these rows by variety in ascending order.
7. When no report is countable, return an empty table.
# 6. Constraints
- Release target: 8.16.
- Coding standards: Clean ABAP. Method length below 40 statements. No global
variables. No comment that restates the code.
- Out of scope: do not change {{P}}IF_HARVEST.
# 7. Acceptance
- The class is active and has no syntax error.
- The hidden tests pass.
- Write your own ABAP Unit tests for the class.

View File

@@ -0,0 +1,53 @@
{
"id": "G1001",
"category": "C",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "INTF",
"name": "{{P}}IF_HARVEST",
"file": "seed/if_harvest.intf.abap",
"description": "Data types for harvest reports, member master data, and the evaluation result"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}HARVEST_EVALUATOR",
"description": "Evaluates the harvest reports per grape variety"
}
],
"out_of_scope": [
"{{P}}IF_HARVEST"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}HARVEST_HIDDEN",
"file": "hidden/harvest_hidden.clas.abap",
"description": "Hidden tests for the harvest evaluation"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}HARVEST_EVALUATOR",
"file": "reference/harvest_evaluator.clas.abap",
"description": "Harvest evaluator",
"testclasses_file": "reference/harvest_evaluator.testclasses.abap"
}
],
"craft_checks": [
"table_kind",
"key_kind",
"access_path",
"method_length"
]
}