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,108 @@
CLASS {{p}}shift_booker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_hours TYPE p LENGTH 5 DECIMALS 2.
TYPES ty_mode TYPE c LENGTH 3.
TYPES ty_group TYPE c LENGTH 1.
TYPES ty_order TYPE c LENGTH 10.
TYPES:
BEGIN OF ty_shift,
order_no TYPE ty_order,
start_date TYPE d,
work_hours TYPE ty_hours,
calc_mode TYPE ty_mode,
group_code TYPE ty_group,
piece_count TYPE i,
END OF ty_shift.
METHODS evaluate
IMPORTING is_shift TYPE ty_shift
RETURNING VALUE(rv_pay) TYPE ty_amount
RAISING {{p}}cx_shift_error.
PRIVATE SECTION.
TYPES ty_reason TYPE c LENGTH 10.
CONSTANTS c_piece_bonus TYPE ty_amount VALUE '0.50'.
METHODS check_shift
IMPORTING is_shift TYPE ty_shift
RAISING {{p}}cx_shift_error.
METHODS raise_error
IMPORTING iv_reason TYPE ty_reason
RAISING {{p}}cx_shift_error.
METHODS base_rate
IMPORTING iv_group_code TYPE ty_group
RETURNING VALUE(rv_rate) TYPE ty_amount.
METHODS mode_factor
IMPORTING iv_calc_mode TYPE ty_mode
RETURNING VALUE(rv_factor) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}shift_booker IMPLEMENTATION.
METHOD evaluate.
check_shift( is_shift ).
DATA lv_hour_rate TYPE ty_amount.
lv_hour_rate = base_rate( is_shift-group_code ) * mode_factor( is_shift-calc_mode ).
rv_pay = is_shift-work_hours * lv_hour_rate - is_shift-piece_count * c_piece_bonus.
ENDMETHOD.
METHOD check_shift.
IF is_shift-order_no IS INITIAL.
raise_error( 'ORDER' ).
ENDIF.
IF is_shift-start_date IS INITIAL.
raise_error( 'DATE' ).
ENDIF.
IF is_shift-work_hours <= 0.
raise_error( 'HOURS' ).
ENDIF.
IF is_shift-calc_mode <> 'STD'
AND is_shift-calc_mode <> 'OT1'
AND is_shift-calc_mode <> 'OT2'.
raise_error( 'MODE' ).
ENDIF.
IF is_shift-group_code <> 'A'
AND is_shift-group_code <> 'B'
AND is_shift-group_code <> 'C'.
raise_error( 'GROUP' ).
ENDIF.
IF is_shift-piece_count < 1.
raise_error( 'COUNT' ).
ENDIF.
ENDMETHOD.
METHOD raise_error.
DATA(lx_error) = NEW {{p}}cx_shift_error( ).
lx_error->mv_reason = iv_reason.
RAISE EXCEPTION lx_error.
ENDMETHOD.
METHOD base_rate.
CASE iv_group_code.
WHEN 'A'.
rv_rate = '18.00'.
WHEN 'B'.
rv_rate = '22.00'.
WHEN 'C'.
rv_rate = '26.00'.
WHEN OTHERS.
rv_rate = '0.00'.
ENDCASE.
ENDMETHOD.
METHOD mode_factor.
CASE iv_calc_mode.
WHEN 'STD'.
rv_factor = '1.00'.
WHEN 'OT1'.
rv_factor = '1.50'.
WHEN 'OT2'.
rv_factor = '2.00'.
WHEN OTHERS.
rv_factor = '0.00'.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,108 @@
CLASS {{p}}shift_booker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_hours TYPE p LENGTH 5 DECIMALS 2.
TYPES ty_mode TYPE c LENGTH 3.
TYPES ty_group TYPE c LENGTH 1.
TYPES ty_order TYPE c LENGTH 10.
TYPES:
BEGIN OF ty_shift,
order_no TYPE ty_order,
start_date TYPE d,
work_hours TYPE ty_hours,
calc_mode TYPE ty_mode,
group_code TYPE ty_group,
piece_count TYPE i,
END OF ty_shift.
METHODS evaluate
IMPORTING is_shift TYPE ty_shift
RETURNING VALUE(rv_pay) TYPE ty_amount
RAISING {{p}}cx_shift_error.
PRIVATE SECTION.
TYPES ty_reason TYPE c LENGTH 10.
CONSTANTS c_piece_bonus TYPE ty_amount VALUE '0.50'.
METHODS check_shift
IMPORTING is_shift TYPE ty_shift
RAISING {{p}}cx_shift_error.
METHODS raise_error
IMPORTING iv_reason TYPE ty_reason
RAISING {{p}}cx_shift_error.
METHODS base_rate
IMPORTING iv_group_code TYPE ty_group
RETURNING VALUE(rv_rate) TYPE ty_amount.
METHODS mode_factor
IMPORTING iv_calc_mode TYPE ty_mode
RETURNING VALUE(rv_factor) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}shift_booker IMPLEMENTATION.
METHOD evaluate.
check_shift( is_shift ).
DATA lv_hour_rate TYPE ty_amount.
lv_hour_rate = base_rate( is_shift-group_code ) * mode_factor( is_shift-calc_mode ).
rv_pay = is_shift-work_hours * lv_hour_rate + is_shift-piece_count * c_piece_bonus.
ENDMETHOD.
METHOD check_shift.
IF is_shift-order_no IS INITIAL.
raise_error( 'ORDER' ).
ENDIF.
IF is_shift-start_date IS INITIAL.
raise_error( 'DATE' ).
ENDIF.
IF is_shift-work_hours > 0.
raise_error( 'HOURS' ).
ENDIF.
IF is_shift-calc_mode <> 'STD'
AND is_shift-calc_mode <> 'OT1'
AND is_shift-calc_mode <> 'OT2'.
raise_error( 'MODE' ).
ENDIF.
IF is_shift-group_code <> 'A'
AND is_shift-group_code <> 'B'
AND is_shift-group_code <> 'C'.
raise_error( 'GROUP' ).
ENDIF.
IF is_shift-piece_count < 1.
raise_error( 'COUNT' ).
ENDIF.
ENDMETHOD.
METHOD raise_error.
DATA(lx_error) = NEW {{p}}cx_shift_error( ).
lx_error->mv_reason = iv_reason.
RAISE EXCEPTION lx_error.
ENDMETHOD.
METHOD base_rate.
CASE iv_group_code.
WHEN 'A'.
rv_rate = '18.00'.
WHEN 'B'.
rv_rate = '22.00'.
WHEN 'C'.
rv_rate = '26.00'.
WHEN OTHERS.
rv_rate = '0.00'.
ENDCASE.
ENDMETHOD.
METHOD mode_factor.
CASE iv_calc_mode.
WHEN 'STD'.
rv_factor = '1.00'.
WHEN 'OT1'.
rv_factor = '1.50'.
WHEN 'OT2'.
rv_factor = '2.00'.
WHEN OTHERS.
rv_factor = '0.00'.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,108 @@
CLASS {{p}}shift_booker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_hours TYPE p LENGTH 5 DECIMALS 2.
TYPES ty_mode TYPE c LENGTH 3.
TYPES ty_group TYPE c LENGTH 1.
TYPES ty_order TYPE c LENGTH 10.
TYPES:
BEGIN OF ty_shift,
order_no TYPE ty_order,
start_date TYPE d,
work_hours TYPE ty_hours,
calc_mode TYPE ty_mode,
group_code TYPE ty_group,
piece_count TYPE i,
END OF ty_shift.
METHODS evaluate
IMPORTING is_shift TYPE ty_shift
RETURNING VALUE(rv_pay) TYPE ty_amount
RAISING {{p}}cx_shift_error.
PRIVATE SECTION.
TYPES ty_reason TYPE c LENGTH 10.
CONSTANTS c_piece_bonus TYPE ty_amount VALUE '0.50'.
METHODS check_shift
IMPORTING is_shift TYPE ty_shift
RAISING {{p}}cx_shift_error.
METHODS raise_error
IMPORTING iv_reason TYPE ty_reason
RAISING {{p}}cx_shift_error.
METHODS base_rate
IMPORTING iv_group_code TYPE ty_group
RETURNING VALUE(rv_rate) TYPE ty_amount.
METHODS mode_factor
IMPORTING iv_calc_mode TYPE ty_mode
RETURNING VALUE(rv_factor) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}shift_booker IMPLEMENTATION.
METHOD evaluate.
check_shift( is_shift ).
DATA lv_hour_rate TYPE ty_amount.
lv_hour_rate = base_rate( is_shift-group_code ) * mode_factor( is_shift-calc_mode ).
rv_pay = is_shift-work_hours * lv_hour_rate + is_shift-piece_count * c_piece_bonus.
ENDMETHOD.
METHOD check_shift.
IF is_shift-order_no IS INITIAL.
raise_error( 'ORDER' ).
ENDIF.
IF is_shift-start_date IS INITIAL.
raise_error( 'DATE' ).
ENDIF.
IF is_shift-work_hours <= 0.
raise_error( 'HOURS' ).
ENDIF.
IF is_shift-calc_mode <> 'STD'
AND is_shift-calc_mode = 'OT1'
AND is_shift-calc_mode <> 'OT2'.
raise_error( 'MODE' ).
ENDIF.
IF is_shift-group_code <> 'A'
AND is_shift-group_code <> 'B'
AND is_shift-group_code <> 'C'.
raise_error( 'GROUP' ).
ENDIF.
IF is_shift-piece_count < 1.
raise_error( 'COUNT' ).
ENDIF.
ENDMETHOD.
METHOD raise_error.
DATA(lx_error) = NEW {{p}}cx_shift_error( ).
lx_error->mv_reason = iv_reason.
RAISE EXCEPTION lx_error.
ENDMETHOD.
METHOD base_rate.
CASE iv_group_code.
WHEN 'A'.
rv_rate = '18.00'.
WHEN 'B'.
rv_rate = '22.00'.
WHEN 'C'.
rv_rate = '26.00'.
WHEN OTHERS.
rv_rate = '0.00'.
ENDCASE.
ENDMETHOD.
METHOD mode_factor.
CASE iv_calc_mode.
WHEN 'STD'.
rv_factor = '1.00'.
WHEN 'OT1'.
rv_factor = '1.50'.
WHEN 'OT2'.
rv_factor = '2.00'.
WHEN OTHERS.
rv_factor = '0.00'.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,108 @@
CLASS {{p}}shift_booker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_hours TYPE p LENGTH 5 DECIMALS 2.
TYPES ty_mode TYPE c LENGTH 3.
TYPES ty_group TYPE c LENGTH 1.
TYPES ty_order TYPE c LENGTH 10.
TYPES:
BEGIN OF ty_shift,
order_no TYPE ty_order,
start_date TYPE d,
work_hours TYPE ty_hours,
calc_mode TYPE ty_mode,
group_code TYPE ty_group,
piece_count TYPE i,
END OF ty_shift.
METHODS evaluate
IMPORTING is_shift TYPE ty_shift
RETURNING VALUE(rv_pay) TYPE ty_amount
RAISING {{p}}cx_shift_error.
PRIVATE SECTION.
TYPES ty_reason TYPE c LENGTH 10.
CONSTANTS c_piece_bonus TYPE ty_amount VALUE '0.50'.
METHODS check_shift
IMPORTING is_shift TYPE ty_shift
RAISING {{p}}cx_shift_error.
METHODS raise_error
IMPORTING iv_reason TYPE ty_reason
RAISING {{p}}cx_shift_error.
METHODS base_rate
IMPORTING iv_group_code TYPE ty_group
RETURNING VALUE(rv_rate) TYPE ty_amount.
METHODS mode_factor
IMPORTING iv_calc_mode TYPE ty_mode
RETURNING VALUE(rv_factor) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}shift_booker IMPLEMENTATION.
METHOD evaluate.
check_shift( is_shift ).
DATA lv_hour_rate TYPE ty_amount.
lv_hour_rate = base_rate( is_shift-group_code ) * mode_factor( is_shift-calc_mode ).
rv_pay = is_shift-work_hours * lv_hour_rate + is_shift-piece_count * c_piece_bonus.
ENDMETHOD.
METHOD check_shift.
IF is_shift-order_no IS INITIAL.
raise_error( 'ORDER' ).
ENDIF.
IF is_shift-start_date IS INITIAL.
raise_error( 'DATE' ).
ENDIF.
IF is_shift-work_hours <= 0.
raise_error( 'HOURS' ).
ENDIF.
IF is_shift-calc_mode <> 'STD'
AND is_shift-calc_mode <> 'OT1'
AND is_shift-calc_mode = 'OT2'.
raise_error( 'MODE' ).
ENDIF.
IF is_shift-group_code <> 'A'
AND is_shift-group_code <> 'B'
AND is_shift-group_code <> 'C'.
raise_error( 'GROUP' ).
ENDIF.
IF is_shift-piece_count < 1.
raise_error( 'COUNT' ).
ENDIF.
ENDMETHOD.
METHOD raise_error.
DATA(lx_error) = NEW {{p}}cx_shift_error( ).
lx_error->mv_reason = iv_reason.
RAISE EXCEPTION lx_error.
ENDMETHOD.
METHOD base_rate.
CASE iv_group_code.
WHEN 'A'.
rv_rate = '18.00'.
WHEN 'B'.
rv_rate = '22.00'.
WHEN 'C'.
rv_rate = '26.00'.
WHEN OTHERS.
rv_rate = '0.00'.
ENDCASE.
ENDMETHOD.
METHOD mode_factor.
CASE iv_calc_mode.
WHEN 'STD'.
rv_factor = '1.00'.
WHEN 'OT1'.
rv_factor = '1.50'.
WHEN 'OT2'.
rv_factor = '2.00'.
WHEN OTHERS.
rv_factor = '0.00'.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,108 @@
CLASS {{p}}shift_booker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_hours TYPE p LENGTH 5 DECIMALS 2.
TYPES ty_mode TYPE c LENGTH 3.
TYPES ty_group TYPE c LENGTH 1.
TYPES ty_order TYPE c LENGTH 10.
TYPES:
BEGIN OF ty_shift,
order_no TYPE ty_order,
start_date TYPE d,
work_hours TYPE ty_hours,
calc_mode TYPE ty_mode,
group_code TYPE ty_group,
piece_count TYPE i,
END OF ty_shift.
METHODS evaluate
IMPORTING is_shift TYPE ty_shift
RETURNING VALUE(rv_pay) TYPE ty_amount
RAISING {{p}}cx_shift_error.
PRIVATE SECTION.
TYPES ty_reason TYPE c LENGTH 10.
CONSTANTS c_piece_bonus TYPE ty_amount VALUE '0.50'.
METHODS check_shift
IMPORTING is_shift TYPE ty_shift
RAISING {{p}}cx_shift_error.
METHODS raise_error
IMPORTING iv_reason TYPE ty_reason
RAISING {{p}}cx_shift_error.
METHODS base_rate
IMPORTING iv_group_code TYPE ty_group
RETURNING VALUE(rv_rate) TYPE ty_amount.
METHODS mode_factor
IMPORTING iv_calc_mode TYPE ty_mode
RETURNING VALUE(rv_factor) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}shift_booker IMPLEMENTATION.
METHOD evaluate.
check_shift( is_shift ).
DATA lv_hour_rate TYPE ty_amount.
lv_hour_rate = base_rate( is_shift-group_code ) * mode_factor( is_shift-calc_mode ).
rv_pay = is_shift-work_hours * lv_hour_rate + is_shift-piece_count * c_piece_bonus.
ENDMETHOD.
METHOD check_shift.
IF is_shift-order_no IS INITIAL.
raise_error( 'ORDER' ).
ENDIF.
IF is_shift-start_date IS INITIAL.
raise_error( 'DATE' ).
ENDIF.
IF is_shift-work_hours <= 0.
raise_error( 'HOURS' ).
ENDIF.
IF is_shift-calc_mode <> 'STD'
AND is_shift-calc_mode <> 'OT1'
AND is_shift-calc_mode <> 'OT2'.
raise_error( 'MODE' ).
ENDIF.
IF is_shift-group_code <> 'A'
OR is_shift-group_code <> 'B'
AND is_shift-group_code <> 'C'.
raise_error( 'GROUP' ).
ENDIF.
IF is_shift-piece_count < 1.
raise_error( 'COUNT' ).
ENDIF.
ENDMETHOD.
METHOD raise_error.
DATA(lx_error) = NEW {{p}}cx_shift_error( ).
lx_error->mv_reason = iv_reason.
RAISE EXCEPTION lx_error.
ENDMETHOD.
METHOD base_rate.
CASE iv_group_code.
WHEN 'A'.
rv_rate = '18.00'.
WHEN 'B'.
rv_rate = '22.00'.
WHEN 'C'.
rv_rate = '26.00'.
WHEN OTHERS.
rv_rate = '0.00'.
ENDCASE.
ENDMETHOD.
METHOD mode_factor.
CASE iv_calc_mode.
WHEN 'STD'.
rv_factor = '1.00'.
WHEN 'OT1'.
rv_factor = '1.50'.
WHEN 'OT2'.
rv_factor = '2.00'.
WHEN OTHERS.
rv_factor = '0.00'.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

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

View File

@@ -0,0 +1,139 @@
CLASS {{p}}d02_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_reason TYPE c LENGTH 10.
DATA mo_cut TYPE REF TO {{p}}shift_booker.
METHODS setup.
METHODS valid_shift
RETURNING VALUE(rs_shift) TYPE {{p}}shift_booker=>ty_shift.
METHODS expect_reason
IMPORTING is_shift TYPE {{p}}shift_booker=>ty_shift
iv_reason TYPE ty_reason.
METHODS expect_pay
IMPORTING is_shift TYPE {{p}}shift_booker=>ty_shift
iv_pay TYPE {{p}}shift_booker=>ty_amount.
METHODS books_standard_shift FOR TESTING.
METHODS books_overtime_shift FOR TESTING.
METHODS books_second_overtime FOR TESTING.
METHODS books_small_shift FOR TESTING.
METHODS rejects_empty_order FOR TESTING.
METHODS rejects_initial_date FOR TESTING.
METHODS rejects_zero_hours FOR TESTING.
METHODS rejects_unknown_mode FOR TESTING.
METHODS rejects_unknown_group FOR TESTING.
METHODS rejects_zero_pieces FOR TESTING.
METHODS order_rule_wins FOR TESTING.
ENDCLASS.
CLASS {{p}}d02_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}shift_booker( ).
ENDMETHOD.
METHOD valid_shift.
rs_shift = VALUE #( order_no = '4711'
start_date = '20240212'
work_hours = '8.00'
calc_mode = 'STD'
group_code = 'A'
piece_count = 100 ).
ENDMETHOD.
METHOD expect_reason.
TRY.
mo_cut->evaluate( is_shift ).
cl_abap_unit_assert=>fail( msg = |no exception for { iv_reason }| ).
CATCH {{p}}cx_shift_error INTO DATA(lx_error).
cl_abap_unit_assert=>assert_equals( exp = iv_reason
act = lx_error->mv_reason ).
ENDTRY.
ENDMETHOD.
METHOD expect_pay.
TRY.
cl_abap_unit_assert=>assert_equals( exp = iv_pay
act = mo_cut->evaluate( is_shift ) ).
CATCH {{p}}cx_shift_error.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD books_standard_shift.
expect_pay( is_shift = valid_shift( ) iv_pay = '194.00' ).
ENDMETHOD.
METHOD books_overtime_shift.
DATA(ls_shift) = valid_shift( ).
ls_shift-work_hours = '7.50'.
ls_shift-calc_mode = 'OT1'.
ls_shift-group_code = 'B'.
ls_shift-piece_count = 40.
expect_pay( is_shift = ls_shift iv_pay = '267.50' ).
ENDMETHOD.
METHOD books_second_overtime.
DATA(ls_shift) = valid_shift( ).
ls_shift-work_hours = '6.00'.
ls_shift-calc_mode = 'OT2'.
ls_shift-group_code = 'C'.
ls_shift-piece_count = 10.
expect_pay( is_shift = ls_shift iv_pay = '317.00' ).
ENDMETHOD.
METHOD books_small_shift.
DATA(ls_shift) = valid_shift( ).
ls_shift-work_hours = '0.50'.
ls_shift-piece_count = 1.
expect_pay( is_shift = ls_shift iv_pay = '9.50' ).
ENDMETHOD.
METHOD rejects_empty_order.
DATA(ls_shift) = valid_shift( ).
ls_shift-order_no = ''.
expect_reason( is_shift = ls_shift iv_reason = 'ORDER' ).
ENDMETHOD.
METHOD rejects_initial_date.
DATA(ls_shift) = valid_shift( ).
ls_shift-start_date = '00000000'.
expect_reason( is_shift = ls_shift iv_reason = 'DATE' ).
ENDMETHOD.
METHOD rejects_zero_hours.
DATA(ls_shift) = valid_shift( ).
ls_shift-work_hours = '0.00'.
expect_reason( is_shift = ls_shift iv_reason = 'HOURS' ).
ENDMETHOD.
METHOD rejects_unknown_mode.
DATA(ls_shift) = valid_shift( ).
ls_shift-calc_mode = 'XXX'.
expect_reason( is_shift = ls_shift iv_reason = 'MODE' ).
ENDMETHOD.
METHOD rejects_unknown_group.
DATA(ls_shift) = valid_shift( ).
ls_shift-group_code = 'Z'.
expect_reason( is_shift = ls_shift iv_reason = 'GROUP' ).
ENDMETHOD.
METHOD rejects_zero_pieces.
DATA(ls_shift) = valid_shift( ).
ls_shift-piece_count = 0.
expect_reason( is_shift = ls_shift iv_reason = 'COUNT' ).
ENDMETHOD.
METHOD order_rule_wins.
DATA(ls_shift) = valid_shift( ).
ls_shift-order_no = ''.
ls_shift-work_hours = '0.00'.
expect_reason( is_shift = ls_shift iv_reason = 'ORDER' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,70 @@
{
"task": "G1124",
"mutants": [
{
"object": "{{P}}SHIFT_BOOKER",
"mutant": "line 49: + -> - (arith)",
"status": "killed",
"hidden": "7/11",
"failed_tests": [
"BOOKS_OVERTIME_SHIFT",
"BOOKS_SECOND_OVERTIME",
"BOOKS_SMALL_SHIFT",
"BOOKS_STANDARD_SHIFT"
]
},
{
"object": "{{P}}SHIFT_BOOKER",
"mutant": "line 59: <= -> > (rel)",
"status": "killed",
"hidden": "3/11",
"failed_tests": [
"BOOKS_OVERTIME_SHIFT",
"BOOKS_SECOND_OVERTIME",
"BOOKS_SMALL_SHIFT",
"BOOKS_STANDARD_SHIFT",
"REJECTS_UNKNOWN_GROUP",
"REJECTS_UNKNOWN_MODE",
"REJECTS_ZERO_HOURS",
"REJECTS_ZERO_PIECES"
]
},
{
"object": "{{P}}SHIFT_BOOKER",
"mutant": "line 63: <> -> = (rel)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"BOOKS_OVERTIME_SHIFT",
"REJECTS_UNKNOWN_MODE"
]
},
{
"object": "{{P}}SHIFT_BOOKER",
"mutant": "line 64: <> -> = (rel)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"BOOKS_SECOND_OVERTIME",
"REJECTS_UNKNOWN_MODE"
]
},
{
"object": "{{P}}SHIFT_BOOKER",
"mutant": "line 68: AND -> OR (logic)",
"status": "killed",
"hidden": "6/11",
"failed_tests": [
"BOOKS_OVERTIME_SHIFT",
"BOOKS_SECOND_OVERTIME",
"BOOKS_SMALL_SHIFT",
"BOOKS_STANDARD_SHIFT",
"REJECTS_ZERO_PIECES"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,9 @@
CLASS {{p}}cx_shift_error DEFINITION PUBLIC INHERITING FROM cx_static_check
FINAL CREATE PUBLIC.
PUBLIC SECTION.
DATA mv_reason TYPE c LENGTH 10.
ENDCLASS.
CLASS {{p}}cx_shift_error IMPLEMENTATION.
ENDCLASS.

View File

@@ -0,0 +1,108 @@
CLASS {{p}}shift_booker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_hours TYPE p LENGTH 5 DECIMALS 2.
TYPES ty_mode TYPE c LENGTH 3.
TYPES ty_group TYPE c LENGTH 1.
TYPES ty_order TYPE c LENGTH 10.
TYPES:
BEGIN OF ty_shift,
order_no TYPE ty_order,
start_date TYPE d,
work_hours TYPE ty_hours,
calc_mode TYPE ty_mode,
group_code TYPE ty_group,
piece_count TYPE i,
END OF ty_shift.
METHODS evaluate
IMPORTING is_shift TYPE ty_shift
RETURNING VALUE(rv_pay) TYPE ty_amount
RAISING {{p}}cx_shift_error.
PRIVATE SECTION.
TYPES ty_reason TYPE c LENGTH 10.
CONSTANTS c_piece_bonus TYPE ty_amount VALUE '0.50'.
METHODS check_shift
IMPORTING is_shift TYPE ty_shift
RAISING {{p}}cx_shift_error.
METHODS raise_error
IMPORTING iv_reason TYPE ty_reason
RAISING {{p}}cx_shift_error.
METHODS base_rate
IMPORTING iv_group_code TYPE ty_group
RETURNING VALUE(rv_rate) TYPE ty_amount.
METHODS mode_factor
IMPORTING iv_calc_mode TYPE ty_mode
RETURNING VALUE(rv_factor) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}shift_booker IMPLEMENTATION.
METHOD evaluate.
check_shift( is_shift ).
DATA lv_hour_rate TYPE ty_amount.
lv_hour_rate = base_rate( is_shift-group_code ) * mode_factor( is_shift-calc_mode ).
rv_pay = is_shift-work_hours * lv_hour_rate + is_shift-piece_count * c_piece_bonus.
ENDMETHOD.
METHOD check_shift.
IF is_shift-order_no IS INITIAL.
raise_error( 'ORDER' ).
ENDIF.
IF is_shift-start_date IS INITIAL.
raise_error( 'DATE' ).
ENDIF.
IF is_shift-work_hours <= 0.
raise_error( 'HOURS' ).
ENDIF.
IF is_shift-calc_mode <> 'STD'
AND is_shift-calc_mode <> 'OT1'
AND is_shift-calc_mode <> 'OT2'.
raise_error( 'MODE' ).
ENDIF.
IF is_shift-group_code <> 'A'
AND is_shift-group_code <> 'B'
AND is_shift-group_code <> 'C'.
raise_error( 'GROUP' ).
ENDIF.
IF is_shift-piece_count < 1.
raise_error( 'COUNT' ).
ENDIF.
ENDMETHOD.
METHOD raise_error.
DATA(lx_error) = NEW {{p}}cx_shift_error( ).
lx_error->mv_reason = iv_reason.
RAISE EXCEPTION lx_error.
ENDMETHOD.
METHOD base_rate.
CASE iv_group_code.
WHEN 'A'.
rv_rate = '18.00'.
WHEN 'B'.
rv_rate = '22.00'.
WHEN 'C'.
rv_rate = '26.00'.
WHEN OTHERS.
rv_rate = '0.00'.
ENDCASE.
ENDMETHOD.
METHOD mode_factor.
CASE iv_calc_mode.
WHEN 'STD'.
rv_factor = '1.00'.
WHEN 'OT1'.
rv_factor = '1.50'.
WHEN 'OT2'.
rv_factor = '2.00'.
WHEN OTHERS.
rv_factor = '0.00'.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,105 @@
CLASS ltc_shift_booker DEFINITION FINAL FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_reason TYPE c LENGTH 10.
DATA mo_cut TYPE REF TO {{p}}shift_booker.
METHODS setup.
METHODS valid_shift
RETURNING VALUE(rs_shift) TYPE {{p}}shift_booker=>ty_shift.
METHODS expect_reason
IMPORTING is_shift TYPE {{p}}shift_booker=>ty_shift
iv_reason TYPE ty_reason.
METHODS expect_pay
IMPORTING is_shift TYPE {{p}}shift_booker=>ty_shift
iv_pay TYPE {{p}}shift_booker=>ty_amount.
METHODS standard_pay FOR TESTING.
METHODS overtime_pay FOR TESTING.
METHODS empty_order FOR TESTING.
METHODS zero_hours FOR TESTING.
METHODS bad_mode FOR TESTING.
METHODS bad_group FOR TESTING.
METHODS zero_pieces FOR TESTING.
ENDCLASS.
CLASS ltc_shift_booker IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}shift_booker( ).
ENDMETHOD.
METHOD valid_shift.
rs_shift = VALUE #( order_no = '4711'
start_date = '20240212'
work_hours = '8.00'
calc_mode = 'STD'
group_code = 'A'
piece_count = 100 ).
ENDMETHOD.
METHOD expect_reason.
TRY.
mo_cut->evaluate( is_shift ).
cl_abap_unit_assert=>fail( msg = |no exception for { iv_reason }| ).
CATCH {{p}}cx_shift_error INTO DATA(lx_error).
cl_abap_unit_assert=>assert_equals( exp = iv_reason
act = lx_error->mv_reason ).
ENDTRY.
ENDMETHOD.
METHOD expect_pay.
TRY.
cl_abap_unit_assert=>assert_equals( exp = iv_pay
act = mo_cut->evaluate( is_shift ) ).
CATCH {{p}}cx_shift_error.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD standard_pay.
expect_pay( is_shift = valid_shift( ) iv_pay = '194.00' ).
ENDMETHOD.
METHOD overtime_pay.
DATA(ls_shift) = valid_shift( ).
ls_shift-work_hours = '7.50'.
ls_shift-calc_mode = 'OT1'.
ls_shift-group_code = 'B'.
ls_shift-piece_count = 40.
expect_pay( is_shift = ls_shift iv_pay = '267.50' ).
ENDMETHOD.
METHOD empty_order.
DATA(ls_shift) = valid_shift( ).
ls_shift-order_no = ''.
expect_reason( is_shift = ls_shift iv_reason = 'ORDER' ).
ENDMETHOD.
METHOD zero_hours.
DATA(ls_shift) = valid_shift( ).
ls_shift-work_hours = '0.00'.
expect_reason( is_shift = ls_shift iv_reason = 'HOURS' ).
ENDMETHOD.
METHOD bad_mode.
DATA(ls_shift) = valid_shift( ).
ls_shift-calc_mode = 'XX'.
expect_reason( is_shift = ls_shift iv_reason = 'MODE' ).
ENDMETHOD.
METHOD bad_group.
DATA(ls_shift) = valid_shift( ).
ls_shift-group_code = 'D'.
expect_reason( is_shift = ls_shift iv_reason = 'GROUP' ).
ENDMETHOD.
METHOD zero_pieces.
DATA(ls_shift) = valid_shift( ).
ls_shift-piece_count = 0.
expect_reason( is_shift = ls_shift iv_reason = 'COUNT' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,76 @@
# 1. Goal
Check a work booking of a production shift and calculate the pay of the shift. A
payroll program calls the check before it posts the pay. The program needs one
reason code for each booking that is not correct.
# 2. Open questions
None.
# 3. Context
- The class {{P}}SHIFT_BOOKER does not exist. You create it.
- The exception class {{P}}CX_SHIFT_ERROR does not exist. You create it.
- The business uses the words hours, mode, order, date, count, group and value.
These words are reserved words or SQL words. The contract below uses other
names for the same concepts.
# 4. Contract
## 4.1 Exception class {{P}}CX_SHIFT_ERROR
- The class is in package $TMP. It inherits from CX_STATIC_CHECK.
- The class has the public instance attribute MV_REASON. The type is CHAR 10.
MV_REASON holds the reason code of the error.
- Do not add other public components.
## 4.2 Class {{P}}SHIFT_BOOKER
- The class is in package $TMP. It is public, final, and has a public constructor
without parameters.
- Public types:
- TY_AMOUNT: packed number, length 9, 2 decimal places.
- TY_HOURS: packed number, length 5, 2 decimal places.
- TY_MODE: CHAR 3.
- TY_GROUP: CHAR 1.
- TY_ORDER: CHAR 10.
- TY_SHIFT: structure with these components:
- ORDER_NO: TYPE TY_ORDER
- START_DATE: TYPE d
- WORK_HOURS: TYPE TY_HOURS
- CALC_MODE: TYPE TY_MODE
- GROUP_CODE: TYPE TY_GROUP
- PIECE_COUNT: TYPE i
- Public method:
EVALUATE
IMPORTING is_shift TYPE ty_shift
RETURNING VALUE(rv_pay) TYPE ty_amount
RAISING {{P}}CX_SHIFT_ERROR
- Do not add other public methods.
# 5. Business rules
The method EVALUATE checks the booking. Apply the rules in this sequence. The
method raises {{P}}CX_SHIFT_ERROR with the reason code of the first rule that
fails.
1. If ORDER_NO is empty, the reason code is ORDER.
2. If START_DATE is initial, the reason code is DATE.
3. If WORK_HOURS is not greater than zero, the reason code is HOURS.
4. CALC_MODE must be STD, OT1 or OT2. If not, the reason code is MODE.
5. GROUP_CODE must be A, B or C. If not, the reason code is GROUP.
6. If PIECE_COUNT is less than 1, the reason code is COUNT.
If all rules pass, the method returns the value of the shift.
The value of the shift is:
WORK_HOURS x base rate x mode factor + PIECE_COUNT x 0.50
- The base rate of the group is: A = 18.00, B = 22.00, C = 26.00.
- The mode factor is: STD = 1.0, OT1 = 1.5, OT2 = 2.0.
- The value has 2 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.
- Do not use the words HOURS, MODE, ORDER, DATE, COUNT, GROUP or VALUE as the name
of a field, of a component or of a parameter. The reason codes in the rules
above are values, not names.
- Out of scope: do not create other objects. Do not use transports.
# 7. Acceptance
- The two classes are active and have no syntax error.
- The hidden tests pass.
- Write your own ABAP Unit tests for {{P}}SHIFT_BOOKER.

View File

@@ -0,0 +1,51 @@
{
"id": "G1124",
"category": "D",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 70,
"max_activations": 18
},
"seed": [],
"contract": [
{
"type": "CLAS",
"name": "{{P}}CX_SHIFT_ERROR"
},
{
"type": "CLAS",
"name": "{{P}}SHIFT_BOOKER"
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}D02_HIDDEN",
"file": "hidden/d02_hidden.clas.abap",
"description": "D02 hidden tests"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}CX_SHIFT_ERROR",
"file": "reference/cx_shift_error.clas.abap",
"description": "Shift error exception class"
},
{
"type": "CLAS",
"name": "{{P}}SHIFT_BOOKER",
"file": "reference/shift_booker.clas.abap",
"description": "Shift booker",
"testclasses_file": "reference/shift_booker.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"no_reserved_words"
]
}