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,110 @@
CLASS {{p}}dispatch_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_delivery,
delivery_id TYPE c LENGTH 10,
district TYPE c LENGTH 4,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
urgency TYPE i,
END OF ty_delivery,
tt_delivery TYPE STANDARD TABLE OF ty_delivery WITH EMPTY KEY,
BEGIN OF ty_district,
district TYPE c LENGTH 4,
deliveries TYPE i,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
top_urgency TYPE i,
END OF ty_district,
tt_district TYPE STANDARD TABLE OF ty_district WITH EMPTY KEY.
METHODS constructor.
METHODS plan
IMPORTING it_delivery TYPE tt_delivery
RETURNING VALUE(rt_district) TYPE tt_district.
METHODS merge
IMPORTING it_left TYPE tt_district
it_right TYPE tt_district
RETURNING VALUE(rt_merged) TYPE tt_district.
PRIVATE SECTION.
TYPES tt_group TYPE SORTED TABLE OF ty_district WITH UNIQUE KEY district.
METHODS add_delivery
IMPORTING is_delivery TYPE ty_delivery
CHANGING ct_group TYPE tt_group.
METHODS add_line
IMPORTING is_line TYPE ty_district
CHANGING ct_group TYPE tt_group.
METHODS to_result
IMPORTING it_group TYPE tt_group
RETURNING VALUE(rt_result) TYPE tt_district.
ENDCLASS.
CLASS {{p}}dispatch_planner IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD plan.
DATA lt_group TYPE tt_group.
LOOP AT it_delivery INTO DATA(ls_delivery).
add_delivery( EXPORTING is_delivery = ls_delivery
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_district = to_result( lt_group ).
ENDMETHOD.
METHOD merge.
DATA lt_group TYPE tt_group.
LOOP AT it_left INTO DATA(ls_left).
add_line( EXPORTING is_line = ls_left
CHANGING ct_group = lt_group ).
ENDLOOP.
LOOP AT it_right INTO DATA(ls_right).
add_line( EXPORTING is_line = ls_right
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_merged = to_result( lt_group ).
ENDMETHOD.
METHOD add_delivery.
IF is_delivery-parcels > 0.
RETURN.
ENDIF.
DATA(ls_new) = VALUE ty_district( district = is_delivery-district
deliveries = 1
parcels = is_delivery-parcels
weight = is_delivery-weight
top_urgency = is_delivery-urgency ).
READ TABLE ct_group WITH TABLE KEY district = is_delivery-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT ls_new INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries + ls_new-deliveries.
<ls_group>-parcels = <ls_group>-parcels + ls_new-parcels.
<ls_group>-weight = <ls_group>-weight + ls_new-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = ls_new-top_urgency ).
ENDMETHOD.
METHOD add_line.
READ TABLE ct_group WITH TABLE KEY district = is_line-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT is_line INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries + is_line-deliveries.
<ls_group>-parcels = <ls_group>-parcels + is_line-parcels.
<ls_group>-weight = <ls_group>-weight + is_line-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = is_line-top_urgency ).
ENDMETHOD.
METHOD to_result.
rt_result = it_group.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,110 @@
CLASS {{p}}dispatch_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_delivery,
delivery_id TYPE c LENGTH 10,
district TYPE c LENGTH 4,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
urgency TYPE i,
END OF ty_delivery,
tt_delivery TYPE STANDARD TABLE OF ty_delivery WITH EMPTY KEY,
BEGIN OF ty_district,
district TYPE c LENGTH 4,
deliveries TYPE i,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
top_urgency TYPE i,
END OF ty_district,
tt_district TYPE STANDARD TABLE OF ty_district WITH EMPTY KEY.
METHODS constructor.
METHODS plan
IMPORTING it_delivery TYPE tt_delivery
RETURNING VALUE(rt_district) TYPE tt_district.
METHODS merge
IMPORTING it_left TYPE tt_district
it_right TYPE tt_district
RETURNING VALUE(rt_merged) TYPE tt_district.
PRIVATE SECTION.
TYPES tt_group TYPE SORTED TABLE OF ty_district WITH UNIQUE KEY district.
METHODS add_delivery
IMPORTING is_delivery TYPE ty_delivery
CHANGING ct_group TYPE tt_group.
METHODS add_line
IMPORTING is_line TYPE ty_district
CHANGING ct_group TYPE tt_group.
METHODS to_result
IMPORTING it_group TYPE tt_group
RETURNING VALUE(rt_result) TYPE tt_district.
ENDCLASS.
CLASS {{p}}dispatch_planner IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD plan.
DATA lt_group TYPE tt_group.
LOOP AT it_delivery INTO DATA(ls_delivery).
add_delivery( EXPORTING is_delivery = ls_delivery
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_district = to_result( lt_group ).
ENDMETHOD.
METHOD merge.
DATA lt_group TYPE tt_group.
LOOP AT it_left INTO DATA(ls_left).
add_line( EXPORTING is_line = ls_left
CHANGING ct_group = lt_group ).
ENDLOOP.
LOOP AT it_right INTO DATA(ls_right).
add_line( EXPORTING is_line = ls_right
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_merged = to_result( lt_group ).
ENDMETHOD.
METHOD add_delivery.
IF is_delivery-parcels <= 0.
RETURN.
ENDIF.
DATA(ls_new) = VALUE ty_district( district = is_delivery-district
deliveries = 2
parcels = is_delivery-parcels
weight = is_delivery-weight
top_urgency = is_delivery-urgency ).
READ TABLE ct_group WITH TABLE KEY district = is_delivery-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT ls_new INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries + ls_new-deliveries.
<ls_group>-parcels = <ls_group>-parcels + ls_new-parcels.
<ls_group>-weight = <ls_group>-weight + ls_new-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = ls_new-top_urgency ).
ENDMETHOD.
METHOD add_line.
READ TABLE ct_group WITH TABLE KEY district = is_line-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT is_line INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries + is_line-deliveries.
<ls_group>-parcels = <ls_group>-parcels + is_line-parcels.
<ls_group>-weight = <ls_group>-weight + is_line-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = is_line-top_urgency ).
ENDMETHOD.
METHOD to_result.
rt_result = it_group.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,110 @@
CLASS {{p}}dispatch_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_delivery,
delivery_id TYPE c LENGTH 10,
district TYPE c LENGTH 4,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
urgency TYPE i,
END OF ty_delivery,
tt_delivery TYPE STANDARD TABLE OF ty_delivery WITH EMPTY KEY,
BEGIN OF ty_district,
district TYPE c LENGTH 4,
deliveries TYPE i,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
top_urgency TYPE i,
END OF ty_district,
tt_district TYPE STANDARD TABLE OF ty_district WITH EMPTY KEY.
METHODS constructor.
METHODS plan
IMPORTING it_delivery TYPE tt_delivery
RETURNING VALUE(rt_district) TYPE tt_district.
METHODS merge
IMPORTING it_left TYPE tt_district
it_right TYPE tt_district
RETURNING VALUE(rt_merged) TYPE tt_district.
PRIVATE SECTION.
TYPES tt_group TYPE SORTED TABLE OF ty_district WITH UNIQUE KEY district.
METHODS add_delivery
IMPORTING is_delivery TYPE ty_delivery
CHANGING ct_group TYPE tt_group.
METHODS add_line
IMPORTING is_line TYPE ty_district
CHANGING ct_group TYPE tt_group.
METHODS to_result
IMPORTING it_group TYPE tt_group
RETURNING VALUE(rt_result) TYPE tt_district.
ENDCLASS.
CLASS {{p}}dispatch_planner IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD plan.
DATA lt_group TYPE tt_group.
LOOP AT it_delivery INTO DATA(ls_delivery).
add_delivery( EXPORTING is_delivery = ls_delivery
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_district = to_result( lt_group ).
ENDMETHOD.
METHOD merge.
DATA lt_group TYPE tt_group.
LOOP AT it_left INTO DATA(ls_left).
add_line( EXPORTING is_line = ls_left
CHANGING ct_group = lt_group ).
ENDLOOP.
LOOP AT it_right INTO DATA(ls_right).
add_line( EXPORTING is_line = ls_right
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_merged = to_result( lt_group ).
ENDMETHOD.
METHOD add_delivery.
IF is_delivery-parcels <= 0.
RETURN.
ENDIF.
DATA(ls_new) = VALUE ty_district( district = is_delivery-district
deliveries = 1
parcels = is_delivery-parcels
weight = is_delivery-weight
top_urgency = is_delivery-urgency ).
READ TABLE ct_group WITH TABLE KEY district = is_delivery-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT ls_new INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries - ls_new-deliveries.
<ls_group>-parcels = <ls_group>-parcels + ls_new-parcels.
<ls_group>-weight = <ls_group>-weight + ls_new-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = ls_new-top_urgency ).
ENDMETHOD.
METHOD add_line.
READ TABLE ct_group WITH TABLE KEY district = is_line-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT is_line INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries + is_line-deliveries.
<ls_group>-parcels = <ls_group>-parcels + is_line-parcels.
<ls_group>-weight = <ls_group>-weight + is_line-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = is_line-top_urgency ).
ENDMETHOD.
METHOD to_result.
rt_result = it_group.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,110 @@
CLASS {{p}}dispatch_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_delivery,
delivery_id TYPE c LENGTH 10,
district TYPE c LENGTH 4,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
urgency TYPE i,
END OF ty_delivery,
tt_delivery TYPE STANDARD TABLE OF ty_delivery WITH EMPTY KEY,
BEGIN OF ty_district,
district TYPE c LENGTH 4,
deliveries TYPE i,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
top_urgency TYPE i,
END OF ty_district,
tt_district TYPE STANDARD TABLE OF ty_district WITH EMPTY KEY.
METHODS constructor.
METHODS plan
IMPORTING it_delivery TYPE tt_delivery
RETURNING VALUE(rt_district) TYPE tt_district.
METHODS merge
IMPORTING it_left TYPE tt_district
it_right TYPE tt_district
RETURNING VALUE(rt_merged) TYPE tt_district.
PRIVATE SECTION.
TYPES tt_group TYPE SORTED TABLE OF ty_district WITH UNIQUE KEY district.
METHODS add_delivery
IMPORTING is_delivery TYPE ty_delivery
CHANGING ct_group TYPE tt_group.
METHODS add_line
IMPORTING is_line TYPE ty_district
CHANGING ct_group TYPE tt_group.
METHODS to_result
IMPORTING it_group TYPE tt_group
RETURNING VALUE(rt_result) TYPE tt_district.
ENDCLASS.
CLASS {{p}}dispatch_planner IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD plan.
DATA lt_group TYPE tt_group.
LOOP AT it_delivery INTO DATA(ls_delivery).
add_delivery( EXPORTING is_delivery = ls_delivery
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_district = to_result( lt_group ).
ENDMETHOD.
METHOD merge.
DATA lt_group TYPE tt_group.
LOOP AT it_left INTO DATA(ls_left).
add_line( EXPORTING is_line = ls_left
CHANGING ct_group = lt_group ).
ENDLOOP.
LOOP AT it_right INTO DATA(ls_right).
add_line( EXPORTING is_line = ls_right
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_merged = to_result( lt_group ).
ENDMETHOD.
METHOD add_delivery.
IF is_delivery-parcels <= 0.
RETURN.
ENDIF.
DATA(ls_new) = VALUE ty_district( district = is_delivery-district
deliveries = 1
parcels = is_delivery-parcels
weight = is_delivery-weight
top_urgency = is_delivery-urgency ).
READ TABLE ct_group WITH TABLE KEY district = is_delivery-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT ls_new INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries + ls_new-deliveries.
<ls_group>-parcels = <ls_group>-parcels + ls_new-parcels.
<ls_group>-weight = <ls_group>-weight + ls_new-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = ls_new-top_urgency ).
ENDMETHOD.
METHOD add_line.
READ TABLE ct_group WITH TABLE KEY district = is_line-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT is_line INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries - is_line-deliveries.
<ls_group>-parcels = <ls_group>-parcels + is_line-parcels.
<ls_group>-weight = <ls_group>-weight + is_line-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = is_line-top_urgency ).
ENDMETHOD.
METHOD to_result.
rt_result = it_group.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,110 @@
CLASS {{p}}dispatch_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_delivery,
delivery_id TYPE c LENGTH 10,
district TYPE c LENGTH 4,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
urgency TYPE i,
END OF ty_delivery,
tt_delivery TYPE STANDARD TABLE OF ty_delivery WITH EMPTY KEY,
BEGIN OF ty_district,
district TYPE c LENGTH 4,
deliveries TYPE i,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
top_urgency TYPE i,
END OF ty_district,
tt_district TYPE STANDARD TABLE OF ty_district WITH EMPTY KEY.
METHODS constructor.
METHODS plan
IMPORTING it_delivery TYPE tt_delivery
RETURNING VALUE(rt_district) TYPE tt_district.
METHODS merge
IMPORTING it_left TYPE tt_district
it_right TYPE tt_district
RETURNING VALUE(rt_merged) TYPE tt_district.
PRIVATE SECTION.
TYPES tt_group TYPE SORTED TABLE OF ty_district WITH UNIQUE KEY district.
METHODS add_delivery
IMPORTING is_delivery TYPE ty_delivery
CHANGING ct_group TYPE tt_group.
METHODS add_line
IMPORTING is_line TYPE ty_district
CHANGING ct_group TYPE tt_group.
METHODS to_result
IMPORTING it_group TYPE tt_group
RETURNING VALUE(rt_result) TYPE tt_district.
ENDCLASS.
CLASS {{p}}dispatch_planner IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD plan.
DATA lt_group TYPE tt_group.
LOOP AT it_delivery INTO DATA(ls_delivery).
add_delivery( EXPORTING is_delivery = ls_delivery
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_district = to_result( lt_group ).
ENDMETHOD.
METHOD merge.
DATA lt_group TYPE tt_group.
LOOP AT it_left INTO DATA(ls_left).
add_line( EXPORTING is_line = ls_left
CHANGING ct_group = lt_group ).
ENDLOOP.
LOOP AT it_right INTO DATA(ls_right).
add_line( EXPORTING is_line = ls_right
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_merged = to_result( lt_group ).
ENDMETHOD.
METHOD add_delivery.
IF is_delivery-parcels <= 0.
RETURN.
ENDIF.
DATA(ls_new) = VALUE ty_district( district = is_delivery-district
deliveries = 1
parcels = is_delivery-parcels
weight = is_delivery-weight
top_urgency = is_delivery-urgency ).
READ TABLE ct_group WITH TABLE KEY district = is_delivery-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT ls_new INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries + ls_new-deliveries.
<ls_group>-parcels = <ls_group>-parcels + ls_new-parcels.
<ls_group>-weight = <ls_group>-weight + ls_new-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = ls_new-top_urgency ).
ENDMETHOD.
METHOD add_line.
READ TABLE ct_group WITH TABLE KEY district = is_line-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT is_line INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries + is_line-deliveries.
<ls_group>-parcels = <ls_group>-parcels + is_line-parcels.
<ls_group>-weight = <ls_group>-weight - is_line-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = is_line-top_urgency ).
ENDMETHOD.
METHOD to_result.
rt_result = it_group.
ENDMETHOD.
ENDCLASS.

View File

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

View File

@@ -0,0 +1,238 @@
CLASS {{p}}t02_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_id TYPE c LENGTH 10.
TYPES ty_district TYPE c LENGTH 4.
TYPES ty_weight TYPE p LENGTH 8 DECIMALS 2.
DATA mo_cut TYPE REF TO {{p}}dispatch_planner.
METHODS setup.
METHODS make_delivery
IMPORTING iv_id TYPE ty_id
iv_district TYPE ty_district
iv_parcels TYPE i
iv_weight TYPE ty_weight
iv_urgency TYPE i
RETURNING VALUE(rs_delivery) TYPE {{p}}dispatch_planner=>ty_delivery.
METHODS make_line
IMPORTING iv_district TYPE ty_district
iv_deliveries TYPE i
iv_parcels TYPE i
iv_weight TYPE ty_weight
iv_urgency TYPE i
RETURNING VALUE(rs_line) TYPE {{p}}dispatch_planner=>ty_district.
METHODS empty_input FOR TESTING.
METHODS one_delivery FOR TESTING.
METHODS groups_districts FOR TESTING.
METHODS ignores_zero_parcels FOR TESTING.
METHODS sums_parcels_weight FOR TESTING.
METHODS top_urgency_is_min FOR TESTING.
METHODS result_is_sorted FOR TESTING.
METHODS merge_adds_values FOR TESTING.
METHODS merge_single_district FOR TESTING.
METHODS merge_urgency_min FOR TESTING.
METHODS merge_sorted FOR TESTING.
METHODS merge_empty FOR TESTING.
ENDCLASS.
CLASS {{p}}t02_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}dispatch_planner( ).
ENDMETHOD.
METHOD make_delivery.
rs_delivery = VALUE #( delivery_id = iv_id
district = iv_district
parcels = iv_parcels
weight = iv_weight
urgency = iv_urgency ).
ENDMETHOD.
METHOD make_line.
rs_line = VALUE #( district = iv_district
deliveries = iv_deliveries
parcels = iv_parcels
weight = iv_weight
top_urgency = iv_urgency ).
ENDMETHOD.
METHOD empty_input.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
DATA(lt_result) = mo_cut->plan( lt_delivery ).
cl_abap_unit_assert=>assert_initial( act = lt_result ).
ENDMETHOD.
METHOD one_delivery.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
lt_delivery = VALUE #(
( make_delivery( iv_id = 'D1' iv_district = 'NORD' iv_parcels = 3
iv_weight = '10.50' iv_urgency = 2 ) ) ).
DATA(lt_result) = mo_cut->plan( lt_delivery ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_result ) ).
DATA(ls_line) = lt_result[ district = 'NORD' ].
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_line-deliveries ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = ls_line-parcels ).
DATA lv_weight TYPE ty_weight.
lv_weight = '10.50'.
cl_abap_unit_assert=>assert_equals( exp = lv_weight act = ls_line-weight ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_line-top_urgency ).
ENDMETHOD.
METHOD groups_districts.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
lt_delivery = VALUE #(
( make_delivery( iv_id = 'D1' iv_district = 'NORD' iv_parcels = 2
iv_weight = '5.00' iv_urgency = 1 ) )
( make_delivery( iv_id = 'D2' iv_district = 'SUED' iv_parcels = 4
iv_weight = '7.00' iv_urgency = 3 ) )
( make_delivery( iv_id = 'D3' iv_district = 'NORD' iv_parcels = 1
iv_weight = '2.00' iv_urgency = 5 ) ) ).
DATA(lt_result) = mo_cut->plan( lt_delivery ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_result ) ).
DATA(ls_nord) = lt_result[ district = 'NORD' ].
DATA(ls_sued) = lt_result[ district = 'SUED' ].
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_nord-deliveries ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_sued-deliveries ).
ENDMETHOD.
METHOD ignores_zero_parcels.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
lt_delivery = VALUE #(
( make_delivery( iv_id = 'D1' iv_district = 'NORD' iv_parcels = 0
iv_weight = '5.00' iv_urgency = 1 ) )
( make_delivery( iv_id = 'D2' iv_district = 'OST' iv_parcels = -2
iv_weight = '3.00' iv_urgency = 2 ) )
( make_delivery( iv_id = 'D3' iv_district = 'WEST' iv_parcels = 2
iv_weight = '3.00' iv_urgency = 2 ) ) ).
DATA(lt_result) = mo_cut->plan( lt_delivery ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_result ) ).
READ TABLE lt_result WITH KEY district = 'NORD' TRANSPORTING NO FIELDS.
cl_abap_unit_assert=>assert_subrc( exp = 4 msg = 'NORD must not be in the result' ).
READ TABLE lt_result WITH KEY district = 'OST' TRANSPORTING NO FIELDS.
cl_abap_unit_assert=>assert_subrc( exp = 4 msg = 'OST must not be in the result' ).
DATA(ls_line) = lt_result[ 1 ].
cl_abap_unit_assert=>assert_equals( exp = 'WEST' act = ls_line-district ).
ENDMETHOD.
METHOD sums_parcels_weight.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
lt_delivery = VALUE #(
( make_delivery( iv_id = 'D1' iv_district = 'NORD' iv_parcels = 2
iv_weight = '10.25' iv_urgency = 1 ) )
( make_delivery( iv_id = 'D2' iv_district = 'NORD' iv_parcels = 3
iv_weight = '4.75' iv_urgency = 1 ) ) ).
DATA(lt_result) = mo_cut->plan( lt_delivery ).
DATA(ls_line) = lt_result[ district = 'NORD' ].
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_line-deliveries ).
cl_abap_unit_assert=>assert_equals( exp = 5 act = ls_line-parcels ).
DATA lv_weight TYPE ty_weight.
lv_weight = '15.00'.
cl_abap_unit_assert=>assert_equals( exp = lv_weight act = ls_line-weight ).
ENDMETHOD.
METHOD top_urgency_is_min.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
lt_delivery = VALUE #(
( make_delivery( iv_id = 'D1' iv_district = 'NORD' iv_parcels = 1
iv_weight = '1.00' iv_urgency = 5 ) )
( make_delivery( iv_id = 'D2' iv_district = 'NORD' iv_parcels = 1
iv_weight = '1.00' iv_urgency = 2 ) )
( make_delivery( iv_id = 'D3' iv_district = 'NORD' iv_parcels = 1
iv_weight = '1.00' iv_urgency = 4 ) ) ).
DATA(lt_result) = mo_cut->plan( lt_delivery ).
DATA(ls_line) = lt_result[ district = 'NORD' ].
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_line-top_urgency ).
ENDMETHOD.
METHOD result_is_sorted.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
lt_delivery = VALUE #(
( make_delivery( iv_id = 'D1' iv_district = 'WEST' iv_parcels = 1
iv_weight = '1.00' iv_urgency = 1 ) )
( make_delivery( iv_id = 'D2' iv_district = 'NORD' iv_parcels = 1
iv_weight = '1.00' iv_urgency = 1 ) )
( make_delivery( iv_id = 'D3' iv_district = 'OST' iv_parcels = 1
iv_weight = '1.00' iv_urgency = 1 ) ) ).
DATA(lt_result) = mo_cut->plan( lt_delivery ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lines( lt_result ) ).
DATA(ls_first) = lt_result[ 1 ].
DATA(ls_second) = lt_result[ 2 ].
DATA(ls_third) = lt_result[ 3 ].
cl_abap_unit_assert=>assert_equals( exp = 'NORD' act = ls_first-district ).
cl_abap_unit_assert=>assert_equals( exp = 'OST' act = ls_second-district ).
cl_abap_unit_assert=>assert_equals( exp = 'WEST' act = ls_third-district ).
ENDMETHOD.
METHOD merge_adds_values.
DATA lt_left TYPE {{p}}dispatch_planner=>tt_district.
DATA lt_right TYPE {{p}}dispatch_planner=>tt_district.
lt_left = VALUE #( ( make_line( iv_district = 'NORD' iv_deliveries = 2 iv_parcels = 5
iv_weight = '10.00' iv_urgency = 3 ) ) ).
lt_right = VALUE #( ( make_line( iv_district = 'NORD' iv_deliveries = 1 iv_parcels = 4
iv_weight = '2.50' iv_urgency = 2 ) ) ).
DATA(lt_result) = mo_cut->merge( it_left = lt_left it_right = lt_right ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_result ) ).
DATA(ls_line) = lt_result[ district = 'NORD' ].
cl_abap_unit_assert=>assert_equals( exp = 3 act = ls_line-deliveries ).
cl_abap_unit_assert=>assert_equals( exp = 9 act = ls_line-parcels ).
DATA lv_weight TYPE ty_weight.
lv_weight = '12.50'.
cl_abap_unit_assert=>assert_equals( exp = lv_weight act = ls_line-weight ).
ENDMETHOD.
METHOD merge_single_district.
DATA lt_left TYPE {{p}}dispatch_planner=>tt_district.
DATA lt_right TYPE {{p}}dispatch_planner=>tt_district.
lt_left = VALUE #( ( make_line( iv_district = 'NORD' iv_deliveries = 2 iv_parcels = 5
iv_weight = '10.00' iv_urgency = 3 ) ) ).
lt_right = VALUE #( ( make_line( iv_district = 'SUED' iv_deliveries = 4 iv_parcels = 8
iv_weight = '6.00' iv_urgency = 1 ) ) ).
DATA(lt_result) = mo_cut->merge( it_left = lt_left it_right = lt_right ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_result ) ).
DATA(ls_sued) = lt_result[ district = 'SUED' ].
cl_abap_unit_assert=>assert_equals( exp = 4 act = ls_sued-deliveries ).
cl_abap_unit_assert=>assert_equals( exp = 8 act = ls_sued-parcels ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_sued-top_urgency ).
ENDMETHOD.
METHOD merge_urgency_min.
DATA lt_left TYPE {{p}}dispatch_planner=>tt_district.
DATA lt_right TYPE {{p}}dispatch_planner=>tt_district.
lt_left = VALUE #( ( make_line( iv_district = 'NORD' iv_deliveries = 1 iv_parcels = 1
iv_weight = '1.00' iv_urgency = 4 ) ) ).
lt_right = VALUE #( ( make_line( iv_district = 'NORD' iv_deliveries = 1 iv_parcels = 1
iv_weight = '1.00' iv_urgency = 7 ) ) ).
DATA(lt_result) = mo_cut->merge( it_left = lt_left it_right = lt_right ).
DATA(ls_line) = lt_result[ district = 'NORD' ].
cl_abap_unit_assert=>assert_equals( exp = 4 act = ls_line-top_urgency ).
ENDMETHOD.
METHOD merge_sorted.
DATA lt_left TYPE {{p}}dispatch_planner=>tt_district.
DATA lt_right TYPE {{p}}dispatch_planner=>tt_district.
lt_left = VALUE #( ( make_line( iv_district = 'WEST' iv_deliveries = 1 iv_parcels = 1
iv_weight = '1.00' iv_urgency = 1 ) ) ).
lt_right = VALUE #( ( make_line( iv_district = 'OST' iv_deliveries = 1 iv_parcels = 1
iv_weight = '1.00' iv_urgency = 1 ) )
( make_line( iv_district = 'NORD' iv_deliveries = 1 iv_parcels = 1
iv_weight = '1.00' iv_urgency = 1 ) ) ).
DATA(lt_result) = mo_cut->merge( it_left = lt_left it_right = lt_right ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lines( lt_result ) ).
DATA(ls_first) = lt_result[ 1 ].
DATA(ls_second) = lt_result[ 2 ].
DATA(ls_third) = lt_result[ 3 ].
cl_abap_unit_assert=>assert_equals( exp = 'NORD' act = ls_first-district ).
cl_abap_unit_assert=>assert_equals( exp = 'OST' act = ls_second-district ).
cl_abap_unit_assert=>assert_equals( exp = 'WEST' act = ls_third-district ).
ENDMETHOD.
METHOD merge_empty.
DATA lt_left TYPE {{p}}dispatch_planner=>tt_district.
DATA lt_right TYPE {{p}}dispatch_planner=>tt_district.
DATA(lt_result) = mo_cut->merge( it_left = lt_left it_right = lt_right ).
cl_abap_unit_assert=>assert_initial( act = lt_result ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,62 @@
{
"task": "G0114",
"mutants": [
{
"object": "{{P}}DISPATCH_PLANNER",
"mutant": "line 72: <= -> > (rel)",
"status": "killed",
"hidden": "6/12",
"failed_tests": [
"GROUPS_DISTRICTS",
"IGNORES_ZERO_PARCELS",
"ONE_DELIVERY",
"RESULT_IS_SORTED",
"SUMS_PARCELS_WEIGHT",
"TOP_URGENCY_IS_MIN"
]
},
{
"object": "{{P}}DISPATCH_PLANNER",
"mutant": "line 76: 1 -> 2 (const)",
"status": "killed",
"hidden": "9/12",
"failed_tests": [
"GROUPS_DISTRICTS",
"ONE_DELIVERY",
"SUMS_PARCELS_WEIGHT"
]
},
{
"object": "{{P}}DISPATCH_PLANNER",
"mutant": "line 86: + -> - (arith)",
"status": "killed",
"hidden": "10/12",
"failed_tests": [
"GROUPS_DISTRICTS",
"SUMS_PARCELS_WEIGHT"
]
},
{
"object": "{{P}}DISPATCH_PLANNER",
"mutant": "line 100: + -> - (arith)",
"status": "killed",
"hidden": "11/12",
"failed_tests": [
"MERGE_ADDS_VALUES"
]
},
{
"object": "{{P}}DISPATCH_PLANNER",
"mutant": "line 102: + -> - (arith)",
"status": "killed",
"hidden": "11/12",
"failed_tests": [
"MERGE_ADDS_VALUES"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,110 @@
CLASS {{p}}dispatch_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_delivery,
delivery_id TYPE c LENGTH 10,
district TYPE c LENGTH 4,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
urgency TYPE i,
END OF ty_delivery,
tt_delivery TYPE STANDARD TABLE OF ty_delivery WITH EMPTY KEY,
BEGIN OF ty_district,
district TYPE c LENGTH 4,
deliveries TYPE i,
parcels TYPE i,
weight TYPE p LENGTH 8 DECIMALS 2,
top_urgency TYPE i,
END OF ty_district,
tt_district TYPE STANDARD TABLE OF ty_district WITH EMPTY KEY.
METHODS constructor.
METHODS plan
IMPORTING it_delivery TYPE tt_delivery
RETURNING VALUE(rt_district) TYPE tt_district.
METHODS merge
IMPORTING it_left TYPE tt_district
it_right TYPE tt_district
RETURNING VALUE(rt_merged) TYPE tt_district.
PRIVATE SECTION.
TYPES tt_group TYPE SORTED TABLE OF ty_district WITH UNIQUE KEY district.
METHODS add_delivery
IMPORTING is_delivery TYPE ty_delivery
CHANGING ct_group TYPE tt_group.
METHODS add_line
IMPORTING is_line TYPE ty_district
CHANGING ct_group TYPE tt_group.
METHODS to_result
IMPORTING it_group TYPE tt_group
RETURNING VALUE(rt_result) TYPE tt_district.
ENDCLASS.
CLASS {{p}}dispatch_planner IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD plan.
DATA lt_group TYPE tt_group.
LOOP AT it_delivery INTO DATA(ls_delivery).
add_delivery( EXPORTING is_delivery = ls_delivery
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_district = to_result( lt_group ).
ENDMETHOD.
METHOD merge.
DATA lt_group TYPE tt_group.
LOOP AT it_left INTO DATA(ls_left).
add_line( EXPORTING is_line = ls_left
CHANGING ct_group = lt_group ).
ENDLOOP.
LOOP AT it_right INTO DATA(ls_right).
add_line( EXPORTING is_line = ls_right
CHANGING ct_group = lt_group ).
ENDLOOP.
rt_merged = to_result( lt_group ).
ENDMETHOD.
METHOD add_delivery.
IF is_delivery-parcels <= 0.
RETURN.
ENDIF.
DATA(ls_new) = VALUE ty_district( district = is_delivery-district
deliveries = 1
parcels = is_delivery-parcels
weight = is_delivery-weight
top_urgency = is_delivery-urgency ).
READ TABLE ct_group WITH TABLE KEY district = is_delivery-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT ls_new INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries + ls_new-deliveries.
<ls_group>-parcels = <ls_group>-parcels + ls_new-parcels.
<ls_group>-weight = <ls_group>-weight + ls_new-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = ls_new-top_urgency ).
ENDMETHOD.
METHOD add_line.
READ TABLE ct_group WITH TABLE KEY district = is_line-district
ASSIGNING FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT is_line INTO TABLE ct_group.
RETURN.
ENDIF.
<ls_group>-deliveries = <ls_group>-deliveries + is_line-deliveries.
<ls_group>-parcels = <ls_group>-parcels + is_line-parcels.
<ls_group>-weight = <ls_group>-weight + is_line-weight.
<ls_group>-top_urgency = nmin( val1 = <ls_group>-top_urgency
val2 = is_line-top_urgency ).
ENDMETHOD.
METHOD to_result.
rt_result = it_group.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,126 @@
CLASS ltc_dispatch_planner DEFINITION FINAL FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_weight TYPE p LENGTH 8 DECIMALS 2.
DATA mo_cut TYPE REF TO {{p}}dispatch_planner.
METHODS setup.
METHODS plan_groups_districts FOR TESTING.
METHODS plan_ignores_zero FOR TESTING.
METHODS plan_sums_values FOR TESTING.
METHODS plan_sorts_result FOR TESTING.
METHODS plan_empty_input FOR TESTING.
METHODS merge_adds_values FOR TESTING.
METHODS merge_keeps_single FOR TESTING.
METHODS merge_urgency_min FOR TESTING.
METHODS merge_empty FOR TESTING.
ENDCLASS.
CLASS ltc_dispatch_planner IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}dispatch_planner( ).
ENDMETHOD.
METHOD plan_groups_districts.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
lt_delivery = VALUE #(
( delivery_id = 'D1' district = 'NORD' parcels = 2 weight = '5.00' urgency = 1 )
( delivery_id = 'D2' district = 'SUED' parcels = 4 weight = '7.00' urgency = 3 )
( delivery_id = 'D3' district = 'NORD' parcels = 1 weight = '2.00' urgency = 5 ) ).
DATA(lt_result) = mo_cut->plan( lt_delivery ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_result ) ).
DATA(ls_nord) = lt_result[ district = 'NORD' ].
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_nord-deliveries ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = ls_nord-parcels ).
ENDMETHOD.
METHOD plan_ignores_zero.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
lt_delivery = VALUE #(
( delivery_id = 'D1' district = 'NORD' parcels = 0 weight = '5.00' urgency = 1 ) ).
DATA(lt_result) = mo_cut->plan( lt_delivery ).
cl_abap_unit_assert=>assert_initial( act = lt_result ).
ENDMETHOD.
METHOD plan_sums_values.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
lt_delivery = VALUE #(
( delivery_id = 'D1' district = 'NORD' parcels = 2 weight = '10.25' urgency = 1 )
( delivery_id = 'D2' district = 'NORD' parcels = 3 weight = '4.75' urgency = 4 ) ).
DATA(lt_result) = mo_cut->plan( lt_delivery ).
DATA(ls_line) = lt_result[ district = 'NORD' ].
cl_abap_unit_assert=>assert_equals( exp = 5 act = ls_line-parcels ).
DATA lv_weight TYPE ty_weight.
lv_weight = '15.00'.
cl_abap_unit_assert=>assert_equals( exp = lv_weight act = ls_line-weight ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_line-top_urgency ).
ENDMETHOD.
METHOD plan_sorts_result.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
lt_delivery = VALUE #(
( delivery_id = 'D1' district = 'WEST' parcels = 1 weight = '1.00' urgency = 1 )
( delivery_id = 'D2' district = 'NORD' parcels = 1 weight = '1.00' urgency = 1 ) ).
DATA(lt_result) = mo_cut->plan( lt_delivery ).
DATA(ls_first) = lt_result[ 1 ].
cl_abap_unit_assert=>assert_equals( exp = 'NORD' act = ls_first-district ).
ENDMETHOD.
METHOD plan_empty_input.
DATA lt_delivery TYPE {{p}}dispatch_planner=>tt_delivery.
DATA(lt_result) = mo_cut->plan( lt_delivery ).
cl_abap_unit_assert=>assert_initial( act = lt_result ).
ENDMETHOD.
METHOD merge_adds_values.
DATA lt_left TYPE {{p}}dispatch_planner=>tt_district.
DATA lt_right TYPE {{p}}dispatch_planner=>tt_district.
lt_left = VALUE #( ( district = 'NORD' deliveries = 2 parcels = 5
weight = '10.00' top_urgency = 3 ) ).
lt_right = VALUE #( ( district = 'NORD' deliveries = 1 parcels = 4
weight = '2.50' top_urgency = 2 ) ).
DATA(lt_result) = mo_cut->merge( it_left = lt_left it_right = lt_right ).
DATA(ls_line) = lt_result[ district = 'NORD' ].
cl_abap_unit_assert=>assert_equals( exp = 3 act = ls_line-deliveries ).
cl_abap_unit_assert=>assert_equals( exp = 9 act = ls_line-parcels ).
DATA lv_weight TYPE ty_weight.
lv_weight = '12.50'.
cl_abap_unit_assert=>assert_equals( exp = lv_weight act = ls_line-weight ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_line-top_urgency ).
ENDMETHOD.
METHOD merge_keeps_single.
DATA lt_left TYPE {{p}}dispatch_planner=>tt_district.
DATA lt_right TYPE {{p}}dispatch_planner=>tt_district.
lt_left = VALUE #( ( district = 'NORD' deliveries = 2 parcels = 5
weight = '10.00' top_urgency = 3 ) ).
lt_right = VALUE #( ( district = 'SUED' deliveries = 4 parcels = 8
weight = '6.00' top_urgency = 1 ) ).
DATA(lt_result) = mo_cut->merge( it_left = lt_left it_right = lt_right ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_result ) ).
DATA(ls_sued) = lt_result[ district = 'SUED' ].
cl_abap_unit_assert=>assert_equals( exp = 4 act = ls_sued-deliveries ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_sued-top_urgency ).
ENDMETHOD.
METHOD merge_urgency_min.
DATA lt_left TYPE {{p}}dispatch_planner=>tt_district.
DATA lt_right TYPE {{p}}dispatch_planner=>tt_district.
lt_left = VALUE #( ( district = 'NORD' deliveries = 1 parcels = 1
weight = '1.00' top_urgency = 4 ) ).
lt_right = VALUE #( ( district = 'NORD' deliveries = 1 parcels = 1
weight = '1.00' top_urgency = 7 ) ).
DATA(lt_result) = mo_cut->merge( it_left = lt_left it_right = lt_right ).
DATA(ls_line) = lt_result[ district = 'NORD' ].
cl_abap_unit_assert=>assert_equals( exp = 4 act = ls_line-top_urgency ).
ENDMETHOD.
METHOD merge_empty.
DATA lt_left TYPE {{p}}dispatch_planner=>tt_district.
DATA lt_right TYPE {{p}}dispatch_planner=>tt_district.
DATA(lt_result) = mo_cut->merge( it_left = lt_left it_right = lt_right ).
cl_abap_unit_assert=>assert_initial( act = lt_result ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,68 @@
# 1. Goal
A courier company dispatches deliveries. Each delivery belongs to a district. The
dispatcher needs one service that groups the deliveries per district, and one
service that merges two district plans. A planning program calls both services.
# 2. Open questions
None.
# 3. Context
- The class {{P}}DISPATCH_PLANNER does not exist. Create it in package $TMP.
- A delivery has an ID, a district code, a number of parcels, a weight and an
urgency. A small urgency value means a high urgency.
- A district plan has one line per district.
- The planning program reads the deliveries of one day and calls PLAN.
- A second depot sends its own plan. The dispatcher calls MERGE with the plan of
the first depot and the plan of the second depot.
# 4. Contract
- Create the class {{P}}DISPATCH_PLANNER in package $TMP.
- The class is public and final. It has a public constructor without parameters.
- The class has the public methods PLAN and MERGE. It has no other public method.
- Public types of the class:
- TY_DELIVERY with the components DELIVERY_ID (character 10), DISTRICT
(character 4), PARCELS (integer), WEIGHT (packed number, length 8, 2
decimals) and URGENCY (integer).
- TT_DELIVERY: a standard table of TY_DELIVERY with an empty key.
- TY_DISTRICT with the components DISTRICT (character 4), DELIVERIES
(integer), PARCELS (integer), WEIGHT (packed number, length 8, 2 decimals)
and TOP_URGENCY (integer).
- TT_DISTRICT: a standard table of TY_DISTRICT with an empty key.
- Method PLAN:
IMPORTING it_delivery TYPE tt_delivery
RETURNING VALUE(rt_district) TYPE tt_district.
- Method MERGE:
IMPORTING it_left TYPE tt_district
it_right TYPE tt_district
RETURNING VALUE(rt_merged) TYPE tt_district.
# 5. Business rules
Method PLAN:
1. Ignore each delivery whose PARCELS value is zero or negative.
2. Group the other deliveries by DISTRICT. Compare the district codes exactly.
3. Each district has exactly one line in the result:
- DELIVERIES: the number of deliveries of the district.
- PARCELS: the sum of the parcels of the deliveries of the district.
- WEIGHT: the sum of the weights of the deliveries of the district.
- TOP_URGENCY: the smallest urgency of the deliveries of the district.
4. Sort the result by DISTRICT in ascending order.
5. If no delivery remains, the result is empty.
Method MERGE:
6. A district that occurs in both plans has exactly one line in the result:
- DELIVERIES, PARCELS and WEIGHT: the sum of the two values.
- TOP_URGENCY: the smaller of the two values.
7. A district that occurs in only one plan keeps its values.
8. Sort the result by DISTRICT in ascending order.
9. If both plans are empty, the result is empty.
# 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: no other global object in package $TMP.
# 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,42 @@
{
"id": "G0114",
"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}}DISPATCH_PLANNER"
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T02_HIDDEN",
"file": "hidden/t02_hidden.clas.abap",
"description": "T02 hidden tests"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}DISPATCH_PLANNER",
"file": "reference/dispatch_planner.clas.abap",
"description": "Dispatch planner",
"testclasses_file": "reference/dispatch_planner.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"linear_search_in_loop",
"table_kind"
]
}