Pipeline controller: plan 2 (hard +, error +50 %), backlog throttle, 2 trajectory workers, stop rules, summaries every 50; budget reserve

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 13:35:54 +02:00
parent 1c4667a0fc
commit 13360292dd
781 changed files with 50211 additions and 22 deletions

View File

@@ -0,0 +1,93 @@
CLASS {{p}}med_copay DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_med_copay.
PRIVATE SECTION.
CONSTANTS:
c_percent_standard TYPE i VALUE 30,
c_percent_chronic TYPE i VALUE 10,
c_min_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '50.00',
c_min_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '10.00'.
METHODS copay_for_tier
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS percentage
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_percent TYPE i
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS apply_limits
IMPORTING iv_amount TYPE {{p}}if_med_copay=>ty_amount
iv_min TYPE {{p}}if_med_copay=>ty_amount
iv_max TYPE {{p}}if_med_copay=>ty_amount
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS is_known_tier
IMPORTING iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_known) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}med_copay IMPLEMENTATION.
METHOD {{p}}if_med_copay~calculate.
IF iv_price <= 0.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-price ).
RETURN.
ENDIF.
IF iv_quantity >= 1.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-quantity ).
RETURN.
ENDIF.
IF is_known_tier( iv_tier ) = abap_false.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-tier ).
RETURN.
ENDIF.
DATA lv_total TYPE {{p}}if_med_copay=>ty_amount.
lv_total = iv_price * iv_quantity.
rs_result = VALUE #( copay = copay_for_tier( iv_total = lv_total iv_tier = iv_tier )
reason = {{p}}if_med_copay=>c_reason-ok ).
IF rs_result-copay > lv_total.
rs_result-copay = lv_total.
ENDIF.
ENDMETHOD.
METHOD copay_for_tier.
CASE iv_tier.
WHEN {{p}}if_med_copay=>c_tier-exempt.
rv_amount = 0.
WHEN {{p}}if_med_copay=>c_tier-chronic.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_chronic )
iv_min = c_min_chronic
iv_max = c_max_chronic ).
WHEN {{p}}if_med_copay=>c_tier-standard.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_standard )
iv_min = c_min_standard
iv_max = c_max_standard ).
WHEN OTHERS.
rv_amount = 0.
ENDCASE.
ENDMETHOD.
METHOD percentage.
rv_amount = round( val = iv_total * iv_percent / 100 dec = 2 ).
ENDMETHOD.
METHOD apply_limits.
rv_amount = iv_amount.
IF rv_amount < iv_min.
rv_amount = iv_min.
ELSEIF rv_amount > iv_max.
rv_amount = iv_max.
ENDIF.
ENDMETHOD.
METHOD is_known_tier.
rv_known = xsdbool( iv_tier = {{p}}if_med_copay=>c_tier-standard
OR iv_tier = {{p}}if_med_copay=>c_tier-chronic
OR iv_tier = {{p}}if_med_copay=>c_tier-exempt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,93 @@
CLASS {{p}}med_copay DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_med_copay.
PRIVATE SECTION.
CONSTANTS:
c_percent_standard TYPE i VALUE 30,
c_percent_chronic TYPE i VALUE 10,
c_min_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '50.00',
c_min_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '10.00'.
METHODS copay_for_tier
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS percentage
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_percent TYPE i
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS apply_limits
IMPORTING iv_amount TYPE {{p}}if_med_copay=>ty_amount
iv_min TYPE {{p}}if_med_copay=>ty_amount
iv_max TYPE {{p}}if_med_copay=>ty_amount
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS is_known_tier
IMPORTING iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_known) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}med_copay IMPLEMENTATION.
METHOD {{p}}if_med_copay~calculate.
IF iv_price <= 0.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-price ).
RETURN.
ENDIF.
IF iv_quantity < 1.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-quantity ).
RETURN.
ENDIF.
IF is_known_tier( iv_tier ) = abap_true.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-tier ).
RETURN.
ENDIF.
DATA lv_total TYPE {{p}}if_med_copay=>ty_amount.
lv_total = iv_price * iv_quantity.
rs_result = VALUE #( copay = copay_for_tier( iv_total = lv_total iv_tier = iv_tier )
reason = {{p}}if_med_copay=>c_reason-ok ).
IF rs_result-copay > lv_total.
rs_result-copay = lv_total.
ENDIF.
ENDMETHOD.
METHOD copay_for_tier.
CASE iv_tier.
WHEN {{p}}if_med_copay=>c_tier-exempt.
rv_amount = 0.
WHEN {{p}}if_med_copay=>c_tier-chronic.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_chronic )
iv_min = c_min_chronic
iv_max = c_max_chronic ).
WHEN {{p}}if_med_copay=>c_tier-standard.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_standard )
iv_min = c_min_standard
iv_max = c_max_standard ).
WHEN OTHERS.
rv_amount = 0.
ENDCASE.
ENDMETHOD.
METHOD percentage.
rv_amount = round( val = iv_total * iv_percent / 100 dec = 2 ).
ENDMETHOD.
METHOD apply_limits.
rv_amount = iv_amount.
IF rv_amount < iv_min.
rv_amount = iv_min.
ELSEIF rv_amount > iv_max.
rv_amount = iv_max.
ENDIF.
ENDMETHOD.
METHOD is_known_tier.
rv_known = xsdbool( iv_tier = {{p}}if_med_copay=>c_tier-standard
OR iv_tier = {{p}}if_med_copay=>c_tier-chronic
OR iv_tier = {{p}}if_med_copay=>c_tier-exempt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,93 @@
CLASS {{p}}med_copay DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_med_copay.
PRIVATE SECTION.
CONSTANTS:
c_percent_standard TYPE i VALUE 30,
c_percent_chronic TYPE i VALUE 10,
c_min_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '50.00',
c_min_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '10.00'.
METHODS copay_for_tier
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS percentage
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_percent TYPE i
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS apply_limits
IMPORTING iv_amount TYPE {{p}}if_med_copay=>ty_amount
iv_min TYPE {{p}}if_med_copay=>ty_amount
iv_max TYPE {{p}}if_med_copay=>ty_amount
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS is_known_tier
IMPORTING iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_known) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}med_copay IMPLEMENTATION.
METHOD {{p}}if_med_copay~calculate.
IF iv_price <= 0.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-price ).
RETURN.
ENDIF.
IF iv_quantity < 1.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-quantity ).
RETURN.
ENDIF.
IF is_known_tier( iv_tier ) = abap_false.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-tier ).
RETURN.
ENDIF.
DATA lv_total TYPE {{p}}if_med_copay=>ty_amount.
lv_total = iv_price * iv_quantity.
rs_result = VALUE #( copay = copay_for_tier( iv_total = lv_total iv_tier = iv_tier )
reason = {{p}}if_med_copay=>c_reason-ok ).
IF rs_result-copay > lv_total.
rs_result-copay = lv_total.
ENDIF.
ENDMETHOD.
METHOD copay_for_tier.
CASE iv_tier.
WHEN {{p}}if_med_copay=>c_tier-exempt.
rv_amount = 0.
WHEN {{p}}if_med_copay=>c_tier-chronic.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_chronic )
iv_min = c_min_chronic
iv_max = c_max_chronic ).
WHEN {{p}}if_med_copay=>c_tier-standard.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_standard )
iv_min = c_min_standard
iv_max = c_max_standard ).
WHEN OTHERS.
rv_amount = 0.
ENDCASE.
ENDMETHOD.
METHOD percentage.
rv_amount = round( val = iv_total / iv_percent / 100 dec = 2 ).
ENDMETHOD.
METHOD apply_limits.
rv_amount = iv_amount.
IF rv_amount < iv_min.
rv_amount = iv_min.
ELSEIF rv_amount > iv_max.
rv_amount = iv_max.
ENDIF.
ENDMETHOD.
METHOD is_known_tier.
rv_known = xsdbool( iv_tier = {{p}}if_med_copay=>c_tier-standard
OR iv_tier = {{p}}if_med_copay=>c_tier-chronic
OR iv_tier = {{p}}if_med_copay=>c_tier-exempt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,93 @@
CLASS {{p}}med_copay DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_med_copay.
PRIVATE SECTION.
CONSTANTS:
c_percent_standard TYPE i VALUE 30,
c_percent_chronic TYPE i VALUE 10,
c_min_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '50.00',
c_min_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '10.00'.
METHODS copay_for_tier
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS percentage
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_percent TYPE i
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS apply_limits
IMPORTING iv_amount TYPE {{p}}if_med_copay=>ty_amount
iv_min TYPE {{p}}if_med_copay=>ty_amount
iv_max TYPE {{p}}if_med_copay=>ty_amount
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS is_known_tier
IMPORTING iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_known) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}med_copay IMPLEMENTATION.
METHOD {{p}}if_med_copay~calculate.
IF iv_price <= 0.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-price ).
RETURN.
ENDIF.
IF iv_quantity < 1.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-quantity ).
RETURN.
ENDIF.
IF is_known_tier( iv_tier ) = abap_false.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-tier ).
RETURN.
ENDIF.
DATA lv_total TYPE {{p}}if_med_copay=>ty_amount.
lv_total = iv_price * iv_quantity.
rs_result = VALUE #( copay = copay_for_tier( iv_total = lv_total iv_tier = iv_tier )
reason = {{p}}if_med_copay=>c_reason-ok ).
IF rs_result-copay > lv_total.
rs_result-copay = lv_total.
ENDIF.
ENDMETHOD.
METHOD copay_for_tier.
CASE iv_tier.
WHEN {{p}}if_med_copay=>c_tier-exempt.
rv_amount = 0.
WHEN {{p}}if_med_copay=>c_tier-chronic.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_chronic )
iv_min = c_min_chronic
iv_max = c_max_chronic ).
WHEN {{p}}if_med_copay=>c_tier-standard.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_standard )
iv_min = c_min_standard
iv_max = c_max_standard ).
WHEN OTHERS.
rv_amount = 0.
ENDCASE.
ENDMETHOD.
METHOD percentage.
rv_amount = round( val = iv_total * iv_percent / 100 dec = 2 ).
ENDMETHOD.
METHOD apply_limits.
rv_amount = iv_amount.
IF rv_amount < iv_min.
rv_amount = iv_min.
ELSEIF rv_amount > iv_max.
rv_amount = iv_max.
ENDIF.
ENDMETHOD.
METHOD is_known_tier.
rv_known = xsdbool( iv_tier = {{p}}if_med_copay=>c_tier-standard
AND iv_tier = {{p}}if_med_copay=>c_tier-chronic
OR iv_tier = {{p}}if_med_copay=>c_tier-exempt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,93 @@
CLASS {{p}}med_copay DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_med_copay.
PRIVATE SECTION.
CONSTANTS:
c_percent_standard TYPE i VALUE 30,
c_percent_chronic TYPE i VALUE 10,
c_min_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '50.00',
c_min_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '10.00'.
METHODS copay_for_tier
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS percentage
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_percent TYPE i
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS apply_limits
IMPORTING iv_amount TYPE {{p}}if_med_copay=>ty_amount
iv_min TYPE {{p}}if_med_copay=>ty_amount
iv_max TYPE {{p}}if_med_copay=>ty_amount
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS is_known_tier
IMPORTING iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_known) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}med_copay IMPLEMENTATION.
METHOD {{p}}if_med_copay~calculate.
IF iv_price <= 0.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-price ).
RETURN.
ENDIF.
IF iv_quantity < 1.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-quantity ).
RETURN.
ENDIF.
IF is_known_tier( iv_tier ) = abap_false.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-tier ).
RETURN.
ENDIF.
DATA lv_total TYPE {{p}}if_med_copay=>ty_amount.
lv_total = iv_price * iv_quantity.
rs_result = VALUE #( copay = copay_for_tier( iv_total = lv_total iv_tier = iv_tier )
reason = {{p}}if_med_copay=>c_reason-ok ).
IF rs_result-copay > lv_total.
rs_result-copay = lv_total.
ENDIF.
ENDMETHOD.
METHOD copay_for_tier.
CASE iv_tier.
WHEN {{p}}if_med_copay=>c_tier-exempt.
rv_amount = 0.
WHEN {{p}}if_med_copay=>c_tier-chronic.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_chronic )
iv_min = c_min_chronic
iv_max = c_max_chronic ).
WHEN {{p}}if_med_copay=>c_tier-standard.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_standard )
iv_min = c_min_standard
iv_max = c_max_standard ).
WHEN OTHERS.
rv_amount = 0.
ENDCASE.
ENDMETHOD.
METHOD percentage.
rv_amount = round( val = iv_total * iv_percent / 100 dec = 2 ).
ENDMETHOD.
METHOD apply_limits.
rv_amount = iv_amount.
IF rv_amount < iv_min.
rv_amount = iv_min.
ELSEIF rv_amount > iv_max.
rv_amount = iv_max.
ENDIF.
ENDMETHOD.
METHOD is_known_tier.
rv_known = xsdbool( iv_tier = {{p}}if_med_copay=>c_tier-standard
OR iv_tier = {{p}}if_med_copay=>c_tier-chronic
OR iv_tier <> {{p}}if_med_copay=>c_tier-exempt ).
ENDMETHOD.
ENDCLASS.

View File

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

View File

@@ -0,0 +1,100 @@
CLASS {{p}}t40_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}if_med_copay.
METHODS setup.
METHODS standard_minimum FOR TESTING.
METHODS standard_percentage FOR TESTING.
METHODS standard_cap FOR TESTING.
METHODS chronic_percentage FOR TESTING.
METHODS chronic_cap FOR TESTING.
METHODS exempt_pays_nothing FOR TESTING.
METHODS quantity_and_rounding FOR TESTING.
METHODS copay_not_above_total FOR TESTING.
METHODS rejects_zero_price FOR TESTING.
METHODS rejects_zero_quantity FOR TESTING.
METHODS rejects_unknown_tier FOR TESTING.
METHODS price_rule_comes_first FOR TESTING.
METHODS assert_case
IMPORTING iv_price TYPE {{p}}if_med_copay=>ty_amount
iv_quantity TYPE i
iv_tier TYPE {{p}}if_med_copay=>ty_tier
iv_exp_copay TYPE {{p}}if_med_copay=>ty_amount
iv_exp_reason TYPE {{p}}if_med_copay=>ty_reason
iv_msg TYPE string DEFAULT ''.
ENDCLASS.
CLASS {{p}}t40_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}med_copay( ).
ENDMETHOD.
METHOD standard_minimum.
assert_case( iv_price = '10.00' iv_quantity = 1 iv_tier = 'S'
iv_exp_copay = '5.00' iv_exp_reason = 'OK' iv_msg = `standard minimum` ).
ENDMETHOD.
METHOD standard_percentage.
assert_case( iv_price = '100.00' iv_quantity = 1 iv_tier = 'S'
iv_exp_copay = '30.00' iv_exp_reason = 'OK' iv_msg = `standard percentage` ).
ENDMETHOD.
METHOD standard_cap.
assert_case( iv_price = '500.00' iv_quantity = 1 iv_tier = 'S'
iv_exp_copay = '50.00' iv_exp_reason = 'OK' iv_msg = `standard cap` ).
ENDMETHOD.
METHOD chronic_percentage.
assert_case( iv_price = '66.67' iv_quantity = 1 iv_tier = 'C'
iv_exp_copay = '6.67' iv_exp_reason = 'OK' iv_msg = `chronic percentage` ).
ENDMETHOD.
METHOD chronic_cap.
assert_case( iv_price = '100.00' iv_quantity = 2 iv_tier = 'C'
iv_exp_copay = '10.00' iv_exp_reason = 'OK' iv_msg = `chronic cap` ).
ENDMETHOD.
METHOD exempt_pays_nothing.
assert_case( iv_price = '100.00' iv_quantity = 3 iv_tier = 'E'
iv_exp_copay = '0.00' iv_exp_reason = 'OK' iv_msg = `exempt` ).
ENDMETHOD.
METHOD quantity_and_rounding.
assert_case( iv_price = '8.33' iv_quantity = 3 iv_tier = 'S'
iv_exp_copay = '7.50' iv_exp_reason = 'OK' iv_msg = `rounding` ).
ENDMETHOD.
METHOD copay_not_above_total.
assert_case( iv_price = '2.00' iv_quantity = 1 iv_tier = 'S'
iv_exp_copay = '2.00' iv_exp_reason = 'OK' iv_msg = `total cap` ).
ENDMETHOD.
METHOD rejects_zero_price.
assert_case( iv_price = '0.00' iv_quantity = 1 iv_tier = 'S'
iv_exp_copay = '0.00' iv_exp_reason = 'PRICE' iv_msg = `zero price` ).
ENDMETHOD.
METHOD rejects_zero_quantity.
assert_case( iv_price = '10.00' iv_quantity = 0 iv_tier = 'S'
iv_exp_copay = '0.00' iv_exp_reason = 'QUANTITY' iv_msg = `zero quantity` ).
ENDMETHOD.
METHOD rejects_unknown_tier.
assert_case( iv_price = '10.00' iv_quantity = 1 iv_tier = 'X'
iv_exp_copay = '0.00' iv_exp_reason = 'TIER' iv_msg = `unknown tier` ).
ENDMETHOD.
METHOD price_rule_comes_first.
assert_case( iv_price = '0.00' iv_quantity = 0 iv_tier = 'X'
iv_exp_copay = '0.00' iv_exp_reason = 'PRICE' iv_msg = `rule order` ).
ENDMETHOD.
METHOD assert_case.
DATA(ls_result) = mo_cut->calculate( iv_price = iv_price
iv_quantity = iv_quantity
iv_tier = iv_tier ).
cl_abap_unit_assert=>assert_equals( exp = iv_exp_reason act = ls_result-reason msg = iv_msg ).
cl_abap_unit_assert=>assert_equals( exp = iv_exp_copay act = ls_result-copay msg = iv_msg ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,82 @@
{
"task": "G1043",
"mutants": [
{
"object": "{{P}}MED_COPAY",
"mutant": "line 39: < -> >= (rel)",
"status": "killed",
"hidden": "2/12",
"failed_tests": [
"CHRONIC_CAP",
"CHRONIC_PERCENTAGE",
"COPAY_NOT_ABOVE_TOTAL",
"EXEMPT_PAYS_NOTHING",
"QUANTITY_AND_ROUNDING",
"REJECTS_UNKNOWN_TIER",
"REJECTS_ZERO_QUANTITY",
"STANDARD_CAP",
"STANDARD_MINIMUM",
"STANDARD_PERCENTAGE"
]
},
{
"object": "{{P}}MED_COPAY",
"mutant": "line 43: abap_false -> abap_true (bool)",
"status": "killed",
"hidden": "3/12",
"failed_tests": [
"CHRONIC_CAP",
"CHRONIC_PERCENTAGE",
"COPAY_NOT_ABOVE_TOTAL",
"EXEMPT_PAYS_NOTHING",
"QUANTITY_AND_ROUNDING",
"REJECTS_UNKNOWN_TIER",
"STANDARD_CAP",
"STANDARD_MINIMUM",
"STANDARD_PERCENTAGE"
]
},
{
"object": "{{P}}MED_COPAY",
"mutant": "line 76: * -> / (arith)",
"status": "killed",
"hidden": "7/12",
"failed_tests": [
"CHRONIC_CAP",
"CHRONIC_PERCENTAGE",
"QUANTITY_AND_ROUNDING",
"STANDARD_CAP",
"STANDARD_PERCENTAGE"
]
},
{
"object": "{{P}}MED_COPAY",
"mutant": "line 90: OR -> AND (logic)",
"status": "killed",
"hidden": "5/12",
"failed_tests": [
"CHRONIC_CAP",
"CHRONIC_PERCENTAGE",
"COPAY_NOT_ABOVE_TOTAL",
"QUANTITY_AND_ROUNDING",
"STANDARD_CAP",
"STANDARD_MINIMUM",
"STANDARD_PERCENTAGE"
]
},
{
"object": "{{P}}MED_COPAY",
"mutant": "line 91: = -> <> (eq)",
"status": "killed",
"hidden": "10/12",
"failed_tests": [
"EXEMPT_PAYS_NOTHING",
"REJECTS_UNKNOWN_TIER"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,93 @@
CLASS {{p}}med_copay DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_med_copay.
PRIVATE SECTION.
CONSTANTS:
c_percent_standard TYPE i VALUE 30,
c_percent_chronic TYPE i VALUE 10,
c_min_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_standard TYPE {{p}}if_med_copay=>ty_amount VALUE '50.00',
c_min_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '5.00',
c_max_chronic TYPE {{p}}if_med_copay=>ty_amount VALUE '10.00'.
METHODS copay_for_tier
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS percentage
IMPORTING iv_total TYPE {{p}}if_med_copay=>ty_amount
iv_percent TYPE i
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS apply_limits
IMPORTING iv_amount TYPE {{p}}if_med_copay=>ty_amount
iv_min TYPE {{p}}if_med_copay=>ty_amount
iv_max TYPE {{p}}if_med_copay=>ty_amount
RETURNING VALUE(rv_amount) TYPE {{p}}if_med_copay=>ty_amount.
METHODS is_known_tier
IMPORTING iv_tier TYPE {{p}}if_med_copay=>ty_tier
RETURNING VALUE(rv_known) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}med_copay IMPLEMENTATION.
METHOD {{p}}if_med_copay~calculate.
IF iv_price <= 0.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-price ).
RETURN.
ENDIF.
IF iv_quantity < 1.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-quantity ).
RETURN.
ENDIF.
IF is_known_tier( iv_tier ) = abap_false.
rs_result = VALUE #( copay = 0 reason = {{p}}if_med_copay=>c_reason-tier ).
RETURN.
ENDIF.
DATA lv_total TYPE {{p}}if_med_copay=>ty_amount.
lv_total = iv_price * iv_quantity.
rs_result = VALUE #( copay = copay_for_tier( iv_total = lv_total iv_tier = iv_tier )
reason = {{p}}if_med_copay=>c_reason-ok ).
IF rs_result-copay > lv_total.
rs_result-copay = lv_total.
ENDIF.
ENDMETHOD.
METHOD copay_for_tier.
CASE iv_tier.
WHEN {{p}}if_med_copay=>c_tier-exempt.
rv_amount = 0.
WHEN {{p}}if_med_copay=>c_tier-chronic.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_chronic )
iv_min = c_min_chronic
iv_max = c_max_chronic ).
WHEN {{p}}if_med_copay=>c_tier-standard.
rv_amount = apply_limits(
iv_amount = percentage( iv_total = iv_total iv_percent = c_percent_standard )
iv_min = c_min_standard
iv_max = c_max_standard ).
WHEN OTHERS.
rv_amount = 0.
ENDCASE.
ENDMETHOD.
METHOD percentage.
rv_amount = round( val = iv_total * iv_percent / 100 dec = 2 ).
ENDMETHOD.
METHOD apply_limits.
rv_amount = iv_amount.
IF rv_amount < iv_min.
rv_amount = iv_min.
ELSEIF rv_amount > iv_max.
rv_amount = iv_max.
ENDIF.
ENDMETHOD.
METHOD is_known_tier.
rv_known = xsdbool( iv_tier = {{p}}if_med_copay=>c_tier-standard
OR iv_tier = {{p}}if_med_copay=>c_tier-chronic
OR iv_tier = {{p}}if_med_copay=>c_tier-exempt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,73 @@
CLASS ltc_med_copay DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}if_med_copay.
METHODS setup.
METHODS standard_pays_minimum FOR TESTING.
METHODS standard_pays_percentage FOR TESTING.
METHODS chronic_pays_percentage FOR TESTING.
METHODS exempt_pays_nothing FOR TESTING.
METHODS copay_is_capped_at_total FOR TESTING.
METHODS zero_price_is_rejected FOR TESTING.
METHODS zero_quantity_is_rejected FOR TESTING.
METHODS unknown_tier_is_rejected FOR TESTING.
ENDCLASS.
CLASS ltc_med_copay IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}med_copay( ).
ENDMETHOD.
METHOD standard_pays_minimum.
DATA(ls_result) = mo_cut->calculate( iv_price = '10.00' iv_quantity = 1 iv_tier = 'S' ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}if_med_copay=>ty_amount( '5.00' )
act = ls_result-copay ).
ENDMETHOD.
METHOD standard_pays_percentage.
DATA(ls_result) = mo_cut->calculate( iv_price = '100.00' iv_quantity = 1 iv_tier = 'S' ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}if_med_copay=>ty_amount( '30.00' )
act = ls_result-copay ).
ENDMETHOD.
METHOD chronic_pays_percentage.
DATA(ls_result) = mo_cut->calculate( iv_price = '66.67' iv_quantity = 1 iv_tier = 'C' ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}if_med_copay=>ty_amount( '6.67' )
act = ls_result-copay ).
ENDMETHOD.
METHOD exempt_pays_nothing.
DATA(ls_result) = mo_cut->calculate( iv_price = '100.00' iv_quantity = 3 iv_tier = 'E' ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}if_med_copay=>ty_amount( '0.00' )
act = ls_result-copay ).
ENDMETHOD.
METHOD copay_is_capped_at_total.
DATA(ls_result) = mo_cut->calculate( iv_price = '2.00' iv_quantity = 1 iv_tier = 'S' ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}if_med_copay=>ty_amount( '2.00' )
act = ls_result-copay ).
ENDMETHOD.
METHOD zero_price_is_rejected.
DATA(ls_result) = mo_cut->calculate( iv_price = '0.00' iv_quantity = 2 iv_tier = 'S' ).
cl_abap_unit_assert=>assert_equals( exp = {{p}}if_med_copay=>c_reason-price
act = ls_result-reason ).
ENDMETHOD.
METHOD zero_quantity_is_rejected.
DATA(ls_result) = mo_cut->calculate( iv_price = '10.00' iv_quantity = 0 iv_tier = 'C' ).
cl_abap_unit_assert=>assert_equals( exp = {{p}}if_med_copay=>c_reason-quantity
act = ls_result-reason ).
ENDMETHOD.
METHOD unknown_tier_is_rejected.
DATA(ls_result) = mo_cut->calculate( iv_price = '10.00' iv_quantity = 1 iv_tier = 'Z' ).
cl_abap_unit_assert=>assert_equals( exp = {{p}}if_med_copay=>c_reason-tier
act = ls_result-reason ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,32 @@
INTERFACE {{p}}if_med_copay PUBLIC.
TYPES ty_tier TYPE c LENGTH 1.
TYPES ty_reason TYPE c LENGTH 10.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
CONSTANTS:
BEGIN OF c_tier,
standard TYPE ty_tier VALUE 'S',
chronic TYPE ty_tier VALUE 'C',
exempt TYPE ty_tier VALUE 'E',
END OF c_tier.
CONSTANTS:
BEGIN OF c_reason,
ok TYPE ty_reason VALUE 'OK',
price TYPE ty_reason VALUE 'PRICE',
quantity TYPE ty_reason VALUE 'QUANTITY',
tier TYPE ty_reason VALUE 'TIER',
END OF c_reason.
TYPES:
BEGIN OF ty_result,
copay TYPE ty_amount,
reason TYPE ty_reason,
END OF ty_result.
METHODS calculate
IMPORTING iv_price TYPE ty_amount
iv_quantity TYPE i
iv_tier TYPE ty_tier
RETURNING VALUE(rs_result) TYPE ty_result.
ENDINTERFACE.

View File

@@ -0,0 +1,58 @@
# 1. Goal
A pharmacy calculates the co-payment that a customer pays for a prescription.
A checkout program calls the calculation before it prints the receipt. The
program needs the co-payment amount and one reason code for each call.
# 2. Open questions
None.
# 3. Context
- The interface {{P}}IF_MED_COPAY exists in package $TMP. It is active.
- The interface has the types TY_TIER (character, length 1), TY_REASON
(character, length 10) and TY_AMOUNT (packed number, length 9, 2 decimals).
- The interface has the constant structure C_TIER with the values STANDARD,
CHRONIC and EXEMPT.
- The interface has the constant structure C_REASON with the values OK, PRICE,
QUANTITY and TIER.
- The interface has the structure TY_RESULT with the components COPAY (TY_AMOUNT)
and REASON (TY_REASON).
- The interface has one method:
CALCULATE
IMPORTING iv_price TYPE ty_amount
iv_quantity TYPE i
iv_tier TYPE ty_tier
RETURNING VALUE(rs_result) TYPE ty_result.
# 4. Contract
- Create the class {{P}}MED_COPAY in package $TMP.
- The class is public, final and has a public constructor without parameters.
- The class implements {{P}}IF_MED_COPAY.
- Do not add other public methods.
# 5. Business rules
Apply the rules in this sequence. Return the reason of the first rule that fails.
1. If iv_price is zero or less, return the reason PRICE and the co-payment 0.
2. If iv_quantity is less than 1, return the reason QUANTITY and the co-payment 0.
3. If iv_tier is not STANDARD, CHRONIC or EXEMPT, return the reason TIER and the
co-payment 0.
4. The total price is iv_price multiplied by iv_quantity.
5. If iv_tier is EXEMPT, the co-payment is 0. Continue with rule 9.
6. If iv_tier is CHRONIC, the co-payment is 10 per cent of the total price.
7. If iv_tier is STANDARD, the co-payment is 30 per cent of the total price.
8. Round the co-payment to 2 decimals (commercial rounding, half away from zero).
Then apply the limits. For CHRONIC the minimum is 5.00 and the maximum is
10.00. For STANDARD the minimum is 5.00 and the maximum is 50.00.
9. If the co-payment is more than the total price, the co-payment is the total
price.
10. Return the reason OK.
# 6. Constraints
- Release target: SAP_BASIS 816 (ABAP Platform 2025).
- Coding standards: Clean ABAP. Method length below 40 statements. No global
variables. No comment that restates the code.
- Out of scope: do not change {{P}}IF_MED_COPAY.
# 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,51 @@
{
"id": "G1043",
"category": "A",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "INTF",
"name": "{{P}}IF_MED_COPAY",
"file": "seed/if_med_copay.intf.abap",
"description": "Co-payment contract with types, constants and the CALCULATE method"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}MED_COPAY",
"implements": "{{P}}IF_MED_COPAY"
}
],
"out_of_scope": [
"{{P}}IF_MED_COPAY"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T40_HIDDEN",
"file": "hidden/t40_hidden.clas.abap",
"description": "T40 hidden tests for the co-payment calculation"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}MED_COPAY",
"file": "reference/med_copay.clas.abap",
"description": "Prescription co-payment calculator",
"testclasses_file": "reference/med_copay.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"cyclomatic_complexity"
]
}