Step F first pass: 81/92 accepted; budget floor 60 calls; rejected slots moved for regeneration

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 12:10:52 +02:00
parent d3250acfb8
commit 39769afce8
741 changed files with 40573 additions and 317 deletions

View File

@@ -0,0 +1,152 @@
CLASS {{p}}duty_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS call
IMPORTING
iv_value TYPE decfloat34
iv_country TYPE string
iv_category TYPE string
EXPORTING
ev_rate TYPE decfloat34
ev_duty TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS food_rate FOR TESTING.
METHODS textile_rate FOR TESTING.
METHODS machine_rate FOR TESTING.
METHODS unknown_category FOR TESTING.
METHODS rounds_half_up FOR TESTING.
METHODS minimum_duty FOR TESTING.
METHODS zero_value FOR TESTING.
METHODS pref_no_minimum FOR TESTING.
METHODS pref_ch_de FOR TESTING.
METHODS pref_fr_it_es FOR TESTING.
METHODS negative_value FOR TESTING.
ENDCLASS.
CLASS {{p}}duty_hidden IMPLEMENTATION.
METHOD call.
CALL FUNCTION '{{P}}CUSTOMS_DUTY_OLD'
EXPORTING
iv_value = iv_value
iv_country = iv_country
iv_category = iv_category
IMPORTING
ev_rate = ev_rate
ev_duty = ev_duty
EXCEPTIONS
invalid_value = 1
OTHERS = 2.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD food_rate.
DATA lv_rate TYPE decfloat34.
DATA lv_duty TYPE decfloat34.
call( EXPORTING iv_value = 1000 iv_country = 'US' iv_category = 'FOOD'
IMPORTING ev_rate = lv_rate ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 5 ) act = lv_rate ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 50 ) act = lv_duty ).
ENDMETHOD.
METHOD textile_rate.
DATA lv_rate TYPE decfloat34.
DATA lv_duty TYPE decfloat34.
call( EXPORTING iv_value = '250.50' iv_country = 'US' iv_category = 'TEXTILE'
IMPORTING ev_rate = lv_rate ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 12 ) act = lv_rate ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '30.06' ) act = lv_duty ).
ENDMETHOD.
METHOD machine_rate.
DATA lv_rate TYPE decfloat34.
DATA lv_duty TYPE decfloat34.
call( EXPORTING iv_value = 2000 iv_country = 'US' iv_category = 'MACHINE'
IMPORTING ev_rate = lv_rate ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 3 ) act = lv_rate ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 60 ) act = lv_duty ).
ENDMETHOD.
METHOD unknown_category.
DATA lv_rate TYPE decfloat34.
DATA lv_duty TYPE decfloat34.
call( EXPORTING iv_value = 1000 iv_country = 'US' iv_category = 'TOY'
IMPORTING ev_rate = lv_rate ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_rate ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_duty ).
ENDMETHOD.
METHOD rounds_half_up.
DATA lv_duty TYPE decfloat34.
call( EXPORTING iv_value = '123.7' iv_country = 'US' iv_category = 'FOOD'
IMPORTING ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '6.19' ) act = lv_duty ).
call( EXPORTING iv_value = '123.45' iv_country = 'US' iv_category = 'FOOD'
IMPORTING ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '6.17' ) act = lv_duty ).
ENDMETHOD.
METHOD minimum_duty.
DATA lv_duty TYPE decfloat34.
call( EXPORTING iv_value = 50 iv_country = 'US' iv_category = 'FOOD'
IMPORTING ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 5 ) act = lv_duty ).
ENDMETHOD.
METHOD zero_value.
DATA lv_rate TYPE decfloat34.
DATA lv_duty TYPE decfloat34.
DATA lv_subrc TYPE sysubrc.
call( EXPORTING iv_value = 0 iv_country = 'US' iv_category = 'FOOD'
IMPORTING ev_rate = lv_rate ev_duty = lv_duty ev_subrc = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 5 ) act = lv_rate ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_duty ).
ENDMETHOD.
METHOD pref_no_minimum.
DATA lv_rate TYPE decfloat34.
DATA lv_duty TYPE decfloat34.
call( EXPORTING iv_value = 10000 iv_country = 'CH' iv_category = 'TEXTILE'
IMPORTING ev_rate = lv_rate ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_rate ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_duty ).
ENDMETHOD.
METHOD pref_ch_de.
DATA lv_rate TYPE decfloat34.
DATA lv_duty TYPE decfloat34.
call( EXPORTING iv_value = 10000 iv_country = 'DE' iv_category = 'MACHINE'
IMPORTING ev_rate = lv_rate ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_rate ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_duty ).
ENDMETHOD.
METHOD pref_fr_it_es.
DATA lv_rate TYPE decfloat34.
DATA lv_duty TYPE decfloat34.
call( EXPORTING iv_value = 10000 iv_country = 'FR' iv_category = 'FOOD'
IMPORTING ev_rate = lv_rate ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_rate ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_duty ).
call( EXPORTING iv_value = 10000 iv_country = 'IT' iv_category = 'FOOD'
IMPORTING ev_rate = lv_rate ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_rate ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_duty ).
call( EXPORTING iv_value = 10000 iv_country = 'ES' iv_category = 'FOOD'
IMPORTING ev_rate = lv_rate ev_duty = lv_duty ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_rate ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_duty ).
ENDMETHOD.
METHOD negative_value.
DATA lv_duty TYPE decfloat34.
DATA lv_subrc TYPE sysubrc.
call( EXPORTING iv_value = -100 iv_country = 'US' iv_category = 'FOOD'
IMPORTING ev_duty = lv_duty ev_subrc = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_subrc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,58 @@
{
"task": "T14",
"mutants": [
{
"object": "{{P}}CUSTOMS_DUTY_OLD",
"mutant": "line 14: < -> <= (rel)",
"status": "killed",
"hidden": "10/11",
"failed_tests": [
"ZERO_VALUE"
]
},
{
"object": "{{P}}CUSTOMS_DUTY_OLD",
"mutant": "line 22: 12 -> 15 (const)",
"status": "killed",
"hidden": "10/11",
"failed_tests": [
"TEXTILE_RATE"
]
},
{
"object": "{{P}}CUSTOMS_DUTY_OLD",
"mutant": "line 30: 'ES' -> 'XX' (const)",
"status": "killed",
"hidden": "10/11",
"failed_tests": [
"PREF_FR_IT_ES"
]
},
{
"object": "{{P}}CUSTOMS_DUTY_OLD",
"mutant": "line 35: round() -> plain (arith)",
"status": "killed",
"hidden": "10/11",
"failed_tests": [
"ROUNDS_HALF_UP"
]
},
{
"object": "{{P}}CUSTOMS_DUTY_OLD",
"mutant": "line 37: ev_duty > 0 AND -> removed (bool)",
"status": "killed",
"hidden": "6/11",
"failed_tests": [
"PREF_NO_MINIMUM",
"PREF_CH_DE",
"PREF_FR_IT_ES",
"UNKNOWN_CATEGORY",
"ZERO_VALUE"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,41 @@
FUNCTION {{p}}customs_duty_old
IMPORTING
iv_value TYPE decfloat34
iv_country TYPE string
iv_category TYPE string
EXPORTING
ev_rate TYPE decfloat34
ev_duty TYPE decfloat34
EXCEPTIONS
invalid_value.
DATA lv_rate TYPE decfloat34.
IF iv_value < 0.
RAISE invalid_value.
ENDIF.
CASE iv_category.
WHEN 'FOOD'.
lv_rate = 5.
WHEN 'TEXTILE'.
lv_rate = 12.
WHEN 'MACHINE'.
lv_rate = 3.
WHEN OTHERS.
lv_rate = 0.
ENDCASE.
IF iv_country = 'CH' OR iv_country = 'DE' OR iv_country = 'FR'
OR iv_country = 'IT' OR iv_country = 'ES'.
lv_rate = 0.
ENDIF.
ev_rate = lv_rate.
ev_duty = round( val = iv_value * lv_rate / 100 dec = 2 ).
IF ev_duty > 0 AND ev_duty < 5.
ev_duty = 5.
ENDIF.
ENDFUNCTION.

View File

@@ -0,0 +1,72 @@
CLASS {{p}}duty_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS duty_for
IMPORTING
iv_value TYPE decfloat34
iv_country TYPE string
iv_category TYPE string
RETURNING
VALUE(rv_duty) TYPE decfloat34.
METHODS food_duty FOR TESTING.
METHODS rounding FOR TESTING.
METHODS minimum FOR TESTING.
METHODS preferential FOR TESTING.
METHODS negative_value FOR TESTING.
ENDCLASS.
CLASS {{p}}duty_test IMPLEMENTATION.
METHOD duty_for.
CALL FUNCTION '{{P}}CUSTOMS_DUTY_OLD'
EXPORTING
iv_value = iv_value
iv_country = iv_country
iv_category = iv_category
IMPORTING
ev_duty = rv_duty
EXCEPTIONS
invalid_value = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD food_duty.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( 50 )
act = duty_for( iv_value = 1000 iv_country = 'US' iv_category = 'FOOD' ) ).
ENDMETHOD.
METHOD rounding.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '6.19' )
act = duty_for( iv_value = '123.7' iv_country = 'US' iv_category = 'FOOD' ) ).
ENDMETHOD.
METHOD minimum.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( 5 )
act = duty_for( iv_value = 50 iv_country = 'US' iv_category = 'FOOD' ) ).
ENDMETHOD.
METHOD preferential.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( 0 )
act = duty_for( iv_value = 10000 iv_country = 'FR' iv_category = 'FOOD' ) ).
ENDMETHOD.
METHOD negative_value.
DATA lv_duty TYPE decfloat34.
CALL FUNCTION '{{P}}CUSTOMS_DUTY_OLD'
EXPORTING
iv_value = -1
iv_country = 'US'
iv_category = 'FOOD'
IMPORTING
ev_duty = lv_duty
EXCEPTIONS
invalid_value = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,36 @@
FUNCTION {{p}}customs_duty_old
IMPORTING
iv_value TYPE decfloat34
iv_country TYPE string
iv_category TYPE string
EXPORTING
ev_rate TYPE decfloat34
ev_duty TYPE decfloat34
EXCEPTIONS
invalid_value.
DATA lv_rate TYPE decfloat34.
CASE iv_category.
WHEN 'FOOD'.
lv_rate = 5.
WHEN 'TEXTILE'.
lv_rate = 12.
WHEN 'MACHINE'.
lv_rate = 3.
WHEN OTHERS.
lv_rate = 0.
ENDCASE.
IF iv_country = 'CH' OR iv_country = 'DE'.
lv_rate = 0.
ENDIF.
ev_rate = lv_rate.
ev_duty = iv_value * lv_rate / 100.
IF ev_duty < 5.
ev_duty = 5.
ENDIF.
ENDFUNCTION.

View File

@@ -0,0 +1,54 @@
# 1. Goal
A customs broker calculates the import duty for a shipment. The broker program
calls one function module for each shipment. The function module
{{P}}CUSTOMS_DUTY_OLD calculates the duty rate and the duty. Users report
several defects. Fix the function module in place. All other behavior stays the
same.
# 2. Open questions
None.
# 3. Context
- Function group {{P}}FG_CUST exists in package $TMP.
- Function module {{P}}CUSTOMS_DUTY_OLD exists in this group. It is the only
function module in the group. Read its source. It defines the duty rates of
the goods categories and all the other behavior that must stay the same.
- The broker program calls the function module with a customs value, a country
of origin and a goods category. The program reads the duty rate and the duty.
# 4. Contract
- Fix the function module {{P}}CUSTOMS_DUTY_OLD in function group {{P}}FG_CUST.
- Do not change the interface. The parameters are:
- IV_VALUE, importing, decfloat34: the customs value in euro.
- IV_COUNTRY, importing, string: the country of origin.
- IV_CATEGORY, importing, string: the goods category.
- EV_RATE, exporting, decfloat34: the duty rate in percent.
- EV_DUTY, exporting, decfloat34: the duty in euro.
- The exception INVALID_VALUE stays.
# 5. Business rules
1. The duty is rounded half up to 2 decimals. Users report duties with more
than 2 decimals, for example 6.185 instead of 6.19.
2. The minimum duty is 5.00. The minimum applies only to a shipment that has a
duty. A shipment with a duty of zero keeps a duty of zero. Users report that
duty-free shipments are charged 5.00.
3. A shipment with a preferential origin is duty-free: the duty is 0 and the
rate is 0. The preferential origins are Switzerland (CH), Germany (DE),
France (FR), Italy (IT) and Spain (ES). Users report that shipments from
France, Italy and Spain are charged duty.
4. A negative customs value is not valid. Users report that a negative value is
accepted and gives a duty. The function module must raise the exception
INVALID_VALUE for a negative customs value.
5. The duty rates of the goods categories and all other behavior stay the same
as they are in {{P}}CUSTOMS_DUTY_OLD today.
# 6. Constraints
- Release target: 8.16 (SAP_BASIS 816, ABAP Platform 2025).
- Package $TMP. Do not use transports.
- Out of scope: do not change other objects.
- Clean ABAP. Keep the methods below 40 statements.
# 7. Acceptance
- The function module {{P}}CUSTOMS_DUTY_OLD 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,83 @@
{
"id": "G0189",
"category": "I",
"object_type": "FUNC",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 40,
"max_activations": 10
},
"seed": [
{
"type": "FUGR",
"name": "{{P}}FG_CUST",
"description": "Customs duty function group"
},
{
"type": "FUNC",
"name": "{{P}}CUSTOMS_DUTY_OLD",
"functionGroup": "{{P}}FG_CUST",
"file": "seed/customs_duty_old.func.abap",
"description": "Legacy customs duty calculation with defects"
}
],
"contract": [
{
"type": "FUNC",
"name": "{{P}}CUSTOMS_DUTY_OLD",
"functionGroup": "{{P}}FG_CUST",
"params": [
{
"name": "iv_value",
"type": "decfloat34"
},
{
"name": "iv_country",
"type": "string"
},
{
"name": "iv_category",
"type": "string"
},
{
"name": "ev_rate",
"type": "decfloat34"
},
{
"name": "ev_duty",
"type": "decfloat34"
}
]
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}DUTY_HIDDEN",
"file": "hidden/duty_hidden.clas.abap",
"description": "Hidden tests for the customs duty function module"
}
],
"reference": [
{
"type": "FUNC",
"name": "{{P}}CUSTOMS_DUTY_OLD",
"functionGroup": "{{P}}FG_CUST",
"existing": true,
"file": "reference/customs_duty_old.func.abap",
"description": "Fixed customs duty calculation"
},
{
"type": "CLAS",
"name": "{{P}}DUTY_TEST",
"file": "reference/duty_test.clas.abap",
"description": "Own tests for the customs duty function module"
}
],
"craft_checks": [
"method_length"
]
}