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,45 @@
{
"id": "G0144",
"pool": "eval",
"object_type": "FUNC",
"category": "E",
"attempts": [
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "bundle",
"errors": [
"category E: 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": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "revalidate",
"by": "harness fix 2026-10-03",
"change": "ADT activation fallback for a second FUNC write. Bundle not changed.",
"oracle": 0,
"null": 0,
"mutation": {
"valid": 0,
"killed": 0,
"ok": false
}
}
],
"accepted": false
}

View File

@@ -1,135 +0,0 @@
CLASS {{p}}cine_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CONSTANTS: c_evening TYPE t VALUE '200000',
c_matinee TYPE t VALUE '160000',
c_boundary TYPE t VALUE '170000',
c_morning TYPE t VALUE '100000'.
METHODS call_fee
IMPORTING iv_show TYPE string
iv_seats TYPE i
iv_time TYPE t
iv_cust TYPE string
EXPORTING ev_total TYPE decfloat34
ev_disc TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS base_price_2d FOR TESTING.
METHODS base_prices_3d_imax FOR TESTING.
METHODS invalid_seats FOR TESTING.
METHODS invalid_show_type FOR TESTING.
METHODS invalid_cust_type FOR TESTING.
METHODS matinee_discount FOR TESTING.
METHODS matinee_boundary FOR TESTING.
METHODS child_skips_matinee FOR TESTING.
METHODS group_threshold FOR TESTING.
METHODS discount_cap FOR TESTING.
METHODS rounding_half_up FOR TESTING.
ENDCLASS.
CLASS {{p}}cine_hidden IMPLEMENTATION.
METHOD call_fee.
ev_total = 0.
ev_disc = 0.
CALL FUNCTION '{{P}}CINE_FEE_OLD'
EXPORTING
iv_show_type = iv_show
iv_seats = iv_seats
iv_show_time = iv_time
iv_cust_type = iv_cust
IMPORTING
ev_total = ev_total
ev_discount = ev_disc
EXCEPTIONS
invalid_input = 1
OTHERS = 2.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD base_price_2d.
call_fee( EXPORTING iv_show = `2D` iv_seats = 1 iv_time = c_evening iv_cust = `ADULT`
IMPORTING ev_total = DATA(lv_total) ev_disc = DATA(lv_disc) ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_rc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '9.50' ) act = lv_total ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_disc ).
ENDMETHOD.
METHOD base_prices_3d_imax.
call_fee( EXPORTING iv_show = `3D` iv_seats = 1 iv_time = c_evening iv_cust = `ADULT`
IMPORTING ev_total = DATA(lv_total) ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_rc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '13.00' ) act = lv_total ).
call_fee( EXPORTING iv_show = `IMAX` iv_seats = 1 iv_time = c_evening iv_cust = `ADULT`
IMPORTING ev_total = DATA(lv_total2) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '16.50' ) act = lv_total2 ).
ENDMETHOD.
METHOD invalid_seats.
call_fee( EXPORTING iv_show = `2D` iv_seats = 0 iv_time = c_evening iv_cust = `ADULT`
IMPORTING ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc ).
ENDMETHOD.
METHOD invalid_show_type.
call_fee( EXPORTING iv_show = `XX` iv_seats = 1 iv_time = c_evening iv_cust = `ADULT`
IMPORTING ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc ).
ENDMETHOD.
METHOD invalid_cust_type.
call_fee( EXPORTING iv_show = `2D` iv_seats = 1 iv_time = c_evening iv_cust = `VIP`
IMPORTING ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc ).
ENDMETHOD.
METHOD matinee_discount.
call_fee( EXPORTING iv_show = `2D` iv_seats = 1 iv_time = c_matinee iv_cust = `ADULT`
IMPORTING ev_total = DATA(lv_total) ev_disc = DATA(lv_disc) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '7.25' ) act = lv_total ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 25 ) act = lv_disc ).
ENDMETHOD.
METHOD matinee_boundary.
call_fee( EXPORTING iv_show = `2D` iv_seats = 1 iv_time = c_boundary iv_cust = `ADULT`
IMPORTING ev_total = DATA(lv_total) ev_disc = DATA(lv_disc) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '9.50' ) act = lv_total ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_disc ).
ENDMETHOD.
METHOD child_skips_matinee.
call_fee( EXPORTING iv_show = `2D` iv_seats = 1 iv_time = c_morning iv_cust = `CHILD`
IMPORTING ev_total = DATA(lv_total) ev_disc = DATA(lv_disc) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '5.90' ) act = lv_total ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 40 ) act = lv_disc ).
ENDMETHOD.
METHOD group_threshold.
call_fee( EXPORTING iv_show = `2D` iv_seats = 7 iv_time = c_evening iv_cust = `ADULT`
IMPORTING ev_total = DATA(lv_total) ev_disc = DATA(lv_disc) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '66.50' ) act = lv_total ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_disc ).
call_fee( EXPORTING iv_show = `2D` iv_seats = 8 iv_time = c_evening iv_cust = `ADULT`
IMPORTING ev_total = DATA(lv_total2) ev_disc = DATA(lv_disc2) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '68.80' ) act = lv_total2 ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 10 ) act = lv_disc2 ).
ENDMETHOD.
METHOD discount_cap.
call_fee( EXPORTING iv_show = `2D` iv_seats = 8 iv_time = c_morning iv_cust = `SENIOR`
IMPORTING ev_total = DATA(lv_total) ev_disc = DATA(lv_disc) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '32.80' ) act = lv_total ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 60 ) act = lv_disc ).
ENDMETHOD.
METHOD rounding_half_up.
call_fee( EXPORTING iv_show = `3D` iv_seats = 3 iv_time = c_matinee iv_cust = `ADULT`
IMPORTING ev_total = DATA(lv_total) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '29.63' ) act = lv_total ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,102 @@
CLASS {{p}}t_ski_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS call
IMPORTING iv_equipment TYPE string
iv_days TYPE i
iv_customer TYPE string
iv_insurance TYPE abap_bool
EXPORTING ev_price TYPE decfloat34
ev_deposit TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS invalid_days FOR TESTING.
METHODS invalid_equipment FOR TESTING.
METHODS invalid_customer FOR TESTING.
METHODS adult_ski_one_day FOR TESTING.
METHODS child_boots_two_days FOR TESTING.
METHODS senior_snowboard_3d FOR TESTING.
METHODS adult_ski_7d_insurance FOR TESTING.
METHODS child_helmet_10d_ins FOR TESTING.
METHODS rounding_case FOR TESTING.
ENDCLASS.
CLASS {{p}}t_ski_hidden IMPLEMENTATION.
METHOD call.
CALL FUNCTION '{{P}}SKI_RENTAL_OLD'
EXPORTING
iv_equipment = iv_equipment
iv_days = iv_days
iv_customer = iv_customer
iv_insurance = iv_insurance
IMPORTING
ev_price = ev_price
ev_deposit = ev_deposit
EXCEPTIONS
invalid_equipment = 1
invalid_days = 2
invalid_customer = 3
OTHERS = 4.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD invalid_days.
call( EXPORTING iv_equipment = 'SKI' iv_days = 0 iv_customer = 'ADULT' iv_insurance = abap_false
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_subrc ).
ENDMETHOD.
METHOD invalid_equipment.
call( EXPORTING iv_equipment = 'X' iv_days = 1 iv_customer = 'ADULT' iv_insurance = abap_false
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_subrc ).
ENDMETHOD.
METHOD invalid_customer.
call( EXPORTING iv_equipment = 'SKI' iv_days = 1 iv_customer = 'X' iv_insurance = abap_false
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lv_subrc ).
ENDMETHOD.
METHOD adult_ski_one_day.
call( EXPORTING iv_equipment = 'SKI' iv_days = 1 iv_customer = 'ADULT' iv_insurance = abap_false
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 25 ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 100 ) act = lv_deposit ).
ENDMETHOD.
METHOD child_boots_two_days.
call( EXPORTING iv_equipment = 'BOOTS' iv_days = 2 iv_customer = 'CHILD' iv_insurance = abap_false
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 10 ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 20 ) act = lv_deposit ).
ENDMETHOD.
METHOD senior_snowboard_3d.
call( EXPORTING iv_equipment = 'SNOWBOARD' iv_days = 3 iv_customer = 'SENIOR' iv_insurance = abap_false
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '68.40' ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 120 ) act = lv_deposit ).
ENDMETHOD.
METHOD adult_ski_7d_insurance.
call( EXPORTING iv_equipment = 'SKI' iv_days = 7 iv_customer = 'ADULT' iv_insurance = abap_true
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '192.50' ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 150 ) act = lv_deposit ).
ENDMETHOD.
METHOD child_helmet_10d_ins.
call( EXPORTING iv_equipment = 'HELMET' iv_days = 10 iv_customer = 'CHILD' iv_insurance = abap_true
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '72.50' ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 60 ) act = lv_deposit ).
ENDMETHOD.
METHOD rounding_case.
call( EXPORTING iv_equipment = 'SKI' iv_days = 3 iv_customer = 'CHILD' iv_insurance = abap_false
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '35.63' ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 100 ) act = lv_deposit ).
ENDMETHOD.
ENDCLASS.

View File

@@ -1,77 +0,0 @@
FUNCTION {{p}}cine_fee_old
IMPORTING
iv_show_type TYPE string
iv_seats TYPE i
iv_show_time TYPE t
iv_cust_type TYPE string
EXPORTING
ev_total TYPE decfloat34
ev_discount TYPE decfloat34
EXCEPTIONS
invalid_input.
CONSTANTS:
c_price_2d TYPE decfloat34 VALUE '9.00',
c_price_3d TYPE decfloat34 VALUE '12.50',
c_price_imax TYPE decfloat34 VALUE '16.00',
c_booking_fee TYPE decfloat34 VALUE '0.50',
c_percent TYPE decfloat34 VALUE 100,
c_disc_child TYPE decfloat34 VALUE 40,
c_disc_senior TYPE decfloat34 VALUE 30,
c_disc_student TYPE decfloat34 VALUE 20,
c_disc_matinee TYPE decfloat34 VALUE 25,
c_disc_group TYPE decfloat34 VALUE 10,
c_disc_max TYPE decfloat34 VALUE 60,
c_group_seats TYPE i VALUE 8,
c_matinee_end TYPE t VALUE '170000'.
DATA: lv_base TYPE decfloat34,
lv_discount TYPE decfloat34,
lv_price TYPE decfloat34.
IF iv_seats < 1.
RAISE invalid_input.
ENDIF.
CASE iv_show_type.
WHEN '2D'.
lv_base = c_price_2d.
WHEN '3D'.
lv_base = c_price_3d.
WHEN 'IMAX'.
lv_base = c_price_imax.
WHEN OTHERS.
RAISE invalid_input.
ENDCASE.
CASE iv_cust_type.
WHEN 'CHILD'.
lv_discount = c_disc_child.
WHEN 'SENIOR'.
lv_discount = c_disc_senior.
WHEN 'STUDENT'.
lv_discount = c_disc_student.
WHEN 'ADULT'.
lv_discount = 0.
WHEN OTHERS.
RAISE invalid_input.
ENDCASE.
IF iv_show_time < c_matinee_end AND iv_cust_type <> 'CHILD'.
lv_discount = lv_discount + c_disc_matinee.
ENDIF.
IF iv_seats >= c_group_seats.
lv_discount = lv_discount + c_disc_group.
ENDIF.
IF lv_discount > c_disc_max.
lv_discount = c_disc_max.
ENDIF.
lv_price = lv_base - lv_base * lv_discount / c_percent + c_booking_fee.
ev_total = round( val = lv_price * iv_seats dec = 2 mode = cl_abap_math=>round_half_up ).
ev_discount = lv_discount.
ENDFUNCTION.

View File

@@ -1,72 +0,0 @@
CLASS {{p}}cine_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CONSTANTS: c_evening TYPE t VALUE '200000',
c_matinee TYPE t VALUE '160000'.
METHODS fee
IMPORTING iv_show TYPE string
iv_seats TYPE i
iv_time TYPE t
iv_cust TYPE string
RETURNING VALUE(rv_total) TYPE decfloat34.
METHODS adult_evening FOR TESTING.
METHODS matinee_discount FOR TESTING.
METHODS child_price FOR TESTING.
METHODS invalid_seats FOR TESTING.
ENDCLASS.
CLASS {{p}}cine_test IMPLEMENTATION.
METHOD fee.
CALL FUNCTION '{{P}}CINE_FEE_OLD'
EXPORTING
iv_show_type = iv_show
iv_seats = iv_seats
iv_show_time = iv_time
iv_cust_type = iv_cust
IMPORTING
ev_total = rv_total
EXCEPTIONS
invalid_input = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD adult_evening.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '9.50' )
act = fee( iv_show = `2D` iv_seats = 1 iv_time = c_evening iv_cust = `ADULT` ) ).
ENDMETHOD.
METHOD matinee_discount.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '7.25' )
act = fee( iv_show = `2D` iv_seats = 1 iv_time = c_matinee iv_cust = `ADULT` ) ).
ENDMETHOD.
METHOD child_price.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '5.90' )
act = fee( iv_show = `2D` iv_seats = 1 iv_time = c_matinee iv_cust = `CHILD` ) ).
ENDMETHOD.
METHOD invalid_seats.
DATA lv_total TYPE decfloat34.
CALL FUNCTION '{{P}}CINE_FEE_OLD'
EXPORTING
iv_show_type = `2D`
iv_seats = 0
iv_show_time = c_evening
iv_cust_type = `ADULT`
IMPORTING
ev_total = lv_total
EXCEPTIONS
invalid_input = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,166 @@
FUNCTION {{p}}ski_rental_old
IMPORTING
iv_equipment TYPE string
iv_days TYPE i
iv_customer TYPE string
iv_insurance TYPE abap_bool
EXPORTING
ev_price TYPE decfloat34
ev_deposit TYPE decfloat34
EXCEPTIONS
invalid_equipment
invalid_days
invalid_customer.
CLASS lcx_invalid_equipment DEFINITION INHERITING FROM cx_static_check.
ENDCLASS.
CLASS lcx_invalid_equipment IMPLEMENTATION.
ENDCLASS.
CLASS lcx_invalid_days DEFINITION INHERITING FROM cx_static_check.
ENDCLASS.
CLASS lcx_invalid_days IMPLEMENTATION.
ENDCLASS.
CLASS lcx_invalid_customer DEFINITION INHERITING FROM cx_static_check.
ENDCLASS.
CLASS lcx_invalid_customer IMPLEMENTATION.
ENDCLASS.
CLASS lcl_ski_pricer DEFINITION.
PUBLIC SECTION.
TYPES: BEGIN OF ty_result,
price TYPE decfloat34,
deposit TYPE decfloat34,
END OF ty_result.
CLASS-METHODS calculate
IMPORTING iv_equipment TYPE string
iv_days TYPE i
iv_customer TYPE string
iv_insurance TYPE abap_bool
RETURNING VALUE(rs_result) TYPE ty_result
RAISING lcx_invalid_equipment lcx_invalid_days lcx_invalid_customer.
PRIVATE SECTION.
CLASS-METHODS get_daily_rate
IMPORTING iv_equipment TYPE string
RETURNING VALUE(rv_rate) TYPE decfloat34
RAISING lcx_invalid_equipment.
CLASS-METHODS get_deposit
IMPORTING iv_equipment TYPE string
RETURNING VALUE(rv_deposit) TYPE decfloat34
RAISING lcx_invalid_equipment.
CLASS-METHODS get_customer_discount
IMPORTING iv_customer TYPE string
RETURNING VALUE(rv_discount) TYPE decfloat34
RAISING lcx_invalid_customer.
CLASS-METHODS get_duration_discount
IMPORTING iv_days TYPE i
RETURNING VALUE(rv_discount) TYPE decfloat34.
ENDCLASS.
CLASS lcl_ski_pricer IMPLEMENTATION.
METHOD calculate.
CONSTANTS: c_insurance_per_day TYPE decfloat34 VALUE 5,
c_insurance_deposit TYPE decfloat34 VALUE 50.
IF iv_days < 1.
RAISE EXCEPTION TYPE lcx_invalid_days.
ENDIF.
DATA(lv_daily_rate) = get_daily_rate( iv_equipment ).
DATA(lv_customer_disc) = get_customer_discount( iv_customer ).
DATA(lv_total) = lv_daily_rate * iv_days.
lv_total = lv_total - lv_total * lv_customer_disc / 100.
DATA(lv_duration_disc) = get_duration_discount( iv_days ).
lv_total = lv_total - lv_total * lv_duration_disc / 100.
IF iv_insurance = abap_true.
lv_total = lv_total + c_insurance_per_day * iv_days.
ENDIF.
rs_result-price = round( val = lv_total dec = 2 mode = cl_abap_math=>round_half_up ).
rs_result-deposit = get_deposit( iv_equipment ).
IF iv_insurance = abap_true.
rs_result-deposit = rs_result-deposit + c_insurance_deposit.
ENDIF.
ENDMETHOD.
METHOD get_daily_rate.
CONSTANTS: c_ski_rate TYPE decfloat34 VALUE 25,
c_snowboard_rate TYPE decfloat34 VALUE 30,
c_boots_rate TYPE decfloat34 VALUE 10,
c_helmet_rate TYPE decfloat34 VALUE 5.
CASE iv_equipment.
WHEN 'SKI'.
rv_rate = c_ski_rate.
WHEN 'SNOWBOARD'.
rv_rate = c_snowboard_rate.
WHEN 'BOOTS'.
rv_rate = c_boots_rate.
WHEN 'HELMET'.
rv_rate = c_helmet_rate.
WHEN OTHERS.
RAISE EXCEPTION TYPE lcx_invalid_equipment.
ENDCASE.
ENDMETHOD.
METHOD get_deposit.
CONSTANTS: c_ski_deposit TYPE decfloat34 VALUE 100,
c_snowboard_deposit TYPE decfloat34 VALUE 120,
c_boots_deposit TYPE decfloat34 VALUE 20,
c_helmet_deposit TYPE decfloat34 VALUE 10.
CASE iv_equipment.
WHEN 'SKI'.
rv_deposit = c_ski_deposit.
WHEN 'SNOWBOARD'.
rv_deposit = c_snowboard_deposit.
WHEN 'BOOTS'.
rv_deposit = c_boots_deposit.
WHEN 'HELMET'.
rv_deposit = c_helmet_deposit.
WHEN OTHERS.
RAISE EXCEPTION TYPE lcx_invalid_equipment.
ENDCASE.
ENDMETHOD.
METHOD get_customer_discount.
CONSTANTS: c_child_discount TYPE decfloat34 VALUE 50,
c_senior_discount TYPE decfloat34 VALUE 20.
CASE iv_customer.
WHEN 'ADULT'.
rv_discount = 0.
WHEN 'CHILD'.
rv_discount = c_child_discount.
WHEN 'SENIOR'.
rv_discount = c_senior_discount.
WHEN OTHERS.
RAISE EXCEPTION TYPE lcx_invalid_customer.
ENDCASE.
ENDMETHOD.
METHOD get_duration_discount.
CONSTANTS: c_disc_7 TYPE decfloat34 VALUE 10,
c_disc_3 TYPE decfloat34 VALUE 5.
IF iv_days >= 7.
rv_discount = c_disc_7.
ELSEIF iv_days >= 3.
rv_discount = c_disc_3.
ELSE.
rv_discount = 0.
ENDIF.
ENDMETHOD.
ENDCLASS.
TRY.
DATA(ls_result) = lcl_ski_pricer=>calculate(
iv_equipment = iv_equipment
iv_days = iv_days
iv_customer = iv_customer
iv_insurance = iv_insurance ).
ev_price = ls_result-price.
ev_deposit = ls_result-deposit.
CATCH lcx_invalid_equipment.
RAISE invalid_equipment.
CATCH lcx_invalid_days.
RAISE invalid_days.
CATCH lcx_invalid_customer.
RAISE invalid_customer.
ENDTRY.
ENDFUNCTION.

View File

@@ -0,0 +1,94 @@
CLASS {{p}}t_ski_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS call
IMPORTING iv_equipment TYPE string
iv_days TYPE i
iv_customer TYPE string
iv_insurance TYPE abap_bool
EXPORTING ev_price TYPE decfloat34
ev_deposit TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS test_invalid_days FOR TESTING.
METHODS test_invalid_equipment FOR TESTING.
METHODS test_invalid_customer FOR TESTING.
METHODS test_adult_ski FOR TESTING.
METHODS test_child_boots FOR TESTING.
METHODS test_senior_snowboard FOR TESTING.
METHODS test_insurance FOR TESTING.
METHODS test_rounding FOR TESTING.
ENDCLASS.
CLASS {{p}}t_ski_test IMPLEMENTATION.
METHOD call.
CALL FUNCTION '{{P}}SKI_RENTAL_OLD'
EXPORTING
iv_equipment = iv_equipment
iv_days = iv_days
iv_customer = iv_customer
iv_insurance = iv_insurance
IMPORTING
ev_price = ev_price
ev_deposit = ev_deposit
EXCEPTIONS
invalid_equipment = 1
invalid_days = 2
invalid_customer = 3
OTHERS = 4.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD test_invalid_days.
call( EXPORTING iv_equipment = 'SKI' iv_days = 0 iv_customer = 'ADULT' iv_insurance = abap_false
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_subrc ).
ENDMETHOD.
METHOD test_invalid_equipment.
call( EXPORTING iv_equipment = 'X' iv_days = 1 iv_customer = 'ADULT' iv_insurance = abap_false
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_subrc ).
ENDMETHOD.
METHOD test_invalid_customer.
call( EXPORTING iv_equipment = 'SKI' iv_days = 1 iv_customer = 'X' iv_insurance = abap_false
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lv_subrc ).
ENDMETHOD.
METHOD test_adult_ski.
call( EXPORTING iv_equipment = 'SKI' iv_days = 1 iv_customer = 'ADULT' iv_insurance = abap_false
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 25 ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 100 ) act = lv_deposit ).
ENDMETHOD.
METHOD test_child_boots.
call( EXPORTING iv_equipment = 'BOOTS' iv_days = 2 iv_customer = 'CHILD' iv_insurance = abap_false
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 10 ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 20 ) act = lv_deposit ).
ENDMETHOD.
METHOD test_senior_snowboard.
call( EXPORTING iv_equipment = 'SNOWBOARD' iv_days = 3 iv_customer = 'SENIOR' iv_insurance = abap_false
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '68.40' ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 120 ) act = lv_deposit ).
ENDMETHOD.
METHOD test_insurance.
call( EXPORTING iv_equipment = 'SKI' iv_days = 7 iv_customer = 'ADULT' iv_insurance = abap_true
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '192.50' ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 150 ) act = lv_deposit ).
ENDMETHOD.
METHOD test_rounding.
call( EXPORTING iv_equipment = 'SKI' iv_days = 3 iv_customer = 'CHILD' iv_insurance = abap_false
IMPORTING ev_price = DATA(lv_price) ev_deposit = DATA(lv_deposit) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '35.63' ) act = lv_price ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 100 ) act = lv_deposit ).
ENDMETHOD.
ENDCLASS.

View File

@@ -1,71 +0,0 @@
FUNCTION {{p}}cine_fee_old
IMPORTING
iv_show_type TYPE string
iv_seats TYPE i
iv_show_time TYPE t
iv_cust_type TYPE string
EXPORTING
ev_total TYPE decfloat34
ev_discount TYPE decfloat34
EXCEPTIONS
invalid_input.
" legacy: price per seat
DATA: lv_x TYPE decfloat34,
lv_y TYPE decfloat34,
lv_z TYPE i.
IF iv_seats < 1.
RAISE invalid_input.
ENDIF.
IF iv_show_type = '2D' OR iv_show_type = '3D' OR iv_show_type = 'IMAX'.
IF iv_show_type = '2D'.
lv_x = 9.
ELSEIF iv_show_type = '3D'.
lv_x = '12.50'.
ELSE.
lv_x = 16.
ENDIF.
ELSE.
RAISE invalid_input.
ENDIF.
IF iv_cust_type = 'CHILD'.
lv_y = 40.
ELSEIF iv_cust_type = 'SENIOR'.
lv_y = 30.
ELSEIF iv_cust_type = 'STUDENT'.
lv_y = 20.
ELSEIF iv_cust_type = 'ADULT'.
lv_y = 0.
ELSE.
RAISE invalid_input.
ENDIF.
IF iv_show_time < '170000'.
IF iv_cust_type <> 'CHILD'.
lv_y = lv_y + 25.
ENDIF.
ENDIF.
IF iv_seats >= 8.
lv_y = lv_y + 10.
ENDIF.
IF lv_y > 60.
lv_y = 60.
ENDIF.
lv_x = lv_x - lv_x * lv_y / 100.
lv_x = lv_x + '0.5'.
lv_z = 0.
DO iv_seats TIMES.
lv_z = lv_z + 1.
ENDDO.
ev_total = round( val = lv_x * lv_z dec = 2 mode = cl_abap_math=>round_half_up ).
ev_discount = lv_y.
ENDFUNCTION.

View File

@@ -0,0 +1,78 @@
FUNCTION {{p}}ski_rental_old
IMPORTING
iv_equipment TYPE string
iv_days TYPE i
iv_customer TYPE string
iv_insurance TYPE abap_bool
EXPORTING
ev_price TYPE decfloat34
ev_deposit TYPE decfloat34
EXCEPTIONS
invalid_equipment
invalid_days
invalid_customer.
DATA lv_daily TYPE decfloat34.
DATA lv_discount TYPE decfloat34.
DATA lv_total TYPE decfloat34.
DATA lv_duration_disc TYPE decfloat34.
IF iv_days < 1.
RAISE invalid_days.
ENDIF.
IF iv_equipment = 'SKI'.
lv_daily = 25.
ELSEIF iv_equipment = 'SNOWBOARD'.
lv_daily = 30.
ELSEIF iv_equipment = 'BOOTS'.
lv_daily = 10.
ELSEIF iv_equipment = 'HELMET'.
lv_daily = 5.
ELSE.
RAISE invalid_equipment.
ENDIF.
IF iv_customer = 'ADULT'.
lv_discount = 0.
ELSEIF iv_customer = 'CHILD'.
lv_discount = 50.
ELSEIF iv_customer = 'SENIOR'.
lv_discount = 20.
ELSE.
RAISE invalid_customer.
ENDIF.
lv_total = lv_daily * iv_days.
lv_total = lv_total - lv_total * lv_discount / 100.
IF iv_days >= 7.
lv_duration_disc = 10.
ELSEIF iv_days >= 3.
lv_duration_disc = 5.
ELSE.
lv_duration_disc = 0.
ENDIF.
lv_total = lv_total - lv_total * lv_duration_disc / 100.
IF iv_insurance = abap_true.
lv_total = lv_total + 5 * iv_days.
ENDIF.
ev_price = round( val = lv_total dec = 2 mode = cl_abap_math=>round_half_up ).
IF iv_equipment = 'SKI'.
ev_deposit = 100.
ELSEIF iv_equipment = 'SNOWBOARD'.
ev_deposit = 120.
ELSEIF iv_equipment = 'BOOTS'.
ev_deposit = 20.
ELSEIF iv_equipment = 'HELMET'.
ev_deposit = 10.
ENDIF.
IF iv_insurance = abap_true.
ev_deposit = ev_deposit + 50.
ENDIF.
ENDFUNCTION.

View File

@@ -1,44 +1,32 @@
# 1. Goal
The function module {{P}}CINE_FEE_OLD in function group {{P}}FG_CINE calculates
the price of a cinema ticket order. The code is legacy code. Refactor the
function module in place. The behavior stays the same. The name and the public
interface stay the same.
Refactor the legacy function module {{P}}SKI_RENTAL_OLD in function group {{P}}FG_SKI. The function module calculates the rental price and the deposit for ski equipment. Improve the readability, the maintainability, and the structure of the code. The behavior must stay the same. The public interface must not change.
# 2. Open questions
None.
# 3. Context
- Function group {{P}}FG_CINE exists in package $TMP.
- The function module {{P}}CINE_FEE_OLD exists in this function group. It holds
the legacy code.
- A ticket desk program calls {{P}}CINE_FEE_OLD for each ticket order. This call
must not change.
- Function group {{P}}FG_SKI exists in package $TMP.
- Function module {{P}}SKI_RENTAL_OLD exists in this group. It contains legacy code.
- A rental program calls the function module. The callers use the current interface.
# 4. Contract
- Object: the function module {{P}}CINE_FEE_OLD in function group {{P}}FG_CINE.
- Keep the name and the interface of the function module: the same parameter
names, parameter kinds, parameter types and the same exception.
- Importing parameters: iv_show_type TYPE string, iv_seats TYPE i,
iv_show_time TYPE t, iv_cust_type TYPE string.
- Exporting parameters: ev_total TYPE decfloat34, ev_discount TYPE decfloat34.
- Exception: invalid_input.
- The function module {{P}}SKI_RENTAL_OLD keeps its name and its function group.
- The interface stays exactly the same:
- Importing: iv_equipment TYPE string, iv_days TYPE i, iv_customer TYPE string, iv_insurance TYPE abap_bool
- Exporting: ev_price TYPE decfloat34, ev_deposit TYPE decfloat34
- Exceptions: invalid_equipment, invalid_days, invalid_customer
# 5. Business rules
The legacy source code of {{P}}CINE_FEE_OLD is the only source of the business
rules. Read this source code. The one rule of this task: for every input the
function module returns the same output values and the same exception as before
the refactoring. Do not add, remove or change a rule.
The business rules are defined by the current implementation of {{P}}SKI_RENTAL_OLD. The behavior must stay the same. Read the legacy code to understand the rules.
# 6. Constraints
- Release target: SAP_BASIS 816.
- Coding standards: Clean ABAP. No ATC priority 1 or priority 2 finding. Keep
every procedure and every method below 40 statements. Replace literal numbers
with named constants. Use meaningful names.
- Out of scope: do not change the interface. Do not change the function group
{{P}}FG_CINE.
- Release target: 8.16.
- The function module must be active and have no syntax error.
- Refactor the code in place. Do not change the public interface.
- Follow Clean ABAP: small methods, no duplication, meaningful names, constants for literals.
- Out of scope: do not change the function group {{P}}FG_SKI. Do not create new function modules.
# 7. Acceptance
- {{P}}CINE_FEE_OLD is active and has no syntax error.
- The behavior is unchanged.
- 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

@@ -12,75 +12,77 @@
"seed": [
{
"type": "FUGR",
"name": "{{P}}FG_CINE",
"description": "Cinema ticket function group"
"name": "{{P}}FG_SKI",
"description": "Ski rental function group"
},
{
"type": "FUNC",
"name": "{{P}}CINE_FEE_OLD",
"functionGroup": "{{P}}FG_CINE",
"file": "seed/cine_fee_old.func.abap",
"description": "Legacy ticket price calculation"
"name": "{{P}}SKI_RENTAL_OLD",
"functionGroup": "{{P}}FG_SKI",
"file": "seed/ski_rental_old.func.abap",
"description": "Legacy ski rental pricing"
}
],
"contract": [
{
"type": "FUNC",
"name": "{{P}}CINE_FEE_OLD",
"functionGroup": "{{P}}FG_CINE",
"name": "{{P}}SKI_RENTAL_OLD",
"functionGroup": "{{P}}FG_SKI",
"params": [
{
"name": "iv_show_type",
"name": "iv_equipment",
"type": "string"
},
{
"name": "iv_seats",
"name": "iv_days",
"type": "i"
},
{
"name": "iv_show_time",
"type": "t"
},
{
"name": "iv_cust_type",
"name": "iv_customer",
"type": "string"
},
{
"name": "ev_total",
"name": "iv_insurance",
"type": "abap_bool"
},
{
"name": "ev_price",
"type": "decfloat34"
},
{
"name": "ev_discount",
"name": "ev_deposit",
"type": "decfloat34"
}
],
"exceptions": [
"invalid_equipment",
"invalid_days",
"invalid_customer"
]
}
],
"out_of_scope": [
"{{P}}FG_CINE"
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}CINE_HIDDEN",
"file": "hidden/cine_hidden.clas.abap",
"description": "Hidden behavior tests for the refactored ticket price calculation"
"name": "{{P}}T_SKI_HIDDEN",
"file": "hidden/t_ski_hidden.clas.abap",
"description": "Hidden tests for ski rental pricing"
}
],
"reference": [
{
"type": "FUNC",
"name": "{{P}}CINE_FEE_OLD",
"functionGroup": "{{P}}FG_CINE",
"file": "reference/cine_fee_old.func.abap",
"description": "Refactored ticket price calculation, same interface and behavior",
"overwrite": true
"name": "{{P}}SKI_RENTAL_OLD",
"functionGroup": "{{P}}FG_SKI",
"file": "reference/ski_rental_old.func.abap",
"description": "Refactored ski rental pricing"
},
{
"type": "CLAS",
"name": "{{P}}CINE_TEST",
"file": "reference/cine_test.clas.abap",
"description": "Own tests for the ticket price calculation"
"name": "{{P}}T_SKI_TEST",
"file": "reference/t_ski_test.clas.abap",
"description": "Own tests for ski rental pricing"
}
],
"craft_checks": [