ADT fallback: Accept headers for FUNC; G0189 accepted; regen2 results

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 16:31:03 +02:00
parent 428b3565b2
commit 7510131a7d
335 changed files with 12047 additions and 5545 deletions

View File

@@ -0,0 +1,59 @@
FUNCTION {{p}}theme_fee
IMPORTING
iv_visitor_type TYPE string
iv_tickets TYPE i
iv_date TYPE d
EXPORTING
ev_unit_price TYPE decfloat34
ev_total_price TYPE decfloat34
ev_discount TYPE decfloat34
EXCEPTIONS
invalid_visitor_type
invalid_tickets.
DATA lv_base_price TYPE decfloat34.
DATA lv_gross TYPE decfloat34.
DATA lv_discount_pct TYPE decfloat34.
DATA lv_month TYPE c LENGTH 2.
IF iv_tickets <= 0.
RAISE invalid_tickets.
ENDIF.
CASE iv_visitor_type.
WHEN 'ADULT'.
lv_base_price = '45.50'.
WHEN 'CHILD'.
lv_base_price = '25.25'.
WHEN 'SENIOR'.
lv_base_price = '30.75'.
WHEN 'FAMILY'.
lv_base_price = '40.00'.
WHEN OTHERS.
RAISE invalid_visitor_type.
ENDCASE.
" Peak season surcharge: June, July, August
IF iv_date IS NOT INITIAL.
lv_month = iv_date+5(2).
IF lv_month = '06' OR lv_month = '07' OR lv_month = '08'.
lv_base_price = lv_base_price + 5.
ENDIF.
ENDIF.
" Group discount
IF iv_tickets >= 20.
lv_discount_pct = 15.
ELSEIF iv_tickets >= 10.
lv_discount_pct = 10.
ENDIF.
lv_gross = lv_base_price * iv_tickets.
ev_discount = round( val = lv_gross * lv_discount_pct / 100
dec = 2 mode = cl_abap_math=>round_half_up ).
ev_total_price = round( val = lv_gross - ev_discount
dec = 2 mode = cl_abap_math=>round_half_up ).
ev_unit_price = round( val = lv_base_price
dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,59 @@
FUNCTION {{p}}theme_fee
IMPORTING
iv_visitor_type TYPE string
iv_tickets TYPE i
iv_date TYPE d
EXPORTING
ev_unit_price TYPE decfloat34
ev_total_price TYPE decfloat34
ev_discount TYPE decfloat34
EXCEPTIONS
invalid_visitor_type
invalid_tickets.
DATA lv_base_price TYPE decfloat34.
DATA lv_gross TYPE decfloat34.
DATA lv_discount_pct TYPE decfloat34.
DATA lv_month TYPE c LENGTH 2.
IF iv_tickets <= 0.
RAISE invalid_tickets.
ENDIF.
CASE iv_visitor_type.
WHEN 'ADULT'.
lv_base_price = '45.50'.
WHEN 'CHILD'.
lv_base_price = '25.25'.
WHEN 'SENIOR'.
lv_base_price = '30.75'.
WHEN 'FAMILY'.
lv_base_price = '40.00'.
WHEN OTHERS.
RAISE invalid_visitor_type.
ENDCASE.
" Peak season surcharge: June, July, August
IF iv_date IS NOT INITIAL.
lv_month = iv_date+4(2).
IF lv_month = '06' OR lv_month = '07' OR lv_month <> '08'.
lv_base_price = lv_base_price + 5.
ENDIF.
ENDIF.
" Group discount
IF iv_tickets >= 20.
lv_discount_pct = 15.
ELSEIF iv_tickets >= 10.
lv_discount_pct = 10.
ENDIF.
lv_gross = lv_base_price * iv_tickets.
ev_discount = round( val = lv_gross * lv_discount_pct / 100
dec = 2 mode = cl_abap_math=>round_half_up ).
ev_total_price = round( val = lv_gross - ev_discount
dec = 2 mode = cl_abap_math=>round_half_up ).
ev_unit_price = round( val = lv_base_price
dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,59 @@
FUNCTION {{p}}theme_fee
IMPORTING
iv_visitor_type TYPE string
iv_tickets TYPE i
iv_date TYPE d
EXPORTING
ev_unit_price TYPE decfloat34
ev_total_price TYPE decfloat34
ev_discount TYPE decfloat34
EXCEPTIONS
invalid_visitor_type
invalid_tickets.
DATA lv_base_price TYPE decfloat34.
DATA lv_gross TYPE decfloat34.
DATA lv_discount_pct TYPE decfloat34.
DATA lv_month TYPE c LENGTH 2.
IF iv_tickets <= 0.
RAISE invalid_tickets.
ENDIF.
CASE iv_visitor_type.
WHEN 'ADULT'.
lv_base_price = '45.50'.
WHEN 'CHILD'.
lv_base_price = '25.25'.
WHEN 'SENIOR'.
lv_base_price = '30.75'.
WHEN 'FAMILY'.
lv_base_price = '40.00'.
WHEN OTHERS.
RAISE invalid_visitor_type.
ENDCASE.
" Peak season surcharge: June, July, August
IF iv_date IS NOT INITIAL.
lv_month = iv_date+4(2).
IF lv_month = '06' OR lv_month = '07' OR lv_month = '08'.
lv_base_price = lv_base_price + 5.
ENDIF.
ENDIF.
" Group discount
IF iv_tickets >= 20.
lv_discount_pct = 15.
ELSEIF iv_tickets < 10.
lv_discount_pct = 10.
ENDIF.
lv_gross = lv_base_price * iv_tickets.
ev_discount = round( val = lv_gross * lv_discount_pct / 100
dec = 2 mode = cl_abap_math=>round_half_up ).
ev_total_price = round( val = lv_gross - ev_discount
dec = 2 mode = cl_abap_math=>round_half_up ).
ev_unit_price = round( val = lv_base_price
dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,59 @@
FUNCTION {{p}}theme_fee
IMPORTING
iv_visitor_type TYPE string
iv_tickets TYPE i
iv_date TYPE d
EXPORTING
ev_unit_price TYPE decfloat34
ev_total_price TYPE decfloat34
ev_discount TYPE decfloat34
EXCEPTIONS
invalid_visitor_type
invalid_tickets.
DATA lv_base_price TYPE decfloat34.
DATA lv_gross TYPE decfloat34.
DATA lv_discount_pct TYPE decfloat34.
DATA lv_month TYPE c LENGTH 2.
IF iv_tickets <= 0.
RAISE invalid_tickets.
ENDIF.
CASE iv_visitor_type.
WHEN 'ADULT'.
lv_base_price = '45.50'.
WHEN 'CHILD'.
lv_base_price = '25.25'.
WHEN 'SENIOR'.
lv_base_price = '30.75'.
WHEN 'FAMILY'.
lv_base_price = '40.00'.
WHEN OTHERS.
RAISE invalid_visitor_type.
ENDCASE.
" Peak season surcharge: June, July, August
IF iv_date IS NOT INITIAL.
lv_month = iv_date+4(2).
IF lv_month = '06' OR lv_month = '07' OR lv_month = '08'.
lv_base_price = lv_base_price + 5.
ENDIF.
ENDIF.
" Group discount
IF iv_tickets >= 20.
lv_discount_pct = 15.
ELSEIF iv_tickets >= 10.
lv_discount_pct = 10.
ENDIF.
lv_gross = lv_base_price / iv_tickets.
ev_discount = round( val = lv_gross * lv_discount_pct / 100
dec = 2 mode = cl_abap_math=>round_half_up ).
ev_total_price = round( val = lv_gross - ev_discount
dec = 2 mode = cl_abap_math=>round_half_up ).
ev_unit_price = round( val = lv_base_price
dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,45 @@
{
"id": "G0189",
"pool": "eval",
"object_type": "FUNC",
"category": "I",
"attempts": [
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "bundle",
"errors": [
"category I: the contract object must be the seed object that the model changes in place (same name in seed, contract and reference)"
],
"by_check": {
"static": 1
}
},
{
"stage": "revalidate",
"by": "harness fix 2026-10-03",
"change": "ADT activation fallback for a second FUNC write. Bundle not changed.",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 4,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -1,152 +0,0 @@
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,127 @@
CLASS {{p}}theme_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS call
IMPORTING
iv_type TYPE string
iv_tickets TYPE i
iv_date TYPE d
EXPORTING
ev_unit TYPE decfloat34
ev_total TYPE decfloat34
ev_discount TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS peak_season_surcharge FOR TESTING.
METHODS no_surcharge_off_peak FOR TESTING.
METHODS discount_tiers FOR TESTING.
METHODS discount_rounding FOR TESTING.
METHODS base_prices FOR TESTING.
METHODS invalid_visitor_type FOR TESTING.
METHODS invalid_tickets FOR TESTING.
METHODS unit_price_with_surcharge FOR TESTING.
ENDCLASS.
CLASS {{p}}theme_hidden IMPLEMENTATION.
METHOD call.
CALL FUNCTION '{{P}}THEME_FEE'
EXPORTING
iv_visitor_type = iv_type
iv_tickets = iv_tickets
iv_date = iv_date
IMPORTING
ev_unit_price = ev_unit
ev_total_price = ev_total
ev_discount = ev_discount
EXCEPTIONS
invalid_visitor_type = 1
invalid_tickets = 2
OTHERS = 3.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD peak_season_surcharge.
call( EXPORTING iv_type = 'ADULT' iv_tickets = 1 iv_date = '20250715'
IMPORTING ev_unit = DATA(lv_jul) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '50.50' ) act = lv_jul ).
call( EXPORTING iv_type = 'ADULT' iv_tickets = 1 iv_date = '20250801'
IMPORTING ev_unit = DATA(lv_aug) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '50.50' ) act = lv_aug ).
call( EXPORTING iv_type = 'ADULT' iv_tickets = 1 iv_date = '20250630'
IMPORTING ev_unit = DATA(lv_jun) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '50.50' ) act = lv_jun ).
ENDMETHOD.
METHOD no_surcharge_off_peak.
call( EXPORTING iv_type = 'ADULT' iv_tickets = 1 iv_date = '20250115'
IMPORTING ev_unit = DATA(lv_jan) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '45.50' ) act = lv_jan ).
call( EXPORTING iv_type = 'ADULT' iv_tickets = 1 iv_date = '20251215'
IMPORTING ev_unit = DATA(lv_dec) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '45.50' ) act = lv_dec ).
call( EXPORTING iv_type = 'ADULT' iv_tickets = 1 iv_date = '20250531'
IMPORTING ev_unit = DATA(lv_may) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '45.50' ) act = lv_may ).
ENDMETHOD.
METHOD discount_tiers.
call( EXPORTING iv_type = 'ADULT' iv_tickets = 9 iv_date = '20250115'
IMPORTING ev_discount = DATA(lv_d9) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_d9 ).
call( EXPORTING iv_type = 'ADULT' iv_tickets = 10 iv_date = '20250115'
IMPORTING ev_discount = DATA(lv_d10) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '45.50' ) act = lv_d10 ).
call( EXPORTING iv_type = 'ADULT' iv_tickets = 19 iv_date = '20250115'
IMPORTING ev_discount = DATA(lv_d19) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '86.45' ) act = lv_d19 ).
call( EXPORTING iv_type = 'ADULT' iv_tickets = 20 iv_date = '20250115'
IMPORTING ev_discount = DATA(lv_d20) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '136.50' ) act = lv_d20 ).
call( EXPORTING iv_type = 'ADULT' iv_tickets = 25 iv_date = '20250115'
IMPORTING ev_discount = DATA(lv_d25) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '170.63' ) act = lv_d25 ).
ENDMETHOD.
METHOD discount_rounding.
call( EXPORTING iv_type = 'ADULT' iv_tickets = 25 iv_date = '20250115'
IMPORTING ev_discount = DATA(lv_disc) ev_total = DATA(lv_total) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '170.63' ) act = lv_disc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '966.87' ) act = lv_total ).
ENDMETHOD.
METHOD base_prices.
call( EXPORTING iv_type = 'ADULT' iv_tickets = 1 iv_date = '20250115'
IMPORTING ev_unit = DATA(lv_adult) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '45.50' ) act = lv_adult ).
call( EXPORTING iv_type = 'CHILD' iv_tickets = 1 iv_date = '20250115'
IMPORTING ev_unit = DATA(lv_child) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '25.25' ) act = lv_child ).
call( EXPORTING iv_type = 'SENIOR' iv_tickets = 1 iv_date = '20250115'
IMPORTING ev_unit = DATA(lv_senior) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '30.75' ) act = lv_senior ).
call( EXPORTING iv_type = 'FAMILY' iv_tickets = 1 iv_date = '20250115'
IMPORTING ev_unit = DATA(lv_family) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '40.00' ) act = lv_family ).
ENDMETHOD.
METHOD invalid_visitor_type.
call( EXPORTING iv_type = 'STUDENT' iv_tickets = 1 iv_date = '20250115'
IMPORTING ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc ).
ENDMETHOD.
METHOD invalid_tickets.
call( EXPORTING iv_type = 'ADULT' iv_tickets = 0 iv_date = '20250115'
IMPORTING ev_subrc = DATA(lv_rc0) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_rc0 ).
call( EXPORTING iv_type = 'ADULT' iv_tickets = -1 iv_date = '20250115'
IMPORTING ev_subrc = DATA(lv_rc1) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_rc1 ).
ENDMETHOD.
METHOD unit_price_with_surcharge.
call( EXPORTING iv_type = 'CHILD' iv_tickets = 1 iv_date = '20250704'
IMPORTING ev_unit = DATA(lv_unit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '30.25' ) act = lv_unit ).
ENDMETHOD.
ENDCLASS.

View File

@@ -1,58 +1,58 @@
{
"task": "T14",
"task": "G0189",
"mutants": [
{
"object": "{{P}}CUSTOMS_DUTY_OLD",
"mutant": "line 14: < -> <= (rel)",
"object": "{{P}}THEME_FEE",
"mutant": "line 38: 4 -> 5 (const)",
"status": "killed",
"hidden": "10/11",
"hidden": "6/8",
"failed_tests": [
"ZERO_VALUE"
"PEAK_SEASON_SURCHARGE",
"UNIT_PRICE_WITH_SURCHARGE"
]
},
{
"object": "{{P}}CUSTOMS_DUTY_OLD",
"mutant": "line 22: 12 -> 15 (const)",
"object": "{{P}}THEME_FEE",
"mutant": "line 39: = -> <> (eq)",
"status": "killed",
"hidden": "10/11",
"hidden": "3/8",
"failed_tests": [
"TEXTILE_RATE"
"BASE_PRICES",
"DISCOUNT_ROUNDING",
"DISCOUNT_TIERS",
"NO_SURCHARGE_OFF_PEAK",
"PEAK_SEASON_SURCHARGE"
]
},
{
"object": "{{P}}CUSTOMS_DUTY_OLD",
"mutant": "line 30: 'ES' -> 'XX' (const)",
"object": "{{P}}THEME_FEE",
"mutant": "line 47: >= -> < (rel)",
"status": "killed",
"hidden": "10/11",
"hidden": "7/8",
"failed_tests": [
"PREF_FR_IT_ES"
"DISCOUNT_TIERS"
]
},
{
"object": "{{P}}CUSTOMS_DUTY_OLD",
"mutant": "line 35: round() -> plain (arith)",
"object": "{{P}}THEME_FEE",
"mutant": "line 51: * -> / (arith)",
"status": "killed",
"hidden": "10/11",
"hidden": "6/8",
"failed_tests": [
"ROUNDS_HALF_UP"
"DISCOUNT_ROUNDING",
"DISCOUNT_TIERS"
]
},
{
"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"
]
"object": "{{P}}THEME_FEE",
"mutant": "line 55: 2 -> 3 (const)",
"status": "survived",
"hidden": "8/8",
"failed_tests": []
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"killed": 4,
"kill_rate": 0.8,
"ok": true
}

View File

@@ -1,41 +0,0 @@
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

@@ -1,72 +0,0 @@
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,59 @@
FUNCTION {{p}}theme_fee
IMPORTING
iv_visitor_type TYPE string
iv_tickets TYPE i
iv_date TYPE d
EXPORTING
ev_unit_price TYPE decfloat34
ev_total_price TYPE decfloat34
ev_discount TYPE decfloat34
EXCEPTIONS
invalid_visitor_type
invalid_tickets.
DATA lv_base_price TYPE decfloat34.
DATA lv_gross TYPE decfloat34.
DATA lv_discount_pct TYPE decfloat34.
DATA lv_month TYPE c LENGTH 2.
IF iv_tickets <= 0.
RAISE invalid_tickets.
ENDIF.
CASE iv_visitor_type.
WHEN 'ADULT'.
lv_base_price = '45.50'.
WHEN 'CHILD'.
lv_base_price = '25.25'.
WHEN 'SENIOR'.
lv_base_price = '30.75'.
WHEN 'FAMILY'.
lv_base_price = '40.00'.
WHEN OTHERS.
RAISE invalid_visitor_type.
ENDCASE.
" Peak season surcharge: June, July, August
IF iv_date IS NOT INITIAL.
lv_month = iv_date+4(2).
IF lv_month = '06' OR lv_month = '07' OR lv_month = '08'.
lv_base_price = lv_base_price + 5.
ENDIF.
ENDIF.
" Group discount
IF iv_tickets >= 20.
lv_discount_pct = 15.
ELSEIF iv_tickets >= 10.
lv_discount_pct = 10.
ENDIF.
lv_gross = lv_base_price * iv_tickets.
ev_discount = round( val = lv_gross * lv_discount_pct / 100
dec = 2 mode = cl_abap_math=>round_half_up ).
ev_total_price = round( val = lv_gross - ev_discount
dec = 2 mode = cl_abap_math=>round_half_up ).
ev_unit_price = round( val = lv_base_price
dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,68 @@
CLASS {{p}}theme_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS fee_for
IMPORTING
iv_type TYPE string
iv_tickets TYPE i
iv_date TYPE d
RETURNING VALUE(rv_total) TYPE decfloat34.
METHODS adult_price FOR TESTING.
METHODS child_price FOR TESTING.
METHODS group_discount FOR TESTING.
METHODS peak_season FOR TESTING.
METHODS invalid_type FOR TESTING.
ENDCLASS.
CLASS {{p}}theme_test IMPLEMENTATION.
METHOD fee_for.
CALL FUNCTION '{{P}}THEME_FEE'
EXPORTING
iv_visitor_type = iv_type
iv_tickets = iv_tickets
iv_date = iv_date
IMPORTING
ev_total_price = rv_total
EXCEPTIONS
invalid_visitor_type = 1
invalid_tickets = 2
OTHERS = 3.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD adult_price.
DATA(lv_total) = fee_for( iv_type = 'ADULT' iv_tickets = 1 iv_date = '20250115' ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '45.50' ) act = lv_total ).
ENDMETHOD.
METHOD child_price.
DATA(lv_total) = fee_for( iv_type = 'CHILD' iv_tickets = 1 iv_date = '20250115' ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '25.25' ) act = lv_total ).
ENDMETHOD.
METHOD group_discount.
DATA(lv_total) = fee_for( iv_type = 'ADULT' iv_tickets = 10 iv_date = '20250115' ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '409.50' ) act = lv_total ).
ENDMETHOD.
METHOD peak_season.
DATA(lv_total) = fee_for( iv_type = 'ADULT' iv_tickets = 1 iv_date = '20250715' ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '50.50' ) act = lv_total ).
ENDMETHOD.
METHOD invalid_type.
DATA lv_total TYPE decfloat34.
CALL FUNCTION '{{P}}THEME_FEE'
EXPORTING
iv_visitor_type = 'STUDENT'
iv_tickets = 1
iv_date = '20250115'
IMPORTING
ev_total_price = lv_total
EXCEPTIONS
invalid_visitor_type = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -1,36 +0,0 @@
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,53 @@
FUNCTION {{p}}theme_fee
IMPORTING
iv_visitor_type TYPE string
iv_tickets TYPE i
iv_date TYPE d
EXPORTING
ev_unit_price TYPE decfloat34
ev_total_price TYPE decfloat34
ev_discount TYPE decfloat34
EXCEPTIONS
invalid_visitor_type
invalid_tickets.
DATA lv_base_price TYPE decfloat34.
DATA lv_gross TYPE decfloat34.
DATA lv_discount_pct TYPE decfloat34.
IF iv_tickets <= 0.
RAISE invalid_tickets.
ENDIF.
CASE iv_visitor_type.
WHEN 'ADULT'.
lv_base_price = '45.50'.
WHEN 'CHILD'.
lv_base_price = '25.25'.
WHEN 'SENIOR'.
lv_base_price = '30.75'.
WHEN 'FAMILY'.
lv_base_price = '40.00'.
WHEN OTHERS.
RAISE invalid_visitor_type.
ENDCASE.
" Peak season surcharge
IF iv_date IS NOT INITIAL.
lv_base_price = lv_base_price + 5.
ENDIF.
" Group discount
IF iv_tickets >= 10.
lv_discount_pct = 10.
ENDIF.
IF iv_tickets > 20.
lv_discount_pct = 15.
ENDIF.
lv_gross = lv_base_price * iv_tickets.
ev_discount = lv_gross * lv_discount_pct / 100.
ev_total_price = lv_gross - ev_discount.
ev_unit_price = lv_base_price.
ENDFUNCTION.

View File

@@ -1,54 +1,53 @@
# 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.
The function module {{P}}THEME_FEE calculates the price of a theme park ticket
order. Users report three defects. Fix the defects in the function module. 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.
- Function group {{P}}FG_THEME exists in package $TMP.
- Function module {{P}}THEME_FEE exists in this group. It is the function
module that the ticket program calls.
- The function module has defects. Read the existing code before you change
it. The existing code holds rules that this specification does not repeat.
# 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.
- Function module {{P}}THEME_FEE in function group {{P}}FG_THEME.
- Parameters:
- iv_visitor_type TYPE string
- iv_tickets TYPE i
- iv_date TYPE d
- ev_unit_price TYPE decfloat34
- ev_total_price TYPE decfloat34
- ev_discount TYPE decfloat34
- Exceptions: invalid_visitor_type, invalid_tickets.
- Do not change the interface.
# 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.
The function module calculates the price of a theme park ticket order. These
defects are reported:
1. Peak season surcharge: The surcharge must apply only to visit dates in
June, July, or August. Currently the surcharge applies to all dates.
2. Group discount: An order with 20 tickets or more must get a 15 % discount.
Currently an order with exactly 20 tickets gets only 10 %. An order with 10
to 19 tickets must get a 10 % discount. An order with fewer than 10 tickets
must get no discount.
3. Rounding: The discount amount and the total price must be rounded to 2
decimals, half up. Currently they are not rounded. The discount amount is
rounded first. The total price is the gross amount minus the rounded
discount amount, rounded to 2 decimals.
All other behavior stays the same.
# 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.
- Release target: SAP_BASIS 816.
- Do not change the function module interface.
- Out of scope: no other object.
# 7. Acceptance
- The function module {{P}}CUSTOMS_DUTY_OLD is active and has no syntax error.
- The function module 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

@@ -6,47 +6,51 @@
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 40,
"max_activations": 10
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "FUGR",
"name": "{{P}}FG_CUST",
"description": "Customs duty function group"
"name": "{{P}}FG_THEME",
"description": "Theme park ticket fee"
},
{
"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"
"name": "{{P}}THEME_FEE",
"functionGroup": "{{P}}FG_THEME",
"file": "seed/theme_fee.func.abap",
"description": "Theme park ticket fee"
}
],
"contract": [
{
"type": "FUNC",
"name": "{{P}}CUSTOMS_DUTY_OLD",
"functionGroup": "{{P}}FG_CUST",
"name": "{{P}}THEME_FEE",
"functionGroup": "{{P}}FG_THEME",
"params": [
{
"name": "iv_value",
"type": "decfloat34"
},
{
"name": "iv_country",
"name": "iv_visitor_type",
"type": "string"
},
{
"name": "iv_category",
"type": "string"
"name": "iv_tickets",
"type": "i"
},
{
"name": "ev_rate",
"name": "iv_date",
"type": "d"
},
{
"name": "ev_unit_price",
"type": "decfloat34"
},
{
"name": "ev_duty",
"name": "ev_total_price",
"type": "decfloat34"
},
{
"name": "ev_discount",
"type": "decfloat34"
}
]
@@ -56,25 +60,24 @@
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}DUTY_HIDDEN",
"file": "hidden/duty_hidden.clas.abap",
"description": "Hidden tests for the customs duty function module"
"name": "{{P}}THEME_HIDDEN",
"file": "hidden/theme_hidden.clas.abap",
"description": "Hidden tests for theme park ticket fee"
}
],
"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"
"name": "{{P}}THEME_FEE",
"functionGroup": "{{P}}FG_THEME",
"file": "reference/theme_fee.func.abap",
"description": "Theme park ticket fee"
},
{
"type": "CLAS",
"name": "{{P}}DUTY_TEST",
"file": "reference/duty_test.clas.abap",
"description": "Own tests for the customs duty function module"
"name": "{{P}}THEME_TEST",
"file": "reference/theme_test.clas.abap",
"description": "Own tests for theme park ticket fee"
}
],
"craft_checks": [