Stage 2 summary at 50 accepted trajectories

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

View File

@@ -0,0 +1,87 @@
CLASS {{p}}water_bill DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate
IMPORTING iv_consumption TYPE i
iv_days TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
PRIVATE SECTION.
DATA mo_tariff TYPE REF TO {{p}}water_tariff.
METHODS consumption_charge
IMPORTING iv_consumption TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS sewage_charge
IMPORTING iv_consumption_charge TYPE ty_amount
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS standing_charge
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS tier_charge
IMPORTING iv_from TYPE i
iv_to TYPE i
iv_price TYPE {{p}}water_tariff=>ty_price
RETURNING VALUE(rv_charge) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}water_bill IMPLEMENTATION.
METHOD constructor.
mo_tariff = NEW {{p}}water_tariff( ).
ENDMETHOD.
METHOD calculate.
DATA(lv_consumption_charge) = consumption_charge( iv_consumption ).
DATA lv_net TYPE ty_amount.
lv_net = lv_consumption_charge
+ sewage_charge( lv_consumption_charge )
- standing_charge( iv_days ).
DATA(lv_minimum) = mo_tariff->get_minimum_charge( ).
IF lv_net < lv_minimum.
rv_amount = lv_minimum.
ELSE.
rv_amount = lv_net.
ENDIF.
ENDMETHOD.
METHOD consumption_charge.
DATA(lt_tiers) = mo_tariff->get_tiers( ).
DATA lv_from TYPE i.
LOOP AT lt_tiers INTO DATA(ls_tier).
DATA(lv_to) = COND i( WHEN ls_tier-limit_cbm = 0 OR ls_tier-limit_cbm > iv_consumption
THEN iv_consumption
ELSE ls_tier-limit_cbm ).
rv_charge = rv_charge + tier_charge( iv_from = lv_from
iv_to = lv_to
iv_price = ls_tier-price_cbm ).
lv_from = lv_to.
IF lv_from >= iv_consumption.
EXIT.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD sewage_charge.
DATA lv_product TYPE p LENGTH 16 DECIMALS 4.
lv_product = iv_consumption_charge * mo_tariff->get_sewage_percent( ).
rv_charge = lv_product / 100.
ENDMETHOD.
METHOD standing_charge.
rv_charge = iv_days * mo_tariff->get_standing_charge( ).
ENDMETHOD.
METHOD tier_charge.
DATA(lv_units) = iv_to - iv_from.
IF lv_units > 0.
rv_charge = lv_units * iv_price.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,87 @@
CLASS {{p}}water_bill DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate
IMPORTING iv_consumption TYPE i
iv_days TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
PRIVATE SECTION.
DATA mo_tariff TYPE REF TO {{p}}water_tariff.
METHODS consumption_charge
IMPORTING iv_consumption TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS sewage_charge
IMPORTING iv_consumption_charge TYPE ty_amount
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS standing_charge
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS tier_charge
IMPORTING iv_from TYPE i
iv_to TYPE i
iv_price TYPE {{p}}water_tariff=>ty_price
RETURNING VALUE(rv_charge) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}water_bill IMPLEMENTATION.
METHOD constructor.
mo_tariff = NEW {{p}}water_tariff( ).
ENDMETHOD.
METHOD calculate.
DATA(lv_consumption_charge) = consumption_charge( iv_consumption ).
DATA lv_net TYPE ty_amount.
lv_net = lv_consumption_charge
+ sewage_charge( lv_consumption_charge )
+ standing_charge( iv_days ).
DATA(lv_minimum) = mo_tariff->get_minimum_charge( ).
IF lv_net >= lv_minimum.
rv_amount = lv_minimum.
ELSE.
rv_amount = lv_net.
ENDIF.
ENDMETHOD.
METHOD consumption_charge.
DATA(lt_tiers) = mo_tariff->get_tiers( ).
DATA lv_from TYPE i.
LOOP AT lt_tiers INTO DATA(ls_tier).
DATA(lv_to) = COND i( WHEN ls_tier-limit_cbm = 0 OR ls_tier-limit_cbm > iv_consumption
THEN iv_consumption
ELSE ls_tier-limit_cbm ).
rv_charge = rv_charge + tier_charge( iv_from = lv_from
iv_to = lv_to
iv_price = ls_tier-price_cbm ).
lv_from = lv_to.
IF lv_from >= iv_consumption.
EXIT.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD sewage_charge.
DATA lv_product TYPE p LENGTH 16 DECIMALS 4.
lv_product = iv_consumption_charge * mo_tariff->get_sewage_percent( ).
rv_charge = lv_product / 100.
ENDMETHOD.
METHOD standing_charge.
rv_charge = iv_days * mo_tariff->get_standing_charge( ).
ENDMETHOD.
METHOD tier_charge.
DATA(lv_units) = iv_to - iv_from.
IF lv_units > 0.
rv_charge = lv_units * iv_price.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,87 @@
CLASS {{p}}water_bill DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate
IMPORTING iv_consumption TYPE i
iv_days TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
PRIVATE SECTION.
DATA mo_tariff TYPE REF TO {{p}}water_tariff.
METHODS consumption_charge
IMPORTING iv_consumption TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS sewage_charge
IMPORTING iv_consumption_charge TYPE ty_amount
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS standing_charge
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS tier_charge
IMPORTING iv_from TYPE i
iv_to TYPE i
iv_price TYPE {{p}}water_tariff=>ty_price
RETURNING VALUE(rv_charge) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}water_bill IMPLEMENTATION.
METHOD constructor.
mo_tariff = NEW {{p}}water_tariff( ).
ENDMETHOD.
METHOD calculate.
DATA(lv_consumption_charge) = consumption_charge( iv_consumption ).
DATA lv_net TYPE ty_amount.
lv_net = lv_consumption_charge
+ sewage_charge( lv_consumption_charge )
+ standing_charge( iv_days ).
DATA(lv_minimum) = mo_tariff->get_minimum_charge( ).
IF lv_net < lv_minimum.
rv_amount = lv_minimum.
ELSE.
rv_amount = lv_net.
ENDIF.
ENDMETHOD.
METHOD consumption_charge.
DATA(lt_tiers) = mo_tariff->get_tiers( ).
DATA lv_from TYPE i.
LOOP AT lt_tiers INTO DATA(ls_tier).
DATA(lv_to) = COND i( WHEN ls_tier-limit_cbm = 0 OR ls_tier-limit_cbm > iv_consumption
THEN iv_consumption
ELSE ls_tier-limit_cbm ).
rv_charge = rv_charge - tier_charge( iv_from = lv_from
iv_to = lv_to
iv_price = ls_tier-price_cbm ).
lv_from = lv_to.
IF lv_from >= iv_consumption.
EXIT.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD sewage_charge.
DATA lv_product TYPE p LENGTH 16 DECIMALS 4.
lv_product = iv_consumption_charge * mo_tariff->get_sewage_percent( ).
rv_charge = lv_product / 100.
ENDMETHOD.
METHOD standing_charge.
rv_charge = iv_days * mo_tariff->get_standing_charge( ).
ENDMETHOD.
METHOD tier_charge.
DATA(lv_units) = iv_to - iv_from.
IF lv_units > 0.
rv_charge = lv_units * iv_price.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,87 @@
CLASS {{p}}water_bill DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate
IMPORTING iv_consumption TYPE i
iv_days TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
PRIVATE SECTION.
DATA mo_tariff TYPE REF TO {{p}}water_tariff.
METHODS consumption_charge
IMPORTING iv_consumption TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS sewage_charge
IMPORTING iv_consumption_charge TYPE ty_amount
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS standing_charge
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS tier_charge
IMPORTING iv_from TYPE i
iv_to TYPE i
iv_price TYPE {{p}}water_tariff=>ty_price
RETURNING VALUE(rv_charge) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}water_bill IMPLEMENTATION.
METHOD constructor.
mo_tariff = NEW {{p}}water_tariff( ).
ENDMETHOD.
METHOD calculate.
DATA(lv_consumption_charge) = consumption_charge( iv_consumption ).
DATA lv_net TYPE ty_amount.
lv_net = lv_consumption_charge
+ sewage_charge( lv_consumption_charge )
+ standing_charge( iv_days ).
DATA(lv_minimum) = mo_tariff->get_minimum_charge( ).
IF lv_net < lv_minimum.
rv_amount = lv_minimum.
ELSE.
rv_amount = lv_net.
ENDIF.
ENDMETHOD.
METHOD consumption_charge.
DATA(lt_tiers) = mo_tariff->get_tiers( ).
DATA lv_from TYPE i.
LOOP AT lt_tiers INTO DATA(ls_tier).
DATA(lv_to) = COND i( WHEN ls_tier-limit_cbm = 0 OR ls_tier-limit_cbm > iv_consumption
THEN iv_consumption
ELSE ls_tier-limit_cbm ).
rv_charge = rv_charge + tier_charge( iv_from = lv_from
iv_to = lv_to
iv_price = ls_tier-price_cbm ).
lv_from = lv_to.
IF lv_from >= iv_consumption.
EXIT.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD sewage_charge.
DATA lv_product TYPE p LENGTH 16 DECIMALS 4.
lv_product = iv_consumption_charge * mo_tariff->get_sewage_percent( ).
rv_charge = lv_product / 100.
ENDMETHOD.
METHOD standing_charge.
rv_charge = iv_days / mo_tariff->get_standing_charge( ).
ENDMETHOD.
METHOD tier_charge.
DATA(lv_units) = iv_to - iv_from.
IF lv_units > 0.
rv_charge = lv_units * iv_price.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,87 @@
CLASS {{p}}water_bill DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate
IMPORTING iv_consumption TYPE i
iv_days TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
PRIVATE SECTION.
DATA mo_tariff TYPE REF TO {{p}}water_tariff.
METHODS consumption_charge
IMPORTING iv_consumption TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS sewage_charge
IMPORTING iv_consumption_charge TYPE ty_amount
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS standing_charge
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS tier_charge
IMPORTING iv_from TYPE i
iv_to TYPE i
iv_price TYPE {{p}}water_tariff=>ty_price
RETURNING VALUE(rv_charge) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}water_bill IMPLEMENTATION.
METHOD constructor.
mo_tariff = NEW {{p}}water_tariff( ).
ENDMETHOD.
METHOD calculate.
DATA(lv_consumption_charge) = consumption_charge( iv_consumption ).
DATA lv_net TYPE ty_amount.
lv_net = lv_consumption_charge
+ sewage_charge( lv_consumption_charge )
+ standing_charge( iv_days ).
DATA(lv_minimum) = mo_tariff->get_minimum_charge( ).
IF lv_net < lv_minimum.
rv_amount = lv_minimum.
ELSE.
rv_amount = lv_net.
ENDIF.
ENDMETHOD.
METHOD consumption_charge.
DATA(lt_tiers) = mo_tariff->get_tiers( ).
DATA lv_from TYPE i.
LOOP AT lt_tiers INTO DATA(ls_tier).
DATA(lv_to) = COND i( WHEN ls_tier-limit_cbm = 0 OR ls_tier-limit_cbm > iv_consumption
THEN iv_consumption
ELSE ls_tier-limit_cbm ).
rv_charge = rv_charge + tier_charge( iv_from = lv_from
iv_to = lv_to
iv_price = ls_tier-price_cbm ).
lv_from = lv_to.
IF lv_from >= iv_consumption.
EXIT.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD sewage_charge.
DATA lv_product TYPE p LENGTH 16 DECIMALS 4.
lv_product = iv_consumption_charge * mo_tariff->get_sewage_percent( ).
rv_charge = lv_product / 100.
ENDMETHOD.
METHOD standing_charge.
rv_charge = iv_days * mo_tariff->get_standing_charge( ).
ENDMETHOD.
METHOD tier_charge.
DATA(lv_units) = iv_to - iv_from.
IF lv_units <= 0.
rv_charge = lv_units * iv_price.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

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

View File

@@ -0,0 +1,76 @@
CLASS {{p}}water_bill_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
DATA mo_cut TYPE REF TO {{p}}water_bill.
METHODS setup.
METHODS assert_bill
IMPORTING iv_consumption TYPE i
iv_days TYPE i
iv_expected TYPE ty_amount.
METHODS zero_consumption FOR TESTING.
METHODS first_tier_only FOR TESTING.
METHODS second_tier FOR TESTING.
METHODS tier_boundary_50 FOR TESTING.
METHODS third_tier FOR TESTING.
METHODS sewage_rounding FOR TESTING.
METHODS standing_charge_only FOR TESTING.
METHODS below_minimum FOR TESTING.
METHODS large_consumption FOR TESTING.
ENDCLASS.
CLASS {{p}}water_bill_test IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}water_bill( ).
ENDMETHOD.
METHOD assert_bill.
DATA(lv_actual) = CONV ty_amount( mo_cut->calculate( iv_consumption = iv_consumption
iv_days = iv_days ) ).
cl_abap_unit_assert=>assert_equals(
exp = iv_expected
act = lv_actual
msg = |consumption { iv_consumption } cbm, { iv_days } days| ).
ENDMETHOD.
METHOD zero_consumption.
assert_bill( iv_consumption = 0 iv_days = 30 iv_expected = '35.00' ).
ENDMETHOD.
METHOD first_tier_only.
assert_bill( iv_consumption = 20 iv_days = 1 iv_expected = '68.91' ).
ENDMETHOD.
METHOD second_tier.
assert_bill( iv_consumption = 30 iv_days = 1 iv_expected = '114.55' ).
ENDMETHOD.
METHOD tier_boundary_50.
assert_bill( iv_consumption = 50 iv_days = 1 iv_expected = '205.83' ).
ENDMETHOD.
METHOD third_tier.
assert_bill( iv_consumption = 60 iv_days = 1 iv_expected = '264.51' ).
ENDMETHOD.
METHOD sewage_rounding.
assert_bill( iv_consumption = 22 iv_days = 1 iv_expected = '78.04' ).
ENDMETHOD.
METHOD standing_charge_only.
assert_bill( iv_consumption = 0 iv_days = 100 iv_expected = '45.00' ).
ENDMETHOD.
METHOD below_minimum.
assert_bill( iv_consumption = 4 iv_days = 30 iv_expected = '35.00' ).
ENDMETHOD.
METHOD large_consumption.
assert_bill( iv_consumption = 120 iv_days = 90 iv_expected = '656.64' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,86 @@
{
"task": "G1077",
"mutants": [
{
"object": "{{P}}WATER_BILL",
"mutant": "line 45: + -> - (arith)",
"status": "killed",
"hidden": "2/9",
"failed_tests": [
"FIRST_TIER_ONLY",
"LARGE_CONSUMPTION",
"SECOND_TIER",
"SEWAGE_ROUNDING",
"STANDING_CHARGE_ONLY",
"THIRD_TIER",
"TIER_BOUNDARY_50"
]
},
{
"object": "{{P}}WATER_BILL",
"mutant": "line 47: < -> >= (rel)",
"status": "killed",
"hidden": "0/9",
"failed_tests": [
"BELOW_MINIMUM",
"FIRST_TIER_ONLY",
"LARGE_CONSUMPTION",
"SECOND_TIER",
"SEWAGE_ROUNDING",
"STANDING_CHARGE_ONLY",
"THIRD_TIER",
"TIER_BOUNDARY_50",
"ZERO_CONSUMPTION"
]
},
{
"object": "{{P}}WATER_BILL",
"mutant": "line 61: + -> - (arith)",
"status": "killed",
"hidden": "3/9",
"failed_tests": [
"FIRST_TIER_ONLY",
"LARGE_CONSUMPTION",
"SECOND_TIER",
"SEWAGE_ROUNDING",
"THIRD_TIER",
"TIER_BOUNDARY_50"
]
},
{
"object": "{{P}}WATER_BILL",
"mutant": "line 78: * -> / (arith)",
"status": "killed",
"hidden": "0/9",
"failed_tests": [
"BELOW_MINIMUM",
"FIRST_TIER_ONLY",
"LARGE_CONSUMPTION",
"SECOND_TIER",
"SEWAGE_ROUNDING",
"STANDING_CHARGE_ONLY",
"THIRD_TIER",
"TIER_BOUNDARY_50",
"ZERO_CONSUMPTION"
]
},
{
"object": "{{P}}WATER_BILL",
"mutant": "line 83: > -> <= (rel)",
"status": "killed",
"hidden": "3/9",
"failed_tests": [
"FIRST_TIER_ONLY",
"LARGE_CONSUMPTION",
"SECOND_TIER",
"SEWAGE_ROUNDING",
"THIRD_TIER",
"TIER_BOUNDARY_50"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,87 @@
CLASS {{p}}water_bill DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate
IMPORTING iv_consumption TYPE i
iv_days TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
PRIVATE SECTION.
DATA mo_tariff TYPE REF TO {{p}}water_tariff.
METHODS consumption_charge
IMPORTING iv_consumption TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS sewage_charge
IMPORTING iv_consumption_charge TYPE ty_amount
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS standing_charge
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_charge) TYPE ty_amount.
METHODS tier_charge
IMPORTING iv_from TYPE i
iv_to TYPE i
iv_price TYPE {{p}}water_tariff=>ty_price
RETURNING VALUE(rv_charge) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}water_bill IMPLEMENTATION.
METHOD constructor.
mo_tariff = NEW {{p}}water_tariff( ).
ENDMETHOD.
METHOD calculate.
DATA(lv_consumption_charge) = consumption_charge( iv_consumption ).
DATA lv_net TYPE ty_amount.
lv_net = lv_consumption_charge
+ sewage_charge( lv_consumption_charge )
+ standing_charge( iv_days ).
DATA(lv_minimum) = mo_tariff->get_minimum_charge( ).
IF lv_net < lv_minimum.
rv_amount = lv_minimum.
ELSE.
rv_amount = lv_net.
ENDIF.
ENDMETHOD.
METHOD consumption_charge.
DATA(lt_tiers) = mo_tariff->get_tiers( ).
DATA lv_from TYPE i.
LOOP AT lt_tiers INTO DATA(ls_tier).
DATA(lv_to) = COND i( WHEN ls_tier-limit_cbm = 0 OR ls_tier-limit_cbm > iv_consumption
THEN iv_consumption
ELSE ls_tier-limit_cbm ).
rv_charge = rv_charge + tier_charge( iv_from = lv_from
iv_to = lv_to
iv_price = ls_tier-price_cbm ).
lv_from = lv_to.
IF lv_from >= iv_consumption.
EXIT.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD sewage_charge.
DATA lv_product TYPE p LENGTH 16 DECIMALS 4.
lv_product = iv_consumption_charge * mo_tariff->get_sewage_percent( ).
rv_charge = lv_product / 100.
ENDMETHOD.
METHOD standing_charge.
rv_charge = iv_days * mo_tariff->get_standing_charge( ).
ENDMETHOD.
METHOD tier_charge.
DATA(lv_units) = iv_to - iv_from.
IF lv_units > 0.
rv_charge = lv_units * iv_price.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,51 @@
CLASS ltc_water_bill DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
DATA mo_cut TYPE REF TO {{p}}water_bill.
METHODS setup.
METHODS assert_bill
IMPORTING iv_consumption TYPE i
iv_days TYPE i
iv_expected TYPE ty_amount.
METHODS first_tier_only FOR TESTING.
METHODS third_tier FOR TESTING.
METHODS minimum_charge FOR TESTING.
METHODS standing_charge_only FOR TESTING.
METHODS sewage_is_rounded FOR TESTING.
ENDCLASS.
CLASS ltc_water_bill IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}water_bill( ).
ENDMETHOD.
METHOD assert_bill.
DATA(lv_actual) = CONV ty_amount( mo_cut->calculate( iv_consumption = iv_consumption
iv_days = iv_days ) ).
cl_abap_unit_assert=>assert_equals( exp = iv_expected act = lv_actual ).
ENDMETHOD.
METHOD first_tier_only.
assert_bill( iv_consumption = 20 iv_days = 1 iv_expected = '68.91' ).
ENDMETHOD.
METHOD third_tier.
assert_bill( iv_consumption = 60 iv_days = 1 iv_expected = '264.51' ).
ENDMETHOD.
METHOD minimum_charge.
assert_bill( iv_consumption = 4 iv_days = 30 iv_expected = '35.00' ).
ENDMETHOD.
METHOD standing_charge_only.
assert_bill( iv_consumption = 0 iv_days = 100 iv_expected = '45.00' ).
ENDMETHOD.
METHOD sewage_is_rounded.
assert_bill( iv_consumption = 22 iv_days = 1 iv_expected = '78.04' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,44 @@
CLASS {{p}}water_tariff DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_price TYPE p LENGTH 8 DECIMALS 2.
TYPES:
BEGIN OF ty_tier,
limit_cbm TYPE i,
price_cbm TYPE ty_price,
END OF ty_tier,
tt_tiers TYPE STANDARD TABLE OF ty_tier WITH EMPTY KEY.
METHODS get_tiers
RETURNING VALUE(rt_tiers) TYPE tt_tiers.
METHODS get_standing_charge
RETURNING VALUE(rv_charge) TYPE ty_price.
METHODS get_sewage_percent
RETURNING VALUE(rv_percent) TYPE ty_price.
METHODS get_minimum_charge
RETURNING VALUE(rv_charge) TYPE ty_price.
ENDCLASS.
CLASS {{p}}water_tariff IMPLEMENTATION.
METHOD get_tiers.
rt_tiers = VALUE #( ( limit_cbm = 20 price_cbm = '2.10' )
( limit_cbm = 50 price_cbm = '2.80' )
( limit_cbm = 0 price_cbm = '3.60' ) ).
ENDMETHOD.
METHOD get_standing_charge.
rv_charge = '0.45'.
ENDMETHOD.
METHOD get_sewage_percent.
rv_percent = '63.00'.
ENDMETHOD.
METHOD get_minimum_charge.
rv_charge = '35.00'.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,62 @@
# 1. Goal
A water utility bills a household for one quarter. The billing program calls the
class {{P}}WATER_BILL for each meter reading. The class calculates the amount of
the bill in euro.
# 2. Open questions
None.
# 3. Context
- The class {{P}}WATER_TARIFF exists in package $TMP. It is active. It gives the
tariff data of the utility. Read its definition before you start.
- The tariff data contains a list of price tiers, the standing charge for one
day, the sewage percentage, and the minimum charge.
- All objects are in package $TMP.
# 4. Contract
- Create the class {{P}}WATER_BILL in package $TMP.
- The class is public and final. It has a public constructor without parameters.
- The class has the public type TY_AMOUNT. TY_AMOUNT is a packed number with
two decimal places.
- The class has this public method and no other public method:
calculate
IMPORTING iv_consumption TYPE i
iv_days TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
- iv_consumption is the consumption of the household in cubic metres.
- iv_days is the number of days of the billing period.
# 5. Business rules
Use the values of the tariff in {{P}}WATER_TARIFF.
1. Consumption charge:
- The tariff gives the price tiers in ascending order.
- The tiers are cumulative. The upper limit of a tier is a total consumption,
not the width of the tier.
- A tier covers the consumption up to its upper limit.
- The tier with the upper limit 0 is the last tier. It covers all the
consumption above the upper limit of the previous tier.
- Multiply the consumption of each tier by the price of that tier.
- The consumption charge is the sum of these products.
2. Sewage charge: it is the sewage percentage of the consumption charge. The
sewage percentage is a number of percent (50 means 50 percent). Round the
sewage charge to two decimal places.
3. Standing charge: it is the number of days multiplied by the standing charge
of the tariff for one day.
4. The net amount is the consumption charge plus the sewage charge plus the
standing charge.
5. If the net amount is below the minimum charge of the tariff, the amount of
the bill is the minimum charge.
6. Else the amount of the bill is the net amount.
7. The amount of the bill has two decimal places.
# 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. Pass large parameters by
reference.
- Out of scope: do not change {{P}}WATER_TARIFF.
# 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,50 @@
{
"id": "G1077",
"category": "F",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 80,
"max_activations": 20
},
"seed": [
{
"type": "CLAS",
"name": "{{P}}WATER_TARIFF",
"file": "seed/water_tariff.clas.abap",
"description": "Tariff provider of the water utility"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}WATER_BILL"
}
],
"out_of_scope": [
"{{P}}WATER_TARIFF"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}WATER_BILL_TEST",
"file": "hidden/water_bill_test.clas.abap",
"description": "Hidden tests for the water bill calculation"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}WATER_BILL",
"file": "reference/water_bill.clas.abap",
"description": "Water bill calculator",
"testclasses_file": "reference/water_bill.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"db_operation_in_loop"
]
}