Stage 2 summary at 50 accepted trajectories

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 18:02:52 +02:00
parent 332fb4601d
commit 5bcd1bf9cd
1230 changed files with 77563 additions and 33 deletions

View File

@@ -0,0 +1,36 @@
{
"id": "G1101",
"pool": "train",
"object_type": "FUNC",
"category": "C",
"attempts": [
{
"stage": "bundle",
"errors": [
"seed/dish.tabl.abap: a table needs the annotation @AbapCatalog.tableCategory (for example #TRANSPARENT, #A)",
"seed/dish.tabl.abap: a table needs the annotation @AbapCatalog.deliveryClass (for example #TRANSPARENT, #A)",
"seed/pos.tabl.abap: a table needs the annotation @AbapCatalog.tableCategory (for example #TRANSPARENT, #A)",
"seed/pos.tabl.abap: a table needs the annotation @AbapCatalog.deliveryClass (for example #TRANSPARENT, #A)"
],
"by_check": {
"static": 4
}
},
{
"stage": "validate",
"oracle": null,
"null": null
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": null,
"null": null
}
],
"accepted": false
}

View File

@@ -0,0 +1,212 @@
CLASS {{p}}t41_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS setup.
METHODS teardown.
METHODS insert_dishes.
METHODS insert_positions
IMPORTING it_positions TYPE STANDARD TABLE OF {{p}}pos.
METHODS call
IMPORTING iv_order_id TYPE string
EXPORTING ev_total TYPE decfloat34
ev_portions TYPE i
ev_dishes TYPE i
ev_subrc TYPE sysubrc.
METHODS total_and_portions FOR TESTING.
METHODS distinct_dishes FOR TESTING.
METHODS ignores_other_orders FOR TESTING.
METHODS empty_order FOR TESTING.
METHODS zero_quantity FOR TESTING.
METHODS unknown_dish FOR TESTING.
METHODS quantity_before_dish FOR TESTING.
METHODS discount_from_fifty FOR TESTING.
METHODS no_discount_below_fifty FOR TESTING.
ENDCLASS.
CLASS {{p}}t41_hidden IMPLEMENTATION.
METHOD setup.
DELETE FROM {{p}}pos WHERE client = @sy-mandt.
DELETE FROM {{p}}dish WHERE client = @sy-mandt.
insert_dishes( ).
ENDMETHOD.
METHOD teardown.
DELETE FROM {{p}}pos WHERE client = @sy-mandt.
DELETE FROM {{p}}dish WHERE client = @sy-mandt.
ENDMETHOD.
METHOD insert_dishes.
DATA lt_dishes TYPE STANDARD TABLE OF {{p}}dish.
lt_dishes = VALUE #(
( client = sy-mandt dish_id = 'D001' dish_name = 'Tomato soup' price = '4.50' )
( client = sy-mandt dish_id = 'D002' dish_name = 'Roast beef' price = '18.00' )
( client = sy-mandt dish_id = 'D003' dish_name = 'Apple pie' price = '5.25' )
( client = sy-mandt dish_id = 'D004' dish_name = 'Sparkling water' price = '2.00' )
( client = sy-mandt dish_id = 'D005' dish_name = 'Bread basket' price = '2.05' )
).
INSERT {{p}}dish FROM TABLE @lt_dishes.
ENDMETHOD.
METHOD insert_positions.
INSERT {{p}}pos FROM TABLE @it_positions.
ENDMETHOD.
METHOD call.
CLEAR: ev_total, ev_portions, ev_dishes.
CALL FUNCTION '{{P}}BANQUET_FEE'
EXPORTING
iv_order_id = iv_order_id
IMPORTING
ev_total = ev_total
ev_portions = ev_portions
ev_dishes = ev_dishes
EXCEPTIONS
no_positions = 1
unknown_dish = 2
invalid_quantity = 3
OTHERS = 4.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD total_and_portions.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'D001' qty = 2 )
( client = sy-mandt order_id = 'T41A' pos_no = 2 dish_id = 'D002' qty = 1 ) ).
insert_positions( lt_positions ).
call( EXPORTING iv_order_id = 'T41A'
IMPORTING ev_total = DATA(lv_total)
ev_portions = DATA(lv_portions)
ev_dishes = DATA(lv_dishes)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '27.00' ) act = lv_total ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lv_portions ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_dishes ).
ENDMETHOD.
METHOD distinct_dishes.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'D001' qty = 2 )
( client = sy-mandt order_id = 'T41A' pos_no = 2 dish_id = 'D001' qty = 3 )
( client = sy-mandt order_id = 'T41A' pos_no = 3 dish_id = 'D003' qty = 1 ) ).
insert_positions( lt_positions ).
call( EXPORTING iv_order_id = 'T41A'
IMPORTING ev_total = DATA(lv_total)
ev_portions = DATA(lv_portions)
ev_dishes = DATA(lv_dishes)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '27.75' ) act = lv_total ).
cl_abap_unit_assert=>assert_equals( exp = 6 act = lv_portions ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_dishes ).
ENDMETHOD.
METHOD ignores_other_orders.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41B' pos_no = 1 dish_id = 'D002' qty = 10 )
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'D001' qty = 2 ) ).
insert_positions( lt_positions ).
call( EXPORTING iv_order_id = 'T41A'
IMPORTING ev_total = DATA(lv_total)
ev_portions = DATA(lv_portions)
ev_dishes = DATA(lv_dishes)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '9.00' ) act = lv_total ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_portions ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_dishes ).
ENDMETHOD.
METHOD empty_order.
call( EXPORTING iv_order_id = 'T41Z'
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_subrc ).
ENDMETHOD.
METHOD zero_quantity.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'D001' qty = 0 ) ).
insert_positions( lt_positions ).
call( EXPORTING iv_order_id = 'T41A'
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lv_subrc ).
ENDMETHOD.
METHOD unknown_dish.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'X999' qty = 2 ) ).
insert_positions( lt_positions ).
call( EXPORTING iv_order_id = 'T41A'
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_subrc ).
ENDMETHOD.
METHOD quantity_before_dish.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'X999' qty = 0 ) ).
insert_positions( lt_positions ).
call( EXPORTING iv_order_id = 'T41A'
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lv_subrc ).
ENDMETHOD.
METHOD discount_from_fifty.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'D004' qty = 49 )
( client = sy-mandt order_id = 'T41A' pos_no = 2 dish_id = 'D005' qty = 1 ) ).
insert_positions( lt_positions ).
call( EXPORTING iv_order_id = 'T41A'
IMPORTING ev_total = DATA(lv_total)
ev_portions = DATA(lv_portions)
ev_dishes = DATA(lv_dishes)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 50 act = lv_portions ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_dishes ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '95.05' ) act = lv_total ).
ENDMETHOD.
METHOD no_discount_below_fifty.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'D004' qty = 49 ) ).
insert_positions( lt_positions ).
call( EXPORTING iv_order_id = 'T41A'
IMPORTING ev_total = DATA(lv_total)
ev_portions = DATA(lv_portions)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 49 act = lv_portions ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '98.00' ) act = lv_total ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,77 @@
{
"task": "T41",
"mutants": [
{
"object": "{{P}}BANQUET_FEE",
"mutant": "line 30: + -> - (arith)",
"status": "killed",
"hidden": "5/9",
"failed_tests": [
"TOTAL_AND_PORTIONS",
"DISTINCT_DISHES",
"IGNORES_OTHER_ORDERS",
"DISCOUNT_FROM_FIFTY",
"NO_DISCOUNT_BELOW_FIFTY"
]
},
{
"object": "{{P}}BANQUET_FEE",
"mutant": "line 22: IS INITIAL -> IS NOT INITIAL (bool)",
"status": "killed",
"hidden": "8/9",
"failed_tests": [
"EMPTY_ORDER"
]
},
{
"object": "{{P}}BANQUET_FEE",
"mutant": "line 27: <= -> < (rel)",
"status": "killed",
"hidden": "7/9",
"failed_tests": [
"ZERO_QUANTITY",
"QUANTITY_BEFORE_DISH"
]
},
{
"object": "{{P}}BANQUET_FEE",
"mutant": "line 36: <> -> = (rel)",
"status": "killed",
"hidden": "8/9",
"failed_tests": [
"UNKNOWN_DISH"
]
},
{
"object": "{{P}}BANQUET_FEE",
"mutant": "line 41: + -> - (arith)",
"status": "killed",
"hidden": "8/9",
"failed_tests": [
"TOTAL_AND_PORTIONS"
]
},
{
"object": "{{P}}BANQUET_FEE",
"mutant": "line 47: >= -> > (rel)",
"status": "killed",
"hidden": "8/9",
"failed_tests": [
"DISCOUNT_FROM_FIFTY"
]
},
{
"object": "{{P}}BANQUET_FEE",
"mutant": "line 48: 95 -> 90 (const)",
"status": "killed",
"hidden": "8/9",
"failed_tests": [
"DISCOUNT_FROM_FIFTY"
]
}
],
"valid": 7,
"killed": 7,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,57 @@
FUNCTION {{p}}banquet_fee
IMPORTING
iv_order_id TYPE string
EXPORTING
ev_total TYPE decfloat34
ev_portions TYPE i
ev_dishes TYPE i
EXCEPTIONS
no_positions
unknown_dish
invalid_quantity.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
DATA lt_dishes TYPE HASHED TABLE OF {{p}}dish WITH UNIQUE KEY dish_id.
DATA lt_seen TYPE HASHED TABLE OF {{p}}pos WITH UNIQUE KEY dish_id.
DATA ls_position TYPE {{p}}pos.
DATA ls_dish TYPE {{p}}dish.
CLEAR: ev_total, ev_portions, ev_dishes.
SELECT order_id, pos_no, dish_id, qty
FROM {{p}}pos
WHERE order_id = @iv_order_id
INTO TABLE @lt_positions.
IF lt_positions IS INITIAL.
RAISE no_positions.
ENDIF.
LOOP AT lt_positions INTO ls_position.
IF ls_position-qty <= 0.
RAISE invalid_quantity.
ENDIF.
ENDLOOP.
SELECT dish_id, dish_name, price
FROM {{p}}dish
INTO TABLE @lt_dishes.
LOOP AT lt_positions INTO ls_position.
READ TABLE lt_dishes INTO ls_dish WITH TABLE KEY dish_id = ls_position-dish_id.
IF sy-subrc <> 0.
RAISE unknown_dish.
ENDIF.
ev_total = ev_total + ls_dish-price * ls_position-qty.
ev_portions = ev_portions + ls_position-qty.
INSERT ls_position INTO TABLE lt_seen.
ENDLOOP.
ev_dishes = lines( lt_seen ).
IF ev_portions >= 50.
ev_total = round( val = ev_total * 95 / 100 dec = 2 mode = cl_abap_math=>round_half_up ).
ENDIF.
ENDFUNCTION.

View File

@@ -0,0 +1,120 @@
CLASS {{p}}t41_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS setup.
METHODS teardown.
METHODS insert_dishes.
METHODS insert_positions
IMPORTING it_positions TYPE STANDARD TABLE OF {{p}}pos.
METHODS fee_for
IMPORTING iv_order_id TYPE string
RETURNING VALUE(rv_total) TYPE decfloat34.
METHODS total_of_order FOR TESTING.
METHODS distinct_dishes FOR TESTING.
METHODS discount_from_fifty FOR TESTING.
METHODS empty_order FOR TESTING.
ENDCLASS.
CLASS {{p}}t41_test IMPLEMENTATION.
METHOD setup.
DELETE FROM {{p}}pos WHERE client = @sy-mandt.
DELETE FROM {{p}}dish WHERE client = @sy-mandt.
insert_dishes( ).
ENDMETHOD.
METHOD teardown.
DELETE FROM {{p}}pos WHERE client = @sy-mandt.
DELETE FROM {{p}}dish WHERE client = @sy-mandt.
ENDMETHOD.
METHOD insert_dishes.
DATA lt_dishes TYPE STANDARD TABLE OF {{p}}dish.
lt_dishes = VALUE #(
( client = sy-mandt dish_id = 'D001' dish_name = 'Tomato soup' price = '4.50' )
( client = sy-mandt dish_id = 'D002' dish_name = 'Roast beef' price = '18.00' )
( client = sy-mandt dish_id = 'D003' dish_name = 'Apple pie' price = '5.25' )
( client = sy-mandt dish_id = 'D004' dish_name = 'Sparkling water' price = '2.00' )
( client = sy-mandt dish_id = 'D005' dish_name = 'Bread basket' price = '2.05' )
).
INSERT {{p}}dish FROM TABLE @lt_dishes.
ENDMETHOD.
METHOD insert_positions.
INSERT {{p}}pos FROM TABLE @it_positions.
ENDMETHOD.
METHOD fee_for.
CALL FUNCTION '{{P}}BANQUET_FEE'
EXPORTING
iv_order_id = iv_order_id
IMPORTING
ev_total = rv_total
EXCEPTIONS
OTHERS = 1.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD total_of_order.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'D001' qty = 2 )
( client = sy-mandt order_id = 'T41A' pos_no = 2 dish_id = 'D002' qty = 1 ) ).
insert_positions( lt_positions ).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '27.00' )
act = fee_for( 'T41A' ) ).
ENDMETHOD.
METHOD distinct_dishes.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'D001' qty = 2 )
( client = sy-mandt order_id = 'T41A' pos_no = 2 dish_id = 'D001' qty = 3 )
( client = sy-mandt order_id = 'T41A' pos_no = 3 dish_id = 'D003' qty = 1 ) ).
insert_positions( lt_positions ).
DATA lv_dishes TYPE i.
CALL FUNCTION '{{P}}BANQUET_FEE'
EXPORTING
iv_order_id = 'T41A'
IMPORTING
ev_dishes = lv_dishes
EXCEPTIONS
OTHERS = 1.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_dishes ).
ENDMETHOD.
METHOD discount_from_fifty.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'T41A' pos_no = 1 dish_id = 'D004' qty = 49 )
( client = sy-mandt order_id = 'T41A' pos_no = 2 dish_id = 'D005' qty = 1 ) ).
insert_positions( lt_positions ).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '95.05' )
act = fee_for( 'T41A' ) ).
ENDMETHOD.
METHOD empty_order.
DATA lv_total TYPE decfloat34.
CALL FUNCTION '{{P}}BANQUET_FEE'
EXPORTING
iv_order_id = 'T41Z'
IMPORTING
ev_total = lv_total
EXCEPTIONS
no_positions = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,11 @@
@EndUserText.label : 'Dish master'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}dish {
key client : abap.clnt not null;
key dish_id : abap.char(10) not null;
dish_name : abap.char(40);
price : abap.dec(15,2);
}

View File

@@ -0,0 +1,12 @@
@EndUserText.label : 'Banquet positions'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}pos {
key client : abap.clnt not null;
key order_id : abap.char(10) not null;
key pos_no : abap.int4 not null;
dish_id : abap.char(10);
qty : abap.int4;
}

View File

@@ -0,0 +1,36 @@
CLASS {{p}}seed_banquet DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS {{p}}seed_banquet IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DELETE FROM {{p}}pos WHERE client = @sy-mandt.
DELETE FROM {{p}}dish WHERE client = @sy-mandt.
DATA lt_dishes TYPE STANDARD TABLE OF {{p}}dish.
lt_dishes = VALUE #(
( client = sy-mandt dish_id = 'D001' dish_name = 'Tomato soup' price = '4.50' )
( client = sy-mandt dish_id = 'D002' dish_name = 'Roast beef' price = '18.00' )
( client = sy-mandt dish_id = 'D003' dish_name = 'Apple pie' price = '5.25' )
( client = sy-mandt dish_id = 'D004' dish_name = 'Sparkling water' price = '2.00' )
( client = sy-mandt dish_id = 'D005' dish_name = 'Bread basket' price = '2.05' )
).
INSERT {{p}}dish FROM TABLE @lt_dishes.
DATA lt_positions TYPE STANDARD TABLE OF {{p}}pos.
lt_positions = VALUE #(
( client = sy-mandt order_id = 'ORD1' pos_no = 1 dish_id = 'D001' qty = 12 )
( client = sy-mandt order_id = 'ORD1' pos_no = 2 dish_id = 'D002' qty = 8 )
( client = sy-mandt order_id = 'ORD1' pos_no = 3 dish_id = 'D004' qty = 30 )
( client = sy-mandt order_id = 'ORD2' pos_no = 1 dish_id = 'D003' qty = 4 )
( client = sy-mandt order_id = 'ORD3' pos_no = 1 dish_id = 'D001' qty = 0 )
( client = sy-mandt order_id = 'ORD4' pos_no = 1 dish_id = 'X999' qty = 2 )
).
INSERT {{p}}pos FROM TABLE @lt_positions.
out->write( |Dishes: { lines( lt_dishes ) }| ).
out->write( |Positions: { lines( lt_positions ) }| ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,61 @@
# 1. Goal
A catering company prices banquet orders. The order desk calls one function
module for each banquet order. The function module reads the ordered positions
of the order and the dish master, and it returns the total price, the number of
portions and the number of different dishes.
# 2. Open questions
None.
# 3. Context
- Function group {{P}}FG_BANQUET exists in package $TMP.
- Table {{P}}DISH is the dish master. Its fields are DISH_ID (character 10),
DISH_NAME (character 40) and PRICE (amount with 2 decimals).
- Table {{P}}POS holds the positions of the banquet orders. Its fields are
ORDER_ID (character 10), POS_NO (integer), DISH_ID (character 10) and QTY
(integer). The key of the table is ORDER_ID and POS_NO. The same dish can
occur in more than one position of the same order.
- The order desk passes only the order number to the function module. The
function module reads the two tables.
# 4. Contract
Create the function module {{P}}BANQUET_FEE in function group {{P}}FG_BANQUET.
The interface of the function module is:
- IMPORTING
- IV_ORDER_ID: string
- EXPORTING
- EV_TOTAL: decfloat34
- EV_PORTIONS: i
- EV_DISHES: i
- EXCEPTIONS
- NO_POSITIONS
- UNKNOWN_DISH
- INVALID_QUANTITY
# 5. Business rules
1. The positions of the order are the rows of {{P}}POS with the given order
number.
2. If the order has no position, raise NO_POSITIONS.
3. If a position has a quantity of 0 or less, raise INVALID_QUANTITY.
4. If a position refers to a dish that is not in {{P}}DISH, raise UNKNOWN_DISH.
5. If more than one of the rules 2 to 4 applies, the function module raises the
exception of the lowest rule number.
6. EV_TOTAL is the sum of the quantity multiplied by the price of the dish over
all positions of the order.
7. EV_PORTIONS is the sum of the quantities of all positions of the order.
8. EV_DISHES is the number of different dishes in the order.
9. If EV_PORTIONS is 50 or more, the caterer gives a discount of 5 % on
EV_TOTAL. Round the discounted total half up to 2 decimals.
# 6. Constraints
- Release target: 8.16 (SAP_BASIS 816).
- Coding standards: Clean ABAP. A method has fewer than 40 statements. The
function module must not cause an ATC finding of priority 1 or 2.
- Out of scope: do not change {{P}}DISH, {{P}}POS, {{P}}FG_BANQUET and
{{P}}SEED_BANQUET.
# 7. Acceptance
- The function module {{P}}BANQUET_FEE is active and has no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests for the function module in a global test class.

View File

@@ -0,0 +1,97 @@
{
"id": "G1101",
"category": "C",
"object_type": "FUNC",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "FUGR",
"name": "{{P}}FG_BANQUET",
"description": "Banquet pricing"
},
{
"type": "TABL",
"name": "{{P}}DISH",
"file": "seed/dish.tabl.abap",
"description": "Dish master"
},
{
"type": "TABL",
"name": "{{P}}POS",
"file": "seed/pos.tabl.abap",
"description": "Banquet positions"
},
{
"type": "CLAS",
"name": "{{P}}SEED_BANQUET",
"file": "seed/seed_banquet.clas.abap",
"description": "Seed data for the dish master and the banquet positions",
"run": true
}
],
"contract": [
{
"type": "FUNC",
"name": "{{P}}BANQUET_FEE",
"functionGroup": "{{P}}FG_BANQUET",
"params": [
{
"name": "iv_order_id",
"type": "string"
},
{
"name": "ev_total",
"type": "decfloat34"
},
{
"name": "ev_portions",
"type": "i"
},
{
"name": "ev_dishes",
"type": "i"
}
]
}
],
"out_of_scope": [
"{{P}}DISH",
"{{P}}POS",
"{{P}}FG_BANQUET",
"{{P}}SEED_BANQUET"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T41_HIDDEN",
"file": "hidden/t41_hidden.clas.abap",
"description": "Hidden tests for {{P}}BANQUET_FEE"
}
],
"reference": [
{
"type": "FUNC",
"name": "{{P}}BANQUET_FEE",
"functionGroup": "{{P}}FG_BANQUET",
"file": "reference/banquet_fee.func.abap",
"description": "Banquet fee module"
},
{
"type": "CLAS",
"name": "{{P}}T41_TEST",
"file": "reference/t41_test.clas.abap",
"description": "Own tests of the banquet fee module"
}
],
"craft_checks": [
"method_length",
"internal_table_key",
"no_linear_search_in_loop"
]
}