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,85 @@
CLASS {{p}}overdraft_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_overdraft.
PRIVATE SECTION.
CONSTANTS:
c_free_days TYPE i VALUE 3,
c_percent_divisor TYPE i VALUE 100,
c_days_per_year TYPE i VALUE 360,
c_business_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '2.00',
c_min_rate TYPE p LENGTH 3 DECIMALS 2 VALUE '5.00'.
TYPES:
ty_rate TYPE p LENGTH 5 DECIMALS 2,
ty_interest TYPE p LENGTH 15 DECIMALS 6.
METHODS chargeable_days
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_days) TYPE i.
METHODS base_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
RETURNING VALUE(rv_rate) TYPE ty_rate.
METHODS interest_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
iv_segment TYPE {{p}}if_overdraft=>ty_segment
RETURNING VALUE(rv_rate) TYPE ty_rate.
ENDCLASS.
CLASS {{p}}overdraft_calc IMPLEMENTATION.
METHOD {{p}}if_overdraft~calculate.
DATA:
lv_days TYPE i,
lv_rate TYPE ty_rate,
lv_annual TYPE ty_interest.
IF iv_amount <= 0 AND iv_days <= 0.
rv_interest = 0.
RETURN.
ENDIF.
lv_days = chargeable_days( iv_days ).
lv_rate = interest_rate( iv_amount = iv_amount
iv_segment = iv_segment ).
lv_annual = iv_amount * lv_rate / c_percent_divisor.
rv_interest = lv_annual * lv_days / c_days_per_year.
IF rv_interest > 0 AND rv_interest < {{p}}if_overdraft=>c_min_interest.
rv_interest = {{p}}if_overdraft=>c_min_interest.
ENDIF.
ENDMETHOD.
METHOD chargeable_days.
rv_days = iv_days - c_free_days.
IF rv_days < 0.
rv_days = 0.
ENDIF.
ENDMETHOD.
METHOD base_rate.
IF iv_amount <= 1000.
rv_rate = '12.00'.
ELSEIF iv_amount <= 5000.
rv_rate = '10.00'.
ELSEIF iv_amount <= 20000.
rv_rate = '8.00'.
ELSE.
rv_rate = '6.50'.
ENDIF.
ENDMETHOD.
METHOD interest_rate.
rv_rate = base_rate( iv_amount ).
IF iv_segment = {{p}}if_overdraft=>c_segment_business.
rv_rate = rv_rate - c_business_discount.
IF rv_rate < c_min_rate.
rv_rate = c_min_rate.
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,85 @@
CLASS {{p}}overdraft_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_overdraft.
PRIVATE SECTION.
CONSTANTS:
c_free_days TYPE i VALUE 3,
c_percent_divisor TYPE i VALUE 100,
c_days_per_year TYPE i VALUE 360,
c_business_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '2.00',
c_min_rate TYPE p LENGTH 3 DECIMALS 2 VALUE '5.00'.
TYPES:
ty_rate TYPE p LENGTH 5 DECIMALS 2,
ty_interest TYPE p LENGTH 15 DECIMALS 6.
METHODS chargeable_days
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_days) TYPE i.
METHODS base_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
RETURNING VALUE(rv_rate) TYPE ty_rate.
METHODS interest_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
iv_segment TYPE {{p}}if_overdraft=>ty_segment
RETURNING VALUE(rv_rate) TYPE ty_rate.
ENDCLASS.
CLASS {{p}}overdraft_calc IMPLEMENTATION.
METHOD {{p}}if_overdraft~calculate.
DATA:
lv_days TYPE i,
lv_rate TYPE ty_rate,
lv_annual TYPE ty_interest.
IF iv_amount <= 0 OR iv_days <= 0.
rv_interest = 0.
RETURN.
ENDIF.
lv_days = chargeable_days( iv_days ).
lv_rate = interest_rate( iv_amount = iv_amount
iv_segment = iv_segment ).
lv_annual = iv_amount / lv_rate / c_percent_divisor.
rv_interest = lv_annual * lv_days / c_days_per_year.
IF rv_interest > 0 AND rv_interest < {{p}}if_overdraft=>c_min_interest.
rv_interest = {{p}}if_overdraft=>c_min_interest.
ENDIF.
ENDMETHOD.
METHOD chargeable_days.
rv_days = iv_days - c_free_days.
IF rv_days < 0.
rv_days = 0.
ENDIF.
ENDMETHOD.
METHOD base_rate.
IF iv_amount <= 1000.
rv_rate = '12.00'.
ELSEIF iv_amount <= 5000.
rv_rate = '10.00'.
ELSEIF iv_amount <= 20000.
rv_rate = '8.00'.
ELSE.
rv_rate = '6.50'.
ENDIF.
ENDMETHOD.
METHOD interest_rate.
rv_rate = base_rate( iv_amount ).
IF iv_segment = {{p}}if_overdraft=>c_segment_business.
rv_rate = rv_rate - c_business_discount.
IF rv_rate < c_min_rate.
rv_rate = c_min_rate.
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,85 @@
CLASS {{p}}overdraft_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_overdraft.
PRIVATE SECTION.
CONSTANTS:
c_free_days TYPE i VALUE 3,
c_percent_divisor TYPE i VALUE 100,
c_days_per_year TYPE i VALUE 360,
c_business_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '2.00',
c_min_rate TYPE p LENGTH 3 DECIMALS 2 VALUE '5.00'.
TYPES:
ty_rate TYPE p LENGTH 5 DECIMALS 2,
ty_interest TYPE p LENGTH 15 DECIMALS 6.
METHODS chargeable_days
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_days) TYPE i.
METHODS base_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
RETURNING VALUE(rv_rate) TYPE ty_rate.
METHODS interest_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
iv_segment TYPE {{p}}if_overdraft=>ty_segment
RETURNING VALUE(rv_rate) TYPE ty_rate.
ENDCLASS.
CLASS {{p}}overdraft_calc IMPLEMENTATION.
METHOD {{p}}if_overdraft~calculate.
DATA:
lv_days TYPE i,
lv_rate TYPE ty_rate,
lv_annual TYPE ty_interest.
IF iv_amount <= 0 OR iv_days <= 0.
rv_interest = 0.
RETURN.
ENDIF.
lv_days = chargeable_days( iv_days ).
lv_rate = interest_rate( iv_amount = iv_amount
iv_segment = iv_segment ).
lv_annual = iv_amount * lv_rate / c_percent_divisor.
rv_interest = lv_annual * lv_days / c_days_per_year.
IF rv_interest > 0 AND rv_interest < {{p}}if_overdraft=>c_min_interest.
rv_interest = {{p}}if_overdraft=>c_min_interest.
ENDIF.
ENDMETHOD.
METHOD chargeable_days.
rv_days = iv_days - c_free_days.
IF rv_days < 0.
rv_days = 0.
ENDIF.
ENDMETHOD.
METHOD base_rate.
IF iv_amount <= 1000.
rv_rate = '12.00'.
ELSEIF iv_amount > 5000.
rv_rate = '10.00'.
ELSEIF iv_amount <= 20000.
rv_rate = '8.00'.
ELSE.
rv_rate = '6.50'.
ENDIF.
ENDMETHOD.
METHOD interest_rate.
rv_rate = base_rate( iv_amount ).
IF iv_segment = {{p}}if_overdraft=>c_segment_business.
rv_rate = rv_rate - c_business_discount.
IF rv_rate < c_min_rate.
rv_rate = c_min_rate.
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,85 @@
CLASS {{p}}overdraft_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_overdraft.
PRIVATE SECTION.
CONSTANTS:
c_free_days TYPE i VALUE 3,
c_percent_divisor TYPE i VALUE 100,
c_days_per_year TYPE i VALUE 360,
c_business_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '2.00',
c_min_rate TYPE p LENGTH 3 DECIMALS 2 VALUE '5.00'.
TYPES:
ty_rate TYPE p LENGTH 5 DECIMALS 2,
ty_interest TYPE p LENGTH 15 DECIMALS 6.
METHODS chargeable_days
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_days) TYPE i.
METHODS base_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
RETURNING VALUE(rv_rate) TYPE ty_rate.
METHODS interest_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
iv_segment TYPE {{p}}if_overdraft=>ty_segment
RETURNING VALUE(rv_rate) TYPE ty_rate.
ENDCLASS.
CLASS {{p}}overdraft_calc IMPLEMENTATION.
METHOD {{p}}if_overdraft~calculate.
DATA:
lv_days TYPE i,
lv_rate TYPE ty_rate,
lv_annual TYPE ty_interest.
IF iv_amount <= 0 OR iv_days <= 0.
rv_interest = 0.
RETURN.
ENDIF.
lv_days = chargeable_days( iv_days ).
lv_rate = interest_rate( iv_amount = iv_amount
iv_segment = iv_segment ).
lv_annual = iv_amount * lv_rate / c_percent_divisor.
rv_interest = lv_annual * lv_days / c_days_per_year.
IF rv_interest > 0 AND rv_interest < {{p}}if_overdraft=>c_min_interest.
rv_interest = {{p}}if_overdraft=>c_min_interest.
ENDIF.
ENDMETHOD.
METHOD chargeable_days.
rv_days = iv_days - c_free_days.
IF rv_days < 0.
rv_days = 0.
ENDIF.
ENDMETHOD.
METHOD base_rate.
IF iv_amount <= 1000.
rv_rate = '12.00'.
ELSEIF iv_amount <= 5000.
rv_rate = '10.00'.
ELSEIF iv_amount <= 20000.
rv_rate = '8.00'.
ELSE.
rv_rate = '6.50'.
ENDIF.
ENDMETHOD.
METHOD interest_rate.
rv_rate = base_rate( iv_amount ).
IF iv_segment <> {{p}}if_overdraft=>c_segment_business.
rv_rate = rv_rate - c_business_discount.
IF rv_rate < c_min_rate.
rv_rate = c_min_rate.
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,85 @@
CLASS {{p}}overdraft_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_overdraft.
PRIVATE SECTION.
CONSTANTS:
c_free_days TYPE i VALUE 3,
c_percent_divisor TYPE i VALUE 100,
c_days_per_year TYPE i VALUE 360,
c_business_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '2.00',
c_min_rate TYPE p LENGTH 3 DECIMALS 2 VALUE '5.00'.
TYPES:
ty_rate TYPE p LENGTH 5 DECIMALS 2,
ty_interest TYPE p LENGTH 15 DECIMALS 6.
METHODS chargeable_days
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_days) TYPE i.
METHODS base_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
RETURNING VALUE(rv_rate) TYPE ty_rate.
METHODS interest_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
iv_segment TYPE {{p}}if_overdraft=>ty_segment
RETURNING VALUE(rv_rate) TYPE ty_rate.
ENDCLASS.
CLASS {{p}}overdraft_calc IMPLEMENTATION.
METHOD {{p}}if_overdraft~calculate.
DATA:
lv_days TYPE i,
lv_rate TYPE ty_rate,
lv_annual TYPE ty_interest.
IF iv_amount <= 0 OR iv_days <= 0.
rv_interest = 0.
RETURN.
ENDIF.
lv_days = chargeable_days( iv_days ).
lv_rate = interest_rate( iv_amount = iv_amount
iv_segment = iv_segment ).
lv_annual = iv_amount * lv_rate / c_percent_divisor.
rv_interest = lv_annual * lv_days / c_days_per_year.
IF rv_interest > 0 AND rv_interest < {{p}}if_overdraft=>c_min_interest.
rv_interest = {{p}}if_overdraft=>c_min_interest.
ENDIF.
ENDMETHOD.
METHOD chargeable_days.
rv_days = iv_days - c_free_days.
IF rv_days < 0.
rv_days = 0.
ENDIF.
ENDMETHOD.
METHOD base_rate.
IF iv_amount <= 1000.
rv_rate = '12.00'.
ELSEIF iv_amount <= 5000.
rv_rate = '10.00'.
ELSEIF iv_amount <= 20000.
rv_rate = '8.00'.
ELSE.
rv_rate = '6.50'.
ENDIF.
ENDMETHOD.
METHOD interest_rate.
rv_rate = base_rate( iv_amount ).
IF iv_segment = {{p}}if_overdraft=>c_segment_business.
rv_rate = rv_rate + c_business_discount.
IF rv_rate < c_min_rate.
rv_rate = c_min_rate.
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,33 @@
{
"id": "G0163",
"pool": "eval",
"object_type": "CLAS",
"category": "G",
"attempts": [
{
"stage": "bundle",
"errors": [
"hidden/overdraft_test.clas.abap line 23: syntax error for release v702 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"mo_cut\""
],
"by_check": {
"abaplint": 1
}
},
{
"stage": "validate",
"oracle": 95.5,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 5,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,220 @@
CLASS {{p}}overdraft_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CONSTANTS c_zero TYPE {{p}}if_overdraft=>ty_amount VALUE '0.00'.
DATA mo_cut TYPE REF TO {{p}}if_overdraft.
METHODS setup.
METHODS non_positive_amount FOR TESTING.
METHODS zero_days FOR TESTING.
METHODS grace_days_free FOR TESTING.
METHODS tier_one_rate FOR TESTING.
METHODS tier_two_boundary FOR TESTING.
METHODS tier_three_boundary FOR TESTING.
METHODS tier_four_boundary FOR TESTING.
METHODS business_discount FOR TESTING.
METHODS business_rate_floor FOR TESTING.
METHODS minimum_interest FOR TESTING.
METHODS rounding_half_up FOR TESTING.
ENDCLASS.
CLASS {{p}}overdraft_test IMPLEMENTATION.
METHOD setup.
CREATE OBJECT mo_cut TYPE {{p}}overdraft_calc.
ENDMETHOD.
METHOD non_positive_amount.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '0.00'
iv_days = 30
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = c_zero act = lv_act
msg = 'zero amount' ).
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '-250.00'
iv_days = 30
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = c_zero act = lv_act
msg = 'negative amount' ).
ENDMETHOD.
METHOD zero_days.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '1000.00'
iv_days = 0
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = c_zero act = lv_act ).
ENDMETHOD.
METHOD grace_days_free.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '30000.00'
iv_days = 3
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = c_zero act = lv_act ).
ENDMETHOD.
METHOD tier_one_rate.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '120.00'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '1000.00'
iv_days = 363
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act ).
ENDMETHOD.
METHOD tier_two_boundary.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '100.00'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '1000.01'
iv_days = 363
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act
msg = 'amount above 1000' ).
ENDMETHOD.
METHOD tier_three_boundary.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '400.00'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '5000.01'
iv_days = 363
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act
msg = 'amount above 5000' ).
lv_exp = '1600.00'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '20000.00'
iv_days = 363
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act
msg = 'amount 20000' ).
ENDMETHOD.
METHOD tier_four_boundary.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '1300.00'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '20000.01'
iv_days = 363
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act ).
ENDMETHOD.
METHOD business_discount.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '13.33'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '2000.00'
iv_days = 33
iv_segment = {{p}}if_overdraft=>c_segment_business
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act ).
ENDMETHOD.
METHOD business_rate_floor.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '1500.00'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '30000.00'
iv_days = 363
iv_segment = {{p}}if_overdraft=>c_segment_business
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act ).
ENDMETHOD.
METHOD minimum_interest.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '5.00'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '500.00'
iv_days = 10
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act ).
ENDMETHOD.
METHOD rounding_half_up.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '5.01'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '715.00'
iv_days = 24
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act
msg = 'exact half cent' ).
lv_exp = '67.56'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '1234.56'
iv_days = 200
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act
msg = 'round up' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,72 @@
{
"task": "G0163",
"mutants": [
{
"object": "{{P}}OVERDRAFT_CALC",
"mutant": "line 39: OR -> AND (logic)",
"status": "killed",
"hidden": "10/11",
"failed_tests": [
"NON_POSITIVE_AMOUNT"
]
},
{
"object": "{{P}}OVERDRAFT_CALC",
"mutant": "line 48: * -> / (arith)",
"status": "killed",
"hidden": "4/11",
"failed_tests": [
"BUSINESS_DISCOUNT",
"BUSINESS_RATE_FLOOR",
"ROUNDING_HALF_UP",
"TIER_FOUR_BOUNDARY",
"TIER_ONE_RATE",
"TIER_THREE_BOUNDARY",
"TIER_TWO_BOUNDARY"
]
},
{
"object": "{{P}}OVERDRAFT_CALC",
"mutant": "line 66: <= -> > (rel)",
"status": "killed",
"hidden": "5/11",
"failed_tests": [
"BUSINESS_DISCOUNT",
"BUSINESS_RATE_FLOOR",
"ROUNDING_HALF_UP",
"TIER_FOUR_BOUNDARY",
"TIER_THREE_BOUNDARY",
"TIER_TWO_BOUNDARY"
]
},
{
"object": "{{P}}OVERDRAFT_CALC",
"mutant": "line 78: = -> <> (eq)",
"status": "killed",
"hidden": "4/11",
"failed_tests": [
"BUSINESS_DISCOUNT",
"BUSINESS_RATE_FLOOR",
"ROUNDING_HALF_UP",
"TIER_FOUR_BOUNDARY",
"TIER_ONE_RATE",
"TIER_THREE_BOUNDARY",
"TIER_TWO_BOUNDARY"
]
},
{
"object": "{{P}}OVERDRAFT_CALC",
"mutant": "line 79: - -> + (arith)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"BUSINESS_DISCOUNT",
"BUSINESS_RATE_FLOOR"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,85 @@
CLASS {{p}}overdraft_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_overdraft.
PRIVATE SECTION.
CONSTANTS:
c_free_days TYPE i VALUE 3,
c_percent_divisor TYPE i VALUE 100,
c_days_per_year TYPE i VALUE 360,
c_business_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '2.00',
c_min_rate TYPE p LENGTH 3 DECIMALS 2 VALUE '5.00'.
TYPES:
ty_rate TYPE p LENGTH 5 DECIMALS 2,
ty_interest TYPE p LENGTH 15 DECIMALS 6.
METHODS chargeable_days
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_days) TYPE i.
METHODS base_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
RETURNING VALUE(rv_rate) TYPE ty_rate.
METHODS interest_rate
IMPORTING iv_amount TYPE {{p}}if_overdraft=>ty_amount
iv_segment TYPE {{p}}if_overdraft=>ty_segment
RETURNING VALUE(rv_rate) TYPE ty_rate.
ENDCLASS.
CLASS {{p}}overdraft_calc IMPLEMENTATION.
METHOD {{p}}if_overdraft~calculate.
DATA:
lv_days TYPE i,
lv_rate TYPE ty_rate,
lv_annual TYPE ty_interest.
IF iv_amount <= 0 OR iv_days <= 0.
rv_interest = 0.
RETURN.
ENDIF.
lv_days = chargeable_days( iv_days ).
lv_rate = interest_rate( iv_amount = iv_amount
iv_segment = iv_segment ).
lv_annual = iv_amount * lv_rate / c_percent_divisor.
rv_interest = lv_annual * lv_days / c_days_per_year.
IF rv_interest > 0 AND rv_interest < {{p}}if_overdraft=>c_min_interest.
rv_interest = {{p}}if_overdraft=>c_min_interest.
ENDIF.
ENDMETHOD.
METHOD chargeable_days.
rv_days = iv_days - c_free_days.
IF rv_days < 0.
rv_days = 0.
ENDIF.
ENDMETHOD.
METHOD base_rate.
IF iv_amount <= 1000.
rv_rate = '12.00'.
ELSEIF iv_amount <= 5000.
rv_rate = '10.00'.
ELSEIF iv_amount <= 20000.
rv_rate = '8.00'.
ELSE.
rv_rate = '6.50'.
ENDIF.
ENDMETHOD.
METHOD interest_rate.
rv_rate = base_rate( iv_amount ).
IF iv_segment = {{p}}if_overdraft=>c_segment_business.
rv_rate = rv_rate - c_business_discount.
IF rv_rate < c_min_rate.
rv_rate = c_min_rate.
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,90 @@
CLASS ltc_overdraft_calc DEFINITION FINAL FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CONSTANTS c_zero TYPE {{p}}if_overdraft=>ty_amount VALUE '0.00'.
DATA mo_cut TYPE REF TO {{p}}if_overdraft.
METHODS setup.
METHODS zero_amount FOR TESTING.
METHODS grace_days FOR TESTING.
METHODS private_tier FOR TESTING.
METHODS business_rate FOR TESTING.
METHODS minimum_charge FOR TESTING.
ENDCLASS.
CLASS ltc_overdraft_calc IMPLEMENTATION.
METHOD setup.
CREATE OBJECT mo_cut TYPE {{p}}overdraft_calc.
ENDMETHOD.
METHOD zero_amount.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '0.00'
iv_days = 30
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = c_zero act = lv_act ).
ENDMETHOD.
METHOD grace_days.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '1000.00'
iv_days = 3
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = c_zero act = lv_act ).
ENDMETHOD.
METHOD private_tier.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '10.00'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '1000.00'
iv_days = 33
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act ).
ENDMETHOD.
METHOD business_rate.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '13.33'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '2000.00'
iv_days = 33
iv_segment = {{p}}if_overdraft=>c_segment_business
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act ).
ENDMETHOD.
METHOD minimum_charge.
DATA lv_act TYPE {{p}}if_overdraft=>ty_amount.
DATA lv_exp TYPE {{p}}if_overdraft=>ty_amount.
lv_exp = '5.00'.
CALL METHOD mo_cut->calculate
EXPORTING
iv_amount = '500.00'
iv_days = 10
iv_segment = {{p}}if_overdraft=>c_segment_private
RECEIVING
rv_interest = lv_act.
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_act ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,13 @@
INTERFACE {{p}}if_overdraft PUBLIC.
TYPES ty_amount TYPE p LENGTH 15 DECIMALS 2.
TYPES ty_segment TYPE c LENGTH 1.
CONSTANTS:
c_segment_private TYPE ty_segment VALUE 'P',
c_segment_business TYPE ty_segment VALUE 'B',
c_min_interest TYPE ty_amount VALUE '5.00'.
METHODS calculate
IMPORTING iv_amount TYPE ty_amount
iv_days TYPE i
iv_segment TYPE ty_segment
RETURNING VALUE(rv_interest) TYPE ty_amount.
ENDINTERFACE.

View File

@@ -0,0 +1,62 @@
# 1. Goal
A bank charges interest on the overdrawn part of a current account. The bank
needs one calculation that returns the interest of one account for one period.
# 2. Open questions
None.
# 3. Context
- All objects are in package $TMP.
- The interface {{P}}IF_OVERDRAFT exists in package $TMP. It is active.
- The interface contains the types TY_AMOUNT (packed number, length 15, two
decimals) and TY_SEGMENT (character, length 1), the constants
C_SEGMENT_PRIVATE (value 'P'), C_SEGMENT_BUSINESS (value 'B') and
C_MIN_INTEREST (value 5.00), and one method:
CALCULATE
IMPORTING iv_amount TYPE ty_amount
iv_days TYPE i
iv_segment TYPE ty_segment
RETURNING VALUE(rv_interest) TYPE ty_amount.
# 4. Contract
- Create the class {{P}}OVERDRAFT_CALC in package $TMP.
- The class is public and final. It implements {{P}}IF_OVERDRAFT.
- The class can be created without parameters.
- Do not add other public methods or attributes.
# 5. Business rules
Apply the rules in this sequence.
1. If iv_amount is zero or negative, or if iv_days is zero or negative,
return 0.00.
2. The first three days of the period carry no interest. The chargeable days
are iv_days minus 3. If this value is negative, the chargeable days are 0.
3. The whole amount uses one annual interest rate. The rate depends on the
amount:
- amount up to and including 1,000.00: 12.00 per cent
- amount up to and including 5,000.00: 10.00 per cent
- amount up to and including 20,000.00: 8.00 per cent
- amount above 20,000.00: 6.50 per cent
4. If iv_segment is 'B', subtract 2.00 percentage points from the rate. The
rate never falls below 5.00 per cent. Every other value of iv_segment
leaves the rate unchanged.
5. The interest is the exact value of
amount * (rate / 100) * (chargeable days / 360).
Do not round intermediate results. Round only the final interest to 2
decimals. Round half away from zero.
6. If the rounded interest is greater than 0.00 and less than 5.00, the
interest is 5.00.
7. Return the interest.
# 6. Constraints
- Release target: 7.02. The code must pass the 7.02 syntax check. Do not use
language elements that are newer than release 7.02. Examples of forbidden
elements are inline declarations, constructor expressions and table
expressions.
- Coding standards: Clean ABAP. Methods below 40 statements. No global
variables.
- Out of scope: do not change {{P}}IF_OVERDRAFT.
# 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": "G0163",
"category": "G",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v702",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 40,
"max_activations": 10
},
"seed": [
{
"type": "INTF",
"name": "{{P}}IF_OVERDRAFT",
"file": "seed/if_overdraft.intf.abap",
"description": "Overdraft interest contract"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}OVERDRAFT_CALC",
"implements": "{{P}}IF_OVERDRAFT"
}
],
"out_of_scope": [
"{{P}}IF_OVERDRAFT"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}OVERDRAFT_TEST",
"file": "hidden/overdraft_test.clas.abap",
"description": "Hidden tests for the overdraft interest calculation"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}OVERDRAFT_CALC",
"file": "reference/overdraft_calc.clas.abap",
"description": "Calculates the overdraft interest of a current account",
"testclasses_file": "reference/overdraft_calc.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"no_newer_syntax"
]
}