Fix coverage with several contract classes; table annotation and file path checks; clean task dir on write

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 08:44:35 +02:00
parent fb576b0954
commit 03ab36149e
388 changed files with 28620 additions and 339 deletions

View File

@@ -0,0 +1,164 @@
CLASS {{p}}refill_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_machine_id TYPE c LENGTH 8,
ty_district TYPE c LENGTH 4,
ty_quantity TYPE i,
ty_fill_level TYPE i,
BEGIN OF ty_machine,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
END OF ty_machine,
tt_machines TYPE STANDARD TABLE OF ty_machine WITH EMPTY KEY,
BEGIN OF ty_refill,
machine_id TYPE ty_machine_id,
quantity TYPE ty_quantity,
END OF ty_refill,
tt_refills TYPE STANDARD TABLE OF ty_refill WITH EMPTY KEY,
BEGIN OF ty_district_summary,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_summary,
tt_district_summary TYPE STANDARD TABLE OF ty_district_summary WITH EMPTY KEY.
METHODS add_machine
IMPORTING iv_machine_id TYPE ty_machine_id
iv_district TYPE ty_district
iv_fill_level TYPE ty_fill_level.
METHODS add_refill
IMPORTING iv_machine_id TYPE ty_machine_id
iv_quantity TYPE ty_quantity
RETURNING VALUE(rv_accepted) TYPE abap_bool.
METHODS get_refill
IMPORTING iv_machine_id TYPE ty_machine_id
RETURNING VALUE(rv_quantity) TYPE ty_quantity.
METHODS machines_below
IMPORTING iv_fill_level TYPE ty_fill_level
RETURNING VALUE(rt_machines) TYPE tt_machines.
METHODS top_refills
IMPORTING iv_count TYPE i
RETURNING VALUE(rt_refills) TYPE tt_refills.
METHODS district_summary
RETURNING VALUE(rt_summary) TYPE tt_district_summary.
METHODS total_quantity
RETURNING VALUE(rv_total) TYPE ty_quantity.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_machine_state,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
quantity TYPE ty_quantity,
END OF ty_machine_state,
tt_machine_state TYPE HASHED TABLE OF ty_machine_state WITH UNIQUE KEY machine_id.
DATA mt_machines TYPE tt_machine_state.
ENDCLASS.
CLASS {{p}}refill_planner IMPLEMENTATION.
METHOD add_machine.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
<ls_machine>-district = to_upper( iv_district ).
<ls_machine>-fill_level = iv_fill_level.
ELSE.
INSERT VALUE #( machine_id = lv_machine_id
district = to_upper( iv_district )
fill_level = iv_fill_level
quantity = 0 ) INTO TABLE mt_machines.
ENDIF.
ENDMETHOD.
METHOD add_refill.
IF iv_quantity <= 0.
rv_accepted = abap_true.
RETURN.
ENDIF.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc <> 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
<ls_machine>-quantity = <ls_machine>-quantity + iv_quantity.
rv_accepted = abap_true.
ENDMETHOD.
METHOD get_refill.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
rv_quantity = <ls_machine>-quantity.
ENDIF.
ENDMETHOD.
METHOD machines_below.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-fill_level < iv_fill_level.
INSERT VALUE #( machine_id = ls_machine-machine_id
district = ls_machine-district
fill_level = ls_machine-fill_level ) INTO TABLE rt_machines.
ENDIF.
ENDLOOP.
SORT rt_machines BY fill_level machine_id.
ENDMETHOD.
METHOD top_refills.
DATA lv_index TYPE i.
DATA lt_refills TYPE tt_refills.
IF iv_count <= 0.
RETURN.
ENDIF.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-quantity > 0.
INSERT VALUE #( machine_id = ls_machine-machine_id
quantity = ls_machine-quantity ) INTO TABLE lt_refills.
ENDIF.
ENDLOOP.
SORT lt_refills BY quantity DESCENDING machine_id ASCENDING.
LOOP AT lt_refills INTO DATA(ls_refill).
lv_index = lv_index + 1.
IF lv_index > iv_count.
EXIT.
ENDIF.
INSERT ls_refill INTO TABLE rt_refills.
ENDLOOP.
ENDMETHOD.
METHOD district_summary.
TYPES:
BEGIN OF ty_district_state,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_state,
tt_district_state TYPE HASHED TABLE OF ty_district_state WITH UNIQUE KEY district.
DATA lt_districts TYPE tt_district_state.
LOOP AT mt_machines INTO DATA(ls_machine).
ASSIGN lt_districts[ district = ls_machine-district ] TO FIELD-SYMBOL(<ls_district>).
IF sy-subrc <> 0.
INSERT VALUE #( district = ls_machine-district )
INTO TABLE lt_districts ASSIGNING <ls_district>.
ENDIF.
<ls_district>-machines = <ls_district>-machines + 1.
<ls_district>-quantity = <ls_district>-quantity + ls_machine-quantity.
ENDLOOP.
LOOP AT lt_districts INTO DATA(ls_district).
INSERT VALUE #( district = ls_district-district
machines = ls_district-machines
quantity = ls_district-quantity ) INTO TABLE rt_summary.
ENDLOOP.
SORT rt_summary BY district.
ENDMETHOD.
METHOD total_quantity.
LOOP AT mt_machines INTO DATA(ls_machine).
rv_total = rv_total + ls_machine-quantity.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,164 @@
CLASS {{p}}refill_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_machine_id TYPE c LENGTH 8,
ty_district TYPE c LENGTH 4,
ty_quantity TYPE i,
ty_fill_level TYPE i,
BEGIN OF ty_machine,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
END OF ty_machine,
tt_machines TYPE STANDARD TABLE OF ty_machine WITH EMPTY KEY,
BEGIN OF ty_refill,
machine_id TYPE ty_machine_id,
quantity TYPE ty_quantity,
END OF ty_refill,
tt_refills TYPE STANDARD TABLE OF ty_refill WITH EMPTY KEY,
BEGIN OF ty_district_summary,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_summary,
tt_district_summary TYPE STANDARD TABLE OF ty_district_summary WITH EMPTY KEY.
METHODS add_machine
IMPORTING iv_machine_id TYPE ty_machine_id
iv_district TYPE ty_district
iv_fill_level TYPE ty_fill_level.
METHODS add_refill
IMPORTING iv_machine_id TYPE ty_machine_id
iv_quantity TYPE ty_quantity
RETURNING VALUE(rv_accepted) TYPE abap_bool.
METHODS get_refill
IMPORTING iv_machine_id TYPE ty_machine_id
RETURNING VALUE(rv_quantity) TYPE ty_quantity.
METHODS machines_below
IMPORTING iv_fill_level TYPE ty_fill_level
RETURNING VALUE(rt_machines) TYPE tt_machines.
METHODS top_refills
IMPORTING iv_count TYPE i
RETURNING VALUE(rt_refills) TYPE tt_refills.
METHODS district_summary
RETURNING VALUE(rt_summary) TYPE tt_district_summary.
METHODS total_quantity
RETURNING VALUE(rv_total) TYPE ty_quantity.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_machine_state,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
quantity TYPE ty_quantity,
END OF ty_machine_state,
tt_machine_state TYPE HASHED TABLE OF ty_machine_state WITH UNIQUE KEY machine_id.
DATA mt_machines TYPE tt_machine_state.
ENDCLASS.
CLASS {{p}}refill_planner IMPLEMENTATION.
METHOD add_machine.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
<ls_machine>-district = to_upper( iv_district ).
<ls_machine>-fill_level = iv_fill_level.
ELSE.
INSERT VALUE #( machine_id = lv_machine_id
district = to_upper( iv_district )
fill_level = iv_fill_level
quantity = 0 ) INTO TABLE mt_machines.
ENDIF.
ENDMETHOD.
METHOD add_refill.
IF iv_quantity <= 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc <> 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
<ls_machine>-quantity = <ls_machine>-quantity + iv_quantity.
rv_accepted = abap_true.
ENDMETHOD.
METHOD get_refill.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
rv_quantity = <ls_machine>-quantity.
ENDIF.
ENDMETHOD.
METHOD machines_below.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-fill_level < iv_fill_level.
INSERT VALUE #( machine_id = ls_machine-machine_id
district = ls_machine-district
fill_level = ls_machine-fill_level ) INTO TABLE rt_machines.
ENDIF.
ENDLOOP.
SORT rt_machines BY fill_level machine_id.
ENDMETHOD.
METHOD top_refills.
DATA lv_index TYPE i.
DATA lt_refills TYPE tt_refills.
IF iv_count > 0.
RETURN.
ENDIF.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-quantity > 0.
INSERT VALUE #( machine_id = ls_machine-machine_id
quantity = ls_machine-quantity ) INTO TABLE lt_refills.
ENDIF.
ENDLOOP.
SORT lt_refills BY quantity DESCENDING machine_id ASCENDING.
LOOP AT lt_refills INTO DATA(ls_refill).
lv_index = lv_index + 1.
IF lv_index > iv_count.
EXIT.
ENDIF.
INSERT ls_refill INTO TABLE rt_refills.
ENDLOOP.
ENDMETHOD.
METHOD district_summary.
TYPES:
BEGIN OF ty_district_state,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_state,
tt_district_state TYPE HASHED TABLE OF ty_district_state WITH UNIQUE KEY district.
DATA lt_districts TYPE tt_district_state.
LOOP AT mt_machines INTO DATA(ls_machine).
ASSIGN lt_districts[ district = ls_machine-district ] TO FIELD-SYMBOL(<ls_district>).
IF sy-subrc <> 0.
INSERT VALUE #( district = ls_machine-district )
INTO TABLE lt_districts ASSIGNING <ls_district>.
ENDIF.
<ls_district>-machines = <ls_district>-machines + 1.
<ls_district>-quantity = <ls_district>-quantity + ls_machine-quantity.
ENDLOOP.
LOOP AT lt_districts INTO DATA(ls_district).
INSERT VALUE #( district = ls_district-district
machines = ls_district-machines
quantity = ls_district-quantity ) INTO TABLE rt_summary.
ENDLOOP.
SORT rt_summary BY district.
ENDMETHOD.
METHOD total_quantity.
LOOP AT mt_machines INTO DATA(ls_machine).
rv_total = rv_total + ls_machine-quantity.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,164 @@
CLASS {{p}}refill_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_machine_id TYPE c LENGTH 8,
ty_district TYPE c LENGTH 4,
ty_quantity TYPE i,
ty_fill_level TYPE i,
BEGIN OF ty_machine,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
END OF ty_machine,
tt_machines TYPE STANDARD TABLE OF ty_machine WITH EMPTY KEY,
BEGIN OF ty_refill,
machine_id TYPE ty_machine_id,
quantity TYPE ty_quantity,
END OF ty_refill,
tt_refills TYPE STANDARD TABLE OF ty_refill WITH EMPTY KEY,
BEGIN OF ty_district_summary,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_summary,
tt_district_summary TYPE STANDARD TABLE OF ty_district_summary WITH EMPTY KEY.
METHODS add_machine
IMPORTING iv_machine_id TYPE ty_machine_id
iv_district TYPE ty_district
iv_fill_level TYPE ty_fill_level.
METHODS add_refill
IMPORTING iv_machine_id TYPE ty_machine_id
iv_quantity TYPE ty_quantity
RETURNING VALUE(rv_accepted) TYPE abap_bool.
METHODS get_refill
IMPORTING iv_machine_id TYPE ty_machine_id
RETURNING VALUE(rv_quantity) TYPE ty_quantity.
METHODS machines_below
IMPORTING iv_fill_level TYPE ty_fill_level
RETURNING VALUE(rt_machines) TYPE tt_machines.
METHODS top_refills
IMPORTING iv_count TYPE i
RETURNING VALUE(rt_refills) TYPE tt_refills.
METHODS district_summary
RETURNING VALUE(rt_summary) TYPE tt_district_summary.
METHODS total_quantity
RETURNING VALUE(rv_total) TYPE ty_quantity.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_machine_state,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
quantity TYPE ty_quantity,
END OF ty_machine_state,
tt_machine_state TYPE HASHED TABLE OF ty_machine_state WITH UNIQUE KEY machine_id.
DATA mt_machines TYPE tt_machine_state.
ENDCLASS.
CLASS {{p}}refill_planner IMPLEMENTATION.
METHOD add_machine.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
<ls_machine>-district = to_upper( iv_district ).
<ls_machine>-fill_level = iv_fill_level.
ELSE.
INSERT VALUE #( machine_id = lv_machine_id
district = to_upper( iv_district )
fill_level = iv_fill_level
quantity = 0 ) INTO TABLE mt_machines.
ENDIF.
ENDMETHOD.
METHOD add_refill.
IF iv_quantity <= 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc <> 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
<ls_machine>-quantity = <ls_machine>-quantity + iv_quantity.
rv_accepted = abap_true.
ENDMETHOD.
METHOD get_refill.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
rv_quantity = <ls_machine>-quantity.
ENDIF.
ENDMETHOD.
METHOD machines_below.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-fill_level < iv_fill_level.
INSERT VALUE #( machine_id = ls_machine-machine_id
district = ls_machine-district
fill_level = ls_machine-fill_level ) INTO TABLE rt_machines.
ENDIF.
ENDLOOP.
SORT rt_machines BY fill_level machine_id.
ENDMETHOD.
METHOD top_refills.
DATA lv_index TYPE i.
DATA lt_refills TYPE tt_refills.
IF iv_count <= 0.
RETURN.
ENDIF.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-quantity <= 0.
INSERT VALUE #( machine_id = ls_machine-machine_id
quantity = ls_machine-quantity ) INTO TABLE lt_refills.
ENDIF.
ENDLOOP.
SORT lt_refills BY quantity DESCENDING machine_id ASCENDING.
LOOP AT lt_refills INTO DATA(ls_refill).
lv_index = lv_index + 1.
IF lv_index > iv_count.
EXIT.
ENDIF.
INSERT ls_refill INTO TABLE rt_refills.
ENDLOOP.
ENDMETHOD.
METHOD district_summary.
TYPES:
BEGIN OF ty_district_state,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_state,
tt_district_state TYPE HASHED TABLE OF ty_district_state WITH UNIQUE KEY district.
DATA lt_districts TYPE tt_district_state.
LOOP AT mt_machines INTO DATA(ls_machine).
ASSIGN lt_districts[ district = ls_machine-district ] TO FIELD-SYMBOL(<ls_district>).
IF sy-subrc <> 0.
INSERT VALUE #( district = ls_machine-district )
INTO TABLE lt_districts ASSIGNING <ls_district>.
ENDIF.
<ls_district>-machines = <ls_district>-machines + 1.
<ls_district>-quantity = <ls_district>-quantity + ls_machine-quantity.
ENDLOOP.
LOOP AT lt_districts INTO DATA(ls_district).
INSERT VALUE #( district = ls_district-district
machines = ls_district-machines
quantity = ls_district-quantity ) INTO TABLE rt_summary.
ENDLOOP.
SORT rt_summary BY district.
ENDMETHOD.
METHOD total_quantity.
LOOP AT mt_machines INTO DATA(ls_machine).
rv_total = rv_total + ls_machine-quantity.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,164 @@
CLASS {{p}}refill_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_machine_id TYPE c LENGTH 8,
ty_district TYPE c LENGTH 4,
ty_quantity TYPE i,
ty_fill_level TYPE i,
BEGIN OF ty_machine,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
END OF ty_machine,
tt_machines TYPE STANDARD TABLE OF ty_machine WITH EMPTY KEY,
BEGIN OF ty_refill,
machine_id TYPE ty_machine_id,
quantity TYPE ty_quantity,
END OF ty_refill,
tt_refills TYPE STANDARD TABLE OF ty_refill WITH EMPTY KEY,
BEGIN OF ty_district_summary,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_summary,
tt_district_summary TYPE STANDARD TABLE OF ty_district_summary WITH EMPTY KEY.
METHODS add_machine
IMPORTING iv_machine_id TYPE ty_machine_id
iv_district TYPE ty_district
iv_fill_level TYPE ty_fill_level.
METHODS add_refill
IMPORTING iv_machine_id TYPE ty_machine_id
iv_quantity TYPE ty_quantity
RETURNING VALUE(rv_accepted) TYPE abap_bool.
METHODS get_refill
IMPORTING iv_machine_id TYPE ty_machine_id
RETURNING VALUE(rv_quantity) TYPE ty_quantity.
METHODS machines_below
IMPORTING iv_fill_level TYPE ty_fill_level
RETURNING VALUE(rt_machines) TYPE tt_machines.
METHODS top_refills
IMPORTING iv_count TYPE i
RETURNING VALUE(rt_refills) TYPE tt_refills.
METHODS district_summary
RETURNING VALUE(rt_summary) TYPE tt_district_summary.
METHODS total_quantity
RETURNING VALUE(rv_total) TYPE ty_quantity.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_machine_state,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
quantity TYPE ty_quantity,
END OF ty_machine_state,
tt_machine_state TYPE HASHED TABLE OF ty_machine_state WITH UNIQUE KEY machine_id.
DATA mt_machines TYPE tt_machine_state.
ENDCLASS.
CLASS {{p}}refill_planner IMPLEMENTATION.
METHOD add_machine.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
<ls_machine>-district = to_upper( iv_district ).
<ls_machine>-fill_level = iv_fill_level.
ELSE.
INSERT VALUE #( machine_id = lv_machine_id
district = to_upper( iv_district )
fill_level = iv_fill_level
quantity = 0 ) INTO TABLE mt_machines.
ENDIF.
ENDMETHOD.
METHOD add_refill.
IF iv_quantity <= 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc <> 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
<ls_machine>-quantity = <ls_machine>-quantity + iv_quantity.
rv_accepted = abap_true.
ENDMETHOD.
METHOD get_refill.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
rv_quantity = <ls_machine>-quantity.
ENDIF.
ENDMETHOD.
METHOD machines_below.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-fill_level < iv_fill_level.
INSERT VALUE #( machine_id = ls_machine-machine_id
district = ls_machine-district
fill_level = ls_machine-fill_level ) INTO TABLE rt_machines.
ENDIF.
ENDLOOP.
SORT rt_machines BY fill_level machine_id.
ENDMETHOD.
METHOD top_refills.
DATA lv_index TYPE i.
DATA lt_refills TYPE tt_refills.
IF iv_count <= 0.
RETURN.
ENDIF.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-quantity > 0.
INSERT VALUE #( machine_id = ls_machine-machine_id
quantity = ls_machine-quantity ) INTO TABLE lt_refills.
ENDIF.
ENDLOOP.
SORT lt_refills BY quantity DESCENDING machine_id ASCENDING.
LOOP AT lt_refills INTO DATA(ls_refill).
lv_index = lv_index - 1.
IF lv_index > iv_count.
EXIT.
ENDIF.
INSERT ls_refill INTO TABLE rt_refills.
ENDLOOP.
ENDMETHOD.
METHOD district_summary.
TYPES:
BEGIN OF ty_district_state,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_state,
tt_district_state TYPE HASHED TABLE OF ty_district_state WITH UNIQUE KEY district.
DATA lt_districts TYPE tt_district_state.
LOOP AT mt_machines INTO DATA(ls_machine).
ASSIGN lt_districts[ district = ls_machine-district ] TO FIELD-SYMBOL(<ls_district>).
IF sy-subrc <> 0.
INSERT VALUE #( district = ls_machine-district )
INTO TABLE lt_districts ASSIGNING <ls_district>.
ENDIF.
<ls_district>-machines = <ls_district>-machines + 1.
<ls_district>-quantity = <ls_district>-quantity + ls_machine-quantity.
ENDLOOP.
LOOP AT lt_districts INTO DATA(ls_district).
INSERT VALUE #( district = ls_district-district
machines = ls_district-machines
quantity = ls_district-quantity ) INTO TABLE rt_summary.
ENDLOOP.
SORT rt_summary BY district.
ENDMETHOD.
METHOD total_quantity.
LOOP AT mt_machines INTO DATA(ls_machine).
rv_total = rv_total + ls_machine-quantity.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,164 @@
CLASS {{p}}refill_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_machine_id TYPE c LENGTH 8,
ty_district TYPE c LENGTH 4,
ty_quantity TYPE i,
ty_fill_level TYPE i,
BEGIN OF ty_machine,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
END OF ty_machine,
tt_machines TYPE STANDARD TABLE OF ty_machine WITH EMPTY KEY,
BEGIN OF ty_refill,
machine_id TYPE ty_machine_id,
quantity TYPE ty_quantity,
END OF ty_refill,
tt_refills TYPE STANDARD TABLE OF ty_refill WITH EMPTY KEY,
BEGIN OF ty_district_summary,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_summary,
tt_district_summary TYPE STANDARD TABLE OF ty_district_summary WITH EMPTY KEY.
METHODS add_machine
IMPORTING iv_machine_id TYPE ty_machine_id
iv_district TYPE ty_district
iv_fill_level TYPE ty_fill_level.
METHODS add_refill
IMPORTING iv_machine_id TYPE ty_machine_id
iv_quantity TYPE ty_quantity
RETURNING VALUE(rv_accepted) TYPE abap_bool.
METHODS get_refill
IMPORTING iv_machine_id TYPE ty_machine_id
RETURNING VALUE(rv_quantity) TYPE ty_quantity.
METHODS machines_below
IMPORTING iv_fill_level TYPE ty_fill_level
RETURNING VALUE(rt_machines) TYPE tt_machines.
METHODS top_refills
IMPORTING iv_count TYPE i
RETURNING VALUE(rt_refills) TYPE tt_refills.
METHODS district_summary
RETURNING VALUE(rt_summary) TYPE tt_district_summary.
METHODS total_quantity
RETURNING VALUE(rv_total) TYPE ty_quantity.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_machine_state,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
quantity TYPE ty_quantity,
END OF ty_machine_state,
tt_machine_state TYPE HASHED TABLE OF ty_machine_state WITH UNIQUE KEY machine_id.
DATA mt_machines TYPE tt_machine_state.
ENDCLASS.
CLASS {{p}}refill_planner IMPLEMENTATION.
METHOD add_machine.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
<ls_machine>-district = to_upper( iv_district ).
<ls_machine>-fill_level = iv_fill_level.
ELSE.
INSERT VALUE #( machine_id = lv_machine_id
district = to_upper( iv_district )
fill_level = iv_fill_level
quantity = 0 ) INTO TABLE mt_machines.
ENDIF.
ENDMETHOD.
METHOD add_refill.
IF iv_quantity <= 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc <> 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
<ls_machine>-quantity = <ls_machine>-quantity + iv_quantity.
rv_accepted = abap_true.
ENDMETHOD.
METHOD get_refill.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
rv_quantity = <ls_machine>-quantity.
ENDIF.
ENDMETHOD.
METHOD machines_below.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-fill_level < iv_fill_level.
INSERT VALUE #( machine_id = ls_machine-machine_id
district = ls_machine-district
fill_level = ls_machine-fill_level ) INTO TABLE rt_machines.
ENDIF.
ENDLOOP.
SORT rt_machines BY fill_level machine_id.
ENDMETHOD.
METHOD top_refills.
DATA lv_index TYPE i.
DATA lt_refills TYPE tt_refills.
IF iv_count <= 0.
RETURN.
ENDIF.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-quantity > 0.
INSERT VALUE #( machine_id = ls_machine-machine_id
quantity = ls_machine-quantity ) INTO TABLE lt_refills.
ENDIF.
ENDLOOP.
SORT lt_refills BY quantity DESCENDING machine_id ASCENDING.
LOOP AT lt_refills INTO DATA(ls_refill).
lv_index = lv_index + 1.
IF lv_index > iv_count.
EXIT.
ENDIF.
INSERT ls_refill INTO TABLE rt_refills.
ENDLOOP.
ENDMETHOD.
METHOD district_summary.
TYPES:
BEGIN OF ty_district_state,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_state,
tt_district_state TYPE HASHED TABLE OF ty_district_state WITH UNIQUE KEY district.
DATA lt_districts TYPE tt_district_state.
LOOP AT mt_machines INTO DATA(ls_machine).
ASSIGN lt_districts[ district = ls_machine-district ] TO FIELD-SYMBOL(<ls_district>).
IF sy-subrc <> 0.
INSERT VALUE #( district = ls_machine-district )
INTO TABLE lt_districts ASSIGNING <ls_district>.
ENDIF.
<ls_district>-machines = <ls_district>-machines - 1.
<ls_district>-quantity = <ls_district>-quantity + ls_machine-quantity.
ENDLOOP.
LOOP AT lt_districts INTO DATA(ls_district).
INSERT VALUE #( district = ls_district-district
machines = ls_district-machines
quantity = ls_district-quantity ) INTO TABLE rt_summary.
ENDLOOP.
SORT rt_summary BY district.
ENDMETHOD.
METHOD total_quantity.
LOOP AT mt_machines INTO DATA(ls_machine).
rv_total = rv_total + ls_machine-quantity.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

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

View File

@@ -0,0 +1,151 @@
CLASS {{p}}refill_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}refill_planner.
METHODS setup.
METHODS adds_and_replaces FOR TESTING.
METHODS ids_are_upper_case FOR TESTING.
METHODS rejects_zero_qty FOR TESTING.
METHODS unknown_machine FOR TESTING.
METHODS refill_accumulates FOR TESTING.
METHODS sorts_by_fill FOR TESTING.
METHODS fill_level_boundary FOR TESTING.
METHODS top_by_quantity FOR TESTING.
METHODS district_totals FOR TESTING.
METHODS total_quantity FOR TESTING.
ENDCLASS.
CLASS {{p}}refill_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}refill_planner( ).
ENDMETHOD.
METHOD adds_and_replaces.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 20 ).
mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 5 ).
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D2' iv_fill_level = 30 ).
DATA(lt_machines) = mo_cut->machines_below( 100 ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_machines ) ).
LOOP AT lt_machines INTO DATA(ls_machine).
cl_abap_unit_assert=>assert_equals( exp = 'D2' act = ls_machine-district ).
cl_abap_unit_assert=>assert_equals( exp = 30 act = ls_machine-fill_level ).
ENDLOOP.
cl_abap_unit_assert=>assert_equals( exp = 5 act = mo_cut->get_refill( 'M1' ) ).
ENDMETHOD.
METHOD ids_are_upper_case.
mo_cut->add_machine( iv_machine_id = 'm1' iv_district = 'd1' iv_fill_level = 10 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true
act = mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 4 ) ).
cl_abap_unit_assert=>assert_equals( exp = 4 act = mo_cut->get_refill( 'm1' ) ).
ENDMETHOD.
METHOD rejects_zero_qty.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 10 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false
act = mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 0 ) ).
cl_abap_unit_assert=>assert_equals( exp = abap_false
act = mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = -3 ) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = mo_cut->get_refill( 'M1' ) ).
ENDMETHOD.
METHOD unknown_machine.
cl_abap_unit_assert=>assert_equals( exp = abap_false
act = mo_cut->add_refill( iv_machine_id = 'M9' iv_quantity = 5 ) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = mo_cut->get_refill( 'M9' ) ).
ENDMETHOD.
METHOD refill_accumulates.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 10 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true
act = mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 5 ) ).
cl_abap_unit_assert=>assert_equals( exp = abap_true
act = mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 7 ) ).
cl_abap_unit_assert=>assert_equals( exp = 12 act = mo_cut->get_refill( 'M1' ) ).
ENDMETHOD.
METHOD sorts_by_fill.
DATA lv_position TYPE i.
mo_cut->add_machine( iv_machine_id = 'M3' iv_district = 'D1' iv_fill_level = 30 ).
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D2' iv_fill_level = 10 ).
mo_cut->add_machine( iv_machine_id = 'M2' iv_district = 'D1' iv_fill_level = 20 ).
DATA(lt_machines) = mo_cut->machines_below( 25 ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_machines ) ).
LOOP AT lt_machines INTO DATA(ls_machine).
lv_position = lv_position + 1.
IF lv_position = 1.
cl_abap_unit_assert=>assert_equals( exp = 'M1' act = ls_machine-machine_id ).
ELSEIF lv_position = 2.
cl_abap_unit_assert=>assert_equals( exp = 'M2' act = ls_machine-machine_id ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD fill_level_boundary.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 20 ).
mo_cut->add_machine( iv_machine_id = 'M2' iv_district = 'D1' iv_fill_level = 19 ).
DATA(lt_below_20) = mo_cut->machines_below( 20 ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_below_20 ) ).
DATA(lt_below_0) = mo_cut->machines_below( 0 ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_below_0 ) ).
ENDMETHOD.
METHOD top_by_quantity.
DATA lv_position TYPE i.
mo_cut->add_machine( iv_machine_id = 'MA' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_machine( iv_machine_id = 'MB' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_machine( iv_machine_id = 'MC' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_machine( iv_machine_id = 'MD' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_refill( iv_machine_id = 'MA' iv_quantity = 5 ).
mo_cut->add_refill( iv_machine_id = 'MB' iv_quantity = 9 ).
mo_cut->add_refill( iv_machine_id = 'MC' iv_quantity = 9 ).
mo_cut->add_refill( iv_machine_id = 'MD' iv_quantity = 1 ).
DATA(lt_top) = mo_cut->top_refills( 2 ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_top ) ).
LOOP AT lt_top INTO DATA(ls_refill).
lv_position = lv_position + 1.
IF lv_position = 1.
cl_abap_unit_assert=>assert_equals( exp = 'MB' act = ls_refill-machine_id ).
ELSEIF lv_position = 2.
cl_abap_unit_assert=>assert_equals( exp = 'MC' act = ls_refill-machine_id ).
ENDIF.
ENDLOOP.
DATA(lt_all) = mo_cut->top_refills( 99 ).
cl_abap_unit_assert=>assert_equals( exp = 4 act = lines( lt_all ) ).
DATA(lt_none) = mo_cut->top_refills( 0 ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_none ) ).
ENDMETHOD.
METHOD district_totals.
DATA lv_position TYPE i.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D2' iv_fill_level = 10 ).
mo_cut->add_machine( iv_machine_id = 'M2' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_machine( iv_machine_id = 'M3' iv_district = 'D2' iv_fill_level = 10 ).
mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 4 ).
mo_cut->add_refill( iv_machine_id = 'M2' iv_quantity = 6 ).
DATA(lt_summary) = mo_cut->district_summary( ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_summary ) ).
LOOP AT lt_summary INTO DATA(ls_row).
lv_position = lv_position + 1.
IF lv_position = 1.
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = ls_row-district ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_row-machines ).
cl_abap_unit_assert=>assert_equals( exp = 6 act = ls_row-quantity ).
ELSEIF lv_position = 2.
cl_abap_unit_assert=>assert_equals( exp = 'D2' act = ls_row-district ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_row-machines ).
cl_abap_unit_assert=>assert_equals( exp = 4 act = ls_row-quantity ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD total_quantity.
cl_abap_unit_assert=>assert_equals( exp = 0 act = mo_cut->total_quantity( ) ).
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_machine( iv_machine_id = 'M2' iv_district = 'D2' iv_fill_level = 10 ).
mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 5 ).
mo_cut->add_refill( iv_machine_id = 'M2' iv_quantity = 8 ).
cl_abap_unit_assert=>assert_equals( exp = 13 act = mo_cut->total_quantity( ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,54 @@
{
"task": "G0115",
"mutants": [
{
"object": "{{P}}REFILL_PLANNER",
"mutant": "line 79: abap_false -> abap_true (bool)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"REJECTS_ZERO_QTY"
]
},
{
"object": "{{P}}REFILL_PLANNER",
"mutant": "line 114: <= -> > (rel)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"TOP_BY_QUANTITY"
]
},
{
"object": "{{P}}REFILL_PLANNER",
"mutant": "line 118: > -> <= (rel)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"TOP_BY_QUANTITY"
]
},
{
"object": "{{P}}REFILL_PLANNER",
"mutant": "line 125: + -> - (arith)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"TOP_BY_QUANTITY"
]
},
{
"object": "{{P}}REFILL_PLANNER",
"mutant": "line 148: + -> - (arith)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"DISTRICT_TOTALS"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,164 @@
CLASS {{p}}refill_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_machine_id TYPE c LENGTH 8,
ty_district TYPE c LENGTH 4,
ty_quantity TYPE i,
ty_fill_level TYPE i,
BEGIN OF ty_machine,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
END OF ty_machine,
tt_machines TYPE STANDARD TABLE OF ty_machine WITH EMPTY KEY,
BEGIN OF ty_refill,
machine_id TYPE ty_machine_id,
quantity TYPE ty_quantity,
END OF ty_refill,
tt_refills TYPE STANDARD TABLE OF ty_refill WITH EMPTY KEY,
BEGIN OF ty_district_summary,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_summary,
tt_district_summary TYPE STANDARD TABLE OF ty_district_summary WITH EMPTY KEY.
METHODS add_machine
IMPORTING iv_machine_id TYPE ty_machine_id
iv_district TYPE ty_district
iv_fill_level TYPE ty_fill_level.
METHODS add_refill
IMPORTING iv_machine_id TYPE ty_machine_id
iv_quantity TYPE ty_quantity
RETURNING VALUE(rv_accepted) TYPE abap_bool.
METHODS get_refill
IMPORTING iv_machine_id TYPE ty_machine_id
RETURNING VALUE(rv_quantity) TYPE ty_quantity.
METHODS machines_below
IMPORTING iv_fill_level TYPE ty_fill_level
RETURNING VALUE(rt_machines) TYPE tt_machines.
METHODS top_refills
IMPORTING iv_count TYPE i
RETURNING VALUE(rt_refills) TYPE tt_refills.
METHODS district_summary
RETURNING VALUE(rt_summary) TYPE tt_district_summary.
METHODS total_quantity
RETURNING VALUE(rv_total) TYPE ty_quantity.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_machine_state,
machine_id TYPE ty_machine_id,
district TYPE ty_district,
fill_level TYPE ty_fill_level,
quantity TYPE ty_quantity,
END OF ty_machine_state,
tt_machine_state TYPE HASHED TABLE OF ty_machine_state WITH UNIQUE KEY machine_id.
DATA mt_machines TYPE tt_machine_state.
ENDCLASS.
CLASS {{p}}refill_planner IMPLEMENTATION.
METHOD add_machine.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
<ls_machine>-district = to_upper( iv_district ).
<ls_machine>-fill_level = iv_fill_level.
ELSE.
INSERT VALUE #( machine_id = lv_machine_id
district = to_upper( iv_district )
fill_level = iv_fill_level
quantity = 0 ) INTO TABLE mt_machines.
ENDIF.
ENDMETHOD.
METHOD add_refill.
IF iv_quantity <= 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc <> 0.
rv_accepted = abap_false.
RETURN.
ENDIF.
<ls_machine>-quantity = <ls_machine>-quantity + iv_quantity.
rv_accepted = abap_true.
ENDMETHOD.
METHOD get_refill.
DATA(lv_machine_id) = to_upper( iv_machine_id ).
ASSIGN mt_machines[ machine_id = lv_machine_id ] TO FIELD-SYMBOL(<ls_machine>).
IF sy-subrc = 0.
rv_quantity = <ls_machine>-quantity.
ENDIF.
ENDMETHOD.
METHOD machines_below.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-fill_level < iv_fill_level.
INSERT VALUE #( machine_id = ls_machine-machine_id
district = ls_machine-district
fill_level = ls_machine-fill_level ) INTO TABLE rt_machines.
ENDIF.
ENDLOOP.
SORT rt_machines BY fill_level machine_id.
ENDMETHOD.
METHOD top_refills.
DATA lv_index TYPE i.
DATA lt_refills TYPE tt_refills.
IF iv_count <= 0.
RETURN.
ENDIF.
LOOP AT mt_machines INTO DATA(ls_machine).
IF ls_machine-quantity > 0.
INSERT VALUE #( machine_id = ls_machine-machine_id
quantity = ls_machine-quantity ) INTO TABLE lt_refills.
ENDIF.
ENDLOOP.
SORT lt_refills BY quantity DESCENDING machine_id ASCENDING.
LOOP AT lt_refills INTO DATA(ls_refill).
lv_index = lv_index + 1.
IF lv_index > iv_count.
EXIT.
ENDIF.
INSERT ls_refill INTO TABLE rt_refills.
ENDLOOP.
ENDMETHOD.
METHOD district_summary.
TYPES:
BEGIN OF ty_district_state,
district TYPE ty_district,
machines TYPE i,
quantity TYPE ty_quantity,
END OF ty_district_state,
tt_district_state TYPE HASHED TABLE OF ty_district_state WITH UNIQUE KEY district.
DATA lt_districts TYPE tt_district_state.
LOOP AT mt_machines INTO DATA(ls_machine).
ASSIGN lt_districts[ district = ls_machine-district ] TO FIELD-SYMBOL(<ls_district>).
IF sy-subrc <> 0.
INSERT VALUE #( district = ls_machine-district )
INTO TABLE lt_districts ASSIGNING <ls_district>.
ENDIF.
<ls_district>-machines = <ls_district>-machines + 1.
<ls_district>-quantity = <ls_district>-quantity + ls_machine-quantity.
ENDLOOP.
LOOP AT lt_districts INTO DATA(ls_district).
INSERT VALUE #( district = ls_district-district
machines = ls_district-machines
quantity = ls_district-quantity ) INTO TABLE rt_summary.
ENDLOOP.
SORT rt_summary BY district.
ENDMETHOD.
METHOD total_quantity.
LOOP AT mt_machines INTO DATA(ls_machine).
rv_total = rv_total + ls_machine-quantity.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,93 @@
CLASS ltc_refill_planner DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}refill_planner.
METHODS setup.
METHODS adds_machine FOR TESTING.
METHODS replaces_machine FOR TESTING.
METHODS accumulates_refill FOR TESTING.
METHODS rejects_bad_quantity FOR TESTING.
METHODS ignores_unknown_machine FOR TESTING.
METHODS sorts_low_fill_level FOR TESTING.
METHODS ranks_largest_refills FOR TESTING.
METHODS sums_per_district FOR TESTING.
ENDCLASS.
CLASS ltc_refill_planner IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}refill_planner( ).
ENDMETHOD.
METHOD adds_machine.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 10 ).
DATA(lt_machines) = mo_cut->machines_below( 50 ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_machines ) ).
ENDMETHOD.
METHOD replaces_machine.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D2' iv_fill_level = 20 ).
DATA(lt_machines) = mo_cut->machines_below( 50 ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_machines ) ).
LOOP AT lt_machines INTO DATA(ls_machine).
cl_abap_unit_assert=>assert_equals( exp = 'D2' act = ls_machine-district ).
ENDLOOP.
ENDMETHOD.
METHOD accumulates_refill.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 5 ).
mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 7 ).
cl_abap_unit_assert=>assert_equals( exp = 12 act = mo_cut->get_refill( 'M1' ) ).
ENDMETHOD.
METHOD rejects_bad_quantity.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 10 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false
act = mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 0 ) ).
ENDMETHOD.
METHOD ignores_unknown_machine.
cl_abap_unit_assert=>assert_equals( exp = abap_false
act = mo_cut->add_refill( iv_machine_id = 'M9' iv_quantity = 5 ) ).
ENDMETHOD.
METHOD sorts_low_fill_level.
DATA lv_position TYPE i.
mo_cut->add_machine( iv_machine_id = 'M2' iv_district = 'D1' iv_fill_level = 20 ).
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 10 ).
DATA(lt_machines) = mo_cut->machines_below( 25 ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_machines ) ).
LOOP AT lt_machines INTO DATA(ls_machine).
lv_position = lv_position + 1.
IF lv_position = 1.
cl_abap_unit_assert=>assert_equals( exp = 'M1' act = ls_machine-machine_id ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD ranks_largest_refills.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_machine( iv_machine_id = 'M2' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 3 ).
mo_cut->add_refill( iv_machine_id = 'M2' iv_quantity = 8 ).
DATA(lt_refills) = mo_cut->top_refills( 1 ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_refills ) ).
LOOP AT lt_refills INTO DATA(ls_refill).
cl_abap_unit_assert=>assert_equals( exp = 'M2' act = ls_refill-machine_id ).
ENDLOOP.
ENDMETHOD.
METHOD sums_per_district.
mo_cut->add_machine( iv_machine_id = 'M1' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_machine( iv_machine_id = 'M2' iv_district = 'D1' iv_fill_level = 10 ).
mo_cut->add_refill( iv_machine_id = 'M1' iv_quantity = 3 ).
mo_cut->add_refill( iv_machine_id = 'M2' iv_quantity = 8 ).
DATA(lt_summary) = mo_cut->district_summary( ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_summary ) ).
LOOP AT lt_summary INTO DATA(ls_row).
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_row-machines ).
cl_abap_unit_assert=>assert_equals( exp = 11 act = ls_row-quantity ).
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,98 @@
# 1. Goal
A vending machine operator plans the refill of its vending machines. A planning
program collects the machines and the refill quantities. The program then asks
the planner for the machines with a low fill level, for the largest refills, and
for the totals per district. The program needs one class for this work.
# 2. Open questions
None.
# 3. Context
- Package $TMP is the development package.
- Only the class is in scope. The planning program is not in scope.
- A machine has a machine ID, a district, and a fill level in percent.
- A refill is a quantity of items for one machine.
- The class holds the machines of one planning run in memory.
- One program calls the class many times during a planning run.
# 4. Contract
Create the class {{P}}REFILL_PLANNER in package $TMP.
The class is public and final. It has a public constructor without parameters.
Do not add other public methods.
The public section of the class contains these types:
- ty_machine_id TYPE c LENGTH 8
- ty_district TYPE c LENGTH 4
- ty_quantity TYPE i
- ty_fill_level TYPE i
- ty_machine with the components machine_id TYPE ty_machine_id,
district TYPE ty_district, and fill_level TYPE ty_fill_level
- tt_machines with the line type ty_machine
- ty_refill with the components machine_id TYPE ty_machine_id and
quantity TYPE ty_quantity
- tt_refills with the line type ty_refill
- ty_district_summary with the components district TYPE ty_district,
machines TYPE i, and quantity TYPE ty_quantity
- tt_district_summary with the line type ty_district_summary
The class has these public methods:
- add_machine with the importing parameters iv_machine_id TYPE ty_machine_id,
iv_district TYPE ty_district, and iv_fill_level TYPE ty_fill_level.
- add_refill with the importing parameters iv_machine_id TYPE ty_machine_id and
iv_quantity TYPE ty_quantity and with the returning parameter rv_accepted TYPE
abap_bool.
- get_refill with the importing parameter iv_machine_id TYPE ty_machine_id and
the returning parameter rv_quantity TYPE ty_quantity.
- machines_below with the importing parameter iv_fill_level TYPE ty_fill_level
and the returning parameter rt_machines TYPE tt_machines.
- top_refills with the importing parameter iv_count TYPE i and the returning
parameter rt_refills TYPE tt_refills.
- district_summary with the returning parameter rt_summary TYPE
tt_district_summary.
- total_quantity with the returning parameter rv_total TYPE ty_quantity.
# 5. Business rules
1. A new instance of the class holds no machine.
2. The key of a machine is the machine ID. Two machines with the same machine ID
are one machine.
3. Convert every machine ID and every district to upper case before the class
stores it or compares it.
4. add_machine: If the machine ID is not known, add the machine with the given
district and the given fill level. If the machine ID is known, replace the
district and the fill level of the machine. The refill quantity of the
machine does not change.
5. add_refill: If iv_quantity is zero or less, return abap_false and change
nothing.
6. add_refill: If the machine ID is not known, return abap_false and change
nothing.
7. add_refill: Else add iv_quantity to the refill quantity of the machine and
return abap_true.
8. get_refill: Return the refill quantity of the machine. Return 0 if the
machine has no refill quantity or if the machine ID is not known.
9. machines_below: Return all machines with a fill level that is less than
iv_fill_level. Sort the result by fill level in ascending order. Sort
machines with the same fill level by machine ID in ascending order.
10. top_refills: Return the machines that have a refill quantity greater than
zero. The result has at most iv_count entries. Sort the result by refill
quantity in descending order. Sort machines with the same refill quantity
by machine ID in ascending order. If iv_count is zero or less, return an
empty table. If fewer machines have a refill quantity, return all of them.
11. district_summary: Return one row for each district that has at least one
machine. machines is the number of machines in the district. quantity is
the sum of the refill quantities of the machines in the district. Sort the
result by district in ascending order.
12. total_quantity: Return the sum of the refill quantities of all machines.
# 6. Constraints
- Release target: SAP_BASIS 816 (ABAP Platform 2025).
- Coding standards: Clean ABAP. Keep every method below 40 statements. Use no
global variable. Add no comment that restates the code. Pass large parameters
by reference.
- Out of scope: database tables, CDS views, reports, function modules, and
screen programming.
# 7. Acceptance
- The class is active and has no syntax error.
- The hidden tests pass.
- Write your own ABAP Unit tests for the class.
- The class has no ATC finding of priority 1 or priority 2.

View File

@@ -0,0 +1,42 @@
{
"id": "G0115",
"category": "C",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [],
"contract": [
{
"type": "CLAS",
"name": "{{P}}REFILL_PLANNER"
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}REFILL_HIDDEN",
"file": "hidden/refill_hidden.clas.abap",
"description": "Hidden tests for the refill planner"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}REFILL_PLANNER",
"file": "reference/refill_planner.clas.abap",
"description": "Refill planner for vending machines",
"testclasses_file": "reference/refill_planner.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"linear_search_in_loop",
"nested_loops"
]
}