Fix coverage with several contract classes; table annotation and file path checks; clean task dir on write

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 08:44:35 +02:00
parent fb576b0954
commit 03ab36149e
388 changed files with 28620 additions and 339 deletions

View File

@@ -0,0 +1,69 @@
{
"id": "G0129",
"pool": "eval",
"object_type": "CLAS",
"category": "D",
"attempts": [
{
"stage": "bundle",
"errors": [
"hidden/t_print_hidden.clas.abap line 72: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"assert_price\"",
"hidden/t_print_hidden.clas.abap line 72: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/t_print_hidden.clas.abap line 77: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"assert_price\"",
"hidden/t_print_hidden.clas.abap line 77: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/t_print_hidden.clas.abap line 82: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"assert_price\"",
"hidden/t_print_hidden.clas.abap line 82: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/t_print_hidden.clas.abap line 84: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"assert_price\"",
"hidden/t_print_hidden.clas.abap line 84: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/t_print_hidden.clas.abap line 89: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"assert_price\"",
"hidden/t_print_hidden.clas.abap line 89: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"50\"",
"hidden/t_print_hidden.clas.abap line 91: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"assert_price\"",
"hidden/t_print_hidden.clas.abap line 91: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"75\"",
"hidden/t_print_hidden.clas.abap line 96: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"assert_price\"",
"hidden/t_print_hidden.clas.abap line 96: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/t_print_hidden.clas.abap line 101: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"assert_price\"",
"hidden/t_print_hidden.clas.abap line 101: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/t_print_hidden.clas.abap line 106: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"assert_price\"",
"hidden/t_print_hidden.clas.abap line 106: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/t_print_hidden.clas.abap line 144: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"assert_price\"",
"hidden/t_print_hidden.clas.abap line 144: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\""
],
"by_check": {
"abaplint": 20
}
},
{
"stage": "bundle",
"errors": [
"reference/print_job_pricer.testclasses.abap line 42: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"reference/print_job_pricer.testclasses.abap line 43: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"reference/print_job_pricer.testclasses.abap line 49: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"reference/print_job_pricer.testclasses.abap line 50: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"reference/print_job_pricer.testclasses.abap line 56: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"reference/print_job_pricer.testclasses.abap line 57: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"50\"",
"reference/print_job_pricer.testclasses.abap line 63: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"reference/print_job_pricer.testclasses.abap line 64: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"reference/print_job_pricer.clas.abap line 26: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"reference/print_job_pricer.clas.abap line 28: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"05\"",
"reference/print_job_pricer.clas.abap line 29: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"10\"",
"reference/print_job_pricer.clas.abap line 123: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"03\"",
"reference/print_job_pricer.clas.abap line 125: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"05\"",
"reference/print_job_pricer.clas.abap line 127: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"09\""
],
"by_check": {
"abaplint": 14
}
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 0,
"null": 0
}
],
"accepted": false
}

View File

@@ -0,0 +1,267 @@
CLASS {{p}}t_print_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS a4_mono_price FOR TESTING.
METHODS a4_color_price FOR TESTING.
METHODS a3_a5_price FOR TESTING.
METHODS volume_discount_5 FOR TESTING.
METHODS volume_discount_10 FOR TESTING.
METHODS minimum_charge FOR TESTING.
METHODS copies_multiply FOR TESTING.
METHODS rejects_zero_pages FOR TESTING.
METHODS rejects_zero_copies FOR TESTING.
METHODS rejects_unknown_values FOR TESTING.
METHODS rejects_over_limit FOR TESTING.
METHODS first_error_wins FOR TESTING.
ENDCLASS.
CLASS {{p}}t_print_hidden IMPLEMENTATION.
METHOD a4_mono_price.
DATA lv_cents TYPE i.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
DATA(lv_price) = lo_cut->calculate_price( iv_pages = 100
iv_copies = 1
iv_paper = 'A4'
iv_color = 'M'
iv_dept = 'SALE' ).
lv_cents = lv_price * 100.
cl_abap_unit_assert=>assert_equals( exp = 500 act = lv_cents ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD a4_color_price.
DATA lv_cents TYPE i.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
DATA(lv_price) = lo_cut->calculate_price( iv_pages = 100
iv_copies = 1
iv_paper = 'A4'
iv_color = 'C'
iv_dept = 'SALE' ).
lv_cents = lv_price * 100.
cl_abap_unit_assert=>assert_equals( exp = 2000 act = lv_cents ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD a3_a5_price.
DATA lv_cents TYPE i.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
DATA(lv_price) = lo_cut->calculate_price( iv_pages = 100
iv_copies = 1
iv_paper = 'A3'
iv_color = 'M'
iv_dept = 'PROD' ).
lv_cents = lv_price * 100.
cl_abap_unit_assert=>assert_equals( exp = 900 act = lv_cents ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
TRY.
DATA(lv_a5) = lo_cut->calculate_price( iv_pages = 100
iv_copies = 1
iv_paper = 'A5'
iv_color = 'M'
iv_dept = 'HR' ).
lv_cents = lv_a5 * 100.
cl_abap_unit_assert=>assert_equals( exp = 300 act = lv_cents ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD volume_discount_5.
DATA lv_cents TYPE i.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
DATA(lv_price) = lo_cut->calculate_price( iv_pages = 600
iv_copies = 1
iv_paper = 'A4'
iv_color = 'M'
iv_dept = 'IT' ).
lv_cents = lv_price * 100.
cl_abap_unit_assert=>assert_equals( exp = 2850 act = lv_cents ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
TRY.
DATA(lv_500) = lo_cut->calculate_price( iv_pages = 500
iv_copies = 1
iv_paper = 'A4'
iv_color = 'M'
iv_dept = 'IT' ).
lv_cents = lv_500 * 100.
cl_abap_unit_assert=>assert_equals( exp = 2375 act = lv_cents ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD volume_discount_10.
DATA lv_cents TYPE i.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
DATA(lv_price) = lo_cut->calculate_price( iv_pages = 1000
iv_copies = 1
iv_paper = 'A4'
iv_color = 'M'
iv_dept = 'SALE' ).
lv_cents = lv_price * 100.
cl_abap_unit_assert=>assert_equals( exp = 4500 act = lv_cents ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD minimum_charge.
DATA lv_cents TYPE i.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
DATA(lv_price) = lo_cut->calculate_price( iv_pages = 10
iv_copies = 1
iv_paper = 'A4'
iv_color = 'M'
iv_dept = 'SALE' ).
lv_cents = lv_price * 100.
cl_abap_unit_assert=>assert_equals( exp = 100 act = lv_cents ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD copies_multiply.
DATA lv_cents TYPE i.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
DATA(lv_price) = lo_cut->calculate_price( iv_pages = 200
iv_copies = 2
iv_paper = 'A3'
iv_color = 'C'
iv_dept = 'PROD' ).
lv_cents = lv_price * 100.
cl_abap_unit_assert=>assert_equals( exp = 14400 act = lv_cents ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD rejects_zero_pages.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
lo_cut->calculate_price( iv_pages = 0
iv_copies = 1
iv_paper = 'A4'
iv_color = 'M'
iv_dept = 'SALE' ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_print_job_error INTO DATA(lo_error).
cl_abap_unit_assert=>assert_equals(
exp = {{p}}cx_print_job_error=>c_reason-pages
act = lo_error->mv_reason ).
ENDTRY.
ENDMETHOD.
METHOD rejects_zero_copies.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
lo_cut->calculate_price( iv_pages = 100
iv_copies = 0
iv_paper = 'A4'
iv_color = 'M'
iv_dept = 'SALE' ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_print_job_error INTO DATA(lo_error).
cl_abap_unit_assert=>assert_equals(
exp = {{p}}cx_print_job_error=>c_reason-copies
act = lo_error->mv_reason ).
ENDTRY.
ENDMETHOD.
METHOD rejects_unknown_values.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
lo_cut->calculate_price( iv_pages = 100
iv_copies = 1
iv_paper = 'B5'
iv_color = 'M'
iv_dept = 'SALE' ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_print_job_error INTO DATA(lo_paper).
cl_abap_unit_assert=>assert_equals(
exp = {{p}}cx_print_job_error=>c_reason-paper
act = lo_paper->mv_reason ).
ENDTRY.
TRY.
lo_cut->calculate_price( iv_pages = 100
iv_copies = 1
iv_paper = 'A4'
iv_color = 'X'
iv_dept = 'SALE' ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_print_job_error INTO DATA(lo_color).
cl_abap_unit_assert=>assert_equals(
exp = {{p}}cx_print_job_error=>c_reason-color
act = lo_color->mv_reason ).
ENDTRY.
TRY.
lo_cut->calculate_price( iv_pages = 100
iv_copies = 1
iv_paper = 'A4'
iv_color = 'M'
iv_dept = 'XYZ' ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_print_job_error INTO DATA(lo_dept).
cl_abap_unit_assert=>assert_equals(
exp = {{p}}cx_print_job_error=>c_reason-dept
act = lo_dept->mv_reason ).
ENDTRY.
ENDMETHOD.
METHOD rejects_over_limit.
DATA lv_cents TYPE i.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
lo_cut->calculate_price( iv_pages = 3000
iv_copies = 2
iv_paper = 'A4'
iv_color = 'M'
iv_dept = 'SALE' ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_print_limit INTO DATA(lo_error).
cl_abap_unit_assert=>assert_equals( exp = 6000
act = lo_error->mv_pages ).
ENDTRY.
TRY.
DATA(lv_price) = lo_cut->calculate_price( iv_pages = 5000
iv_copies = 1
iv_paper = 'A4'
iv_color = 'M'
iv_dept = 'SALE' ).
lv_cents = lv_price * 100.
cl_abap_unit_assert=>assert_equals( exp = 22500 act = lv_cents ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD first_error_wins.
DATA(lo_cut) = NEW {{p}}print_job_pricer( ).
TRY.
lo_cut->calculate_price( iv_pages = 0
iv_copies = 0
iv_paper = 'B5'
iv_color = 'X'
iv_dept = 'XYZ' ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_print_job_error INTO DATA(lo_error).
cl_abap_unit_assert=>assert_equals(
exp = {{p}}cx_print_job_error=>c_reason-pages
act = lo_error->mv_reason ).
ENDTRY.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,31 @@
CLASS {{p}}cx_print_job_error DEFINITION
PUBLIC
INHERITING FROM CX_ROOT
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_reason TYPE c LENGTH 10.
CONSTANTS:
BEGIN OF c_reason,
pages TYPE ty_reason VALUE 'PAGES',
copies TYPE ty_reason VALUE 'COPIES',
paper TYPE ty_reason VALUE 'PAPER',
color TYPE ty_reason VALUE 'COLOR',
dept TYPE ty_reason VALUE 'DEPT',
END OF c_reason.
DATA mv_reason TYPE ty_reason.
METHODS constructor
IMPORTING
iv_reason TYPE ty_reason.
ENDCLASS.
CLASS {{p}}cx_print_job_error IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
mv_reason = iv_reason.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,20 @@
CLASS {{p}}cx_print_limit DEFINITION
PUBLIC
INHERITING FROM CX_ROOT
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
DATA mv_pages TYPE i.
METHODS constructor
IMPORTING
iv_pages TYPE i.
ENDCLASS.
CLASS {{p}}cx_print_limit IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
mv_pages = iv_pages.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,158 @@
CLASS {{p}}print_job_pricer DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_paper TYPE c LENGTH 4,
ty_color TYPE c LENGTH 1,
ty_dept TYPE c LENGTH 4,
ty_price TYPE p LENGTH 8 DECIMALS 2.
CONSTANTS:
BEGIN OF c_paper,
a3 TYPE ty_paper VALUE 'A3',
a4 TYPE ty_paper VALUE 'A4',
a5 TYPE ty_paper VALUE 'A5',
END OF c_paper,
BEGIN OF c_color,
mono TYPE ty_color VALUE 'M',
color TYPE ty_color VALUE 'C',
END OF c_color,
BEGIN OF c_dept,
sale TYPE ty_dept VALUE 'SALE',
hr TYPE ty_dept VALUE 'HR',
it TYPE ty_dept VALUE 'IT',
prod TYPE ty_dept VALUE 'PROD',
END OF c_dept,
c_max_pages TYPE i VALUE 5000,
c_min_cents TYPE i VALUE 100,
c_cents_a5 TYPE i VALUE 3,
c_cents_a4 TYPE i VALUE 5,
c_cents_a3 TYPE i VALUE 9,
c_color_factor TYPE i VALUE 4,
c_cents_per_unit TYPE i VALUE 100,
c_percent_base TYPE i VALUE 100,
c_percent_5 TYPE i VALUE 5,
c_percent_10 TYPE i VALUE 10,
c_pages_discount_5 TYPE i VALUE 500,
c_pages_discount_10 TYPE i VALUE 1000.
METHODS calculate_price
IMPORTING
iv_pages TYPE i
iv_copies TYPE i
iv_paper TYPE ty_paper
iv_color TYPE ty_color
iv_dept TYPE ty_dept
RETURNING
VALUE(rv_price) TYPE ty_price
RAISING
{{p}}cx_print_job_error
{{p}}cx_print_limit.
PRIVATE SECTION.
METHODS validate
IMPORTING
iv_pages TYPE i
iv_copies TYPE i
iv_paper TYPE ty_paper
iv_color TYPE ty_color
iv_dept TYPE ty_dept
RAISING
{{p}}cx_print_job_error.
METHODS page_price_cents
IMPORTING
iv_paper TYPE ty_paper
iv_color TYPE ty_color
RETURNING
VALUE(rv_cents) TYPE i.
METHODS discount_cents
IMPORTING
iv_total_pages TYPE i
iv_gross_cents TYPE i
RETURNING
VALUE(rv_cents) TYPE i.
ENDCLASS.
CLASS {{p}}print_job_pricer IMPLEMENTATION.
METHOD calculate_price.
validate( iv_pages = iv_pages
iv_copies = iv_copies
iv_paper = iv_paper
iv_color = iv_color
iv_dept = iv_dept ).
DATA(lv_total_pages) = iv_pages * iv_copies.
IF lv_total_pages > c_max_pages.
RAISE EXCEPTION TYPE {{p}}cx_print_limit
EXPORTING
iv_pages = lv_total_pages.
ENDIF.
DATA(lv_gross_cents) = lv_total_pages * page_price_cents(
iv_paper = iv_paper
iv_color = iv_color ).
DATA(lv_net_cents) = lv_gross_cents - discount_cents(
iv_total_pages = lv_total_pages
iv_gross_cents = lv_gross_cents ).
IF lv_net_cents < c_min_cents.
lv_net_cents = c_min_cents.
ENDIF.
DATA(lv_net) = CONV ty_price( lv_net_cents ).
rv_price = lv_net / c_cents_per_unit.
ENDMETHOD.
METHOD validate.
IF iv_pages < 1.
RAISE EXCEPTION TYPE {{p}}cx_print_job_error
EXPORTING iv_reason = {{p}}cx_print_job_error=>c_reason-pages.
ENDIF.
IF iv_copies < 1.
RAISE EXCEPTION TYPE {{p}}cx_print_job_error
EXPORTING iv_reason = {{p}}cx_print_job_error=>c_reason-copies.
ENDIF.
IF iv_paper <> c_paper-a4 AND iv_paper <> c_paper-a3
AND iv_paper <> c_paper-a5.
RAISE EXCEPTION TYPE {{p}}cx_print_job_error
EXPORTING iv_reason = {{p}}cx_print_job_error=>c_reason-paper.
ENDIF.
IF iv_color <> c_color-color AND iv_color <> c_color-mono.
RAISE EXCEPTION TYPE {{p}}cx_print_job_error
EXPORTING iv_reason = {{p}}cx_print_job_error=>c_reason-color.
ENDIF.
IF iv_dept <> c_dept-sale AND iv_dept <> c_dept-hr
AND iv_dept <> c_dept-it AND iv_dept <> c_dept-prod.
RAISE EXCEPTION TYPE {{p}}cx_print_job_error
EXPORTING iv_reason = {{p}}cx_print_job_error=>c_reason-dept.
ENDIF.
ENDMETHOD.
METHOD page_price_cents.
CASE iv_paper.
WHEN c_paper-a5.
rv_cents = c_cents_a5.
WHEN c_paper-a4.
rv_cents = c_cents_a4.
WHEN c_paper-a3.
rv_cents = c_cents_a3.
ENDCASE.
IF iv_color = c_color-color.
rv_cents = rv_cents * c_color_factor.
ENDIF.
ENDMETHOD.
METHOD discount_cents.
DATA lv_percent TYPE i.
IF iv_total_pages >= c_pages_discount_10.
lv_percent = c_percent_10.
ELSEIF iv_total_pages >= c_pages_discount_5.
lv_percent = c_percent_5.
ELSE.
RETURN.
ENDIF.
DATA lv_gross TYPE ty_price.
lv_gross = iv_gross_cents.
DATA(lv_discount) = lv_gross * lv_percent / c_percent_base.
rv_cents = lv_discount.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,104 @@
CLASS ltc_print_job_pricer DEFINITION FINAL FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}print_job_pricer.
METHODS setup.
METHODS price
IMPORTING
iv_pages TYPE i
iv_copies TYPE i
iv_paper TYPE {{p}}print_job_pricer=>ty_paper
iv_color TYPE {{p}}print_job_pricer=>ty_color
iv_dept TYPE {{p}}print_job_pricer=>ty_dept
RETURNING
VALUE(rv_price) TYPE {{p}}print_job_pricer=>ty_price.
METHODS cents
IMPORTING
iv_cents TYPE i
RETURNING
VALUE(rv_price) TYPE {{p}}print_job_pricer=>ty_price.
METHODS a4_mono_price FOR TESTING.
METHODS color_price FOR TESTING.
METHODS volume_discount FOR TESTING.
METHODS minimum_charge FOR TESTING.
METHODS zero_pages_raises FOR TESTING.
METHODS over_limit_raises FOR TESTING.
ENDCLASS.
CLASS ltc_print_job_pricer IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}print_job_pricer( ).
ENDMETHOD.
METHOD price.
TRY.
rv_price = mo_cut->calculate_price( iv_pages = iv_pages
iv_copies = iv_copies
iv_paper = iv_paper
iv_color = iv_color
iv_dept = iv_dept ).
CATCH cx_root.
cl_abap_unit_assert=>fail( msg = 'unexpected exception' ).
ENDTRY.
ENDMETHOD.
METHOD cents.
DATA lv_price TYPE {{p}}print_job_pricer=>ty_price.
lv_price = iv_cents.
rv_price = lv_price / 100.
ENDMETHOD.
METHOD a4_mono_price.
cl_abap_unit_assert=>assert_equals(
exp = cents( 500 )
act = price( iv_pages = 100 iv_copies = 1
iv_paper = 'A4' iv_color = 'M' iv_dept = 'SALE' ) ).
ENDMETHOD.
METHOD color_price.
cl_abap_unit_assert=>assert_equals(
exp = cents( 2000 )
act = price( iv_pages = 100 iv_copies = 1
iv_paper = 'A4' iv_color = 'C' iv_dept = 'SALE' ) ).
ENDMETHOD.
METHOD volume_discount.
cl_abap_unit_assert=>assert_equals(
exp = cents( 2850 )
act = price( iv_pages = 600 iv_copies = 1
iv_paper = 'A4' iv_color = 'M' iv_dept = 'IT' ) ).
ENDMETHOD.
METHOD minimum_charge.
cl_abap_unit_assert=>assert_equals(
exp = cents( 100 )
act = price( iv_pages = 10 iv_copies = 1
iv_paper = 'A4' iv_color = 'M' iv_dept = 'SALE' ) ).
ENDMETHOD.
METHOD zero_pages_raises.
TRY.
mo_cut->calculate_price( iv_pages = 0 iv_copies = 1
iv_paper = 'A4' iv_color = 'M'
iv_dept = 'SALE' ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_print_job_error INTO DATA(lo_error).
cl_abap_unit_assert=>assert_equals(
exp = {{p}}cx_print_job_error=>c_reason-pages
act = lo_error->mv_reason ).
ENDTRY.
ENDMETHOD.
METHOD over_limit_raises.
TRY.
mo_cut->calculate_price( iv_pages = 3000 iv_copies = 2
iv_paper = 'A4' iv_color = 'M'
iv_dept = 'SALE' ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_print_limit INTO DATA(lo_error).
cl_abap_unit_assert=>assert_equals( exp = 6000
act = lo_error->mv_pages ).
ENDTRY.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,85 @@
# 1. Goal
Calculate the internal price of a print job for the print shop of a company. A
billing program calls the calculation before it charges the cost centre of a
department. Invalid job data must raise a class-based exception.
# 2. Open questions
None.
# 3. Context
- Package $TMP. No other object exists for this topic.
- The billing program catches the exceptions and shows the reason to the user.
The names of the classes and their public components are fixed.
# 4. Contract
Create three classes in package $TMP.
## {{P}}CX_PRINT_JOB_ERROR
- Public, final, inherits from CX_ROOT.
- Public type TY_REASON, character 10.
- Public constant structure C_REASON with the components PAGES, COPIES, PAPER,
COLOR and DEPT. The values are 'PAGES', 'COPIES', 'PAPER', 'COLOR' and
'DEPT'.
- Public attribute MV_REASON of type TY_REASON.
- Public constructor with the importing parameter IV_REASON of type TY_REASON.
The constructor writes IV_REASON to MV_REASON.
## {{P}}CX_PRINT_LIMIT
- Public, final, inherits from CX_ROOT.
- Public attribute MV_PAGES of type I.
- Public constructor with the importing parameter IV_PAGES of type I. The
constructor writes IV_PAGES to MV_PAGES.
## {{P}}PRINT_JOB_PRICER
- Public, final, public constructor without parameters.
- Public types: TY_PAPER (character 4), TY_COLOR (character 1), TY_DEPT
(character 4), TY_PRICE (packed number, length 8, 2 decimals).
- Public method CALCULATE_PRICE with these parameters:
- IMPORTING IV_PAGES TYPE I
- IMPORTING IV_COPIES TYPE I
- IMPORTING IV_PAPER TYPE TY_PAPER
- IMPORTING IV_COLOR TYPE TY_COLOR
- IMPORTING IV_DEPT TYPE TY_DEPT
- RETURNING VALUE(RV_PRICE) TYPE TY_PRICE
- RAISING {{P}}CX_PRINT_JOB_ERROR and {{P}}CX_PRINT_LIMIT
- Do not add other public methods.
# 5. Business rules
Apply the rules in this sequence.
1. Check the input in this order. Raise the exception of the first rule that
fails.
1. IV_PAGES is smaller than 1: raise {{P}}CX_PRINT_JOB_ERROR with the
reason PAGES.
2. IV_COPIES is smaller than 1: raise {{P}}CX_PRINT_JOB_ERROR with the
reason COPIES.
3. IV_PAPER is not 'A4', 'A3' or 'A5': raise {{P}}CX_PRINT_JOB_ERROR with
the reason PAPER.
4. IV_COLOR is not 'C' or 'M': raise {{P}}CX_PRINT_JOB_ERROR with the
reason COLOR.
5. IV_DEPT is not 'SALE', 'HR', 'IT' or 'PROD': raise
{{P}}CX_PRINT_JOB_ERROR with the reason DEPT.
2. The total number of pages is IV_PAGES multiplied by IV_COPIES.
3. If the total number of pages is greater than 5000, raise
{{P}}CX_PRINT_LIMIT with MV_PAGES equal to the total number of pages.
4. The price of one page is 0.03 for A5, 0.05 for A4 and 0.09 for A3. For the
color mode 'C', multiply the price of one page by 4.
5. The gross price is the total number of pages multiplied by the price of one
page.
6. Volume discount on the gross price: 10 per cent if the total number of
pages is 1000 or more, 5 per cent if the total number of pages is 500 or
more, otherwise no discount.
7. The net price is the gross price minus the discount.
8. If the net price is smaller than 1.00, the price is 1.00 (minimum charge).
9. Return the price.
# 6. Constraints
- Release target: SAP_BASIS 8.16.
- Coding standards: Clean ABAP. Method length below 40 statements. No global
variables. No comment that restates the code.
- Out of scope: no database table, no report, no function module, no CDS view.
# 7. Acceptance
- The three classes are active and have no syntax error.
- The hidden tests pass.
- Write your own ABAP Unit tests for {{P}}PRINT_JOB_PRICER.

View File

@@ -0,0 +1,66 @@
{
"id": "G0129",
"category": "D",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [],
"contract": [
{
"type": "CLAS",
"name": "{{P}}CX_PRINT_JOB_ERROR"
},
{
"type": "CLAS",
"name": "{{P}}CX_PRINT_LIMIT"
},
{
"type": "CLAS",
"name": "{{P}}PRINT_JOB_PRICER"
}
],
"out_of_scope": [
"Database tables",
"Reports",
"Function modules",
"CDS views"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T_PRINT_HIDDEN",
"file": "hidden/t_print_hidden.clas.abap",
"description": "Hidden tests for the print job price"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}CX_PRINT_JOB_ERROR",
"file": "reference/cx_print_job_error.clas.abap",
"description": "Invalid print job data"
},
{
"type": "CLAS",
"name": "{{P}}CX_PRINT_LIMIT",
"file": "reference/cx_print_limit.clas.abap",
"description": "Print job above the page limit"
},
{
"type": "CLAS",
"name": "{{P}}PRINT_JOB_PRICER",
"file": "reference/print_job_pricer.clas.abap",
"description": "Print job price",
"testclasses_file": "reference/print_job_pricer.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"db_operation_in_loop"
]
}