Pipeline controller: plan 2 (hard +, error +50 %), backlog throttle, 2 trajectory workers, stop rules, summaries every 50; budget reserve

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 13:35:54 +02:00
parent 1c4667a0fc
commit 13360292dd
781 changed files with 50211 additions and 22 deletions

View File

@@ -0,0 +1,189 @@
CLASS {{p}}frame_pricer DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_moulding TYPE c LENGTH 1.
TYPES ty_glass TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
METHODS calculate_price
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_moulding,
standard TYPE ty_moulding VALUE 'S',
premium TYPE ty_moulding VALUE 'P',
gold TYPE ty_moulding VALUE 'G',
END OF c_moulding,
BEGIN OF c_glass,
none TYPE ty_glass VALUE 'N',
standard TYPE ty_glass VALUE 'S',
anti_reflex TYPE ty_glass VALUE 'A',
END OF c_glass,
BEGIN OF c_moulding_rate,
standard TYPE ty_amount VALUE '0.08',
premium TYPE ty_amount VALUE '0.15',
gold TYPE ty_amount VALUE '0.28',
END OF c_moulding_rate,
BEGIN OF c_glass_price,
none TYPE ty_amount VALUE '0.00',
standard TYPE ty_amount VALUE '18.00',
anti_reflex TYPE ty_amount VALUE '34.00',
END OF c_glass_price,
c_factor TYPE ty_amount VALUE '2.00',
c_backing TYPE ty_amount VALUE '3.00',
c_labour TYPE ty_amount VALUE '12.00',
c_small_frame TYPE ty_amount VALUE '4.00',
c_small_limit_cm TYPE ty_amount VALUE '50.00',
c_oversized TYPE ty_amount VALUE '25.00',
c_oversize_limit TYPE ty_amount VALUE '20000.00',
c_setup_fee TYPE ty_amount VALUE '15.00',
c_setup_limit TYPE i VALUE 5.
METHODS is_valid
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS perimeter
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_perimeter) TYPE ty_amount.
METHODS area
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_area) TYPE ty_amount.
METHODS quantity_amount
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS moulding_price
IMPORTING iv_moulding TYPE ty_moulding
iv_perimeter TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS glass_price
IMPORTING iv_glass TYPE ty_glass
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS extras
IMPORTING iv_perimeter TYPE ty_amount
iv_area TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS setup_fee
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}frame_pricer IMPLEMENTATION.
METHOD calculate_price.
IF is_valid( iv_width_cm = iv_width_cm
iv_height_cm = iv_height_cm
iv_moulding = iv_moulding
iv_glass = iv_glass
iv_quantity = iv_quantity ) = abap_true.
rv_price = 0.
RETURN.
ENDIF.
DATA lv_perimeter TYPE ty_amount.
lv_perimeter = perimeter( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_area TYPE ty_amount.
lv_area = area( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_per_frame TYPE ty_amount.
lv_per_frame = moulding_price( iv_moulding = iv_moulding
iv_perimeter = lv_perimeter ).
DATA lv_glass TYPE ty_amount.
lv_glass = glass_price( iv_glass = iv_glass ).
lv_per_frame = lv_per_frame + lv_glass.
DATA lv_extra TYPE ty_amount.
lv_extra = extras( iv_perimeter = lv_perimeter iv_area = lv_area ).
lv_per_frame = lv_per_frame + lv_extra.
DATA lv_quantity TYPE ty_amount.
lv_quantity = quantity_amount( iv_quantity = iv_quantity ).
DATA lv_total TYPE ty_amount.
lv_total = lv_per_frame * lv_quantity.
DATA lv_fee TYPE ty_amount.
lv_fee = setup_fee( iv_quantity = iv_quantity ).
rv_price = lv_total + lv_fee.
ENDMETHOD.
METHOD is_valid.
rv_valid = xsdbool( iv_width_cm >= 1
AND iv_height_cm >= 1
AND iv_quantity >= 1
AND ( iv_moulding = c_moulding-standard
OR iv_moulding = c_moulding-premium
OR iv_moulding = c_moulding-gold )
AND ( iv_glass = c_glass-none
OR iv_glass = c_glass-standard
OR iv_glass = c_glass-anti_reflex ) ).
ENDMETHOD.
METHOD perimeter.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_perimeter = ( lv_width + lv_height ) * c_factor.
ENDMETHOD.
METHOD area.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_area = lv_width * lv_height.
ENDMETHOD.
METHOD quantity_amount.
rv_amount = iv_quantity.
ENDMETHOD.
METHOD moulding_price.
CASE iv_moulding.
WHEN c_moulding-standard.
rv_price = iv_perimeter * c_moulding_rate-standard.
WHEN c_moulding-premium.
rv_price = iv_perimeter * c_moulding_rate-premium.
WHEN OTHERS.
rv_price = iv_perimeter * c_moulding_rate-gold.
ENDCASE.
ENDMETHOD.
METHOD glass_price.
CASE iv_glass.
WHEN c_glass-none.
rv_price = c_glass_price-none.
WHEN c_glass-standard.
rv_price = c_glass_price-standard.
WHEN OTHERS.
rv_price = c_glass_price-anti_reflex.
ENDCASE.
ENDMETHOD.
METHOD extras.
rv_price = c_backing + c_labour.
IF iv_perimeter < c_small_limit_cm.
rv_price = rv_price + c_small_frame.
ENDIF.
IF iv_area > c_oversize_limit.
rv_price = rv_price + c_oversized.
ENDIF.
ENDMETHOD.
METHOD setup_fee.
IF iv_quantity < c_setup_limit.
rv_price = c_setup_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,189 @@
CLASS {{p}}frame_pricer DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_moulding TYPE c LENGTH 1.
TYPES ty_glass TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
METHODS calculate_price
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_moulding,
standard TYPE ty_moulding VALUE 'S',
premium TYPE ty_moulding VALUE 'P',
gold TYPE ty_moulding VALUE 'G',
END OF c_moulding,
BEGIN OF c_glass,
none TYPE ty_glass VALUE 'N',
standard TYPE ty_glass VALUE 'S',
anti_reflex TYPE ty_glass VALUE 'A',
END OF c_glass,
BEGIN OF c_moulding_rate,
standard TYPE ty_amount VALUE '0.08',
premium TYPE ty_amount VALUE '0.15',
gold TYPE ty_amount VALUE '0.28',
END OF c_moulding_rate,
BEGIN OF c_glass_price,
none TYPE ty_amount VALUE '0.00',
standard TYPE ty_amount VALUE '18.00',
anti_reflex TYPE ty_amount VALUE '34.00',
END OF c_glass_price,
c_factor TYPE ty_amount VALUE '2.00',
c_backing TYPE ty_amount VALUE '3.00',
c_labour TYPE ty_amount VALUE '12.00',
c_small_frame TYPE ty_amount VALUE '4.00',
c_small_limit_cm TYPE ty_amount VALUE '50.00',
c_oversized TYPE ty_amount VALUE '25.00',
c_oversize_limit TYPE ty_amount VALUE '20000.00',
c_setup_fee TYPE ty_amount VALUE '15.00',
c_setup_limit TYPE i VALUE 5.
METHODS is_valid
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS perimeter
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_perimeter) TYPE ty_amount.
METHODS area
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_area) TYPE ty_amount.
METHODS quantity_amount
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS moulding_price
IMPORTING iv_moulding TYPE ty_moulding
iv_perimeter TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS glass_price
IMPORTING iv_glass TYPE ty_glass
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS extras
IMPORTING iv_perimeter TYPE ty_amount
iv_area TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS setup_fee
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}frame_pricer IMPLEMENTATION.
METHOD calculate_price.
IF is_valid( iv_width_cm = iv_width_cm
iv_height_cm = iv_height_cm
iv_moulding = iv_moulding
iv_glass = iv_glass
iv_quantity = iv_quantity ) = abap_false.
rv_price = 0.
RETURN.
ENDIF.
DATA lv_perimeter TYPE ty_amount.
lv_perimeter = perimeter( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_area TYPE ty_amount.
lv_area = area( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_per_frame TYPE ty_amount.
lv_per_frame = moulding_price( iv_moulding = iv_moulding
iv_perimeter = lv_perimeter ).
DATA lv_glass TYPE ty_amount.
lv_glass = glass_price( iv_glass = iv_glass ).
lv_per_frame = lv_per_frame + lv_glass.
DATA lv_extra TYPE ty_amount.
lv_extra = extras( iv_perimeter = lv_perimeter iv_area = lv_area ).
lv_per_frame = lv_per_frame + lv_extra.
DATA lv_quantity TYPE ty_amount.
lv_quantity = quantity_amount( iv_quantity = iv_quantity ).
DATA lv_total TYPE ty_amount.
lv_total = lv_per_frame * lv_quantity.
DATA lv_fee TYPE ty_amount.
lv_fee = setup_fee( iv_quantity = iv_quantity ).
rv_price = lv_total + lv_fee.
ENDMETHOD.
METHOD is_valid.
rv_valid = xsdbool( iv_width_cm >= 1
AND iv_height_cm < 1
AND iv_quantity >= 1
AND ( iv_moulding = c_moulding-standard
OR iv_moulding = c_moulding-premium
OR iv_moulding = c_moulding-gold )
AND ( iv_glass = c_glass-none
OR iv_glass = c_glass-standard
OR iv_glass = c_glass-anti_reflex ) ).
ENDMETHOD.
METHOD perimeter.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_perimeter = ( lv_width + lv_height ) * c_factor.
ENDMETHOD.
METHOD area.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_area = lv_width * lv_height.
ENDMETHOD.
METHOD quantity_amount.
rv_amount = iv_quantity.
ENDMETHOD.
METHOD moulding_price.
CASE iv_moulding.
WHEN c_moulding-standard.
rv_price = iv_perimeter * c_moulding_rate-standard.
WHEN c_moulding-premium.
rv_price = iv_perimeter * c_moulding_rate-premium.
WHEN OTHERS.
rv_price = iv_perimeter * c_moulding_rate-gold.
ENDCASE.
ENDMETHOD.
METHOD glass_price.
CASE iv_glass.
WHEN c_glass-none.
rv_price = c_glass_price-none.
WHEN c_glass-standard.
rv_price = c_glass_price-standard.
WHEN OTHERS.
rv_price = c_glass_price-anti_reflex.
ENDCASE.
ENDMETHOD.
METHOD extras.
rv_price = c_backing + c_labour.
IF iv_perimeter < c_small_limit_cm.
rv_price = rv_price + c_small_frame.
ENDIF.
IF iv_area > c_oversize_limit.
rv_price = rv_price + c_oversized.
ENDIF.
ENDMETHOD.
METHOD setup_fee.
IF iv_quantity < c_setup_limit.
rv_price = c_setup_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,189 @@
CLASS {{p}}frame_pricer DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_moulding TYPE c LENGTH 1.
TYPES ty_glass TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
METHODS calculate_price
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_moulding,
standard TYPE ty_moulding VALUE 'S',
premium TYPE ty_moulding VALUE 'P',
gold TYPE ty_moulding VALUE 'G',
END OF c_moulding,
BEGIN OF c_glass,
none TYPE ty_glass VALUE 'N',
standard TYPE ty_glass VALUE 'S',
anti_reflex TYPE ty_glass VALUE 'A',
END OF c_glass,
BEGIN OF c_moulding_rate,
standard TYPE ty_amount VALUE '0.08',
premium TYPE ty_amount VALUE '0.15',
gold TYPE ty_amount VALUE '0.28',
END OF c_moulding_rate,
BEGIN OF c_glass_price,
none TYPE ty_amount VALUE '0.00',
standard TYPE ty_amount VALUE '18.00',
anti_reflex TYPE ty_amount VALUE '34.00',
END OF c_glass_price,
c_factor TYPE ty_amount VALUE '2.00',
c_backing TYPE ty_amount VALUE '3.00',
c_labour TYPE ty_amount VALUE '12.00',
c_small_frame TYPE ty_amount VALUE '4.00',
c_small_limit_cm TYPE ty_amount VALUE '50.00',
c_oversized TYPE ty_amount VALUE '25.00',
c_oversize_limit TYPE ty_amount VALUE '20000.00',
c_setup_fee TYPE ty_amount VALUE '15.00',
c_setup_limit TYPE i VALUE 5.
METHODS is_valid
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS perimeter
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_perimeter) TYPE ty_amount.
METHODS area
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_area) TYPE ty_amount.
METHODS quantity_amount
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS moulding_price
IMPORTING iv_moulding TYPE ty_moulding
iv_perimeter TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS glass_price
IMPORTING iv_glass TYPE ty_glass
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS extras
IMPORTING iv_perimeter TYPE ty_amount
iv_area TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS setup_fee
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}frame_pricer IMPLEMENTATION.
METHOD calculate_price.
IF is_valid( iv_width_cm = iv_width_cm
iv_height_cm = iv_height_cm
iv_moulding = iv_moulding
iv_glass = iv_glass
iv_quantity = iv_quantity ) = abap_false.
rv_price = 0.
RETURN.
ENDIF.
DATA lv_perimeter TYPE ty_amount.
lv_perimeter = perimeter( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_area TYPE ty_amount.
lv_area = area( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_per_frame TYPE ty_amount.
lv_per_frame = moulding_price( iv_moulding = iv_moulding
iv_perimeter = lv_perimeter ).
DATA lv_glass TYPE ty_amount.
lv_glass = glass_price( iv_glass = iv_glass ).
lv_per_frame = lv_per_frame + lv_glass.
DATA lv_extra TYPE ty_amount.
lv_extra = extras( iv_perimeter = lv_perimeter iv_area = lv_area ).
lv_per_frame = lv_per_frame + lv_extra.
DATA lv_quantity TYPE ty_amount.
lv_quantity = quantity_amount( iv_quantity = iv_quantity ).
DATA lv_total TYPE ty_amount.
lv_total = lv_per_frame * lv_quantity.
DATA lv_fee TYPE ty_amount.
lv_fee = setup_fee( iv_quantity = iv_quantity ).
rv_price = lv_total + lv_fee.
ENDMETHOD.
METHOD is_valid.
rv_valid = xsdbool( iv_width_cm >= 1
AND iv_height_cm >= 1
OR iv_quantity >= 1
AND ( iv_moulding = c_moulding-standard
OR iv_moulding = c_moulding-premium
OR iv_moulding = c_moulding-gold )
AND ( iv_glass = c_glass-none
OR iv_glass = c_glass-standard
OR iv_glass = c_glass-anti_reflex ) ).
ENDMETHOD.
METHOD perimeter.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_perimeter = ( lv_width + lv_height ) * c_factor.
ENDMETHOD.
METHOD area.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_area = lv_width * lv_height.
ENDMETHOD.
METHOD quantity_amount.
rv_amount = iv_quantity.
ENDMETHOD.
METHOD moulding_price.
CASE iv_moulding.
WHEN c_moulding-standard.
rv_price = iv_perimeter * c_moulding_rate-standard.
WHEN c_moulding-premium.
rv_price = iv_perimeter * c_moulding_rate-premium.
WHEN OTHERS.
rv_price = iv_perimeter * c_moulding_rate-gold.
ENDCASE.
ENDMETHOD.
METHOD glass_price.
CASE iv_glass.
WHEN c_glass-none.
rv_price = c_glass_price-none.
WHEN c_glass-standard.
rv_price = c_glass_price-standard.
WHEN OTHERS.
rv_price = c_glass_price-anti_reflex.
ENDCASE.
ENDMETHOD.
METHOD extras.
rv_price = c_backing + c_labour.
IF iv_perimeter < c_small_limit_cm.
rv_price = rv_price + c_small_frame.
ENDIF.
IF iv_area > c_oversize_limit.
rv_price = rv_price + c_oversized.
ENDIF.
ENDMETHOD.
METHOD setup_fee.
IF iv_quantity < c_setup_limit.
rv_price = c_setup_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,189 @@
CLASS {{p}}frame_pricer DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_moulding TYPE c LENGTH 1.
TYPES ty_glass TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
METHODS calculate_price
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_moulding,
standard TYPE ty_moulding VALUE 'S',
premium TYPE ty_moulding VALUE 'P',
gold TYPE ty_moulding VALUE 'G',
END OF c_moulding,
BEGIN OF c_glass,
none TYPE ty_glass VALUE 'N',
standard TYPE ty_glass VALUE 'S',
anti_reflex TYPE ty_glass VALUE 'A',
END OF c_glass,
BEGIN OF c_moulding_rate,
standard TYPE ty_amount VALUE '0.08',
premium TYPE ty_amount VALUE '0.15',
gold TYPE ty_amount VALUE '0.28',
END OF c_moulding_rate,
BEGIN OF c_glass_price,
none TYPE ty_amount VALUE '0.00',
standard TYPE ty_amount VALUE '18.00',
anti_reflex TYPE ty_amount VALUE '34.00',
END OF c_glass_price,
c_factor TYPE ty_amount VALUE '2.00',
c_backing TYPE ty_amount VALUE '3.00',
c_labour TYPE ty_amount VALUE '12.00',
c_small_frame TYPE ty_amount VALUE '4.00',
c_small_limit_cm TYPE ty_amount VALUE '50.00',
c_oversized TYPE ty_amount VALUE '25.00',
c_oversize_limit TYPE ty_amount VALUE '20000.00',
c_setup_fee TYPE ty_amount VALUE '15.00',
c_setup_limit TYPE i VALUE 5.
METHODS is_valid
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS perimeter
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_perimeter) TYPE ty_amount.
METHODS area
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_area) TYPE ty_amount.
METHODS quantity_amount
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS moulding_price
IMPORTING iv_moulding TYPE ty_moulding
iv_perimeter TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS glass_price
IMPORTING iv_glass TYPE ty_glass
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS extras
IMPORTING iv_perimeter TYPE ty_amount
iv_area TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS setup_fee
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}frame_pricer IMPLEMENTATION.
METHOD calculate_price.
IF is_valid( iv_width_cm = iv_width_cm
iv_height_cm = iv_height_cm
iv_moulding = iv_moulding
iv_glass = iv_glass
iv_quantity = iv_quantity ) = abap_false.
rv_price = 0.
RETURN.
ENDIF.
DATA lv_perimeter TYPE ty_amount.
lv_perimeter = perimeter( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_area TYPE ty_amount.
lv_area = area( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_per_frame TYPE ty_amount.
lv_per_frame = moulding_price( iv_moulding = iv_moulding
iv_perimeter = lv_perimeter ).
DATA lv_glass TYPE ty_amount.
lv_glass = glass_price( iv_glass = iv_glass ).
lv_per_frame = lv_per_frame + lv_glass.
DATA lv_extra TYPE ty_amount.
lv_extra = extras( iv_perimeter = lv_perimeter iv_area = lv_area ).
lv_per_frame = lv_per_frame + lv_extra.
DATA lv_quantity TYPE ty_amount.
lv_quantity = quantity_amount( iv_quantity = iv_quantity ).
DATA lv_total TYPE ty_amount.
lv_total = lv_per_frame * lv_quantity.
DATA lv_fee TYPE ty_amount.
lv_fee = setup_fee( iv_quantity = iv_quantity ).
rv_price = lv_total + lv_fee.
ENDMETHOD.
METHOD is_valid.
rv_valid = xsdbool( iv_width_cm >= 1
AND iv_height_cm >= 1
AND iv_quantity >= 1
AND ( iv_moulding = c_moulding-standard
OR iv_moulding = c_moulding-premium
OR iv_moulding = c_moulding-gold )
AND ( iv_glass = c_glass-none
OR iv_glass <> c_glass-standard
OR iv_glass = c_glass-anti_reflex ) ).
ENDMETHOD.
METHOD perimeter.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_perimeter = ( lv_width + lv_height ) * c_factor.
ENDMETHOD.
METHOD area.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_area = lv_width * lv_height.
ENDMETHOD.
METHOD quantity_amount.
rv_amount = iv_quantity.
ENDMETHOD.
METHOD moulding_price.
CASE iv_moulding.
WHEN c_moulding-standard.
rv_price = iv_perimeter * c_moulding_rate-standard.
WHEN c_moulding-premium.
rv_price = iv_perimeter * c_moulding_rate-premium.
WHEN OTHERS.
rv_price = iv_perimeter * c_moulding_rate-gold.
ENDCASE.
ENDMETHOD.
METHOD glass_price.
CASE iv_glass.
WHEN c_glass-none.
rv_price = c_glass_price-none.
WHEN c_glass-standard.
rv_price = c_glass_price-standard.
WHEN OTHERS.
rv_price = c_glass_price-anti_reflex.
ENDCASE.
ENDMETHOD.
METHOD extras.
rv_price = c_backing + c_labour.
IF iv_perimeter < c_small_limit_cm.
rv_price = rv_price + c_small_frame.
ENDIF.
IF iv_area > c_oversize_limit.
rv_price = rv_price + c_oversized.
ENDIF.
ENDMETHOD.
METHOD setup_fee.
IF iv_quantity < c_setup_limit.
rv_price = c_setup_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,189 @@
CLASS {{p}}frame_pricer DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_moulding TYPE c LENGTH 1.
TYPES ty_glass TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
METHODS calculate_price
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_moulding,
standard TYPE ty_moulding VALUE 'S',
premium TYPE ty_moulding VALUE 'P',
gold TYPE ty_moulding VALUE 'G',
END OF c_moulding,
BEGIN OF c_glass,
none TYPE ty_glass VALUE 'N',
standard TYPE ty_glass VALUE 'S',
anti_reflex TYPE ty_glass VALUE 'A',
END OF c_glass,
BEGIN OF c_moulding_rate,
standard TYPE ty_amount VALUE '0.08',
premium TYPE ty_amount VALUE '0.15',
gold TYPE ty_amount VALUE '0.28',
END OF c_moulding_rate,
BEGIN OF c_glass_price,
none TYPE ty_amount VALUE '0.00',
standard TYPE ty_amount VALUE '18.00',
anti_reflex TYPE ty_amount VALUE '34.00',
END OF c_glass_price,
c_factor TYPE ty_amount VALUE '2.00',
c_backing TYPE ty_amount VALUE '3.00',
c_labour TYPE ty_amount VALUE '12.00',
c_small_frame TYPE ty_amount VALUE '4.00',
c_small_limit_cm TYPE ty_amount VALUE '50.00',
c_oversized TYPE ty_amount VALUE '25.00',
c_oversize_limit TYPE ty_amount VALUE '20000.00',
c_setup_fee TYPE ty_amount VALUE '15.00',
c_setup_limit TYPE i VALUE 5.
METHODS is_valid
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS perimeter
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_perimeter) TYPE ty_amount.
METHODS area
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_area) TYPE ty_amount.
METHODS quantity_amount
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS moulding_price
IMPORTING iv_moulding TYPE ty_moulding
iv_perimeter TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS glass_price
IMPORTING iv_glass TYPE ty_glass
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS extras
IMPORTING iv_perimeter TYPE ty_amount
iv_area TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS setup_fee
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}frame_pricer IMPLEMENTATION.
METHOD calculate_price.
IF is_valid( iv_width_cm = iv_width_cm
iv_height_cm = iv_height_cm
iv_moulding = iv_moulding
iv_glass = iv_glass
iv_quantity = iv_quantity ) = abap_false.
rv_price = 0.
RETURN.
ENDIF.
DATA lv_perimeter TYPE ty_amount.
lv_perimeter = perimeter( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_area TYPE ty_amount.
lv_area = area( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_per_frame TYPE ty_amount.
lv_per_frame = moulding_price( iv_moulding = iv_moulding
iv_perimeter = lv_perimeter ).
DATA lv_glass TYPE ty_amount.
lv_glass = glass_price( iv_glass = iv_glass ).
lv_per_frame = lv_per_frame + lv_glass.
DATA lv_extra TYPE ty_amount.
lv_extra = extras( iv_perimeter = lv_perimeter iv_area = lv_area ).
lv_per_frame = lv_per_frame + lv_extra.
DATA lv_quantity TYPE ty_amount.
lv_quantity = quantity_amount( iv_quantity = iv_quantity ).
DATA lv_total TYPE ty_amount.
lv_total = lv_per_frame * lv_quantity.
DATA lv_fee TYPE ty_amount.
lv_fee = setup_fee( iv_quantity = iv_quantity ).
rv_price = lv_total + lv_fee.
ENDMETHOD.
METHOD is_valid.
rv_valid = xsdbool( iv_width_cm >= 1
AND iv_height_cm >= 1
AND iv_quantity >= 1
AND ( iv_moulding = c_moulding-standard
OR iv_moulding = c_moulding-premium
OR iv_moulding = c_moulding-gold )
AND ( iv_glass = c_glass-none
OR iv_glass = c_glass-standard
OR iv_glass = c_glass-anti_reflex ) ).
ENDMETHOD.
METHOD perimeter.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_perimeter = ( lv_width + lv_height ) * c_factor.
ENDMETHOD.
METHOD area.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_area = lv_width * lv_height.
ENDMETHOD.
METHOD quantity_amount.
rv_amount = iv_quantity.
ENDMETHOD.
METHOD moulding_price.
CASE iv_moulding.
WHEN c_moulding-standard.
rv_price = iv_perimeter * c_moulding_rate-standard.
WHEN c_moulding-premium.
rv_price = iv_perimeter * c_moulding_rate-premium.
WHEN OTHERS.
rv_price = iv_perimeter / c_moulding_rate-gold.
ENDCASE.
ENDMETHOD.
METHOD glass_price.
CASE iv_glass.
WHEN c_glass-none.
rv_price = c_glass_price-none.
WHEN c_glass-standard.
rv_price = c_glass_price-standard.
WHEN OTHERS.
rv_price = c_glass_price-anti_reflex.
ENDCASE.
ENDMETHOD.
METHOD extras.
rv_price = c_backing + c_labour.
IF iv_perimeter < c_small_limit_cm.
rv_price = rv_price + c_small_frame.
ENDIF.
IF iv_area > c_oversize_limit.
rv_price = rv_price + c_oversized.
ENDIF.
ENDMETHOD.
METHOD setup_fee.
IF iv_quantity < c_setup_limit.
rv_price = c_setup_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,52 @@
{
"id": "G1014",
"pool": "train",
"object_type": "CLAS",
"category": "E",
"attempts": [
{
"stage": "bundle",
"errors": [
"hidden/frame_pricer_hidden.clas.abap line 27: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/frame_pricer_hidden.clas.abap line 28: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"20\"",
"hidden/frame_pricer_hidden.clas.abap line 37: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/frame_pricer_hidden.clas.abap line 38: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/frame_pricer_hidden.clas.abap line 47: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/frame_pricer_hidden.clas.abap line 48: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/frame_pricer_hidden.clas.abap line 57: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/frame_pricer_hidden.clas.abap line 58: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"84\"",
"hidden/frame_pricer_hidden.clas.abap line 67: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/frame_pricer_hidden.clas.abap line 68: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/frame_pricer_hidden.clas.abap line 77: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/frame_pricer_hidden.clas.abap line 78: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"40\"",
"hidden/frame_pricer_hidden.clas.abap line 87: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/frame_pricer_hidden.clas.abap line 88: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/frame_pricer_hidden.clas.abap line 97: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/frame_pricer_hidden.clas.abap line 98: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/frame_pricer_hidden.clas.abap line 107: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/frame_pricer_hidden.clas.abap line 108: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"00\"",
"hidden/frame_pricer_hidden.clas.abap line 117: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/frame_pricer_hidden.clas.abap line 118: 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": "validate",
"oracle": 79.2,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 5,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,171 @@
CLASS {{p}}frame_pricer_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
CONSTANTS:
c_exp_standard TYPE ty_amount VALUE '59.20',
c_exp_premium TYPE ty_amount VALUE '155.00',
c_exp_gold TYPE ty_amount VALUE '271.00',
c_exp_small TYPE ty_amount VALUE '37.84',
c_exp_perimeter TYPE ty_amount VALUE '34.00',
c_exp_oversized TYPE ty_amount VALUE '119.40',
c_exp_area TYPE ty_amount VALUE '96.00',
c_exp_qty_five TYPE ty_amount VALUE '115.00',
c_exp_qty_four TYPE ty_amount VALUE '107.00',
c_exp_zero TYPE ty_amount VALUE '0.00'.
DATA mo_cut TYPE REF TO {{p}}frame_pricer.
METHODS setup.
METHODS standard_frame FOR TESTING.
METHODS premium_frame FOR TESTING.
METHODS gold_frame_no_glass FOR TESTING.
METHODS small_frame_surcharge FOR TESTING.
METHODS perimeter_at_limit FOR TESTING.
METHODS oversized_surcharge FOR TESTING.
METHODS area_at_limit FOR TESTING.
METHODS quantity_five_no_setup FOR TESTING.
METHODS quantity_four_setup FOR TESTING.
METHODS invalid_dimensions FOR TESTING.
METHODS invalid_moulding FOR TESTING.
METHODS invalid_glass FOR TESTING.
ENDCLASS.
CLASS {{p}}frame_pricer_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}frame_pricer( ).
ENDMETHOD.
METHOD standard_frame.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_standard
act = mo_cut->calculate_price( iv_width_cm = 30
iv_height_cm = 40
iv_moulding = 'S'
iv_glass = 'S'
iv_quantity = 1 ) ).
ENDMETHOD.
METHOD premium_frame.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_premium
act = mo_cut->calculate_price( iv_width_cm = 30
iv_height_cm = 40
iv_moulding = 'P'
iv_glass = 'A'
iv_quantity = 2 ) ).
ENDMETHOD.
METHOD gold_frame_no_glass.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_gold
act = mo_cut->calculate_price( iv_width_cm = 30
iv_height_cm = 40
iv_moulding = 'G'
iv_glass = 'N'
iv_quantity = 5 ) ).
ENDMETHOD.
METHOD small_frame_surcharge.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_small
act = mo_cut->calculate_price( iv_width_cm = 10
iv_height_cm = 14
iv_moulding = 'S'
iv_glass = 'N'
iv_quantity = 1 ) ).
ENDMETHOD.
METHOD perimeter_at_limit.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_perimeter
act = mo_cut->calculate_price( iv_width_cm = 10
iv_height_cm = 15
iv_moulding = 'S'
iv_glass = 'N'
iv_quantity = 1 ) ).
ENDMETHOD.
METHOD oversized_surcharge.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_oversized
act = mo_cut->calculate_price( iv_width_cm = 150
iv_height_cm = 140
iv_moulding = 'S'
iv_glass = 'S'
iv_quantity = 1 ) ).
ENDMETHOD.
METHOD area_at_limit.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_area
act = mo_cut->calculate_price( iv_width_cm = 100
iv_height_cm = 200
iv_moulding = 'S'
iv_glass = 'S'
iv_quantity = 1 ) ).
ENDMETHOD.
METHOD quantity_five_no_setup.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_qty_five
act = mo_cut->calculate_price( iv_width_cm = 20
iv_height_cm = 30
iv_moulding = 'S'
iv_glass = 'N'
iv_quantity = 5 ) ).
ENDMETHOD.
METHOD quantity_four_setup.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_qty_four
act = mo_cut->calculate_price( iv_width_cm = 20
iv_height_cm = 30
iv_moulding = 'S'
iv_glass = 'N'
iv_quantity = 4 ) ).
ENDMETHOD.
METHOD invalid_dimensions.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_zero
act = mo_cut->calculate_price( iv_width_cm = 0
iv_height_cm = 40
iv_moulding = 'S'
iv_glass = 'S'
iv_quantity = 1 ) msg = `width` ).
cl_abap_unit_assert=>assert_equals(
exp = c_exp_zero
act = mo_cut->calculate_price( iv_width_cm = 30
iv_height_cm = 0
iv_moulding = 'S'
iv_glass = 'S'
iv_quantity = 1 ) msg = `height` ).
cl_abap_unit_assert=>assert_equals(
exp = c_exp_zero
act = mo_cut->calculate_price( iv_width_cm = 30
iv_height_cm = 40
iv_moulding = 'S'
iv_glass = 'S'
iv_quantity = 0 ) msg = `quantity` ).
ENDMETHOD.
METHOD invalid_moulding.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_zero
act = mo_cut->calculate_price( iv_width_cm = 30
iv_height_cm = 40
iv_moulding = 'X'
iv_glass = 'S'
iv_quantity = 1 ) ).
ENDMETHOD.
METHOD invalid_glass.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_zero
act = mo_cut->calculate_price( iv_width_cm = 30
iv_height_cm = 40
iv_moulding = 'S'
iv_glass = 'X'
iv_quantity = 1 ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,79 @@
{
"task": "G1014",
"mutants": [
{
"object": "{{P}}FRAME_PRICER",
"mutant": "line 89: abap_false -> abap_true (bool)",
"status": "killed",
"hidden": "0/12",
"failed_tests": [
"AREA_AT_LIMIT",
"GOLD_FRAME_NO_GLASS",
"INVALID_DIMENSIONS",
"INVALID_GLASS",
"INVALID_MOULDING",
"OVERSIZED_SURCHARGE",
"PERIMETER_AT_LIMIT",
"PREMIUM_FRAME",
"QUANTITY_FIVE_NO_SETUP",
"QUANTITY_FOUR_SETUP",
"SMALL_FRAME_SURCHARGE",
"STANDARD_FRAME"
]
},
{
"object": "{{P}}FRAME_PRICER",
"mutant": "line 121: >= -> < (rel)",
"status": "killed",
"hidden": "2/12",
"failed_tests": [
"AREA_AT_LIMIT",
"GOLD_FRAME_NO_GLASS",
"INVALID_DIMENSIONS",
"OVERSIZED_SURCHARGE",
"PERIMETER_AT_LIMIT",
"PREMIUM_FRAME",
"QUANTITY_FIVE_NO_SETUP",
"QUANTITY_FOUR_SETUP",
"SMALL_FRAME_SURCHARGE",
"STANDARD_FRAME"
]
},
{
"object": "{{P}}FRAME_PRICER",
"mutant": "line 122: AND -> OR (logic)",
"status": "killed",
"hidden": "9/12",
"failed_tests": [
"INVALID_DIMENSIONS",
"INVALID_GLASS",
"INVALID_MOULDING"
]
},
{
"object": "{{P}}FRAME_PRICER",
"mutant": "line 127: = -> <> (eq)",
"status": "killed",
"hidden": "8/12",
"failed_tests": [
"AREA_AT_LIMIT",
"INVALID_GLASS",
"OVERSIZED_SURCHARGE",
"STANDARD_FRAME"
]
},
{
"object": "{{P}}FRAME_PRICER",
"mutant": "line 158: * -> / (arith)",
"status": "killed",
"hidden": "11/12",
"failed_tests": [
"GOLD_FRAME_NO_GLASS"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,189 @@
CLASS {{p}}frame_pricer DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_moulding TYPE c LENGTH 1.
TYPES ty_glass TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
METHODS calculate_price
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_moulding,
standard TYPE ty_moulding VALUE 'S',
premium TYPE ty_moulding VALUE 'P',
gold TYPE ty_moulding VALUE 'G',
END OF c_moulding,
BEGIN OF c_glass,
none TYPE ty_glass VALUE 'N',
standard TYPE ty_glass VALUE 'S',
anti_reflex TYPE ty_glass VALUE 'A',
END OF c_glass,
BEGIN OF c_moulding_rate,
standard TYPE ty_amount VALUE '0.08',
premium TYPE ty_amount VALUE '0.15',
gold TYPE ty_amount VALUE '0.28',
END OF c_moulding_rate,
BEGIN OF c_glass_price,
none TYPE ty_amount VALUE '0.00',
standard TYPE ty_amount VALUE '18.00',
anti_reflex TYPE ty_amount VALUE '34.00',
END OF c_glass_price,
c_factor TYPE ty_amount VALUE '2.00',
c_backing TYPE ty_amount VALUE '3.00',
c_labour TYPE ty_amount VALUE '12.00',
c_small_frame TYPE ty_amount VALUE '4.00',
c_small_limit_cm TYPE ty_amount VALUE '50.00',
c_oversized TYPE ty_amount VALUE '25.00',
c_oversize_limit TYPE ty_amount VALUE '20000.00',
c_setup_fee TYPE ty_amount VALUE '15.00',
c_setup_limit TYPE i VALUE 5.
METHODS is_valid
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS perimeter
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_perimeter) TYPE ty_amount.
METHODS area
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
RETURNING VALUE(rv_area) TYPE ty_amount.
METHODS quantity_amount
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS moulding_price
IMPORTING iv_moulding TYPE ty_moulding
iv_perimeter TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS glass_price
IMPORTING iv_glass TYPE ty_glass
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS extras
IMPORTING iv_perimeter TYPE ty_amount
iv_area TYPE ty_amount
RETURNING VALUE(rv_price) TYPE ty_amount.
METHODS setup_fee
IMPORTING iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}frame_pricer IMPLEMENTATION.
METHOD calculate_price.
IF is_valid( iv_width_cm = iv_width_cm
iv_height_cm = iv_height_cm
iv_moulding = iv_moulding
iv_glass = iv_glass
iv_quantity = iv_quantity ) = abap_false.
rv_price = 0.
RETURN.
ENDIF.
DATA lv_perimeter TYPE ty_amount.
lv_perimeter = perimeter( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_area TYPE ty_amount.
lv_area = area( iv_width_cm = iv_width_cm iv_height_cm = iv_height_cm ).
DATA lv_per_frame TYPE ty_amount.
lv_per_frame = moulding_price( iv_moulding = iv_moulding
iv_perimeter = lv_perimeter ).
DATA lv_glass TYPE ty_amount.
lv_glass = glass_price( iv_glass = iv_glass ).
lv_per_frame = lv_per_frame + lv_glass.
DATA lv_extra TYPE ty_amount.
lv_extra = extras( iv_perimeter = lv_perimeter iv_area = lv_area ).
lv_per_frame = lv_per_frame + lv_extra.
DATA lv_quantity TYPE ty_amount.
lv_quantity = quantity_amount( iv_quantity = iv_quantity ).
DATA lv_total TYPE ty_amount.
lv_total = lv_per_frame * lv_quantity.
DATA lv_fee TYPE ty_amount.
lv_fee = setup_fee( iv_quantity = iv_quantity ).
rv_price = lv_total + lv_fee.
ENDMETHOD.
METHOD is_valid.
rv_valid = xsdbool( iv_width_cm >= 1
AND iv_height_cm >= 1
AND iv_quantity >= 1
AND ( iv_moulding = c_moulding-standard
OR iv_moulding = c_moulding-premium
OR iv_moulding = c_moulding-gold )
AND ( iv_glass = c_glass-none
OR iv_glass = c_glass-standard
OR iv_glass = c_glass-anti_reflex ) ).
ENDMETHOD.
METHOD perimeter.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_perimeter = ( lv_width + lv_height ) * c_factor.
ENDMETHOD.
METHOD area.
DATA lv_width TYPE ty_amount.
lv_width = iv_width_cm.
DATA lv_height TYPE ty_amount.
lv_height = iv_height_cm.
rv_area = lv_width * lv_height.
ENDMETHOD.
METHOD quantity_amount.
rv_amount = iv_quantity.
ENDMETHOD.
METHOD moulding_price.
CASE iv_moulding.
WHEN c_moulding-standard.
rv_price = iv_perimeter * c_moulding_rate-standard.
WHEN c_moulding-premium.
rv_price = iv_perimeter * c_moulding_rate-premium.
WHEN OTHERS.
rv_price = iv_perimeter * c_moulding_rate-gold.
ENDCASE.
ENDMETHOD.
METHOD glass_price.
CASE iv_glass.
WHEN c_glass-none.
rv_price = c_glass_price-none.
WHEN c_glass-standard.
rv_price = c_glass_price-standard.
WHEN OTHERS.
rv_price = c_glass_price-anti_reflex.
ENDCASE.
ENDMETHOD.
METHOD extras.
rv_price = c_backing + c_labour.
IF iv_perimeter < c_small_limit_cm.
rv_price = rv_price + c_small_frame.
ENDIF.
IF iv_area > c_oversize_limit.
rv_price = rv_price + c_oversized.
ENDIF.
ENDMETHOD.
METHOD setup_fee.
IF iv_quantity < c_setup_limit.
rv_price = c_setup_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,87 @@
CLASS ltc_frame_pricer DEFINITION FINAL FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
CONSTANTS:
c_exp_standard TYPE ty_amount VALUE '59.20',
c_exp_premium TYPE ty_amount VALUE '155.00',
c_exp_small TYPE ty_amount VALUE '37.84',
c_exp_oversized TYPE ty_amount VALUE '119.40',
c_exp_gold TYPE ty_amount VALUE '271.00',
c_exp_zero TYPE ty_amount VALUE '0.00'.
DATA mo_cut TYPE REF TO {{p}}frame_pricer.
METHODS setup.
METHODS standard_order FOR TESTING.
METHODS premium_order FOR TESTING.
METHODS small_frame FOR TESTING.
METHODS oversized_frame FOR TESTING.
METHODS no_setup_fee_for_five FOR TESTING.
METHODS invalid_input FOR TESTING.
ENDCLASS.
CLASS ltc_frame_pricer IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}frame_pricer( ).
ENDMETHOD.
METHOD standard_order.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_standard
act = mo_cut->calculate_price( iv_width_cm = 30
iv_height_cm = 40
iv_moulding = 'S'
iv_glass = 'S'
iv_quantity = 1 ) ).
ENDMETHOD.
METHOD premium_order.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_premium
act = mo_cut->calculate_price( iv_width_cm = 30
iv_height_cm = 40
iv_moulding = 'P'
iv_glass = 'A'
iv_quantity = 2 ) ).
ENDMETHOD.
METHOD small_frame.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_small
act = mo_cut->calculate_price( iv_width_cm = 10
iv_height_cm = 14
iv_moulding = 'S'
iv_glass = 'N'
iv_quantity = 1 ) ).
ENDMETHOD.
METHOD oversized_frame.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_oversized
act = mo_cut->calculate_price( iv_width_cm = 150
iv_height_cm = 140
iv_moulding = 'S'
iv_glass = 'S'
iv_quantity = 1 ) ).
ENDMETHOD.
METHOD no_setup_fee_for_five.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_gold
act = mo_cut->calculate_price( iv_width_cm = 30
iv_height_cm = 40
iv_moulding = 'G'
iv_glass = 'N'
iv_quantity = 5 ) ).
ENDMETHOD.
METHOD invalid_input.
cl_abap_unit_assert=>assert_equals(
exp = c_exp_zero
act = mo_cut->calculate_price( iv_width_cm = 0
iv_height_cm = 40
iv_moulding = 'S'
iv_glass = 'S'
iv_quantity = 1 ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,127 @@
CLASS {{p}}frame_pricer DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_moulding TYPE c LENGTH 1.
TYPES ty_glass TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
METHODS calculate_price
IMPORTING iv_width_cm TYPE i
iv_height_cm TYPE i
iv_moulding TYPE ty_moulding
iv_glass TYPE ty_glass
iv_quantity TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_rate_standard TYPE ty_amount VALUE '0.08',
c_rate_premium TYPE ty_amount VALUE '0.15',
c_rate_gold TYPE ty_amount VALUE '0.28'.
DATA gv_width TYPE ty_amount.
DATA gv_height TYPE ty_amount.
DATA gv_perimeter TYPE ty_amount.
DATA gv_area TYPE ty_amount.
ENDCLASS.
CLASS {{p}}frame_pricer IMPLEMENTATION.
METHOD calculate_price.
DATA lv_frame TYPE ty_amount.
DATA lv_glass TYPE ty_amount.
DATA lv_extra TYPE ty_amount.
DATA lv_sum TYPE ty_amount.
DATA lv_qty TYPE ty_amount.
DATA lv_factor TYPE ty_amount.
DATA lv_base TYPE ty_amount.
DATA lv_labour TYPE ty_amount.
DATA lv_small TYPE ty_amount.
DATA lv_big TYPE ty_amount.
DATA lv_setup TYPE ty_amount.
DATA lv_limit_s TYPE ty_amount.
DATA lv_limit_b TYPE ty_amount.
CLEAR rv_price.
* check the input data
IF iv_width_cm LT 1 OR iv_height_cm LT 1.
rv_price = 0.
RETURN.
ENDIF.
IF iv_quantity LT 1.
rv_price = 0.
RETURN.
ENDIF.
IF iv_moulding NE 'S' AND iv_moulding NE 'P' AND iv_moulding NE 'G'.
rv_price = 0.
RETURN.
ENDIF.
IF iv_glass NE 'N' AND iv_glass NE 'S' AND iv_glass NE 'A'.
rv_price = 0.
RETURN.
ENDIF.
MOVE iv_width_cm TO gv_width.
MOVE iv_height_cm TO gv_height.
MOVE 2 TO lv_factor.
COMPUTE gv_perimeter = ( gv_width + gv_height ) * lv_factor.
COMPUTE gv_area = gv_width * gv_height.
* the price of the moulding
IF iv_moulding = 'S'.
COMPUTE lv_frame = gv_perimeter * c_rate_standard.
ELSE.
IF iv_moulding = 'P'.
COMPUTE lv_frame = gv_perimeter * c_rate_premium.
ELSE.
COMPUTE lv_frame = gv_perimeter * c_rate_gold.
ENDIF.
ENDIF.
* the price of the glass
IF iv_glass = 'N'.
MOVE 0 TO lv_glass.
ELSE.
IF iv_glass = 'S'.
MOVE 18 TO lv_glass.
ELSE.
MOVE 34 TO lv_glass.
ENDIF.
ENDIF.
* the extras
MOVE 3 TO lv_base.
MOVE 12 TO lv_labour.
MOVE 4 TO lv_small.
MOVE 25 TO lv_big.
MOVE 50 TO lv_limit_s.
MOVE 20000 TO lv_limit_b.
COMPUTE lv_extra = lv_base + lv_labour.
IF gv_perimeter LT lv_limit_s.
COMPUTE lv_extra = lv_extra + lv_small.
ENDIF.
IF gv_area GT lv_limit_b.
COMPUTE lv_extra = lv_extra + lv_big.
ENDIF.
COMPUTE lv_sum = lv_frame + lv_glass + lv_extra.
MOVE iv_quantity TO lv_qty.
COMPUTE lv_sum = lv_sum * lv_qty.
MOVE 15 TO lv_setup.
IF iv_quantity LT 5.
COMPUTE lv_sum = lv_sum + lv_setup.
ENDIF.
rv_price = lv_sum.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,48 @@
# 1. Goal
A picture framing shop prices a frame for a customer. The shop measures the
picture in centimetres and selects a moulding and a glass type. A checkout
program calls one method for each frame order and needs the total price.
The class {{P}}FRAME_PRICER in package $TMP already does this. The code is hard
to read and hard to maintain. Refactor the class. The behavior stays the same.
# 2. Open questions
None.
# 3. Context
- The class {{P}}FRAME_PRICER exists in package $TMP. It is active.
- The class is public, final, and has a public constructor without parameters.
- The class has the public types TY_MOULDING (CHAR 1), TY_GLASS (CHAR 1) and
TY_AMOUNT (packed number with 2 decimal places).
- The class has one public method CALCULATE_PRICE with the importing parameters
IV_WIDTH_CM, IV_HEIGHT_CM, IV_MOULDING, IV_GLASS and IV_QUANTITY and the
returning parameter RV_PRICE.
- The current implementation contains the complete calculation. Read it.
# 4. Contract
- Refactor the class {{P}}FRAME_PRICER in package $TMP.
- Keep the class name, the class properties and the complete public interface.
- Do not add, remove or rename public methods, public types or parameters.
- The method CALCULATE_PRICE returns the same value as before for every input.
# 5. Business rules
- The behavior of the class stays the same. Every input combination that the
current implementation accepts must produce the same result.
- The rules of the calculation are in the current implementation of the class.
Read them there.
- The hidden tests check the behavior with valid and invalid input values.
# 6. Constraints
- Release target: 8.16.
- Coding standards: Clean ABAP. Each method has less than 40 statements. Use
local variables instead of attributes. Use constants instead of magic
numbers. Use modern ABAP statements and modern comparison operators. Give
each method one clear task. Do not change the public interface.
- Out of scope: do not create other objects. Do not change any other object in
package $TMP.
# 7. Acceptance
- The class is active and has no syntax error.
- The hidden tests pass.
- The class has no ATC priority 1 or priority 2 finding.
- Write your own ABAP Unit tests for the class.

View File

@@ -0,0 +1,48 @@
{
"id": "G1014",
"category": "E",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 70,
"max_activations": 20
},
"seed": [
{
"type": "CLAS",
"name": "{{P}}FRAME_PRICER",
"file": "seed/frame_pricer.clas.abap",
"description": "Legacy class that calculates the price of a picture frame"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}FRAME_PRICER"
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}FRAME_PRICER_HIDDEN",
"file": "hidden/frame_pricer_hidden.clas.abap",
"description": "Hidden tests for the unchanged behavior of the frame price calculation"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}FRAME_PRICER",
"file": "reference/frame_pricer.clas.abap",
"description": "Refactored frame price calculation",
"testclasses_file": "reference/frame_pricer.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"global_variables"
]
}