Mutation check done on all accepted tasks; mutant fixes; dump filter in proxy

- skip sy-subrc lines and CDS type lengths; CDS literal mutants; mutate helper classes
- proxy: sap_short_dumps shows only dumps of the current run
- 26/26 tasks pass; results in docs/faz1-tasarim.md 11g

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 06:02:59 +02:00
parent 0ba25faeea
commit f907351c0d
108 changed files with 7384 additions and 8 deletions

View File

@@ -0,0 +1,92 @@
CLASS {{p}}stock_age DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_stock_age.
PRIVATE SECTION.
TYPES tt_age_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_age_row
WITH UNIQUE KEY material bucket.
TYPES tt_total_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_total
WITH UNIQUE KEY material.
METHODS age_in_days
IMPORTING is_batch TYPE {{p}}if_stock_age=>ty_batch
iv_key_date TYPE dats
RETURNING VALUE(rv_age) TYPE i.
METHODS bucket_of
IMPORTING iv_age TYPE i
RETURNING VALUE(rv_bucket) TYPE {{p}}if_stock_age=>ty_bucket.
ENDCLASS.
CLASS {{p}}stock_age IMPLEMENTATION.
METHOD {{p}}if_stock_age~analyze.
DATA lt_group TYPE tt_age_group.
LOOP AT it_batch INTO DATA(ls_batch).
DATA(lv_age) = age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ).
IF lv_age < 0.
CONTINUE.
ENDIF.
DATA(lv_bucket) = bucket_of( lv_age ).
ASSIGN lt_group[ material = ls_batch-material
bucket = lv_bucket ] TO FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT VALUE #( material = ls_batch-material bucket = lv_bucket )
INTO TABLE lt_group.
ASSIGN lt_group[ material = ls_batch-material
bucket = lv_bucket ] TO <ls_group>.
ENDIF.
<ls_group>-quantity = <ls_group>-quantity + ls_batch-quantity.
<ls_group>-batch_count = <ls_group>-batch_count + 1.
ENDLOOP.
rt_age = lt_group.
SORT rt_age BY material bucket.
ENDMETHOD.
METHOD {{p}}if_stock_age~total_by_material.
DATA lt_group TYPE tt_total_group.
LOOP AT it_batch INTO DATA(ls_batch).
IF age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ) < 0.
CONTINUE.
ENDIF.
ASSIGN lt_group[ material = ls_batch-material ] TO FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT VALUE #( material = ls_batch-material ) INTO TABLE lt_group.
ASSIGN lt_group[ material = ls_batch-material ] TO <ls_group>.
ENDIF.
<ls_group>-quantity = <ls_group>-quantity + ls_batch-quantity.
<ls_group>-batch_count = <ls_group>-batch_count - 1.
ENDLOOP.
rt_total = lt_group.
SORT rt_total BY material.
ENDMETHOD.
METHOD age_in_days.
IF is_batch-gr_date IS INITIAL OR is_batch-gr_date > iv_key_date.
rv_age = -1.
ELSE.
rv_age = iv_key_date - is_batch-gr_date.
ENDIF.
ENDMETHOD.
METHOD bucket_of.
IF iv_age <= 30.
rv_bucket = {{p}}if_stock_age=>c_bucket-d0_30.
ELSEIF iv_age <= 60.
rv_bucket = {{p}}if_stock_age=>c_bucket-d31_60.
ELSEIF iv_age <= 90.
rv_bucket = {{p}}if_stock_age=>c_bucket-d61_90.
ELSE.
rv_bucket = {{p}}if_stock_age=>c_bucket-d91_plus.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,92 @@
CLASS {{p}}stock_age DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_stock_age.
PRIVATE SECTION.
TYPES tt_age_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_age_row
WITH UNIQUE KEY material bucket.
TYPES tt_total_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_total
WITH UNIQUE KEY material.
METHODS age_in_days
IMPORTING is_batch TYPE {{p}}if_stock_age=>ty_batch
iv_key_date TYPE dats
RETURNING VALUE(rv_age) TYPE i.
METHODS bucket_of
IMPORTING iv_age TYPE i
RETURNING VALUE(rv_bucket) TYPE {{p}}if_stock_age=>ty_bucket.
ENDCLASS.
CLASS {{p}}stock_age IMPLEMENTATION.
METHOD {{p}}if_stock_age~analyze.
DATA lt_group TYPE tt_age_group.
LOOP AT it_batch INTO DATA(ls_batch).
DATA(lv_age) = age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ).
IF lv_age < 0.
CONTINUE.
ENDIF.
DATA(lv_bucket) = bucket_of( lv_age ).
ASSIGN lt_group[ material = ls_batch-material
bucket = lv_bucket ] TO FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT VALUE #( material = ls_batch-material bucket = lv_bucket )
INTO TABLE lt_group.
ASSIGN lt_group[ material = ls_batch-material
bucket = lv_bucket ] TO <ls_group>.
ENDIF.
<ls_group>-quantity = <ls_group>-quantity + ls_batch-quantity.
<ls_group>-batch_count = <ls_group>-batch_count + 1.
ENDLOOP.
rt_age = lt_group.
SORT rt_age BY material bucket.
ENDMETHOD.
METHOD {{p}}if_stock_age~total_by_material.
DATA lt_group TYPE tt_total_group.
LOOP AT it_batch INTO DATA(ls_batch).
IF age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ) < 0.
CONTINUE.
ENDIF.
ASSIGN lt_group[ material = ls_batch-material ] TO FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT VALUE #( material = ls_batch-material ) INTO TABLE lt_group.
ASSIGN lt_group[ material = ls_batch-material ] TO <ls_group>.
ENDIF.
<ls_group>-quantity = <ls_group>-quantity + ls_batch-quantity.
<ls_group>-batch_count = <ls_group>-batch_count + 1.
ENDLOOP.
rt_total = lt_group.
SORT rt_total BY material.
ENDMETHOD.
METHOD age_in_days.
IF is_batch-gr_date IS INITIAL AND is_batch-gr_date > iv_key_date.
rv_age = -1.
ELSE.
rv_age = iv_key_date - is_batch-gr_date.
ENDIF.
ENDMETHOD.
METHOD bucket_of.
IF iv_age <= 30.
rv_bucket = {{p}}if_stock_age=>c_bucket-d0_30.
ELSEIF iv_age <= 60.
rv_bucket = {{p}}if_stock_age=>c_bucket-d31_60.
ELSEIF iv_age <= 90.
rv_bucket = {{p}}if_stock_age=>c_bucket-d61_90.
ELSE.
rv_bucket = {{p}}if_stock_age=>c_bucket-d91_plus.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,92 @@
CLASS {{p}}stock_age DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_stock_age.
PRIVATE SECTION.
TYPES tt_age_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_age_row
WITH UNIQUE KEY material bucket.
TYPES tt_total_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_total
WITH UNIQUE KEY material.
METHODS age_in_days
IMPORTING is_batch TYPE {{p}}if_stock_age=>ty_batch
iv_key_date TYPE dats
RETURNING VALUE(rv_age) TYPE i.
METHODS bucket_of
IMPORTING iv_age TYPE i
RETURNING VALUE(rv_bucket) TYPE {{p}}if_stock_age=>ty_bucket.
ENDCLASS.
CLASS {{p}}stock_age IMPLEMENTATION.
METHOD {{p}}if_stock_age~analyze.
DATA lt_group TYPE tt_age_group.
LOOP AT it_batch INTO DATA(ls_batch).
DATA(lv_age) = age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ).
IF lv_age < 0.
CONTINUE.
ENDIF.
DATA(lv_bucket) = bucket_of( lv_age ).
ASSIGN lt_group[ material = ls_batch-material
bucket = lv_bucket ] TO FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT VALUE #( material = ls_batch-material bucket = lv_bucket )
INTO TABLE lt_group.
ASSIGN lt_group[ material = ls_batch-material
bucket = lv_bucket ] TO <ls_group>.
ENDIF.
<ls_group>-quantity = <ls_group>-quantity + ls_batch-quantity.
<ls_group>-batch_count = <ls_group>-batch_count + 1.
ENDLOOP.
rt_age = lt_group.
SORT rt_age BY material bucket.
ENDMETHOD.
METHOD {{p}}if_stock_age~total_by_material.
DATA lt_group TYPE tt_total_group.
LOOP AT it_batch INTO DATA(ls_batch).
IF age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ) < 0.
CONTINUE.
ENDIF.
ASSIGN lt_group[ material = ls_batch-material ] TO FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT VALUE #( material = ls_batch-material ) INTO TABLE lt_group.
ASSIGN lt_group[ material = ls_batch-material ] TO <ls_group>.
ENDIF.
<ls_group>-quantity = <ls_group>-quantity + ls_batch-quantity.
<ls_group>-batch_count = <ls_group>-batch_count + 1.
ENDLOOP.
rt_total = lt_group.
SORT rt_total BY material.
ENDMETHOD.
METHOD age_in_days.
IF is_batch-gr_date IS INITIAL OR is_batch-gr_date > iv_key_date.
rv_age = -1.
ELSE.
rv_age = iv_key_date + is_batch-gr_date.
ENDIF.
ENDMETHOD.
METHOD bucket_of.
IF iv_age <= 30.
rv_bucket = {{p}}if_stock_age=>c_bucket-d0_30.
ELSEIF iv_age <= 60.
rv_bucket = {{p}}if_stock_age=>c_bucket-d31_60.
ELSEIF iv_age <= 90.
rv_bucket = {{p}}if_stock_age=>c_bucket-d61_90.
ELSE.
rv_bucket = {{p}}if_stock_age=>c_bucket-d91_plus.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,92 @@
CLASS {{p}}stock_age DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_stock_age.
PRIVATE SECTION.
TYPES tt_age_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_age_row
WITH UNIQUE KEY material bucket.
TYPES tt_total_group TYPE HASHED TABLE OF {{p}}if_stock_age=>ty_total
WITH UNIQUE KEY material.
METHODS age_in_days
IMPORTING is_batch TYPE {{p}}if_stock_age=>ty_batch
iv_key_date TYPE dats
RETURNING VALUE(rv_age) TYPE i.
METHODS bucket_of
IMPORTING iv_age TYPE i
RETURNING VALUE(rv_bucket) TYPE {{p}}if_stock_age=>ty_bucket.
ENDCLASS.
CLASS {{p}}stock_age IMPLEMENTATION.
METHOD {{p}}if_stock_age~analyze.
DATA lt_group TYPE tt_age_group.
LOOP AT it_batch INTO DATA(ls_batch).
DATA(lv_age) = age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ).
IF lv_age < 0.
CONTINUE.
ENDIF.
DATA(lv_bucket) = bucket_of( lv_age ).
ASSIGN lt_group[ material = ls_batch-material
bucket = lv_bucket ] TO FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT VALUE #( material = ls_batch-material bucket = lv_bucket )
INTO TABLE lt_group.
ASSIGN lt_group[ material = ls_batch-material
bucket = lv_bucket ] TO <ls_group>.
ENDIF.
<ls_group>-quantity = <ls_group>-quantity + ls_batch-quantity.
<ls_group>-batch_count = <ls_group>-batch_count + 1.
ENDLOOP.
rt_age = lt_group.
SORT rt_age BY material bucket.
ENDMETHOD.
METHOD {{p}}if_stock_age~total_by_material.
DATA lt_group TYPE tt_total_group.
LOOP AT it_batch INTO DATA(ls_batch).
IF age_in_days( is_batch = ls_batch iv_key_date = iv_key_date ) < 0.
CONTINUE.
ENDIF.
ASSIGN lt_group[ material = ls_batch-material ] TO FIELD-SYMBOL(<ls_group>).
IF sy-subrc <> 0.
INSERT VALUE #( material = ls_batch-material ) INTO TABLE lt_group.
ASSIGN lt_group[ material = ls_batch-material ] TO <ls_group>.
ENDIF.
<ls_group>-quantity = <ls_group>-quantity + ls_batch-quantity.
<ls_group>-batch_count = <ls_group>-batch_count + 1.
ENDLOOP.
rt_total = lt_group.
SORT rt_total BY material.
ENDMETHOD.
METHOD age_in_days.
IF is_batch-gr_date IS INITIAL OR is_batch-gr_date > iv_key_date.
rv_age = -1.
ELSE.
rv_age = iv_key_date - is_batch-gr_date.
ENDIF.
ENDMETHOD.
METHOD bucket_of.
IF iv_age > 30.
rv_bucket = {{p}}if_stock_age=>c_bucket-d0_30.
ELSEIF iv_age <= 60.
rv_bucket = {{p}}if_stock_age=>c_bucket-d31_60.
ELSEIF iv_age <= 90.
rv_bucket = {{p}}if_stock_age=>c_bucket-d61_90.
ELSE.
rv_bucket = {{p}}if_stock_age=>c_bucket-d91_plus.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,59 @@
{
"task": "G0004",
"mutants": [
{
"object": "{{P}}STOCK_AGE",
"mutant": "line 55: = -> <> (eq)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
},
{
"object": "{{P}}STOCK_AGE",
"mutant": "line 66: + -> - (arith)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"TOTAL_GROUPS_BY_MATERIAL"
]
},
{
"object": "{{P}}STOCK_AGE",
"mutant": "line 74: OR -> AND (logic)",
"status": "killed",
"hidden": "8/10",
"failed_tests": [
"INVALID_ROWS_ARE_IGNORED",
"TOTAL_IGNORES_INVALID_ROWS"
]
},
{
"object": "{{P}}STOCK_AGE",
"mutant": "line 77: - -> + (arith)",
"status": "killed",
"hidden": "6/10",
"failed_tests": [
"BUCKET_BOUNDARIES",
"GROUPS_SUM_QUANTITY_AND_COUNT",
"RESULT_IS_SORTED",
"SINGLE_BATCH_BUCKET_01"
]
},
{
"object": "{{P}}STOCK_AGE",
"mutant": "line 82: <= -> > (rel)",
"status": "killed",
"hidden": "6/10",
"failed_tests": [
"BUCKET_BOUNDARIES",
"GROUPS_SUM_QUANTITY_AND_COUNT",
"RESULT_IS_SORTED",
"SINGLE_BATCH_BUCKET_01"
]
}
],
"valid": 4,
"killed": 4,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,79 @@
CLASS {{p}}loyalty_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_loyalty_rules.
PRIVATE SECTION.
CONSTANTS:
c_silver_threshold TYPE i VALUE 1000,
c_gold_threshold TYPE i VALUE 5000,
c_platinum_threshold TYPE i VALUE 20000.
METHODS normalize_points
IMPORTING iv_points TYPE i
RETURNING VALUE(rv_points) TYPE i.
METHODS tier_of
IMPORTING iv_points TYPE i
RETURNING VALUE(rv_tier) TYPE {{p}}if_loyalty_rules=>ty_tier.
METHODS points_to_tier
IMPORTING iv_points TYPE i
iv_tier TYPE {{p}}if_loyalty_rules=>ty_tier
RETURNING VALUE(rv_points) TYPE i.
ENDCLASS.
CLASS {{p}}loyalty_evaluator IMPLEMENTATION.
METHOD {{p}}if_loyalty_rules~get_tier.
rv_tier = tier_of( normalize_points( iv_points ) ).
ENDMETHOD.
METHOD {{p}}if_loyalty_rules~get_discount.
CASE iv_tier.
WHEN {{p}}if_loyalty_rules=>c_tier-silver.
rv_percent = 3.
WHEN {{p}}if_loyalty_rules=>c_tier-gold.
rv_percent = 7.
WHEN {{p}}if_loyalty_rules=>c_tier-platinum.
rv_percent = 12.
WHEN OTHERS.
rv_percent = 0.
ENDCASE.
ENDMETHOD.
METHOD {{p}}if_loyalty_rules~points_to_next_tier.
DATA(lv_points) = normalize_points( iv_points ).
DATA(lv_tier) = tier_of( lv_points ).
rv_points = points_to_tier( iv_points = lv_points
iv_tier = lv_tier ).
ENDMETHOD.
METHOD normalize_points.
rv_points = COND #( WHEN iv_points < 0 THEN 0 ELSE iv_points ).
ENDMETHOD.
METHOD tier_of.
IF iv_points >= c_platinum_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-platinum.
ELSEIF iv_points < c_gold_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-gold.
ELSEIF iv_points >= c_silver_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-silver.
ELSE.
rv_tier = {{p}}if_loyalty_rules=>c_tier-basic.
ENDIF.
ENDMETHOD.
METHOD points_to_tier.
CASE iv_tier.
WHEN {{p}}if_loyalty_rules=>c_tier-basic.
rv_points = c_silver_threshold - iv_points.
WHEN {{p}}if_loyalty_rules=>c_tier-silver.
rv_points = c_gold_threshold - iv_points.
WHEN {{p}}if_loyalty_rules=>c_tier-gold.
rv_points = c_platinum_threshold - iv_points.
WHEN OTHERS.
rv_points = 0.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,79 @@
CLASS {{p}}loyalty_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_loyalty_rules.
PRIVATE SECTION.
CONSTANTS:
c_silver_threshold TYPE i VALUE 1000,
c_gold_threshold TYPE i VALUE 5000,
c_platinum_threshold TYPE i VALUE 20000.
METHODS normalize_points
IMPORTING iv_points TYPE i
RETURNING VALUE(rv_points) TYPE i.
METHODS tier_of
IMPORTING iv_points TYPE i
RETURNING VALUE(rv_tier) TYPE {{p}}if_loyalty_rules=>ty_tier.
METHODS points_to_tier
IMPORTING iv_points TYPE i
iv_tier TYPE {{p}}if_loyalty_rules=>ty_tier
RETURNING VALUE(rv_points) TYPE i.
ENDCLASS.
CLASS {{p}}loyalty_evaluator IMPLEMENTATION.
METHOD {{p}}if_loyalty_rules~get_tier.
rv_tier = tier_of( normalize_points( iv_points ) ).
ENDMETHOD.
METHOD {{p}}if_loyalty_rules~get_discount.
CASE iv_tier.
WHEN {{p}}if_loyalty_rules=>c_tier-silver.
rv_percent = 3.
WHEN {{p}}if_loyalty_rules=>c_tier-gold.
rv_percent = 7.
WHEN {{p}}if_loyalty_rules=>c_tier-platinum.
rv_percent = 12.
WHEN OTHERS.
rv_percent = 0.
ENDCASE.
ENDMETHOD.
METHOD {{p}}if_loyalty_rules~points_to_next_tier.
DATA(lv_points) = normalize_points( iv_points ).
DATA(lv_tier) = tier_of( lv_points ).
rv_points = points_to_tier( iv_points = lv_points
iv_tier = lv_tier ).
ENDMETHOD.
METHOD normalize_points.
rv_points = COND #( WHEN iv_points < 0 THEN 0 ELSE iv_points ).
ENDMETHOD.
METHOD tier_of.
IF iv_points >= c_platinum_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-platinum.
ELSEIF iv_points >= c_gold_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-gold.
ELSEIF iv_points < c_silver_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-silver.
ELSE.
rv_tier = {{p}}if_loyalty_rules=>c_tier-basic.
ENDIF.
ENDMETHOD.
METHOD points_to_tier.
CASE iv_tier.
WHEN {{p}}if_loyalty_rules=>c_tier-basic.
rv_points = c_silver_threshold - iv_points.
WHEN {{p}}if_loyalty_rules=>c_tier-silver.
rv_points = c_gold_threshold - iv_points.
WHEN {{p}}if_loyalty_rules=>c_tier-gold.
rv_points = c_platinum_threshold - iv_points.
WHEN OTHERS.
rv_points = 0.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,79 @@
CLASS {{p}}loyalty_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_loyalty_rules.
PRIVATE SECTION.
CONSTANTS:
c_silver_threshold TYPE i VALUE 1000,
c_gold_threshold TYPE i VALUE 5000,
c_platinum_threshold TYPE i VALUE 20000.
METHODS normalize_points
IMPORTING iv_points TYPE i
RETURNING VALUE(rv_points) TYPE i.
METHODS tier_of
IMPORTING iv_points TYPE i
RETURNING VALUE(rv_tier) TYPE {{p}}if_loyalty_rules=>ty_tier.
METHODS points_to_tier
IMPORTING iv_points TYPE i
iv_tier TYPE {{p}}if_loyalty_rules=>ty_tier
RETURNING VALUE(rv_points) TYPE i.
ENDCLASS.
CLASS {{p}}loyalty_evaluator IMPLEMENTATION.
METHOD {{p}}if_loyalty_rules~get_tier.
rv_tier = tier_of( normalize_points( iv_points ) ).
ENDMETHOD.
METHOD {{p}}if_loyalty_rules~get_discount.
CASE iv_tier.
WHEN {{p}}if_loyalty_rules=>c_tier-silver.
rv_percent = 3.
WHEN {{p}}if_loyalty_rules=>c_tier-gold.
rv_percent = 7.
WHEN {{p}}if_loyalty_rules=>c_tier-platinum.
rv_percent = 12.
WHEN OTHERS.
rv_percent = 0.
ENDCASE.
ENDMETHOD.
METHOD {{p}}if_loyalty_rules~points_to_next_tier.
DATA(lv_points) = normalize_points( iv_points ).
DATA(lv_tier) = tier_of( lv_points ).
rv_points = points_to_tier( iv_points = lv_points
iv_tier = lv_tier ).
ENDMETHOD.
METHOD normalize_points.
rv_points = COND #( WHEN iv_points < 0 THEN 0 ELSE iv_points ).
ENDMETHOD.
METHOD tier_of.
IF iv_points >= c_platinum_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-platinum.
ELSEIF iv_points >= c_gold_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-gold.
ELSEIF iv_points >= c_silver_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-silver.
ELSE.
rv_tier = {{p}}if_loyalty_rules=>c_tier-basic.
ENDIF.
ENDMETHOD.
METHOD points_to_tier.
CASE iv_tier.
WHEN {{p}}if_loyalty_rules=>c_tier-basic.
rv_points = c_silver_threshold + iv_points.
WHEN {{p}}if_loyalty_rules=>c_tier-silver.
rv_points = c_gold_threshold - iv_points.
WHEN {{p}}if_loyalty_rules=>c_tier-gold.
rv_points = c_platinum_threshold - iv_points.
WHEN OTHERS.
rv_points = 0.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,79 @@
CLASS {{p}}loyalty_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_loyalty_rules.
PRIVATE SECTION.
CONSTANTS:
c_silver_threshold TYPE i VALUE 1000,
c_gold_threshold TYPE i VALUE 5000,
c_platinum_threshold TYPE i VALUE 20000.
METHODS normalize_points
IMPORTING iv_points TYPE i
RETURNING VALUE(rv_points) TYPE i.
METHODS tier_of
IMPORTING iv_points TYPE i
RETURNING VALUE(rv_tier) TYPE {{p}}if_loyalty_rules=>ty_tier.
METHODS points_to_tier
IMPORTING iv_points TYPE i
iv_tier TYPE {{p}}if_loyalty_rules=>ty_tier
RETURNING VALUE(rv_points) TYPE i.
ENDCLASS.
CLASS {{p}}loyalty_evaluator IMPLEMENTATION.
METHOD {{p}}if_loyalty_rules~get_tier.
rv_tier = tier_of( normalize_points( iv_points ) ).
ENDMETHOD.
METHOD {{p}}if_loyalty_rules~get_discount.
CASE iv_tier.
WHEN {{p}}if_loyalty_rules=>c_tier-silver.
rv_percent = 3.
WHEN {{p}}if_loyalty_rules=>c_tier-gold.
rv_percent = 7.
WHEN {{p}}if_loyalty_rules=>c_tier-platinum.
rv_percent = 12.
WHEN OTHERS.
rv_percent = 0.
ENDCASE.
ENDMETHOD.
METHOD {{p}}if_loyalty_rules~points_to_next_tier.
DATA(lv_points) = normalize_points( iv_points ).
DATA(lv_tier) = tier_of( lv_points ).
rv_points = points_to_tier( iv_points = lv_points
iv_tier = lv_tier ).
ENDMETHOD.
METHOD normalize_points.
rv_points = COND #( WHEN iv_points < 0 THEN 0 ELSE iv_points ).
ENDMETHOD.
METHOD tier_of.
IF iv_points >= c_platinum_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-platinum.
ELSEIF iv_points >= c_gold_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-gold.
ELSEIF iv_points >= c_silver_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-silver.
ELSE.
rv_tier = {{p}}if_loyalty_rules=>c_tier-basic.
ENDIF.
ENDMETHOD.
METHOD points_to_tier.
CASE iv_tier.
WHEN {{p}}if_loyalty_rules=>c_tier-basic.
rv_points = c_silver_threshold - iv_points.
WHEN {{p}}if_loyalty_rules=>c_tier-silver.
rv_points = c_gold_threshold + iv_points.
WHEN {{p}}if_loyalty_rules=>c_tier-gold.
rv_points = c_platinum_threshold - iv_points.
WHEN OTHERS.
rv_points = 0.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,79 @@
CLASS {{p}}loyalty_evaluator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_loyalty_rules.
PRIVATE SECTION.
CONSTANTS:
c_silver_threshold TYPE i VALUE 1000,
c_gold_threshold TYPE i VALUE 5000,
c_platinum_threshold TYPE i VALUE 20000.
METHODS normalize_points
IMPORTING iv_points TYPE i
RETURNING VALUE(rv_points) TYPE i.
METHODS tier_of
IMPORTING iv_points TYPE i
RETURNING VALUE(rv_tier) TYPE {{p}}if_loyalty_rules=>ty_tier.
METHODS points_to_tier
IMPORTING iv_points TYPE i
iv_tier TYPE {{p}}if_loyalty_rules=>ty_tier
RETURNING VALUE(rv_points) TYPE i.
ENDCLASS.
CLASS {{p}}loyalty_evaluator IMPLEMENTATION.
METHOD {{p}}if_loyalty_rules~get_tier.
rv_tier = tier_of( normalize_points( iv_points ) ).
ENDMETHOD.
METHOD {{p}}if_loyalty_rules~get_discount.
CASE iv_tier.
WHEN {{p}}if_loyalty_rules=>c_tier-silver.
rv_percent = 3.
WHEN {{p}}if_loyalty_rules=>c_tier-gold.
rv_percent = 7.
WHEN {{p}}if_loyalty_rules=>c_tier-platinum.
rv_percent = 12.
WHEN OTHERS.
rv_percent = 0.
ENDCASE.
ENDMETHOD.
METHOD {{p}}if_loyalty_rules~points_to_next_tier.
DATA(lv_points) = normalize_points( iv_points ).
DATA(lv_tier) = tier_of( lv_points ).
rv_points = points_to_tier( iv_points = lv_points
iv_tier = lv_tier ).
ENDMETHOD.
METHOD normalize_points.
rv_points = COND #( WHEN iv_points < 0 THEN 0 ELSE iv_points ).
ENDMETHOD.
METHOD tier_of.
IF iv_points >= c_platinum_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-platinum.
ELSEIF iv_points >= c_gold_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-gold.
ELSEIF iv_points >= c_silver_threshold.
rv_tier = {{p}}if_loyalty_rules=>c_tier-silver.
ELSE.
rv_tier = {{p}}if_loyalty_rules=>c_tier-basic.
ENDIF.
ENDMETHOD.
METHOD points_to_tier.
CASE iv_tier.
WHEN {{p}}if_loyalty_rules=>c_tier-basic.
rv_points = c_silver_threshold - iv_points.
WHEN {{p}}if_loyalty_rules=>c_tier-silver.
rv_points = c_gold_threshold - iv_points.
WHEN {{p}}if_loyalty_rules=>c_tier-gold.
rv_points = c_platinum_threshold + iv_points.
WHEN OTHERS.
rv_points = 0.
ENDCASE.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,65 @@
{
"task": "G0007",
"mutants": [
{
"object": "{{P}}LOYALTY_EVALUATOR",
"mutant": "line 58: >= -> < (rel)",
"status": "killed",
"hidden": "3/10",
"failed_tests": [
"NEXT_TIER_FROM_BASIC",
"NEXT_TIER_FROM_GOLD",
"NEXT_TIER_FROM_SILVER",
"NEXT_TIER_NEGATIVE_POINTS",
"TIER_BOUNDARIES",
"TIER_NEGATIVE",
"TIER_ZERO"
]
},
{
"object": "{{P}}LOYALTY_EVALUATOR",
"mutant": "line 60: >= -> < (rel)",
"status": "killed",
"hidden": "4/10",
"failed_tests": [
"NEXT_TIER_FROM_BASIC",
"NEXT_TIER_FROM_SILVER",
"NEXT_TIER_NEGATIVE_POINTS",
"TIER_BOUNDARIES",
"TIER_NEGATIVE",
"TIER_ZERO"
]
},
{
"object": "{{P}}LOYALTY_EVALUATOR",
"mutant": "line 70: - -> + (arith)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"NEXT_TIER_FROM_BASIC"
]
},
{
"object": "{{P}}LOYALTY_EVALUATOR",
"mutant": "line 72: - -> + (arith)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"NEXT_TIER_FROM_SILVER"
]
},
{
"object": "{{P}}LOYALTY_EVALUATOR",
"mutant": "line 74: - -> + (arith)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"NEXT_TIER_FROM_GOLD"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,149 @@
CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_freight_calc.
PRIVATE SECTION.
TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3.
CONSTANTS:
c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00',
c_base_weight TYPE ty_quantity VALUE '1000.000',
c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50',
c_free_km TYPE i VALUE 100,
c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00',
c_step TYPE ty_quantity VALUE '100.000',
c_volume_factor TYPE i VALUE 250,
c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'.
METHODS check_input
IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight
iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume
iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance
iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel
RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason.
METHODS chargeable_weight
IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight
iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume
RETURNING VALUE(rv_weight) TYPE ty_quantity.
METHODS base_freight
IMPORTING iv_weight_kg TYPE ty_quantity
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS distance_freight
IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS fuel_freight
IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount
iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS started_steps
IMPORTING iv_excess TYPE ty_quantity
RETURNING VALUE(rv_steps) TYPE i.
ENDCLASS.
CLASS {{p}}freight_calc IMPLEMENTATION.
METHOD {{p}}if_freight_calc~calculate.
DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason.
DATA lv_weight TYPE ty_quantity.
DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount.
CLEAR rs_result.
lv_reason = check_input( iv_weight_kg = iv_weight_kg
iv_volume_m3 = iv_volume_m3
iv_distance_km = iv_distance_km
iv_fuel_index = iv_fuel_index ).
IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok.
rs_result-reason = lv_reason.
RETURN.
ENDIF.
lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg
iv_volume_m3 = iv_volume_m3 ).
rs_result-chargeable_weight = lv_weight.
rs_result-base = base_freight( lv_weight ).
rs_result-distance = distance_freight( iv_distance_km ).
lv_net = rs_result-base - rs_result-distance.
rs_result-fuel = fuel_freight( iv_amount = lv_net
iv_fuel_index = iv_fuel_index ).
rs_result-total = rs_result-base + rs_result-distance + rs_result-fuel.
rs_result-reason = {{p}}if_freight_calc=>c_reason-ok.
ENDMETHOD.
METHOD check_input.
IF iv_weight_kg <= 0.
rv_reason = {{p}}if_freight_calc=>c_reason-weight.
ELSEIF iv_volume_m3 < 0.
rv_reason = {{p}}if_freight_calc=>c_reason-volume.
ELSEIF iv_distance_km <= 0.
rv_reason = {{p}}if_freight_calc=>c_reason-distance.
ELSEIF iv_fuel_index < 0 OR iv_fuel_index > 100.
rv_reason = {{p}}if_freight_calc=>c_reason-fuel.
ELSE.
rv_reason = {{p}}if_freight_calc=>c_reason-ok.
ENDIF.
ENDMETHOD.
METHOD chargeable_weight.
DATA lv_volumetric TYPE ty_quantity.
lv_volumetric = iv_volume_m3 * c_volume_factor.
IF lv_volumetric > iv_weight_kg.
rv_weight = lv_volumetric.
ELSE.
rv_weight = iv_weight_kg.
ENDIF.
ENDMETHOD.
METHOD base_freight.
DATA lv_excess TYPE ty_quantity.
DATA lv_steps TYPE i.
lv_excess = iv_weight_kg - c_base_weight.
IF lv_excess <= 0.
rv_amount = c_base_amount.
ELSE.
lv_steps = started_steps( lv_excess ).
rv_amount = c_base_amount + lv_steps * c_weight_rate.
ENDIF.
ENDMETHOD.
METHOD distance_freight.
DATA lv_excess TYPE ty_quantity.
DATA lv_steps TYPE i.
lv_excess = iv_distance_km - c_free_km.
IF lv_excess <= 0.
rv_amount = 0.
ELSE.
lv_steps = started_steps( lv_excess ).
rv_amount = lv_steps * c_km_rate.
ENDIF.
ENDMETHOD.
METHOD fuel_freight.
DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3.
DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5.
lv_scaled = iv_amount * iv_fuel_index.
lv_fuel = lv_scaled * c_percent.
rv_amount = lv_fuel.
ENDMETHOD.
METHOD started_steps.
DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0.
DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0.
lv_excess_scaled = iv_excess * 1000.
lv_step_scaled = c_step * 1000.
rv_steps = lv_excess_scaled DIV lv_step_scaled.
IF lv_excess_scaled MOD lv_step_scaled > 0.
rv_steps = rv_steps + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,149 @@
CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_freight_calc.
PRIVATE SECTION.
TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3.
CONSTANTS:
c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00',
c_base_weight TYPE ty_quantity VALUE '1000.000',
c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50',
c_free_km TYPE i VALUE 100,
c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00',
c_step TYPE ty_quantity VALUE '100.000',
c_volume_factor TYPE i VALUE 250,
c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'.
METHODS check_input
IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight
iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume
iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance
iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel
RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason.
METHODS chargeable_weight
IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight
iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume
RETURNING VALUE(rv_weight) TYPE ty_quantity.
METHODS base_freight
IMPORTING iv_weight_kg TYPE ty_quantity
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS distance_freight
IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS fuel_freight
IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount
iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS started_steps
IMPORTING iv_excess TYPE ty_quantity
RETURNING VALUE(rv_steps) TYPE i.
ENDCLASS.
CLASS {{p}}freight_calc IMPLEMENTATION.
METHOD {{p}}if_freight_calc~calculate.
DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason.
DATA lv_weight TYPE ty_quantity.
DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount.
CLEAR rs_result.
lv_reason = check_input( iv_weight_kg = iv_weight_kg
iv_volume_m3 = iv_volume_m3
iv_distance_km = iv_distance_km
iv_fuel_index = iv_fuel_index ).
IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok.
rs_result-reason = lv_reason.
RETURN.
ENDIF.
lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg
iv_volume_m3 = iv_volume_m3 ).
rs_result-chargeable_weight = lv_weight.
rs_result-base = base_freight( lv_weight ).
rs_result-distance = distance_freight( iv_distance_km ).
lv_net = rs_result-base + rs_result-distance.
rs_result-fuel = fuel_freight( iv_amount = lv_net
iv_fuel_index = iv_fuel_index ).
rs_result-total = rs_result-base + rs_result-distance - rs_result-fuel.
rs_result-reason = {{p}}if_freight_calc=>c_reason-ok.
ENDMETHOD.
METHOD check_input.
IF iv_weight_kg <= 0.
rv_reason = {{p}}if_freight_calc=>c_reason-weight.
ELSEIF iv_volume_m3 < 0.
rv_reason = {{p}}if_freight_calc=>c_reason-volume.
ELSEIF iv_distance_km <= 0.
rv_reason = {{p}}if_freight_calc=>c_reason-distance.
ELSEIF iv_fuel_index < 0 OR iv_fuel_index > 100.
rv_reason = {{p}}if_freight_calc=>c_reason-fuel.
ELSE.
rv_reason = {{p}}if_freight_calc=>c_reason-ok.
ENDIF.
ENDMETHOD.
METHOD chargeable_weight.
DATA lv_volumetric TYPE ty_quantity.
lv_volumetric = iv_volume_m3 * c_volume_factor.
IF lv_volumetric > iv_weight_kg.
rv_weight = lv_volumetric.
ELSE.
rv_weight = iv_weight_kg.
ENDIF.
ENDMETHOD.
METHOD base_freight.
DATA lv_excess TYPE ty_quantity.
DATA lv_steps TYPE i.
lv_excess = iv_weight_kg - c_base_weight.
IF lv_excess <= 0.
rv_amount = c_base_amount.
ELSE.
lv_steps = started_steps( lv_excess ).
rv_amount = c_base_amount + lv_steps * c_weight_rate.
ENDIF.
ENDMETHOD.
METHOD distance_freight.
DATA lv_excess TYPE ty_quantity.
DATA lv_steps TYPE i.
lv_excess = iv_distance_km - c_free_km.
IF lv_excess <= 0.
rv_amount = 0.
ELSE.
lv_steps = started_steps( lv_excess ).
rv_amount = lv_steps * c_km_rate.
ENDIF.
ENDMETHOD.
METHOD fuel_freight.
DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3.
DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5.
lv_scaled = iv_amount * iv_fuel_index.
lv_fuel = lv_scaled * c_percent.
rv_amount = lv_fuel.
ENDMETHOD.
METHOD started_steps.
DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0.
DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0.
lv_excess_scaled = iv_excess * 1000.
lv_step_scaled = c_step * 1000.
rv_steps = lv_excess_scaled DIV lv_step_scaled.
IF lv_excess_scaled MOD lv_step_scaled > 0.
rv_steps = rv_steps + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,149 @@
CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_freight_calc.
PRIVATE SECTION.
TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3.
CONSTANTS:
c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00',
c_base_weight TYPE ty_quantity VALUE '1000.000',
c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50',
c_free_km TYPE i VALUE 100,
c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00',
c_step TYPE ty_quantity VALUE '100.000',
c_volume_factor TYPE i VALUE 250,
c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'.
METHODS check_input
IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight
iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume
iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance
iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel
RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason.
METHODS chargeable_weight
IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight
iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume
RETURNING VALUE(rv_weight) TYPE ty_quantity.
METHODS base_freight
IMPORTING iv_weight_kg TYPE ty_quantity
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS distance_freight
IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS fuel_freight
IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount
iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS started_steps
IMPORTING iv_excess TYPE ty_quantity
RETURNING VALUE(rv_steps) TYPE i.
ENDCLASS.
CLASS {{p}}freight_calc IMPLEMENTATION.
METHOD {{p}}if_freight_calc~calculate.
DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason.
DATA lv_weight TYPE ty_quantity.
DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount.
CLEAR rs_result.
lv_reason = check_input( iv_weight_kg = iv_weight_kg
iv_volume_m3 = iv_volume_m3
iv_distance_km = iv_distance_km
iv_fuel_index = iv_fuel_index ).
IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok.
rs_result-reason = lv_reason.
RETURN.
ENDIF.
lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg
iv_volume_m3 = iv_volume_m3 ).
rs_result-chargeable_weight = lv_weight.
rs_result-base = base_freight( lv_weight ).
rs_result-distance = distance_freight( iv_distance_km ).
lv_net = rs_result-base + rs_result-distance.
rs_result-fuel = fuel_freight( iv_amount = lv_net
iv_fuel_index = iv_fuel_index ).
rs_result-total = rs_result-base + rs_result-distance + rs_result-fuel.
rs_result-reason = {{p}}if_freight_calc=>c_reason-ok.
ENDMETHOD.
METHOD check_input.
IF iv_weight_kg <= 0.
rv_reason = {{p}}if_freight_calc=>c_reason-weight.
ELSEIF iv_volume_m3 < 0.
rv_reason = {{p}}if_freight_calc=>c_reason-volume.
ELSEIF iv_distance_km <= 0.
rv_reason = {{p}}if_freight_calc=>c_reason-distance.
ELSEIF iv_fuel_index < 0 OR iv_fuel_index <= 100.
rv_reason = {{p}}if_freight_calc=>c_reason-fuel.
ELSE.
rv_reason = {{p}}if_freight_calc=>c_reason-ok.
ENDIF.
ENDMETHOD.
METHOD chargeable_weight.
DATA lv_volumetric TYPE ty_quantity.
lv_volumetric = iv_volume_m3 * c_volume_factor.
IF lv_volumetric > iv_weight_kg.
rv_weight = lv_volumetric.
ELSE.
rv_weight = iv_weight_kg.
ENDIF.
ENDMETHOD.
METHOD base_freight.
DATA lv_excess TYPE ty_quantity.
DATA lv_steps TYPE i.
lv_excess = iv_weight_kg - c_base_weight.
IF lv_excess <= 0.
rv_amount = c_base_amount.
ELSE.
lv_steps = started_steps( lv_excess ).
rv_amount = c_base_amount + lv_steps * c_weight_rate.
ENDIF.
ENDMETHOD.
METHOD distance_freight.
DATA lv_excess TYPE ty_quantity.
DATA lv_steps TYPE i.
lv_excess = iv_distance_km - c_free_km.
IF lv_excess <= 0.
rv_amount = 0.
ELSE.
lv_steps = started_steps( lv_excess ).
rv_amount = lv_steps * c_km_rate.
ENDIF.
ENDMETHOD.
METHOD fuel_freight.
DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3.
DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5.
lv_scaled = iv_amount * iv_fuel_index.
lv_fuel = lv_scaled * c_percent.
rv_amount = lv_fuel.
ENDMETHOD.
METHOD started_steps.
DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0.
DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0.
lv_excess_scaled = iv_excess * 1000.
lv_step_scaled = c_step * 1000.
rv_steps = lv_excess_scaled DIV lv_step_scaled.
IF lv_excess_scaled MOD lv_step_scaled > 0.
rv_steps = rv_steps + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,149 @@
CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_freight_calc.
PRIVATE SECTION.
TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3.
CONSTANTS:
c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00',
c_base_weight TYPE ty_quantity VALUE '1000.000',
c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50',
c_free_km TYPE i VALUE 100,
c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00',
c_step TYPE ty_quantity VALUE '100.000',
c_volume_factor TYPE i VALUE 250,
c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'.
METHODS check_input
IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight
iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume
iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance
iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel
RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason.
METHODS chargeable_weight
IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight
iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume
RETURNING VALUE(rv_weight) TYPE ty_quantity.
METHODS base_freight
IMPORTING iv_weight_kg TYPE ty_quantity
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS distance_freight
IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS fuel_freight
IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount
iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS started_steps
IMPORTING iv_excess TYPE ty_quantity
RETURNING VALUE(rv_steps) TYPE i.
ENDCLASS.
CLASS {{p}}freight_calc IMPLEMENTATION.
METHOD {{p}}if_freight_calc~calculate.
DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason.
DATA lv_weight TYPE ty_quantity.
DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount.
CLEAR rs_result.
lv_reason = check_input( iv_weight_kg = iv_weight_kg
iv_volume_m3 = iv_volume_m3
iv_distance_km = iv_distance_km
iv_fuel_index = iv_fuel_index ).
IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok.
rs_result-reason = lv_reason.
RETURN.
ENDIF.
lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg
iv_volume_m3 = iv_volume_m3 ).
rs_result-chargeable_weight = lv_weight.
rs_result-base = base_freight( lv_weight ).
rs_result-distance = distance_freight( iv_distance_km ).
lv_net = rs_result-base + rs_result-distance.
rs_result-fuel = fuel_freight( iv_amount = lv_net
iv_fuel_index = iv_fuel_index ).
rs_result-total = rs_result-base + rs_result-distance + rs_result-fuel.
rs_result-reason = {{p}}if_freight_calc=>c_reason-ok.
ENDMETHOD.
METHOD check_input.
IF iv_weight_kg <= 0.
rv_reason = {{p}}if_freight_calc=>c_reason-weight.
ELSEIF iv_volume_m3 < 0.
rv_reason = {{p}}if_freight_calc=>c_reason-volume.
ELSEIF iv_distance_km <= 0.
rv_reason = {{p}}if_freight_calc=>c_reason-distance.
ELSEIF iv_fuel_index < 0 OR iv_fuel_index > 100.
rv_reason = {{p}}if_freight_calc=>c_reason-fuel.
ELSE.
rv_reason = {{p}}if_freight_calc=>c_reason-ok.
ENDIF.
ENDMETHOD.
METHOD chargeable_weight.
DATA lv_volumetric TYPE ty_quantity.
lv_volumetric = iv_volume_m3 * c_volume_factor.
IF lv_volumetric > iv_weight_kg.
rv_weight = lv_volumetric.
ELSE.
rv_weight = iv_weight_kg.
ENDIF.
ENDMETHOD.
METHOD base_freight.
DATA lv_excess TYPE ty_quantity.
DATA lv_steps TYPE i.
lv_excess = iv_weight_kg - c_base_weight.
IF lv_excess > 0.
rv_amount = c_base_amount.
ELSE.
lv_steps = started_steps( lv_excess ).
rv_amount = c_base_amount + lv_steps * c_weight_rate.
ENDIF.
ENDMETHOD.
METHOD distance_freight.
DATA lv_excess TYPE ty_quantity.
DATA lv_steps TYPE i.
lv_excess = iv_distance_km - c_free_km.
IF lv_excess <= 0.
rv_amount = 0.
ELSE.
lv_steps = started_steps( lv_excess ).
rv_amount = lv_steps * c_km_rate.
ENDIF.
ENDMETHOD.
METHOD fuel_freight.
DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3.
DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5.
lv_scaled = iv_amount * iv_fuel_index.
lv_fuel = lv_scaled * c_percent.
rv_amount = lv_fuel.
ENDMETHOD.
METHOD started_steps.
DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0.
DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0.
lv_excess_scaled = iv_excess * 1000.
lv_step_scaled = c_step * 1000.
rv_steps = lv_excess_scaled DIV lv_step_scaled.
IF lv_excess_scaled MOD lv_step_scaled > 0.
rv_steps = rv_steps + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,149 @@
CLASS {{p}}freight_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_freight_calc.
PRIVATE SECTION.
TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3.
CONSTANTS:
c_base_amount TYPE {{p}}if_freight_calc=>ty_amount VALUE '45.00',
c_base_weight TYPE ty_quantity VALUE '1000.000',
c_weight_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '6.50',
c_free_km TYPE i VALUE 100,
c_km_rate TYPE {{p}}if_freight_calc=>ty_amount VALUE '9.00',
c_step TYPE ty_quantity VALUE '100.000',
c_volume_factor TYPE i VALUE 250,
c_percent TYPE p LENGTH 3 DECIMALS 2 VALUE '0.01'.
METHODS check_input
IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight
iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume
iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance
iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel
RETURNING VALUE(rv_reason) TYPE {{p}}if_freight_calc=>ty_reason.
METHODS chargeable_weight
IMPORTING iv_weight_kg TYPE {{p}}if_freight_calc=>ty_weight
iv_volume_m3 TYPE {{p}}if_freight_calc=>ty_volume
RETURNING VALUE(rv_weight) TYPE ty_quantity.
METHODS base_freight
IMPORTING iv_weight_kg TYPE ty_quantity
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS distance_freight
IMPORTING iv_distance_km TYPE {{p}}if_freight_calc=>ty_distance
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS fuel_freight
IMPORTING iv_amount TYPE {{p}}if_freight_calc=>ty_amount
iv_fuel_index TYPE {{p}}if_freight_calc=>ty_fuel
RETURNING VALUE(rv_amount) TYPE {{p}}if_freight_calc=>ty_amount.
METHODS started_steps
IMPORTING iv_excess TYPE ty_quantity
RETURNING VALUE(rv_steps) TYPE i.
ENDCLASS.
CLASS {{p}}freight_calc IMPLEMENTATION.
METHOD {{p}}if_freight_calc~calculate.
DATA lv_reason TYPE {{p}}if_freight_calc=>ty_reason.
DATA lv_weight TYPE ty_quantity.
DATA lv_net TYPE {{p}}if_freight_calc=>ty_amount.
CLEAR rs_result.
lv_reason = check_input( iv_weight_kg = iv_weight_kg
iv_volume_m3 = iv_volume_m3
iv_distance_km = iv_distance_km
iv_fuel_index = iv_fuel_index ).
IF lv_reason <> {{p}}if_freight_calc=>c_reason-ok.
rs_result-reason = lv_reason.
RETURN.
ENDIF.
lv_weight = chargeable_weight( iv_weight_kg = iv_weight_kg
iv_volume_m3 = iv_volume_m3 ).
rs_result-chargeable_weight = lv_weight.
rs_result-base = base_freight( lv_weight ).
rs_result-distance = distance_freight( iv_distance_km ).
lv_net = rs_result-base + rs_result-distance.
rs_result-fuel = fuel_freight( iv_amount = lv_net
iv_fuel_index = iv_fuel_index ).
rs_result-total = rs_result-base + rs_result-distance + rs_result-fuel.
rs_result-reason = {{p}}if_freight_calc=>c_reason-ok.
ENDMETHOD.
METHOD check_input.
IF iv_weight_kg <= 0.
rv_reason = {{p}}if_freight_calc=>c_reason-weight.
ELSEIF iv_volume_m3 < 0.
rv_reason = {{p}}if_freight_calc=>c_reason-volume.
ELSEIF iv_distance_km <= 0.
rv_reason = {{p}}if_freight_calc=>c_reason-distance.
ELSEIF iv_fuel_index < 0 OR iv_fuel_index > 100.
rv_reason = {{p}}if_freight_calc=>c_reason-fuel.
ELSE.
rv_reason = {{p}}if_freight_calc=>c_reason-ok.
ENDIF.
ENDMETHOD.
METHOD chargeable_weight.
DATA lv_volumetric TYPE ty_quantity.
lv_volumetric = iv_volume_m3 * c_volume_factor.
IF lv_volumetric > iv_weight_kg.
rv_weight = lv_volumetric.
ELSE.
rv_weight = iv_weight_kg.
ENDIF.
ENDMETHOD.
METHOD base_freight.
DATA lv_excess TYPE ty_quantity.
DATA lv_steps TYPE i.
lv_excess = iv_weight_kg - c_base_weight.
IF lv_excess <= 0.
rv_amount = c_base_amount.
ELSE.
lv_steps = started_steps( lv_excess ).
rv_amount = c_base_amount - lv_steps * c_weight_rate.
ENDIF.
ENDMETHOD.
METHOD distance_freight.
DATA lv_excess TYPE ty_quantity.
DATA lv_steps TYPE i.
lv_excess = iv_distance_km - c_free_km.
IF lv_excess <= 0.
rv_amount = 0.
ELSE.
lv_steps = started_steps( lv_excess ).
rv_amount = lv_steps * c_km_rate.
ENDIF.
ENDMETHOD.
METHOD fuel_freight.
DATA lv_scaled TYPE p LENGTH 15 DECIMALS 3.
DATA lv_fuel TYPE p LENGTH 15 DECIMALS 5.
lv_scaled = iv_amount * iv_fuel_index.
lv_fuel = lv_scaled * c_percent.
rv_amount = lv_fuel.
ENDMETHOD.
METHOD started_steps.
DATA lv_excess_scaled TYPE p LENGTH 16 DECIMALS 0.
DATA lv_step_scaled TYPE p LENGTH 16 DECIMALS 0.
lv_excess_scaled = iv_excess * 1000.
lv_step_scaled = c_step * 1000.
rv_steps = lv_excess_scaled DIV lv_step_scaled.
IF lv_excess_scaled MOD lv_step_scaled > 0.
rv_steps = rv_steps + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,65 @@
{
"task": "G0008",
"mutants": [
{
"object": "{{P}}FREIGHT_CALC",
"mutant": "line 71: + -> - (arith)",
"status": "killed",
"hidden": "10/11",
"failed_tests": [
"FULL_LOAD"
]
},
{
"object": "{{P}}FREIGHT_CALC",
"mutant": "line 74: + -> - (arith)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"FUEL_ROUNDS_HALF_UP",
"FULL_LOAD"
]
},
{
"object": "{{P}}FREIGHT_CALC",
"mutant": "line 85: > -> <= (rel)",
"status": "killed",
"hidden": "4/11",
"failed_tests": [
"BASE_ABOVE_WEIGHT_LIMIT",
"BASE_AT_WEIGHT_LIMIT",
"DISTANCE_COMPONENT",
"FUEL_INDEX_TOO_HIGH",
"FUEL_ROUNDS_HALF_UP",
"FULL_LOAD",
"VOLUMETRIC_WEIGHT_WINS"
]
},
{
"object": "{{P}}FREIGHT_CALC",
"mutant": "line 108: <= -> > (rel)",
"status": "killed",
"hidden": "8/11",
"failed_tests": [
"BASE_ABOVE_WEIGHT_LIMIT",
"FULL_LOAD",
"VOLUMETRIC_WEIGHT_WINS"
]
},
{
"object": "{{P}}FREIGHT_CALC",
"mutant": "line 112: + -> - (arith)",
"status": "killed",
"hidden": "8/11",
"failed_tests": [
"BASE_ABOVE_WEIGHT_LIMIT",
"FULL_LOAD",
"VOLUMETRIC_WEIGHT_WINS"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,56 @@
CLASS {{p}}shipping_cost_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_shipping_cost.
PRIVATE SECTION.
METHODS base_rate
IMPORTING iv_weight TYPE {{p}}if_shipping_cost=>ty_weight
RETURNING VALUE(rv_rate) TYPE {{p}}if_shipping_cost=>ty_amount.
METHODS express_surcharge
IMPORTING iv_rate TYPE {{p}}if_shipping_cost=>ty_amount
RETURNING VALUE(rv_surcharge) TYPE {{p}}if_shipping_cost=>ty_amount.
ENDCLASS.
CLASS {{p}}shipping_cost_calc IMPLEMENTATION.
METHOD {{p}}if_shipping_cost~calculate.
IF iv_weight <= 0.
rv_cost = 0.
RETURN.
ENDIF.
DATA(lv_cost) = base_rate( iv_weight ).
IF iv_express <> abap_true.
lv_cost = lv_cost + express_surcharge( lv_cost ).
ENDIF.
IF lv_cost < {{p}}if_shipping_cost=>c_rate-min_charge.
rv_cost = {{p}}if_shipping_cost=>c_rate-min_charge.
ELSE.
rv_cost = lv_cost.
ENDIF.
ENDMETHOD.
METHOD base_rate.
IF iv_weight <= 1.
rv_rate = '4.90'.
ELSEIF iv_weight <= 5.
rv_rate = '8.50'.
ELSEIF iv_weight <= 10.
rv_rate = '12.00'.
ELSEIF iv_weight <= {{p}}if_shipping_cost=>c_rate-bulk_weight.
rv_rate = '18.75'.
ELSE.
DATA(lv_started_kg) = CONV i(
ceil( iv_weight - {{p}}if_shipping_cost=>c_rate-bulk_weight ) ).
rv_rate = '18.75' + lv_started_kg * {{p}}if_shipping_cost=>c_rate-bulk_step.
ENDIF.
ENDMETHOD.
METHOD express_surcharge.
rv_surcharge = round( val = iv_rate * {{p}}if_shipping_cost=>c_rate-express_percent / 100
dec = 2 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,56 @@
CLASS {{p}}shipping_cost_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_shipping_cost.
PRIVATE SECTION.
METHODS base_rate
IMPORTING iv_weight TYPE {{p}}if_shipping_cost=>ty_weight
RETURNING VALUE(rv_rate) TYPE {{p}}if_shipping_cost=>ty_amount.
METHODS express_surcharge
IMPORTING iv_rate TYPE {{p}}if_shipping_cost=>ty_amount
RETURNING VALUE(rv_surcharge) TYPE {{p}}if_shipping_cost=>ty_amount.
ENDCLASS.
CLASS {{p}}shipping_cost_calc IMPLEMENTATION.
METHOD {{p}}if_shipping_cost~calculate.
IF iv_weight <= 0.
rv_cost = 0.
RETURN.
ENDIF.
DATA(lv_cost) = base_rate( iv_weight ).
IF iv_express = abap_true.
lv_cost = lv_cost - express_surcharge( lv_cost ).
ENDIF.
IF lv_cost < {{p}}if_shipping_cost=>c_rate-min_charge.
rv_cost = {{p}}if_shipping_cost=>c_rate-min_charge.
ELSE.
rv_cost = lv_cost.
ENDIF.
ENDMETHOD.
METHOD base_rate.
IF iv_weight <= 1.
rv_rate = '4.90'.
ELSEIF iv_weight <= 5.
rv_rate = '8.50'.
ELSEIF iv_weight <= 10.
rv_rate = '12.00'.
ELSEIF iv_weight <= {{p}}if_shipping_cost=>c_rate-bulk_weight.
rv_rate = '18.75'.
ELSE.
DATA(lv_started_kg) = CONV i(
ceil( iv_weight - {{p}}if_shipping_cost=>c_rate-bulk_weight ) ).
rv_rate = '18.75' + lv_started_kg * {{p}}if_shipping_cost=>c_rate-bulk_step.
ENDIF.
ENDMETHOD.
METHOD express_surcharge.
rv_surcharge = round( val = iv_rate * {{p}}if_shipping_cost=>c_rate-express_percent / 100
dec = 2 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,56 @@
CLASS {{p}}shipping_cost_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_shipping_cost.
PRIVATE SECTION.
METHODS base_rate
IMPORTING iv_weight TYPE {{p}}if_shipping_cost=>ty_weight
RETURNING VALUE(rv_rate) TYPE {{p}}if_shipping_cost=>ty_amount.
METHODS express_surcharge
IMPORTING iv_rate TYPE {{p}}if_shipping_cost=>ty_amount
RETURNING VALUE(rv_surcharge) TYPE {{p}}if_shipping_cost=>ty_amount.
ENDCLASS.
CLASS {{p}}shipping_cost_calc IMPLEMENTATION.
METHOD {{p}}if_shipping_cost~calculate.
IF iv_weight <= 0.
rv_cost = 0.
RETURN.
ENDIF.
DATA(lv_cost) = base_rate( iv_weight ).
IF iv_express = abap_true.
lv_cost = lv_cost + express_surcharge( lv_cost ).
ENDIF.
IF lv_cost < {{p}}if_shipping_cost=>c_rate-min_charge.
rv_cost = {{p}}if_shipping_cost=>c_rate-min_charge.
ELSE.
rv_cost = lv_cost.
ENDIF.
ENDMETHOD.
METHOD base_rate.
IF iv_weight > 1.
rv_rate = '4.90'.
ELSEIF iv_weight <= 5.
rv_rate = '8.50'.
ELSEIF iv_weight <= 10.
rv_rate = '12.00'.
ELSEIF iv_weight <= {{p}}if_shipping_cost=>c_rate-bulk_weight.
rv_rate = '18.75'.
ELSE.
DATA(lv_started_kg) = CONV i(
ceil( iv_weight - {{p}}if_shipping_cost=>c_rate-bulk_weight ) ).
rv_rate = '18.75' + lv_started_kg * {{p}}if_shipping_cost=>c_rate-bulk_step.
ENDIF.
ENDMETHOD.
METHOD express_surcharge.
rv_surcharge = round( val = iv_rate * {{p}}if_shipping_cost=>c_rate-express_percent / 100
dec = 2 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,56 @@
CLASS {{p}}shipping_cost_calc DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_shipping_cost.
PRIVATE SECTION.
METHODS base_rate
IMPORTING iv_weight TYPE {{p}}if_shipping_cost=>ty_weight
RETURNING VALUE(rv_rate) TYPE {{p}}if_shipping_cost=>ty_amount.
METHODS express_surcharge
IMPORTING iv_rate TYPE {{p}}if_shipping_cost=>ty_amount
RETURNING VALUE(rv_surcharge) TYPE {{p}}if_shipping_cost=>ty_amount.
ENDCLASS.
CLASS {{p}}shipping_cost_calc IMPLEMENTATION.
METHOD {{p}}if_shipping_cost~calculate.
IF iv_weight <= 0.
rv_cost = 0.
RETURN.
ENDIF.
DATA(lv_cost) = base_rate( iv_weight ).
IF iv_express = abap_true.
lv_cost = lv_cost + express_surcharge( lv_cost ).
ENDIF.
IF lv_cost < {{p}}if_shipping_cost=>c_rate-min_charge.
rv_cost = {{p}}if_shipping_cost=>c_rate-min_charge.
ELSE.
rv_cost = lv_cost.
ENDIF.
ENDMETHOD.
METHOD base_rate.
IF iv_weight <= 1.
rv_rate = '4.90'.
ELSEIF iv_weight <= 5.
rv_rate = '8.50'.
ELSEIF iv_weight <= 10.
rv_rate = '12.00'.
ELSEIF iv_weight <= {{p}}if_shipping_cost=>c_rate-bulk_weight.
rv_rate = '18.75'.
ELSE.
DATA(lv_started_kg) = CONV i(
ceil( iv_weight - {{p}}if_shipping_cost=>c_rate-bulk_weight ) ).
rv_rate = '18.75' - lv_started_kg * {{p}}if_shipping_cost=>c_rate-bulk_step.
ENDIF.
ENDMETHOD.
METHOD express_surcharge.
rv_surcharge = round( val = iv_rate * {{p}}if_shipping_cost=>c_rate-express_percent / 100
dec = 2 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,72 @@
{
"task": "G0009",
"mutants": [
{
"object": "{{P}}SHIPPING_COST_CALC",
"mutant": "line 25: = -> <> (eq)",
"status": "killed",
"hidden": "1/10",
"failed_tests": [
"BULK_EXPRESS",
"BULK_WEIGHT_LIMIT",
"BULK_WEIGHT_STARTED_KG",
"EXPRESS_BELOW_MINIMUM",
"EXPRESS_SURCHARGE",
"LIGHT_PARCEL_GETS_MINIMUM",
"TIER_LIMIT_FIVE_KG",
"TIER_LIMIT_ONE_KG",
"TIER_LIMIT_TEN_KG"
]
},
{
"object": "{{P}}SHIPPING_COST_CALC",
"mutant": "line 26: + -> - (arith)",
"status": "killed",
"hidden": "7/10",
"failed_tests": [
"BULK_EXPRESS",
"EXPRESS_BELOW_MINIMUM",
"EXPRESS_SURCHARGE"
]
},
{
"object": "{{P}}SHIPPING_COST_CALC",
"mutant": "line 37: <= -> > (rel)",
"status": "killed",
"hidden": "1/10",
"failed_tests": [
"BULK_EXPRESS",
"BULK_WEIGHT_LIMIT",
"BULK_WEIGHT_STARTED_KG",
"EXPRESS_BELOW_MINIMUM",
"EXPRESS_SURCHARGE",
"LIGHT_PARCEL_GETS_MINIMUM",
"TIER_LIMIT_FIVE_KG",
"TIER_LIMIT_ONE_KG",
"TIER_LIMIT_TEN_KG"
]
},
{
"object": "{{P}}SHIPPING_COST_CALC",
"mutant": "line 48: + -> - (arith)",
"status": "killed",
"hidden": "7/10",
"failed_tests": [
"BULK_EXPRESS",
"BULK_WEIGHT_LIMIT",
"BULK_WEIGHT_STARTED_KG"
]
},
{
"object": "{{P}}SHIPPING_COST_CALC",
"mutant": "line 54: 2 -> 3 (const)",
"status": "survived",
"hidden": "10/10",
"failed_tests": []
}
],
"valid": 5,
"killed": 4,
"kill_rate": 0.8,
"ok": true
}

View File

@@ -0,0 +1,128 @@
CLASS {{p}}stock_cover_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_stock_cover.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_stock,
material TYPE {{p}}if_stock_cover=>ty_material,
plant TYPE {{p}}if_stock_cover=>ty_plant,
remaining TYPE {{p}}if_stock_cover=>ty_quantity,
END OF ty_stock.
TYPES tt_stock TYPE HASHED TABLE OF ty_stock WITH UNIQUE KEY material plant.
METHODS aggregate
IMPORTING it_stock TYPE {{p}}if_stock_cover=>tt_stock_item
RETURNING VALUE(rt_stock) TYPE tt_stock.
METHODS free_quantity
IMPORTING it_stock TYPE tt_stock
iv_material TYPE {{p}}if_stock_cover=>ty_material
iv_plant TYPE {{p}}if_stock_cover=>ty_plant
RETURNING VALUE(rv_quantity) TYPE {{p}}if_stock_cover=>ty_quantity.
METHODS consume
IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material
iv_plant TYPE {{p}}if_stock_cover=>ty_plant
iv_quantity TYPE {{p}}if_stock_cover=>ty_quantity
CHANGING ct_stock TYPE tt_stock.
METHODS normalize_material
IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material
RETURNING VALUE(rv_material) TYPE {{p}}if_stock_cover=>ty_material.
METHODS normalize_plant
IMPORTING iv_plant TYPE {{p}}if_stock_cover=>ty_plant
RETURNING VALUE(rv_plant) TYPE {{p}}if_stock_cover=>ty_plant.
ENDCLASS.
CLASS {{p}}stock_cover_checker IMPLEMENTATION.
METHOD {{p}}if_stock_cover~check.
DATA(lt_stock) = aggregate( it_stock ).
LOOP AT it_requirement INTO DATA(ls_requirement).
DATA(lv_free) = free_quantity( it_stock = lt_stock
iv_material = ls_requirement-material
iv_plant = ls_requirement-plant ).
DATA(ls_result) = VALUE {{p}}if_stock_cover=>ty_result(
material = ls_requirement-material
plant = ls_requirement-plant
required = ls_requirement-required
available = lv_free ).
IF ls_requirement-required > 0.
ls_result-status = {{p}}if_stock_cover=>c_status-invalid.
ELSEIF lv_free >= ls_requirement-required.
ls_result-status = {{p}}if_stock_cover=>c_status-ok.
consume( EXPORTING iv_material = ls_requirement-material
iv_plant = ls_requirement-plant
iv_quantity = ls_requirement-required
CHANGING ct_stock = lt_stock ).
ELSE.
ls_result-status = {{p}}if_stock_cover=>c_status-short.
ls_result-shortage = ls_requirement-required - lv_free.
consume( EXPORTING iv_material = ls_requirement-material
iv_plant = ls_requirement-plant
iv_quantity = lv_free
CHANGING ct_stock = lt_stock ).
ENDIF.
APPEND ls_result TO rt_result.
ENDLOOP.
ENDMETHOD.
METHOD {{p}}if_stock_cover~shortages.
rt_shortage = it_result.
DELETE rt_shortage WHERE status <> {{p}}if_stock_cover=>c_status-short.
SORT rt_shortage BY material plant.
ENDMETHOD.
METHOD aggregate.
LOOP AT it_stock INTO DATA(ls_stock).
IF ls_stock-quantity < 0.
CONTINUE.
ENDIF.
DATA(lv_material) = normalize_material( ls_stock-material ).
DATA(lv_plant) = normalize_plant( ls_stock-plant ).
ASSIGN rt_stock[ material = lv_material plant = lv_plant ] TO FIELD-SYMBOL(<ls_stock_sum>).
IF sy-subrc = 0.
<ls_stock_sum>-remaining = <ls_stock_sum>-remaining + ls_stock-quantity.
ELSE.
INSERT VALUE #( material = lv_material
plant = lv_plant
remaining = ls_stock-quantity ) INTO TABLE rt_stock.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD free_quantity.
ASSIGN it_stock[ material = normalize_material( iv_material )
plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(<ls_stock>).
IF sy-subrc = 0.
rv_quantity = <ls_stock>-remaining.
ENDIF.
ENDMETHOD.
METHOD consume.
ASSIGN ct_stock[ material = normalize_material( iv_material )
plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(<ls_stock>).
IF sy-subrc = 0.
<ls_stock>-remaining = <ls_stock>-remaining - iv_quantity.
ENDIF.
ENDMETHOD.
METHOD normalize_material.
DATA lv_text TYPE string.
lv_text = iv_material.
REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``.
rv_material = to_upper( lv_text ).
ENDMETHOD.
METHOD normalize_plant.
DATA lv_text TYPE string.
lv_text = iv_plant.
REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``.
rv_plant = to_upper( lv_text ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,128 @@
CLASS {{p}}stock_cover_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_stock_cover.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_stock,
material TYPE {{p}}if_stock_cover=>ty_material,
plant TYPE {{p}}if_stock_cover=>ty_plant,
remaining TYPE {{p}}if_stock_cover=>ty_quantity,
END OF ty_stock.
TYPES tt_stock TYPE HASHED TABLE OF ty_stock WITH UNIQUE KEY material plant.
METHODS aggregate
IMPORTING it_stock TYPE {{p}}if_stock_cover=>tt_stock_item
RETURNING VALUE(rt_stock) TYPE tt_stock.
METHODS free_quantity
IMPORTING it_stock TYPE tt_stock
iv_material TYPE {{p}}if_stock_cover=>ty_material
iv_plant TYPE {{p}}if_stock_cover=>ty_plant
RETURNING VALUE(rv_quantity) TYPE {{p}}if_stock_cover=>ty_quantity.
METHODS consume
IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material
iv_plant TYPE {{p}}if_stock_cover=>ty_plant
iv_quantity TYPE {{p}}if_stock_cover=>ty_quantity
CHANGING ct_stock TYPE tt_stock.
METHODS normalize_material
IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material
RETURNING VALUE(rv_material) TYPE {{p}}if_stock_cover=>ty_material.
METHODS normalize_plant
IMPORTING iv_plant TYPE {{p}}if_stock_cover=>ty_plant
RETURNING VALUE(rv_plant) TYPE {{p}}if_stock_cover=>ty_plant.
ENDCLASS.
CLASS {{p}}stock_cover_checker IMPLEMENTATION.
METHOD {{p}}if_stock_cover~check.
DATA(lt_stock) = aggregate( it_stock ).
LOOP AT it_requirement INTO DATA(ls_requirement).
DATA(lv_free) = free_quantity( it_stock = lt_stock
iv_material = ls_requirement-material
iv_plant = ls_requirement-plant ).
DATA(ls_result) = VALUE {{p}}if_stock_cover=>ty_result(
material = ls_requirement-material
plant = ls_requirement-plant
required = ls_requirement-required
available = lv_free ).
IF ls_requirement-required <= 0.
ls_result-status = {{p}}if_stock_cover=>c_status-invalid.
ELSEIF lv_free >= ls_requirement-required.
ls_result-status = {{p}}if_stock_cover=>c_status-ok.
consume( EXPORTING iv_material = ls_requirement-material
iv_plant = ls_requirement-plant
iv_quantity = ls_requirement-required
CHANGING ct_stock = lt_stock ).
ELSE.
ls_result-status = {{p}}if_stock_cover=>c_status-short.
ls_result-shortage = ls_requirement-required - lv_free.
consume( EXPORTING iv_material = ls_requirement-material
iv_plant = ls_requirement-plant
iv_quantity = lv_free
CHANGING ct_stock = lt_stock ).
ENDIF.
APPEND ls_result TO rt_result.
ENDLOOP.
ENDMETHOD.
METHOD {{p}}if_stock_cover~shortages.
rt_shortage = it_result.
DELETE rt_shortage WHERE status = {{p}}if_stock_cover=>c_status-short.
SORT rt_shortage BY material plant.
ENDMETHOD.
METHOD aggregate.
LOOP AT it_stock INTO DATA(ls_stock).
IF ls_stock-quantity < 0.
CONTINUE.
ENDIF.
DATA(lv_material) = normalize_material( ls_stock-material ).
DATA(lv_plant) = normalize_plant( ls_stock-plant ).
ASSIGN rt_stock[ material = lv_material plant = lv_plant ] TO FIELD-SYMBOL(<ls_stock_sum>).
IF sy-subrc = 0.
<ls_stock_sum>-remaining = <ls_stock_sum>-remaining + ls_stock-quantity.
ELSE.
INSERT VALUE #( material = lv_material
plant = lv_plant
remaining = ls_stock-quantity ) INTO TABLE rt_stock.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD free_quantity.
ASSIGN it_stock[ material = normalize_material( iv_material )
plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(<ls_stock>).
IF sy-subrc = 0.
rv_quantity = <ls_stock>-remaining.
ENDIF.
ENDMETHOD.
METHOD consume.
ASSIGN ct_stock[ material = normalize_material( iv_material )
plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(<ls_stock>).
IF sy-subrc = 0.
<ls_stock>-remaining = <ls_stock>-remaining - iv_quantity.
ENDIF.
ENDMETHOD.
METHOD normalize_material.
DATA lv_text TYPE string.
lv_text = iv_material.
REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``.
rv_material = to_upper( lv_text ).
ENDMETHOD.
METHOD normalize_plant.
DATA lv_text TYPE string.
lv_text = iv_plant.
REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``.
rv_plant = to_upper( lv_text ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,128 @@
CLASS {{p}}stock_cover_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_stock_cover.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_stock,
material TYPE {{p}}if_stock_cover=>ty_material,
plant TYPE {{p}}if_stock_cover=>ty_plant,
remaining TYPE {{p}}if_stock_cover=>ty_quantity,
END OF ty_stock.
TYPES tt_stock TYPE HASHED TABLE OF ty_stock WITH UNIQUE KEY material plant.
METHODS aggregate
IMPORTING it_stock TYPE {{p}}if_stock_cover=>tt_stock_item
RETURNING VALUE(rt_stock) TYPE tt_stock.
METHODS free_quantity
IMPORTING it_stock TYPE tt_stock
iv_material TYPE {{p}}if_stock_cover=>ty_material
iv_plant TYPE {{p}}if_stock_cover=>ty_plant
RETURNING VALUE(rv_quantity) TYPE {{p}}if_stock_cover=>ty_quantity.
METHODS consume
IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material
iv_plant TYPE {{p}}if_stock_cover=>ty_plant
iv_quantity TYPE {{p}}if_stock_cover=>ty_quantity
CHANGING ct_stock TYPE tt_stock.
METHODS normalize_material
IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material
RETURNING VALUE(rv_material) TYPE {{p}}if_stock_cover=>ty_material.
METHODS normalize_plant
IMPORTING iv_plant TYPE {{p}}if_stock_cover=>ty_plant
RETURNING VALUE(rv_plant) TYPE {{p}}if_stock_cover=>ty_plant.
ENDCLASS.
CLASS {{p}}stock_cover_checker IMPLEMENTATION.
METHOD {{p}}if_stock_cover~check.
DATA(lt_stock) = aggregate( it_stock ).
LOOP AT it_requirement INTO DATA(ls_requirement).
DATA(lv_free) = free_quantity( it_stock = lt_stock
iv_material = ls_requirement-material
iv_plant = ls_requirement-plant ).
DATA(ls_result) = VALUE {{p}}if_stock_cover=>ty_result(
material = ls_requirement-material
plant = ls_requirement-plant
required = ls_requirement-required
available = lv_free ).
IF ls_requirement-required <= 0.
ls_result-status = {{p}}if_stock_cover=>c_status-invalid.
ELSEIF lv_free >= ls_requirement-required.
ls_result-status = {{p}}if_stock_cover=>c_status-ok.
consume( EXPORTING iv_material = ls_requirement-material
iv_plant = ls_requirement-plant
iv_quantity = ls_requirement-required
CHANGING ct_stock = lt_stock ).
ELSE.
ls_result-status = {{p}}if_stock_cover=>c_status-short.
ls_result-shortage = ls_requirement-required - lv_free.
consume( EXPORTING iv_material = ls_requirement-material
iv_plant = ls_requirement-plant
iv_quantity = lv_free
CHANGING ct_stock = lt_stock ).
ENDIF.
APPEND ls_result TO rt_result.
ENDLOOP.
ENDMETHOD.
METHOD {{p}}if_stock_cover~shortages.
rt_shortage = it_result.
DELETE rt_shortage WHERE status <> {{p}}if_stock_cover=>c_status-short.
SORT rt_shortage BY material plant.
ENDMETHOD.
METHOD aggregate.
LOOP AT it_stock INTO DATA(ls_stock).
IF ls_stock-quantity >= 0.
CONTINUE.
ENDIF.
DATA(lv_material) = normalize_material( ls_stock-material ).
DATA(lv_plant) = normalize_plant( ls_stock-plant ).
ASSIGN rt_stock[ material = lv_material plant = lv_plant ] TO FIELD-SYMBOL(<ls_stock_sum>).
IF sy-subrc = 0.
<ls_stock_sum>-remaining = <ls_stock_sum>-remaining + ls_stock-quantity.
ELSE.
INSERT VALUE #( material = lv_material
plant = lv_plant
remaining = ls_stock-quantity ) INTO TABLE rt_stock.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD free_quantity.
ASSIGN it_stock[ material = normalize_material( iv_material )
plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(<ls_stock>).
IF sy-subrc = 0.
rv_quantity = <ls_stock>-remaining.
ENDIF.
ENDMETHOD.
METHOD consume.
ASSIGN ct_stock[ material = normalize_material( iv_material )
plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(<ls_stock>).
IF sy-subrc = 0.
<ls_stock>-remaining = <ls_stock>-remaining - iv_quantity.
ENDIF.
ENDMETHOD.
METHOD normalize_material.
DATA lv_text TYPE string.
lv_text = iv_material.
REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``.
rv_material = to_upper( lv_text ).
ENDMETHOD.
METHOD normalize_plant.
DATA lv_text TYPE string.
lv_text = iv_plant.
REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``.
rv_plant = to_upper( lv_text ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,128 @@
CLASS {{p}}stock_cover_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_stock_cover.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_stock,
material TYPE {{p}}if_stock_cover=>ty_material,
plant TYPE {{p}}if_stock_cover=>ty_plant,
remaining TYPE {{p}}if_stock_cover=>ty_quantity,
END OF ty_stock.
TYPES tt_stock TYPE HASHED TABLE OF ty_stock WITH UNIQUE KEY material plant.
METHODS aggregate
IMPORTING it_stock TYPE {{p}}if_stock_cover=>tt_stock_item
RETURNING VALUE(rt_stock) TYPE tt_stock.
METHODS free_quantity
IMPORTING it_stock TYPE tt_stock
iv_material TYPE {{p}}if_stock_cover=>ty_material
iv_plant TYPE {{p}}if_stock_cover=>ty_plant
RETURNING VALUE(rv_quantity) TYPE {{p}}if_stock_cover=>ty_quantity.
METHODS consume
IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material
iv_plant TYPE {{p}}if_stock_cover=>ty_plant
iv_quantity TYPE {{p}}if_stock_cover=>ty_quantity
CHANGING ct_stock TYPE tt_stock.
METHODS normalize_material
IMPORTING iv_material TYPE {{p}}if_stock_cover=>ty_material
RETURNING VALUE(rv_material) TYPE {{p}}if_stock_cover=>ty_material.
METHODS normalize_plant
IMPORTING iv_plant TYPE {{p}}if_stock_cover=>ty_plant
RETURNING VALUE(rv_plant) TYPE {{p}}if_stock_cover=>ty_plant.
ENDCLASS.
CLASS {{p}}stock_cover_checker IMPLEMENTATION.
METHOD {{p}}if_stock_cover~check.
DATA(lt_stock) = aggregate( it_stock ).
LOOP AT it_requirement INTO DATA(ls_requirement).
DATA(lv_free) = free_quantity( it_stock = lt_stock
iv_material = ls_requirement-material
iv_plant = ls_requirement-plant ).
DATA(ls_result) = VALUE {{p}}if_stock_cover=>ty_result(
material = ls_requirement-material
plant = ls_requirement-plant
required = ls_requirement-required
available = lv_free ).
IF ls_requirement-required <= 0.
ls_result-status = {{p}}if_stock_cover=>c_status-invalid.
ELSEIF lv_free >= ls_requirement-required.
ls_result-status = {{p}}if_stock_cover=>c_status-ok.
consume( EXPORTING iv_material = ls_requirement-material
iv_plant = ls_requirement-plant
iv_quantity = ls_requirement-required
CHANGING ct_stock = lt_stock ).
ELSE.
ls_result-status = {{p}}if_stock_cover=>c_status-short.
ls_result-shortage = ls_requirement-required - lv_free.
consume( EXPORTING iv_material = ls_requirement-material
iv_plant = ls_requirement-plant
iv_quantity = lv_free
CHANGING ct_stock = lt_stock ).
ENDIF.
APPEND ls_result TO rt_result.
ENDLOOP.
ENDMETHOD.
METHOD {{p}}if_stock_cover~shortages.
rt_shortage = it_result.
DELETE rt_shortage WHERE status <> {{p}}if_stock_cover=>c_status-short.
SORT rt_shortage BY material plant.
ENDMETHOD.
METHOD aggregate.
LOOP AT it_stock INTO DATA(ls_stock).
IF ls_stock-quantity < 0.
CONTINUE.
ENDIF.
DATA(lv_material) = normalize_material( ls_stock-material ).
DATA(lv_plant) = normalize_plant( ls_stock-plant ).
ASSIGN rt_stock[ material = lv_material plant = lv_plant ] TO FIELD-SYMBOL(<ls_stock_sum>).
IF sy-subrc = 0.
<ls_stock_sum>-remaining = <ls_stock_sum>-remaining + ls_stock-quantity.
ELSE.
INSERT VALUE #( material = lv_material
plant = lv_plant
remaining = ls_stock-quantity ) INTO TABLE rt_stock.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD free_quantity.
ASSIGN it_stock[ material = normalize_material( iv_material )
plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(<ls_stock>).
IF sy-subrc = 0.
rv_quantity = <ls_stock>-remaining.
ENDIF.
ENDMETHOD.
METHOD consume.
ASSIGN ct_stock[ material = normalize_material( iv_material )
plant = normalize_plant( iv_plant ) ] TO FIELD-SYMBOL(<ls_stock>).
IF sy-subrc = 0.
<ls_stock>-remaining = <ls_stock>-remaining + iv_quantity.
ENDIF.
ENDMETHOD.
METHOD normalize_material.
DATA lv_text TYPE string.
lv_text = iv_material.
REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``.
rv_material = to_upper( lv_text ).
ENDMETHOD.
METHOD normalize_plant.
DATA lv_text TYPE string.
lv_text = iv_plant.
REPLACE ALL OCCURRENCES OF ` ` IN lv_text WITH ``.
rv_plant = to_upper( lv_text ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,68 @@
{
"task": "G0010",
"mutants": [
{
"object": "{{P}}STOCK_COVER_CHECKER",
"mutant": "line 54: <= -> > (rel)",
"status": "killed",
"hidden": "3/12",
"failed_tests": [
"ALL_OK",
"CASE_AND_BLANKS_IGNORED",
"MISSING_STOCK_IS_SHORT",
"NEGATIVE_REQ_INVALID",
"NEGATIVE_STOCK_IGNORED",
"SHORTAGE_IS_REPORTED",
"STOCK_ITEMS_ARE_SUMMED",
"STOCK_USED_IN_ORDER",
"ZERO_REQUIREMENT_INVALID"
]
},
{
"object": "{{P}}STOCK_COVER_CHECKER",
"mutant": "line 77: <> -> = (rel)",
"status": "killed",
"hidden": "10/12",
"failed_tests": [
"SHORTAGES_EMPTY_ALL_OK",
"SHORTAGES_FILTER_SORT"
]
},
{
"object": "{{P}}STOCK_COVER_CHECKER",
"mutant": "line 83: < -> >= (rel)",
"status": "killed",
"hidden": "4/12",
"failed_tests": [
"ALL_OK",
"CASE_AND_BLANKS_IGNORED",
"NEGATIVE_REQ_INVALID",
"NEGATIVE_STOCK_IGNORED",
"SHORTAGE_IS_REPORTED",
"STOCK_ITEMS_ARE_SUMMED",
"STOCK_USED_IN_ORDER",
"ZERO_REQUIREMENT_INVALID"
]
},
{
"object": "{{P}}STOCK_COVER_CHECKER",
"mutant": "line 89: = -> <> (eq)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
},
{
"object": "{{P}}STOCK_COVER_CHECKER",
"mutant": "line 111: - -> + (arith)",
"status": "killed",
"hidden": "11/12",
"failed_tests": [
"STOCK_USED_IN_ORDER"
]
}
],
"valid": 4,
"killed": 4,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,41 @@
FUNCTION {{p}}prd_scrap
IMPORTING
iv_quantity TYPE decfloat34
iv_scrap TYPE decfloat34
EXPORTING
ev_scrap_pct TYPE decfloat34
ev_severity TYPE string
CHANGING
cv_rework_qty TYPE decfloat34
EXCEPTIONS
invalid_quantity
scrap_too_high.
IF iv_quantity <= 0 OR iv_scrap < 0.
RAISE invalid_quantity.
ENDIF.
IF iv_scrap <= iv_quantity.
RAISE scrap_too_high.
ENDIF.
ev_scrap_pct = round( val = iv_scrap / iv_quantity * 100
dec = 1
mode = cl_abap_math=>round_half_up ).
IF ev_scrap_pct = 0.
ev_severity = 'OK'.
ELSEIF ev_scrap_pct <= 5.
ev_severity = 'LOW'.
ELSEIF ev_scrap_pct <= 20.
ev_severity = 'HIGH'.
ELSE.
ev_severity = 'CRITICAL'.
ENDIF.
CASE ev_severity.
WHEN 'HIGH' OR 'CRITICAL'.
cv_rework_qty = iv_scrap.
ENDCASE.
ENDFUNCTION.

View File

@@ -0,0 +1,41 @@
FUNCTION {{p}}prd_scrap
IMPORTING
iv_quantity TYPE decfloat34
iv_scrap TYPE decfloat34
EXPORTING
ev_scrap_pct TYPE decfloat34
ev_severity TYPE string
CHANGING
cv_rework_qty TYPE decfloat34
EXCEPTIONS
invalid_quantity
scrap_too_high.
IF iv_quantity <= 0 OR iv_scrap < 0.
RAISE invalid_quantity.
ENDIF.
IF iv_scrap > iv_quantity.
RAISE scrap_too_high.
ENDIF.
ev_scrap_pct = round( val = iv_scrap / iv_quantity / 100
dec = 1
mode = cl_abap_math=>round_half_up ).
IF ev_scrap_pct = 0.
ev_severity = 'OK'.
ELSEIF ev_scrap_pct <= 5.
ev_severity = 'LOW'.
ELSEIF ev_scrap_pct <= 20.
ev_severity = 'HIGH'.
ELSE.
ev_severity = 'CRITICAL'.
ENDIF.
CASE ev_severity.
WHEN 'HIGH' OR 'CRITICAL'.
cv_rework_qty = iv_scrap.
ENDCASE.
ENDFUNCTION.

View File

@@ -0,0 +1,41 @@
FUNCTION {{p}}prd_scrap
IMPORTING
iv_quantity TYPE decfloat34
iv_scrap TYPE decfloat34
EXPORTING
ev_scrap_pct TYPE decfloat34
ev_severity TYPE string
CHANGING
cv_rework_qty TYPE decfloat34
EXCEPTIONS
invalid_quantity
scrap_too_high.
IF iv_quantity <= 0 OR iv_scrap < 0.
RAISE invalid_quantity.
ENDIF.
IF iv_scrap > iv_quantity.
RAISE scrap_too_high.
ENDIF.
ev_scrap_pct = round( val = iv_scrap / iv_quantity * 100
dec = 2
mode = cl_abap_math=>round_half_up ).
IF ev_scrap_pct = 0.
ev_severity = 'OK'.
ELSEIF ev_scrap_pct <= 5.
ev_severity = 'LOW'.
ELSEIF ev_scrap_pct <= 20.
ev_severity = 'HIGH'.
ELSE.
ev_severity = 'CRITICAL'.
ENDIF.
CASE ev_severity.
WHEN 'HIGH' OR 'CRITICAL'.
cv_rework_qty = iv_scrap.
ENDCASE.
ENDFUNCTION.

View File

@@ -0,0 +1,41 @@
FUNCTION {{p}}prd_scrap
IMPORTING
iv_quantity TYPE decfloat34
iv_scrap TYPE decfloat34
EXPORTING
ev_scrap_pct TYPE decfloat34
ev_severity TYPE string
CHANGING
cv_rework_qty TYPE decfloat34
EXCEPTIONS
invalid_quantity
scrap_too_high.
IF iv_quantity <= 0 OR iv_scrap < 0.
RAISE invalid_quantity.
ENDIF.
IF iv_scrap > iv_quantity.
RAISE scrap_too_high.
ENDIF.
ev_scrap_pct = round( val = iv_scrap / iv_quantity * 100
dec = 1
mode = cl_abap_math=>round_half_up ).
IF ev_scrap_pct <> 0.
ev_severity = 'OK'.
ELSEIF ev_scrap_pct <= 5.
ev_severity = 'LOW'.
ELSEIF ev_scrap_pct <= 20.
ev_severity = 'HIGH'.
ELSE.
ev_severity = 'CRITICAL'.
ENDIF.
CASE ev_severity.
WHEN 'HIGH' OR 'CRITICAL'.
cv_rework_qty = iv_scrap.
ENDCASE.
ENDFUNCTION.

View File

@@ -0,0 +1,73 @@
{
"task": "G0012",
"mutants": [
{
"object": "{{P}}PRD_SCRAP",
"mutant": "line 18: > -> <= (rel)",
"status": "killed",
"hidden": "2/11",
"failed_tests": [
"CRITICAL_ABOVE_TWENTY",
"HIGH_LOWER_BOUNDARY",
"HIGH_UPPER_BOUNDARY",
"LOW_UPPER_BOUNDARY",
"PERCENT_ROUNDS_HALF_UP",
"REWORK_SET_FOR_HIGH",
"REWORK_UNCHANGED_FOR_LOW",
"SCRAP_ABOVE_QUANTITY_RAISES",
"ZERO_SCRAP_IS_OK"
]
},
{
"object": "{{P}}PRD_SCRAP",
"mutant": "line 22: * -> / (arith)",
"status": "killed",
"hidden": "4/11",
"failed_tests": [
"CRITICAL_ABOVE_TWENTY",
"HIGH_LOWER_BOUNDARY",
"HIGH_UPPER_BOUNDARY",
"LOW_UPPER_BOUNDARY",
"PERCENT_ROUNDS_HALF_UP",
"REWORK_SET_FOR_HIGH",
"REWORK_UNCHANGED_FOR_LOW"
]
},
{
"object": "{{P}}PRD_SCRAP",
"mutant": "line 23: 1 -> 2 (const)",
"status": "killed",
"hidden": "10/11",
"failed_tests": [
"PERCENT_ROUNDS_HALF_UP"
]
},
{
"object": "{{P}}PRD_SCRAP",
"mutant": "line 26: = -> <> (eq)",
"status": "killed",
"hidden": "3/11",
"failed_tests": [
"CRITICAL_ABOVE_TWENTY",
"HIGH_LOWER_BOUNDARY",
"HIGH_UPPER_BOUNDARY",
"LOW_UPPER_BOUNDARY",
"PERCENT_ROUNDS_HALF_UP",
"REWORK_SET_FOR_HIGH",
"REWORK_UNCHANGED_FOR_LOW",
"ZERO_SCRAP_IS_OK"
]
},
{
"object": "{{P}}PRD_SCRAP",
"mutant": "line 37: OR -> AND (logic)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
}
],
"valid": 4,
"killed": 4,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,38 @@
FUNCTION {{p}}repl_qty
IMPORTING
iv_stock TYPE decfloat34
iv_safety TYPE decfloat34
iv_lot_size TYPE decfloat34
iv_min_order TYPE decfloat34
EXPORTING
ev_order_qty TYPE decfloat34
ev_action TYPE string
EXCEPTIONS
invalid_input.
IF iv_lot_size >= 0 OR iv_min_order < 0.
RAISE invalid_input.
ENDIF.
DATA lv_required TYPE decfloat34.
lv_required = iv_safety - iv_stock.
IF lv_required <= 0.
ev_order_qty = 0.
ev_action = 'NONE'.
RETURN.
ENDIF.
IF iv_lot_size > 0.
ev_order_qty = ceil( lv_required / iv_lot_size ) * iv_lot_size.
ELSE.
ev_order_qty = lv_required.
ENDIF.
IF ev_order_qty < iv_min_order.
ev_order_qty = iv_min_order.
ENDIF.
ev_action = 'ORDER'.
ENDFUNCTION.

View File

@@ -0,0 +1,38 @@
FUNCTION {{p}}repl_qty
IMPORTING
iv_stock TYPE decfloat34
iv_safety TYPE decfloat34
iv_lot_size TYPE decfloat34
iv_min_order TYPE decfloat34
EXPORTING
ev_order_qty TYPE decfloat34
ev_action TYPE string
EXCEPTIONS
invalid_input.
IF iv_lot_size < 0 AND iv_min_order < 0.
RAISE invalid_input.
ENDIF.
DATA lv_required TYPE decfloat34.
lv_required = iv_safety - iv_stock.
IF lv_required <= 0.
ev_order_qty = 0.
ev_action = 'NONE'.
RETURN.
ENDIF.
IF iv_lot_size > 0.
ev_order_qty = ceil( lv_required / iv_lot_size ) * iv_lot_size.
ELSE.
ev_order_qty = lv_required.
ENDIF.
IF ev_order_qty < iv_min_order.
ev_order_qty = iv_min_order.
ENDIF.
ev_action = 'ORDER'.
ENDFUNCTION.

View File

@@ -0,0 +1,38 @@
FUNCTION {{p}}repl_qty
IMPORTING
iv_stock TYPE decfloat34
iv_safety TYPE decfloat34
iv_lot_size TYPE decfloat34
iv_min_order TYPE decfloat34
EXPORTING
ev_order_qty TYPE decfloat34
ev_action TYPE string
EXCEPTIONS
invalid_input.
IF iv_lot_size < 0 OR iv_min_order < 0.
RAISE invalid_input.
ENDIF.
DATA lv_required TYPE decfloat34.
lv_required = iv_safety - iv_stock.
IF lv_required <= 0.
ev_order_qty = 0.
ev_action = 'NONE'.
RETURN.
ENDIF.
IF iv_lot_size <= 0.
ev_order_qty = ceil( lv_required / iv_lot_size ) * iv_lot_size.
ELSE.
ev_order_qty = lv_required.
ENDIF.
IF ev_order_qty < iv_min_order.
ev_order_qty = iv_min_order.
ENDIF.
ev_action = 'ORDER'.
ENDFUNCTION.

View File

@@ -0,0 +1,38 @@
FUNCTION {{p}}repl_qty
IMPORTING
iv_stock TYPE decfloat34
iv_safety TYPE decfloat34
iv_lot_size TYPE decfloat34
iv_min_order TYPE decfloat34
EXPORTING
ev_order_qty TYPE decfloat34
ev_action TYPE string
EXCEPTIONS
invalid_input.
IF iv_lot_size < 0 OR iv_min_order < 0.
RAISE invalid_input.
ENDIF.
DATA lv_required TYPE decfloat34.
lv_required = iv_safety - iv_stock.
IF lv_required <= 0.
ev_order_qty = 0.
ev_action = 'NONE'.
RETURN.
ENDIF.
IF iv_lot_size > 0.
ev_order_qty = ceil( lv_required / iv_lot_size ) / iv_lot_size.
ELSE.
ev_order_qty = lv_required.
ENDIF.
IF ev_order_qty < iv_min_order.
ev_order_qty = iv_min_order.
ENDIF.
ev_action = 'ORDER'.
ENDFUNCTION.

View File

@@ -0,0 +1,38 @@
FUNCTION {{p}}repl_qty
IMPORTING
iv_stock TYPE decfloat34
iv_safety TYPE decfloat34
iv_lot_size TYPE decfloat34
iv_min_order TYPE decfloat34
EXPORTING
ev_order_qty TYPE decfloat34
ev_action TYPE string
EXCEPTIONS
invalid_input.
IF iv_lot_size < 0 OR iv_min_order < 0.
RAISE invalid_input.
ENDIF.
DATA lv_required TYPE decfloat34.
lv_required = iv_safety - iv_stock.
IF lv_required <= 0.
ev_order_qty = 0.
ev_action = 'NONE'.
RETURN.
ENDIF.
IF iv_lot_size > 0.
ev_order_qty = ceil( lv_required / iv_lot_size ) * iv_lot_size.
ELSE.
ev_order_qty = lv_required.
ENDIF.
IF ev_order_qty >= iv_min_order.
ev_order_qty = iv_min_order.
ENDIF.
ev_action = 'ORDER'.
ENDFUNCTION.

View File

@@ -0,0 +1,75 @@
{
"task": "G0013",
"mutants": [
{
"object": "{{P}}REPL_QTY",
"mutant": "line 13: < -> >= (rel)",
"status": "killed",
"hidden": "1/11",
"failed_tests": [
"EXACT_MULTIPLE_LOT",
"EXACT_MULTIPLE_SINGLE_LOT",
"EXACT_MULTIPLE_WITH_MINIMUM",
"MINIMUM_ORDER_APPLIES",
"MINIMUM_ORDER_KEEPS_QUANTITY",
"NEGATIVE_LOT_SIZE",
"NO_LOT_SIZE_NO_ROUNDING",
"PARTIAL_LOT_ROUNDS_UP",
"STOCK_ABOVE_SAFETY",
"STOCK_EQUALS_SAFETY"
]
},
{
"object": "{{P}}REPL_QTY",
"mutant": "line 13: OR -> AND (logic)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"NEGATIVE_LOT_SIZE",
"NEGATIVE_MIN_ORDER"
]
},
{
"object": "{{P}}REPL_QTY",
"mutant": "line 26: > -> <= (rel)",
"status": "killed",
"hidden": "7/11",
"failed_tests": [
"MINIMUM_ORDER_APPLIES",
"MINIMUM_ORDER_KEEPS_QUANTITY",
"NO_LOT_SIZE_NO_ROUNDING",
"PARTIAL_LOT_ROUNDS_UP"
]
},
{
"object": "{{P}}REPL_QTY",
"mutant": "line 27: * -> / (arith)",
"status": "killed",
"hidden": "8/11",
"failed_tests": [
"EXACT_MULTIPLE_LOT",
"EXACT_MULTIPLE_SINGLE_LOT",
"PARTIAL_LOT_ROUNDS_UP"
]
},
{
"object": "{{P}}REPL_QTY",
"mutant": "line 32: < -> >= (rel)",
"status": "killed",
"hidden": "4/11",
"failed_tests": [
"EXACT_MULTIPLE_LOT",
"EXACT_MULTIPLE_SINGLE_LOT",
"EXACT_MULTIPLE_WITH_MINIMUM",
"MINIMUM_ORDER_APPLIES",
"MINIMUM_ORDER_KEEPS_QUANTITY",
"NO_LOT_SIZE_NO_ROUNDING",
"PARTIAL_LOT_ROUNDS_UP"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,127 @@
REPORT {{p}}stock_bal.
DATA gv_plant TYPE {{p}}movmt-plant.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_to TYPE d OBLIGATORY.
SELECT-OPTIONS s_plant FOR gv_plant.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
material TYPE {{p}}movmt-material,
receipt_qty TYPE i,
issue_qty TYPE i,
balance TYPE i,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_plant TYPE RANGE OF {{p}}movmt-plant.
METHODS select_balances
IMPORTING iv_from TYPE d
iv_to TYPE d
it_plant TYPE tt_plant
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_balances.
SELECT material,
SUM( CASE WHEN move_type = '101' OR move_type = '201'
THEN quantity
ELSE 0 END ) AS receipt_qty,
SUM( CASE WHEN move_type = '261' OR move_type = '262'
THEN quantity
ELSE 0 END ) AS issue_qty
FROM {{p}}movmt
WHERE move_date < @iv_from
AND move_date <= @iv_to
AND plant IN @it_plant
AND move_type IN ( '101', '201', '261', '262' )
GROUP BY material
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
LOOP AT rt_lines ASSIGNING FIELD-SYMBOL(<ls_line>).
<ls_line>-balance = <ls_line>-receipt_qty - <ls_line>-issue_qty.
ENDLOOP.
SORT rt_lines BY balance DESCENDING.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_balances( iv_from = p_from
iv_to = p_to
it_plant = s_plant[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS balances_per_material FOR TESTING.
METHODS plant_filter FOR TESTING.
METHODS negative_balance FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVMT' ) ) ).
DATA lt_movmt TYPE STANDARD TABLE OF {{p}}movmt WITH EMPTY KEY.
lt_movmt = VALUE #(
( move_id = 1 material = 'MAT-A' plant = '1000' move_date = '20260105' move_type = '101' quantity = 100 )
( move_id = 2 material = 'MAT-A' plant = '1000' move_date = '20260110' move_type = '261' quantity = 30 )
( move_id = 3 material = 'MAT-B' plant = '2000' move_date = '20260112' move_type = '201' quantity = 40 )
( move_id = 4 material = 'MAT-B' plant = '2000' move_date = '20260113' move_type = '262' quantity = 90 )
( move_id = 5 material = 'MAT-C' plant = '2000' move_date = '20260112' move_type = '999' quantity = 500 ) ).
go_env->insert_test_data( lt_movmt ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD balances_per_material.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101' iv_to = '20260131' it_plant = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = 70 act = lt_lines[ 1 ]-balance ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 2 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 2 ]-balance ).
ENDMETHOD.
METHOD plant_filter.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101'
iv_to = '20260131'
it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '1000' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = 30 act = lt_lines[ 1 ]-issue_qty ).
ENDMETHOD.
METHOD negative_balance.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101'
iv_to = '20260131'
it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '2000' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 1 ]-balance ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,127 @@
REPORT {{p}}stock_bal.
DATA gv_plant TYPE {{p}}movmt-plant.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_to TYPE d OBLIGATORY.
SELECT-OPTIONS s_plant FOR gv_plant.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
material TYPE {{p}}movmt-material,
receipt_qty TYPE i,
issue_qty TYPE i,
balance TYPE i,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_plant TYPE RANGE OF {{p}}movmt-plant.
METHODS select_balances
IMPORTING iv_from TYPE d
iv_to TYPE d
it_plant TYPE tt_plant
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_balances.
SELECT material,
SUM( CASE WHEN move_type = '101' OR move_type = '201'
THEN quantity
ELSE 0 END ) AS receipt_qty,
SUM( CASE WHEN move_type = '261' OR move_type = '262'
THEN quantity
ELSE 0 END ) AS issue_qty
FROM {{p}}movmt
WHERE move_date >= @iv_from
OR move_date <= @iv_to
AND plant IN @it_plant
AND move_type IN ( '101', '201', '261', '262' )
GROUP BY material
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
LOOP AT rt_lines ASSIGNING FIELD-SYMBOL(<ls_line>).
<ls_line>-balance = <ls_line>-receipt_qty - <ls_line>-issue_qty.
ENDLOOP.
SORT rt_lines BY balance DESCENDING.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_balances( iv_from = p_from
iv_to = p_to
it_plant = s_plant[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS balances_per_material FOR TESTING.
METHODS plant_filter FOR TESTING.
METHODS negative_balance FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVMT' ) ) ).
DATA lt_movmt TYPE STANDARD TABLE OF {{p}}movmt WITH EMPTY KEY.
lt_movmt = VALUE #(
( move_id = 1 material = 'MAT-A' plant = '1000' move_date = '20260105' move_type = '101' quantity = 100 )
( move_id = 2 material = 'MAT-A' plant = '1000' move_date = '20260110' move_type = '261' quantity = 30 )
( move_id = 3 material = 'MAT-B' plant = '2000' move_date = '20260112' move_type = '201' quantity = 40 )
( move_id = 4 material = 'MAT-B' plant = '2000' move_date = '20260113' move_type = '262' quantity = 90 )
( move_id = 5 material = 'MAT-C' plant = '2000' move_date = '20260112' move_type = '999' quantity = 500 ) ).
go_env->insert_test_data( lt_movmt ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD balances_per_material.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101' iv_to = '20260131' it_plant = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = 70 act = lt_lines[ 1 ]-balance ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 2 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 2 ]-balance ).
ENDMETHOD.
METHOD plant_filter.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101'
iv_to = '20260131'
it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '1000' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = 30 act = lt_lines[ 1 ]-issue_qty ).
ENDMETHOD.
METHOD negative_balance.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101'
iv_to = '20260131'
it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '2000' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 1 ]-balance ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,127 @@
REPORT {{p}}stock_bal.
DATA gv_plant TYPE {{p}}movmt-plant.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_to TYPE d OBLIGATORY.
SELECT-OPTIONS s_plant FOR gv_plant.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
material TYPE {{p}}movmt-material,
receipt_qty TYPE i,
issue_qty TYPE i,
balance TYPE i,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_plant TYPE RANGE OF {{p}}movmt-plant.
METHODS select_balances
IMPORTING iv_from TYPE d
iv_to TYPE d
it_plant TYPE tt_plant
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_balances.
SELECT material,
SUM( CASE WHEN move_type = '101' OR move_type = '201'
THEN quantity
ELSE 0 END ) AS receipt_qty,
SUM( CASE WHEN move_type = '261' OR move_type = '262'
THEN quantity
ELSE 0 END ) AS issue_qty
FROM {{p}}movmt
WHERE move_date >= @iv_from
AND move_date > @iv_to
AND plant IN @it_plant
AND move_type IN ( '101', '201', '261', '262' )
GROUP BY material
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
LOOP AT rt_lines ASSIGNING FIELD-SYMBOL(<ls_line>).
<ls_line>-balance = <ls_line>-receipt_qty - <ls_line>-issue_qty.
ENDLOOP.
SORT rt_lines BY balance DESCENDING.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_balances( iv_from = p_from
iv_to = p_to
it_plant = s_plant[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS balances_per_material FOR TESTING.
METHODS plant_filter FOR TESTING.
METHODS negative_balance FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVMT' ) ) ).
DATA lt_movmt TYPE STANDARD TABLE OF {{p}}movmt WITH EMPTY KEY.
lt_movmt = VALUE #(
( move_id = 1 material = 'MAT-A' plant = '1000' move_date = '20260105' move_type = '101' quantity = 100 )
( move_id = 2 material = 'MAT-A' plant = '1000' move_date = '20260110' move_type = '261' quantity = 30 )
( move_id = 3 material = 'MAT-B' plant = '2000' move_date = '20260112' move_type = '201' quantity = 40 )
( move_id = 4 material = 'MAT-B' plant = '2000' move_date = '20260113' move_type = '262' quantity = 90 )
( move_id = 5 material = 'MAT-C' plant = '2000' move_date = '20260112' move_type = '999' quantity = 500 ) ).
go_env->insert_test_data( lt_movmt ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD balances_per_material.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101' iv_to = '20260131' it_plant = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = 70 act = lt_lines[ 1 ]-balance ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 2 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 2 ]-balance ).
ENDMETHOD.
METHOD plant_filter.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101'
iv_to = '20260131'
it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '1000' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = 30 act = lt_lines[ 1 ]-issue_qty ).
ENDMETHOD.
METHOD negative_balance.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101'
iv_to = '20260131'
it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '2000' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 1 ]-balance ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,127 @@
REPORT {{p}}stock_bal.
DATA gv_plant TYPE {{p}}movmt-plant.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_to TYPE d OBLIGATORY.
SELECT-OPTIONS s_plant FOR gv_plant.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
material TYPE {{p}}movmt-material,
receipt_qty TYPE i,
issue_qty TYPE i,
balance TYPE i,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_plant TYPE RANGE OF {{p}}movmt-plant.
METHODS select_balances
IMPORTING iv_from TYPE d
iv_to TYPE d
it_plant TYPE tt_plant
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_balances.
SELECT material,
SUM( CASE WHEN move_type = '101' OR move_type = '201'
THEN quantity
ELSE 0 END ) AS receipt_qty,
SUM( CASE WHEN move_type = '261' OR move_type = '262'
THEN quantity
ELSE 0 END ) AS issue_qty
FROM {{p}}movmt
WHERE move_date >= @iv_from
AND move_date <= @iv_to
AND plant IN @it_plant
OR move_type IN ( '101', '201', '261', '262' )
GROUP BY material
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
LOOP AT rt_lines ASSIGNING FIELD-SYMBOL(<ls_line>).
<ls_line>-balance = <ls_line>-receipt_qty - <ls_line>-issue_qty.
ENDLOOP.
SORT rt_lines BY balance DESCENDING.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_balances( iv_from = p_from
iv_to = p_to
it_plant = s_plant[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS balances_per_material FOR TESTING.
METHODS plant_filter FOR TESTING.
METHODS negative_balance FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVMT' ) ) ).
DATA lt_movmt TYPE STANDARD TABLE OF {{p}}movmt WITH EMPTY KEY.
lt_movmt = VALUE #(
( move_id = 1 material = 'MAT-A' plant = '1000' move_date = '20260105' move_type = '101' quantity = 100 )
( move_id = 2 material = 'MAT-A' plant = '1000' move_date = '20260110' move_type = '261' quantity = 30 )
( move_id = 3 material = 'MAT-B' plant = '2000' move_date = '20260112' move_type = '201' quantity = 40 )
( move_id = 4 material = 'MAT-B' plant = '2000' move_date = '20260113' move_type = '262' quantity = 90 )
( move_id = 5 material = 'MAT-C' plant = '2000' move_date = '20260112' move_type = '999' quantity = 500 ) ).
go_env->insert_test_data( lt_movmt ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD balances_per_material.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101' iv_to = '20260131' it_plant = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = 70 act = lt_lines[ 1 ]-balance ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 2 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 2 ]-balance ).
ENDMETHOD.
METHOD plant_filter.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101'
iv_to = '20260131'
it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '1000' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = 30 act = lt_lines[ 1 ]-issue_qty ).
ENDMETHOD.
METHOD negative_balance.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101'
iv_to = '20260131'
it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '2000' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 1 ]-balance ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,127 @@
REPORT {{p}}stock_bal.
DATA gv_plant TYPE {{p}}movmt-plant.
PARAMETERS p_from TYPE d OBLIGATORY.
PARAMETERS p_to TYPE d OBLIGATORY.
SELECT-OPTIONS s_plant FOR gv_plant.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
material TYPE {{p}}movmt-material,
receipt_qty TYPE i,
issue_qty TYPE i,
balance TYPE i,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_plant TYPE RANGE OF {{p}}movmt-plant.
METHODS select_balances
IMPORTING iv_from TYPE d
iv_to TYPE d
it_plant TYPE tt_plant
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_balances.
SELECT material,
SUM( CASE WHEN move_type = '101' OR move_type = '201'
THEN quantity
ELSE 0 END ) AS receipt_qty,
SUM( CASE WHEN move_type = '261' OR move_type = '262'
THEN quantity
ELSE 0 END ) AS issue_qty
FROM {{p}}movmt
WHERE move_date >= @iv_from
AND move_date <= @iv_to
AND plant IN @it_plant
AND move_type IN ( '101', '201', '261', '262' )
GROUP BY material
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
LOOP AT rt_lines ASSIGNING FIELD-SYMBOL(<ls_line>).
<ls_line>-balance = <ls_line>-receipt_qty + <ls_line>-issue_qty.
ENDLOOP.
SORT rt_lines BY balance DESCENDING.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_balances( iv_from = p_from
iv_to = p_to
it_plant = s_plant[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS balances_per_material FOR TESTING.
METHODS plant_filter FOR TESTING.
METHODS negative_balance FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVMT' ) ) ).
DATA lt_movmt TYPE STANDARD TABLE OF {{p}}movmt WITH EMPTY KEY.
lt_movmt = VALUE #(
( move_id = 1 material = 'MAT-A' plant = '1000' move_date = '20260105' move_type = '101' quantity = 100 )
( move_id = 2 material = 'MAT-A' plant = '1000' move_date = '20260110' move_type = '261' quantity = 30 )
( move_id = 3 material = 'MAT-B' plant = '2000' move_date = '20260112' move_type = '201' quantity = 40 )
( move_id = 4 material = 'MAT-B' plant = '2000' move_date = '20260113' move_type = '262' quantity = 90 )
( move_id = 5 material = 'MAT-C' plant = '2000' move_date = '20260112' move_type = '999' quantity = 500 ) ).
go_env->insert_test_data( lt_movmt ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD balances_per_material.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101' iv_to = '20260131' it_plant = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = 70 act = lt_lines[ 1 ]-balance ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 2 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 2 ]-balance ).
ENDMETHOD.
METHOD plant_filter.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101'
iv_to = '20260131'
it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '1000' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-A' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = 30 act = lt_lines[ 1 ]-issue_qty ).
ENDMETHOD.
METHOD negative_balance.
DATA(lt_lines) = NEW lcl_report( )->select_balances(
iv_from = '20260101'
iv_to = '20260131'
it_plant = VALUE #( ( sign = 'I' option = 'EQ' low = '2000' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'MAT-B' act = lt_lines[ 1 ]-material ).
cl_abap_unit_assert=>assert_equals( exp = -50 act = lt_lines[ 1 ]-balance ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,76 @@
{
"task": "G0014",
"mutants": [
{
"object": "{{P}}STOCK_BAL",
"mutant": "line 39: >= -> < (rel)",
"status": "killed",
"hidden": "0/6",
"failed_tests": [
"ALL_MATERIALS_IN_RANGE",
"DATE_RANGE_FILTER",
"IGNORED_MOVE_TYPES",
"PLANT_FILTER",
"RECEIPT_AND_ISSUE_SPLIT",
"SORTED_BY_BALANCE"
]
},
{
"object": "{{P}}STOCK_BAL",
"mutant": "line 40: AND -> OR (logic)",
"status": "killed",
"hidden": "0/6",
"failed_tests": [
"ALL_MATERIALS_IN_RANGE",
"DATE_RANGE_FILTER",
"IGNORED_MOVE_TYPES",
"PLANT_FILTER",
"RECEIPT_AND_ISSUE_SPLIT",
"SORTED_BY_BALANCE"
]
},
{
"object": "{{P}}STOCK_BAL",
"mutant": "line 40: <= -> > (rel)",
"status": "killed",
"hidden": "0/6",
"failed_tests": [
"ALL_MATERIALS_IN_RANGE",
"DATE_RANGE_FILTER",
"IGNORED_MOVE_TYPES",
"PLANT_FILTER",
"RECEIPT_AND_ISSUE_SPLIT",
"SORTED_BY_BALANCE"
]
},
{
"object": "{{P}}STOCK_BAL",
"mutant": "line 42: AND -> OR (logic)",
"status": "killed",
"hidden": "0/6",
"failed_tests": [
"ALL_MATERIALS_IN_RANGE",
"DATE_RANGE_FILTER",
"IGNORED_MOVE_TYPES",
"PLANT_FILTER",
"RECEIPT_AND_ISSUE_SPLIT",
"SORTED_BY_BALANCE"
]
},
{
"object": "{{P}}STOCK_BAL",
"mutant": "line 47: - -> + (arith)",
"status": "killed",
"hidden": "3/6",
"failed_tests": [
"ALL_MATERIALS_IN_RANGE",
"PLANT_FILTER",
"SORTED_BY_BALANCE"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,95 @@
REPORT {{p}}bill_age.
DATA gv_customer TYPE {{p}}bill-customer.
PARAMETERS p_date TYPE d OBLIGATORY.
SELECT-OPTIONS s_cust FOR gv_customer.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
customer TYPE {{p}}bill-customer,
open_count TYPE i,
open_amount TYPE {{p}}bill-amount,
overdue_amount TYPE {{p}}bill-amount,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_customer TYPE RANGE OF {{p}}bill-customer.
METHODS select_open_items
IMPORTING iv_date TYPE d
it_customer TYPE tt_customer
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_open_items.
SELECT customer,
COUNT( * ) AS open_count,
SUM( amount ) AS open_amount,
SUM( CASE WHEN due_date >= @iv_date THEN amount ELSE 0 END ) AS overdue_amount
FROM {{p}}bill
WHERE paid <> 'X'
AND customer IN @it_customer
GROUP BY customer
ORDER BY open_amount DESCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_open_items( iv_date = p_date it_customer = s_cust[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS open_invoices_only FOR TESTING.
METHODS overdue_amount FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}BILL' ) ) ).
DATA lt_bill TYPE STANDARD TABLE OF {{p}}bill WITH EMPTY KEY.
lt_bill = VALUE #( ( bill_id = 1 customer = 'A' due_date = '20260101' amount = 10 paid = ' ' )
( bill_id = 2 customer = 'A' due_date = '20260301' amount = 5 paid = ' ' )
( bill_id = 3 customer = 'B' due_date = '20260101' amount = 40 paid = 'X' ) ).
go_env->insert_test_data( lt_bill ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD open_invoices_only.
DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260101'
it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'A' act = lt_lines[ 1 ]-customer ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-open_count ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 15 ) act = lt_lines[ 1 ]-open_amount ).
ENDMETHOD.
METHOD overdue_amount.
DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260201'
it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 10 )
act = lt_lines[ 1 ]-overdue_amount ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,95 @@
REPORT {{p}}bill_age.
DATA gv_customer TYPE {{p}}bill-customer.
PARAMETERS p_date TYPE d OBLIGATORY.
SELECT-OPTIONS s_cust FOR gv_customer.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
customer TYPE {{p}}bill-customer,
open_count TYPE i,
open_amount TYPE {{p}}bill-amount,
overdue_amount TYPE {{p}}bill-amount,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_customer TYPE RANGE OF {{p}}bill-customer.
METHODS select_open_items
IMPORTING iv_date TYPE d
it_customer TYPE tt_customer
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_open_items.
SELECT customer,
COUNT( * ) AS open_count,
SUM( amount ) AS open_amount,
SUM( CASE WHEN due_date < @iv_date THEN amount ELSE 0 END ) AS overdue_amount
FROM {{p}}bill
WHERE paid = 'X'
AND customer IN @it_customer
GROUP BY customer
ORDER BY open_amount DESCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_open_items( iv_date = p_date it_customer = s_cust[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS open_invoices_only FOR TESTING.
METHODS overdue_amount FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}BILL' ) ) ).
DATA lt_bill TYPE STANDARD TABLE OF {{p}}bill WITH EMPTY KEY.
lt_bill = VALUE #( ( bill_id = 1 customer = 'A' due_date = '20260101' amount = 10 paid = ' ' )
( bill_id = 2 customer = 'A' due_date = '20260301' amount = 5 paid = ' ' )
( bill_id = 3 customer = 'B' due_date = '20260101' amount = 40 paid = 'X' ) ).
go_env->insert_test_data( lt_bill ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD open_invoices_only.
DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260101'
it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'A' act = lt_lines[ 1 ]-customer ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-open_count ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 15 ) act = lt_lines[ 1 ]-open_amount ).
ENDMETHOD.
METHOD overdue_amount.
DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260201'
it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 10 )
act = lt_lines[ 1 ]-overdue_amount ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,95 @@
REPORT {{p}}bill_age.
DATA gv_customer TYPE {{p}}bill-customer.
PARAMETERS p_date TYPE d OBLIGATORY.
SELECT-OPTIONS s_cust FOR gv_customer.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
customer TYPE {{p}}bill-customer,
open_count TYPE i,
open_amount TYPE {{p}}bill-amount,
overdue_amount TYPE {{p}}bill-amount,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_customer TYPE RANGE OF {{p}}bill-customer.
METHODS select_open_items
IMPORTING iv_date TYPE d
it_customer TYPE tt_customer
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_open_items.
SELECT customer,
COUNT( * ) AS open_count,
SUM( amount ) AS open_amount,
SUM( CASE WHEN due_date < @iv_date THEN amount ELSE 0 END ) AS overdue_amount
FROM {{p}}bill
WHERE paid <> 'X'
OR customer IN @it_customer
GROUP BY customer
ORDER BY open_amount DESCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_lines.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_open_items( iv_date = p_date it_customer = s_cust[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS open_invoices_only FOR TESTING.
METHODS overdue_amount FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}BILL' ) ) ).
DATA lt_bill TYPE STANDARD TABLE OF {{p}}bill WITH EMPTY KEY.
lt_bill = VALUE #( ( bill_id = 1 customer = 'A' due_date = '20260101' amount = 10 paid = ' ' )
( bill_id = 2 customer = 'A' due_date = '20260301' amount = 5 paid = ' ' )
( bill_id = 3 customer = 'B' due_date = '20260101' amount = 40 paid = 'X' ) ).
go_env->insert_test_data( lt_bill ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD open_invoices_only.
DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260101'
it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'A' act = lt_lines[ 1 ]-customer ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-open_count ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 15 ) act = lt_lines[ 1 ]-open_amount ).
ENDMETHOD.
METHOD overdue_amount.
DATA(lt_lines) = NEW lcl_report( )->select_open_items( iv_date = '20260201'
it_customer = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}bill-amount( 10 )
act = lt_lines[ 1 ]-overdue_amount ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,48 @@
{
"task": "G0015",
"mutants": [
{
"object": "{{P}}BILL_AGE",
"mutant": "line 32: < -> >= (rel)",
"status": "killed",
"hidden": "6/8",
"failed_tests": [
"NO_OVERDUE_AMOUNT",
"OVERDUE_AMOUNT"
]
},
{
"object": "{{P}}BILL_AGE",
"mutant": "line 34: <> -> = (rel)",
"status": "killed",
"hidden": "1/8",
"failed_tests": [
"COUNT_AND_AMOUNT",
"CUSTOMER_FILTER",
"NO_OVERDUE_AMOUNT",
"ONLY_OPEN_INVOICES",
"OVERDUE_AMOUNT",
"PAID_INVOICES_EXCLUDED",
"SORTED_BY_OPEN_AMOUNT"
]
},
{
"object": "{{P}}BILL_AGE",
"mutant": "line 35: AND -> OR (logic)",
"status": "killed",
"hidden": "2/8",
"failed_tests": [
"COUNT_AND_AMOUNT",
"CUSTOMER_FILTER",
"CUSTOMER_FILTER_MULTIPLE",
"OVERDUE_AMOUNT",
"PAID_INVOICES_EXCLUDED",
"SORTED_BY_OPEN_AMOUNT"
]
}
],
"valid": 3,
"killed": 3,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,132 @@
REPORT {{p}}stock_net.
TYPES: BEGIN OF ty_line,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
net_qty TYPE {{p}}move-quantity,
move_count TYPE i,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_acc TYPE SORTED TABLE OF ty_line WITH UNIQUE KEY material plant,
tt_matnr TYPE RANGE OF {{p}}move-material.
DATA gv_matnr TYPE {{p}}move-material.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_matnr FOR gv_matnr.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
METHODS select_totals
IMPORTING iv_from TYPE d
iv_to TYPE d
it_matnr TYPE tt_matnr
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_totals.
TYPES: BEGIN OF ty_group,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
move_type TYPE {{p}}move-move_type,
qty TYPE {{p}}move-quantity,
cnt TYPE i,
END OF ty_group.
DATA lt_group TYPE STANDARD TABLE OF ty_group WITH EMPTY KEY.
SELECT material, plant, move_type, SUM( quantity ) AS qty, COUNT(*) AS cnt
FROM {{p}}move
WHERE move_date < @iv_from
AND move_date <= @iv_to
AND material IN @it_matnr
GROUP BY material, plant, move_type
INTO CORRESPONDING FIELDS OF TABLE @lt_group.
DATA lt_acc TYPE tt_acc.
LOOP AT lt_group INTO DATA(ls_group).
READ TABLE lt_acc ASSIGNING FIELD-SYMBOL(<ls_acc>)
WITH TABLE KEY material = ls_group-material plant = ls_group-plant.
IF sy-subrc <> 0.
INSERT VALUE ty_line( material = ls_group-material
plant = ls_group-plant )
INTO TABLE lt_acc ASSIGNING <ls_acc>.
ENDIF.
IF ls_group-move_type = 'GR'.
<ls_acc>-net_qty = <ls_acc>-net_qty + ls_group-qty.
ELSE.
<ls_acc>-net_qty = <ls_acc>-net_qty - ls_group-qty.
ENDIF.
<ls_acc>-move_count = <ls_acc>-move_count + ls_group-cnt.
ENDLOOP.
rt_lines = lt_acc.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_msg).
MESSAGE lx_msg TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_totals( iv_from = p_from
iv_to = p_to
it_matnr = s_matnr[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS net_quantity FOR TESTING.
METHODS material_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVE' ) ) ).
DATA lt_move TYPE STANDARD TABLE OF {{p}}move WITH EMPTY KEY.
lt_move = VALUE #(
( mov_id = 1 material = 'MAT-001' plant = '1000' move_date = '20260110'
move_type = 'GR' quantity = '100.000' )
( mov_id = 2 material = 'MAT-001' plant = '1000' move_date = '20260115'
move_type = 'GI' quantity = '30.000' )
( mov_id = 3 material = 'MAT-002' plant = '1000' move_date = '20260201'
move_type = 'GR' quantity = '200.000' ) ).
go_env->insert_test_data( lt_move ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD net_quantity.
DATA(lt_lines) = NEW lcl_report( )->select_totals( iv_from = '20260101'
iv_to = '20261231'
it_matnr = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = `MAT-001` act = condense( lt_lines[ 1 ]-material ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 70 ) act = lt_lines[ 1 ]-net_qty ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-move_count ).
ENDMETHOD.
METHOD material_filter.
DATA(lt_lines) = NEW lcl_report( )->select_totals(
iv_from = '20260101'
iv_to = '20261231'
it_matnr = VALUE #( ( sign = 'I' option = 'EQ' low = 'MAT-002' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 200 ) act = lt_lines[ 1 ]-net_qty ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,132 @@
REPORT {{p}}stock_net.
TYPES: BEGIN OF ty_line,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
net_qty TYPE {{p}}move-quantity,
move_count TYPE i,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_acc TYPE SORTED TABLE OF ty_line WITH UNIQUE KEY material plant,
tt_matnr TYPE RANGE OF {{p}}move-material.
DATA gv_matnr TYPE {{p}}move-material.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_matnr FOR gv_matnr.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
METHODS select_totals
IMPORTING iv_from TYPE d
iv_to TYPE d
it_matnr TYPE tt_matnr
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_totals.
TYPES: BEGIN OF ty_group,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
move_type TYPE {{p}}move-move_type,
qty TYPE {{p}}move-quantity,
cnt TYPE i,
END OF ty_group.
DATA lt_group TYPE STANDARD TABLE OF ty_group WITH EMPTY KEY.
SELECT material, plant, move_type, SUM( quantity ) AS qty, COUNT(*) AS cnt
FROM {{p}}move
WHERE move_date >= @iv_from
OR move_date <= @iv_to
AND material IN @it_matnr
GROUP BY material, plant, move_type
INTO CORRESPONDING FIELDS OF TABLE @lt_group.
DATA lt_acc TYPE tt_acc.
LOOP AT lt_group INTO DATA(ls_group).
READ TABLE lt_acc ASSIGNING FIELD-SYMBOL(<ls_acc>)
WITH TABLE KEY material = ls_group-material plant = ls_group-plant.
IF sy-subrc <> 0.
INSERT VALUE ty_line( material = ls_group-material
plant = ls_group-plant )
INTO TABLE lt_acc ASSIGNING <ls_acc>.
ENDIF.
IF ls_group-move_type = 'GR'.
<ls_acc>-net_qty = <ls_acc>-net_qty + ls_group-qty.
ELSE.
<ls_acc>-net_qty = <ls_acc>-net_qty - ls_group-qty.
ENDIF.
<ls_acc>-move_count = <ls_acc>-move_count + ls_group-cnt.
ENDLOOP.
rt_lines = lt_acc.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_msg).
MESSAGE lx_msg TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_totals( iv_from = p_from
iv_to = p_to
it_matnr = s_matnr[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS net_quantity FOR TESTING.
METHODS material_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVE' ) ) ).
DATA lt_move TYPE STANDARD TABLE OF {{p}}move WITH EMPTY KEY.
lt_move = VALUE #(
( mov_id = 1 material = 'MAT-001' plant = '1000' move_date = '20260110'
move_type = 'GR' quantity = '100.000' )
( mov_id = 2 material = 'MAT-001' plant = '1000' move_date = '20260115'
move_type = 'GI' quantity = '30.000' )
( mov_id = 3 material = 'MAT-002' plant = '1000' move_date = '20260201'
move_type = 'GR' quantity = '200.000' ) ).
go_env->insert_test_data( lt_move ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD net_quantity.
DATA(lt_lines) = NEW lcl_report( )->select_totals( iv_from = '20260101'
iv_to = '20261231'
it_matnr = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = `MAT-001` act = condense( lt_lines[ 1 ]-material ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 70 ) act = lt_lines[ 1 ]-net_qty ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-move_count ).
ENDMETHOD.
METHOD material_filter.
DATA(lt_lines) = NEW lcl_report( )->select_totals(
iv_from = '20260101'
iv_to = '20261231'
it_matnr = VALUE #( ( sign = 'I' option = 'EQ' low = 'MAT-002' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 200 ) act = lt_lines[ 1 ]-net_qty ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,132 @@
REPORT {{p}}stock_net.
TYPES: BEGIN OF ty_line,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
net_qty TYPE {{p}}move-quantity,
move_count TYPE i,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_acc TYPE SORTED TABLE OF ty_line WITH UNIQUE KEY material plant,
tt_matnr TYPE RANGE OF {{p}}move-material.
DATA gv_matnr TYPE {{p}}move-material.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_matnr FOR gv_matnr.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
METHODS select_totals
IMPORTING iv_from TYPE d
iv_to TYPE d
it_matnr TYPE tt_matnr
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_totals.
TYPES: BEGIN OF ty_group,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
move_type TYPE {{p}}move-move_type,
qty TYPE {{p}}move-quantity,
cnt TYPE i,
END OF ty_group.
DATA lt_group TYPE STANDARD TABLE OF ty_group WITH EMPTY KEY.
SELECT material, plant, move_type, SUM( quantity ) AS qty, COUNT(*) AS cnt
FROM {{p}}move
WHERE move_date >= @iv_from
AND move_date <= @iv_to
AND material IN @it_matnr
GROUP BY material, plant, move_type
INTO CORRESPONDING FIELDS OF TABLE @lt_group.
DATA lt_acc TYPE tt_acc.
LOOP AT lt_group INTO DATA(ls_group).
READ TABLE lt_acc ASSIGNING FIELD-SYMBOL(<ls_acc>)
WITH TABLE KEY material = ls_group-material plant = ls_group-plant.
IF sy-subrc <> 0.
INSERT VALUE ty_line( material = ls_group-material
plant = ls_group-plant )
INTO TABLE lt_acc ASSIGNING <ls_acc>.
ENDIF.
IF ls_group-move_type <> 'GR'.
<ls_acc>-net_qty = <ls_acc>-net_qty + ls_group-qty.
ELSE.
<ls_acc>-net_qty = <ls_acc>-net_qty - ls_group-qty.
ENDIF.
<ls_acc>-move_count = <ls_acc>-move_count + ls_group-cnt.
ENDLOOP.
rt_lines = lt_acc.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_msg).
MESSAGE lx_msg TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_totals( iv_from = p_from
iv_to = p_to
it_matnr = s_matnr[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS net_quantity FOR TESTING.
METHODS material_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVE' ) ) ).
DATA lt_move TYPE STANDARD TABLE OF {{p}}move WITH EMPTY KEY.
lt_move = VALUE #(
( mov_id = 1 material = 'MAT-001' plant = '1000' move_date = '20260110'
move_type = 'GR' quantity = '100.000' )
( mov_id = 2 material = 'MAT-001' plant = '1000' move_date = '20260115'
move_type = 'GI' quantity = '30.000' )
( mov_id = 3 material = 'MAT-002' plant = '1000' move_date = '20260201'
move_type = 'GR' quantity = '200.000' ) ).
go_env->insert_test_data( lt_move ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD net_quantity.
DATA(lt_lines) = NEW lcl_report( )->select_totals( iv_from = '20260101'
iv_to = '20261231'
it_matnr = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = `MAT-001` act = condense( lt_lines[ 1 ]-material ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 70 ) act = lt_lines[ 1 ]-net_qty ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-move_count ).
ENDMETHOD.
METHOD material_filter.
DATA(lt_lines) = NEW lcl_report( )->select_totals(
iv_from = '20260101'
iv_to = '20261231'
it_matnr = VALUE #( ( sign = 'I' option = 'EQ' low = 'MAT-002' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 200 ) act = lt_lines[ 1 ]-net_qty ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,132 @@
REPORT {{p}}stock_net.
TYPES: BEGIN OF ty_line,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
net_qty TYPE {{p}}move-quantity,
move_count TYPE i,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY,
tt_acc TYPE SORTED TABLE OF ty_line WITH UNIQUE KEY material plant,
tt_matnr TYPE RANGE OF {{p}}move-material.
DATA gv_matnr TYPE {{p}}move-material.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_matnr FOR gv_matnr.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
METHODS select_totals
IMPORTING iv_from TYPE d
iv_to TYPE d
it_matnr TYPE tt_matnr
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_totals.
TYPES: BEGIN OF ty_group,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
move_type TYPE {{p}}move-move_type,
qty TYPE {{p}}move-quantity,
cnt TYPE i,
END OF ty_group.
DATA lt_group TYPE STANDARD TABLE OF ty_group WITH EMPTY KEY.
SELECT material, plant, move_type, SUM( quantity ) AS qty, COUNT(*) AS cnt
FROM {{p}}move
WHERE move_date >= @iv_from
AND move_date <= @iv_to
AND material IN @it_matnr
GROUP BY material, plant, move_type
INTO CORRESPONDING FIELDS OF TABLE @lt_group.
DATA lt_acc TYPE tt_acc.
LOOP AT lt_group INTO DATA(ls_group).
READ TABLE lt_acc ASSIGNING FIELD-SYMBOL(<ls_acc>)
WITH TABLE KEY material = ls_group-material plant = ls_group-plant.
IF sy-subrc <> 0.
INSERT VALUE ty_line( material = ls_group-material
plant = ls_group-plant )
INTO TABLE lt_acc ASSIGNING <ls_acc>.
ENDIF.
IF ls_group-move_type = 'GR'.
<ls_acc>-net_qty = <ls_acc>-net_qty + ls_group-qty.
ELSE.
<ls_acc>-net_qty = <ls_acc>-net_qty + ls_group-qty.
ENDIF.
<ls_acc>-move_count = <ls_acc>-move_count + ls_group-cnt.
ENDLOOP.
rt_lines = lt_acc.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_msg).
MESSAGE lx_msg TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_totals( iv_from = p_from
iv_to = p_to
it_matnr = s_matnr[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS net_quantity FOR TESTING.
METHODS material_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}MOVE' ) ) ).
DATA lt_move TYPE STANDARD TABLE OF {{p}}move WITH EMPTY KEY.
lt_move = VALUE #(
( mov_id = 1 material = 'MAT-001' plant = '1000' move_date = '20260110'
move_type = 'GR' quantity = '100.000' )
( mov_id = 2 material = 'MAT-001' plant = '1000' move_date = '20260115'
move_type = 'GI' quantity = '30.000' )
( mov_id = 3 material = 'MAT-002' plant = '1000' move_date = '20260201'
move_type = 'GR' quantity = '200.000' ) ).
go_env->insert_test_data( lt_move ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD net_quantity.
DATA(lt_lines) = NEW lcl_report( )->select_totals( iv_from = '20260101'
iv_to = '20261231'
it_matnr = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = `MAT-001` act = condense( lt_lines[ 1 ]-material ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 70 ) act = lt_lines[ 1 ]-net_qty ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-move_count ).
ENDMETHOD.
METHOD material_filter.
DATA(lt_lines) = NEW lcl_report( )->select_totals(
iv_from = '20260101'
iv_to = '20261231'
it_matnr = VALUE #( ( sign = 'I' option = 'EQ' low = 'MAT-002' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}move-quantity( 200 ) act = lt_lines[ 1 ]-net_qty ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,67 @@
{
"task": "G0016",
"mutants": [
{
"object": "{{P}}STOCK_NET",
"mutant": "line 43: >= -> < (rel)",
"status": "killed",
"hidden": "0/8",
"failed_tests": [
"ALL_GROUPS",
"DATE_FROM_FILTER",
"DATE_TO_FILTER",
"MATERIAL_FILTER",
"MOVE_COUNT",
"NET_QUANTITY",
"NO_MATCHING_DATA",
"SORT_ORDER"
]
},
{
"object": "{{P}}STOCK_NET",
"mutant": "line 44: AND -> OR (logic)",
"status": "killed",
"hidden": "3/8",
"failed_tests": [
"ALL_GROUPS",
"DATE_FROM_FILTER",
"DATE_TO_FILTER",
"MATERIAL_FILTER",
"NO_MATCHING_DATA"
]
},
{
"object": "{{P}}STOCK_NET",
"mutant": "line 53: <> -> = (rel)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
},
{
"object": "{{P}}STOCK_NET",
"mutant": "line 58: = -> <> (eq)",
"status": "killed",
"hidden": "4/8",
"failed_tests": [
"DATE_FROM_FILTER",
"DATE_TO_FILTER",
"MATERIAL_FILTER",
"NET_QUANTITY"
]
},
{
"object": "{{P}}STOCK_NET",
"mutant": "line 61: - -> + (arith)",
"status": "killed",
"hidden": "6/8",
"failed_tests": [
"DATE_TO_FILTER",
"NET_QUANTITY"
]
}
],
"valid": 4,
"killed": 4,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,22 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Project effort'
define view entity {{P}}I_PROJ_EFFORT
as select from {{p}}proj as proj
inner join {{p}}asgn as asgn on asgn.proj_id <> proj.proj_id
{
key proj.proj_id as proj_id,
proj.proj_name as proj_name,
count( * ) as assign_count,
sum( asgn.work_hours ) as total_hours,
sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) as total_cost,
case
when sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) > proj.budget
then 'X'
else 'N'
end as over_budget
}
where asgn.status = 'A'
group by
proj.proj_id,
proj.proj_name,
proj.budget

View File

@@ -0,0 +1,22 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Project effort'
define view entity {{P}}I_PROJ_EFFORT
as select from {{p}}proj as proj
inner join {{p}}asgn as asgn on asgn.proj_id = proj.proj_id
{
key proj.proj_id as proj_id,
proj.proj_name as proj_name,
count( * ) as assign_count,
max( asgn.work_hours ) as total_hours,
sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) as total_cost,
case
when sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) > proj.budget
then 'X'
else 'N'
end as over_budget
}
where asgn.status = 'A'
group by
proj.proj_id,
proj.proj_name,
proj.budget

View File

@@ -0,0 +1,22 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Project effort'
define view entity {{P}}I_PROJ_EFFORT
as select from {{p}}proj as proj
inner join {{p}}asgn as asgn on asgn.proj_id = proj.proj_id
{
key proj.proj_id as proj_id,
proj.proj_name as proj_name,
count( * ) as assign_count,
sum( asgn.work_hours ) as total_hours,
max( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) as total_cost,
case
when sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) > proj.budget
then 'X'
else 'N'
end as over_budget
}
where asgn.status = 'A'
group by
proj.proj_id,
proj.proj_name,
proj.budget

View File

@@ -0,0 +1,22 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Project effort'
define view entity {{P}}I_PROJ_EFFORT
as select from {{p}}proj as proj
inner join {{p}}asgn as asgn on asgn.proj_id = proj.proj_id
{
key proj.proj_id as proj_id,
proj.proj_name as proj_name,
count( * ) as assign_count,
sum( asgn.work_hours ) as total_hours,
sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) as total_cost,
case
when sum( cast( asgn.work_hours as abap.dec( 15, 2 ) ) * asgn.rate ) <= proj.budget
then 'X'
else 'N'
end as over_budget
}
where asgn.status = 'A'
group by
proj.proj_id,
proj.proj_name,
proj.budget

View File

@@ -0,0 +1,59 @@
{
"task": "G0017",
"mutants": [
{
"object": "{{P}}I_PROJ_EFFORT",
"mutant": "line 5: inner join -> left outer join (join)",
"status": "survived",
"hidden": "8/8",
"failed_tests": []
},
{
"object": "{{P}}I_PROJ_EFFORT",
"mutant": "line 5: = -> <> (eq)",
"status": "killed",
"hidden": "1/8",
"failed_tests": [
"BUDGET_NOT_EXCEEDED",
"COST_OF_PROJECT_ONE",
"COUNT_OF_PROJECT_ONE",
"HOURS_OF_PROJECT_ONE",
"NO_ACTIVE_ASSIGNMENT",
"OVER_BUDGET_FLAG",
"ROW_COUNT"
]
},
{
"object": "{{P}}I_PROJ_EFFORT",
"mutant": "line 10: sum( -> max( (agg)",
"status": "killed",
"hidden": "7/8",
"failed_tests": [
"HOURS_OF_PROJECT_ONE"
]
},
{
"object": "{{P}}I_PROJ_EFFORT",
"mutant": "line 11: sum( -> max( (agg)",
"status": "killed",
"hidden": "7/8",
"failed_tests": [
"COST_OF_PROJECT_ONE"
]
},
{
"object": "{{P}}I_PROJ_EFFORT",
"mutant": "line 13: > -> <= (rel)",
"status": "killed",
"hidden": "6/8",
"failed_tests": [
"BUDGET_NOT_EXCEEDED",
"OVER_BUDGET_FLAG"
]
}
],
"valid": 5,
"killed": 4,
"kill_rate": 0.8,
"ok": true
}

View File

@@ -0,0 +1,15 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Open orders with customer data'
define view entity {{P}}I_ORDER
as select from {{p}}ord as ord
association [0..1] to {{p}}cust as _Customer
on $projection.cust_id <> _Customer.cust_id
{
key ord.order_id,
ord.cust_id,
ord.order_date,
_Customer.cust_name as customer_name,
_Customer.country as country,
_Customer
}
where ord.status = 'O'

View File

@@ -0,0 +1,15 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Open orders with customer data'
define view entity {{P}}I_ORDER
as select from {{p}}ord as ord
association [0..1] to {{p}}cust as _Customer
on $projection.cust_id = _Customer.cust_id
{
key ord.order_id,
ord.cust_id,
ord.order_date,
_Customer.cust_name as customer_name,
_Customer.country as country,
_Customer
}
where ord.status <> 'O'

View File

@@ -0,0 +1,33 @@
{
"task": "G0018",
"mutants": [
{
"object": "{{P}}I_ORDER",
"mutant": "line 6: = -> <> (eq)",
"status": "killed",
"hidden": "3/6",
"failed_tests": [
"ASSOCIATION_PATH",
"CUSTOMER_DATA_SHOWN",
"ORDER_WITHOUT_CUSTOMER"
]
},
{
"object": "{{P}}I_ORDER",
"mutant": "line 15: = -> <> (eq)",
"status": "killed",
"hidden": "1/6",
"failed_tests": [
"ASSOCIATION_PATH",
"CLOSED_ORDER_HIDDEN",
"CUSTOMER_DATA_SHOWN",
"OPEN_ORDERS_ONLY",
"ORDER_KEY_DATA"
]
}
],
"valid": 2,
"killed": 2,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,14 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales items by region and size class'
define view entity {{P}}I_SALES_CLASS
as select from {{p}}sale
{
key region as region,
count( * ) as item_count,
sum( case when amount < 101 then 1 else 0 end ) as small_count,
sum( case when amount >= 100 and amount < 1000 then 1 else 0 end ) as medium_count,
sum( case when amount >= 1000 then 1 else 0 end ) as large_count,
sum( amount ) as total_amount
}
where status <> 'X'
group by region

View File

@@ -0,0 +1,14 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales items by region and size class'
define view entity {{P}}I_SALES_CLASS
as select from {{p}}sale
{
key region as region,
count( * ) as item_count,
sum( case when amount < 100 then 1 else 0 end ) as small_count,
sum( case when amount < 100 and amount < 1000 then 1 else 0 end ) as medium_count,
sum( case when amount >= 1000 then 1 else 0 end ) as large_count,
sum( amount ) as total_amount
}
where status <> 'X'
group by region

View File

@@ -0,0 +1,14 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales items by region and size class'
define view entity {{P}}I_SALES_CLASS
as select from {{p}}sale
{
key region as region,
count( * ) as item_count,
sum( case when amount < 100 then 1 else 0 end ) as small_count,
sum( case when amount >= 100 and amount < 1001 then 1 else 0 end ) as medium_count,
sum( case when amount >= 1000 then 1 else 0 end ) as large_count,
sum( amount ) as total_amount
}
where status <> 'X'
group by region

View File

@@ -0,0 +1,14 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales items by region and size class'
define view entity {{P}}I_SALES_CLASS
as select from {{p}}sale
{
key region as region,
count( * ) as item_count,
sum( case when amount < 100 then 1 else 0 end ) as small_count,
sum( case when amount >= 100 and amount < 1000 then 1 else 0 end ) as medium_count,
sum( case when amount >= 1000 then 1 else 0 end ) as large_count,
sum( amount ) as total_amount
}
where status = 'X'
group by region

View File

@@ -0,0 +1,61 @@
{
"task": "G0019",
"mutants": [
{
"object": "{{P}}I_SALES_CLASS",
"mutant": "line 8: 100 -> 101 (const)",
"status": "killed",
"hidden": "6/8",
"failed_tests": [
"CLASS_BOUNDARIES",
"SMALL_COUNT"
]
},
{
"object": "{{P}}I_SALES_CLASS",
"mutant": "line 9: >= -> < (rel)",
"status": "killed",
"hidden": "7/8",
"failed_tests": [
"MEDIUM_COUNT"
]
},
{
"object": "{{P}}I_SALES_CLASS",
"mutant": "line 9: 1000 -> 1001 (const)",
"status": "killed",
"hidden": "6/8",
"failed_tests": [
"CLASS_BOUNDARIES",
"MEDIUM_COUNT"
]
},
{
"object": "{{P}}I_SALES_CLASS",
"mutant": "line 10: sum( -> max( (agg)",
"status": "survived",
"hidden": "8/8",
"failed_tests": []
},
{
"object": "{{P}}I_SALES_CLASS",
"mutant": "line 13: <> -> = (rel)",
"status": "killed",
"hidden": "0/8",
"failed_tests": [
"CANCELLED_ITEMS_IGNORED",
"CLASS_BOUNDARIES",
"ITEM_COUNT",
"LARGE_COUNT",
"MEDIUM_COUNT",
"REGIONS_IN_RESULT",
"SMALL_COUNT",
"TOTAL_AMOUNT"
]
}
],
"valid": 5,
"killed": 4,
"kill_rate": 0.8,
"ok": true
}

View File

@@ -0,0 +1,20 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Book revenue in period'
define view entity {{P}}I_BOOK_REVENUE
with parameters
p_from : abap.dats,
p_to : abap.dats
as select from {{p}}book as bk
inner join {{p}}sale as sl on sl.book_id <> bk.book_id
{
key bk.book_id as book_id,
bk.title as title,
bk.category as category,
sum( sl.quantity ) as sold_quantity,
sum( cast( sl.quantity as abap.dec( 10, 0 ) ) * bk.price ) as revenue
}
where sl.sale_date between $parameters.p_from and $parameters.p_to
group by
bk.book_id,
bk.title,
bk.category

View File

@@ -0,0 +1,20 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Book revenue in period'
define view entity {{P}}I_BOOK_REVENUE
with parameters
p_from : abap.dats,
p_to : abap.dats
as select from {{p}}book as bk
inner join {{p}}sale as sl on sl.book_id = bk.book_id
{
key bk.book_id as book_id,
bk.title as title,
bk.category as category,
max( sl.quantity ) as sold_quantity,
sum( cast( sl.quantity as abap.dec( 10, 0 ) ) * bk.price ) as revenue
}
where sl.sale_date between $parameters.p_from and $parameters.p_to
group by
bk.book_id,
bk.title,
bk.category

View File

@@ -0,0 +1,20 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Book revenue in period'
define view entity {{P}}I_BOOK_REVENUE
with parameters
p_from : abap.dats,
p_to : abap.dats
as select from {{p}}book as bk
inner join {{p}}sale as sl on sl.book_id = bk.book_id
{
key bk.book_id as book_id,
bk.title as title,
bk.category as category,
sum( sl.quantity ) as sold_quantity,
max( cast( sl.quantity as abap.dec( 10, 0 ) ) * bk.price ) as revenue
}
where sl.sale_date between $parameters.p_from and $parameters.p_to
group by
bk.book_id,
bk.title,
bk.category

View File

@@ -0,0 +1,56 @@
{
"task": "G0020",
"mutants": [
{
"object": "{{P}}I_BOOK_REVENUE",
"mutant": "line 8: inner join -> left outer join (join)",
"status": "survived",
"hidden": "8/8",
"failed_tests": []
},
{
"object": "{{P}}I_BOOK_REVENUE",
"mutant": "line 8: = -> <> (eq)",
"status": "killed",
"hidden": "2/8",
"failed_tests": [
"BOOKS_IN_PERIOD",
"BOOK_OUTSIDE_PERIOD_HIDDEN",
"PERIOD_LIMITS_INCLUDED",
"REVENUE_HAS_TWO_DECIMALS",
"REVENUE_IN_PERIOD",
"SOLD_QUANTITY_IN_PERIOD"
]
},
{
"object": "{{P}}I_BOOK_REVENUE",
"mutant": "line 13: sum( -> max( (agg)",
"status": "killed",
"hidden": "7/8",
"failed_tests": [
"SOLD_QUANTITY_IN_PERIOD"
]
},
{
"object": "{{P}}I_BOOK_REVENUE",
"mutant": "line 14: sum( -> max( (agg)",
"status": "killed",
"hidden": "6/8",
"failed_tests": [
"REVENUE_HAS_TWO_DECIMALS",
"REVENUE_IN_PERIOD"
]
},
{
"object": "{{P}}I_BOOK_REVENUE",
"mutant": "line 16: and -> or (logic)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
}
],
"valid": 4,
"killed": 3,
"kill_rate": 0.75,
"ok": true
}

View File

@@ -0,0 +1,23 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.ignorePropagatedAnnotations: true
@EndUserText.label: 'Shipment overview'
define view entity {{P}}I_SHIPMENT
as select from {{p}}road as road
{
key road.ship_id as ship_id,
road.cust as customer,
'ROAD' as ship_mode,
road.kg as weight,
road.cost as cost
}
where road.kg <= 0
union all
select from {{p}}rail as rail
{
key rail.ship_id as ship_id,
rail.customer as customer,
'RAIL' as ship_mode,
rail.weight as weight,
rail.fee as cost
}
where rail.weight > 0

View File

@@ -0,0 +1,23 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.ignorePropagatedAnnotations: true
@EndUserText.label: 'Shipment overview'
define view entity {{P}}I_SHIPMENT
as select from {{p}}road as road
{
key road.ship_id as ship_id,
road.cust as customer,
'ROAD' as ship_mode,
road.kg as weight,
road.cost as cost
}
where road.kg > 0
union all
select from {{p}}rail as rail
{
key rail.ship_id as ship_id,
rail.customer as customer,
'RAIL' as ship_mode,
rail.weight as weight,
rail.fee as cost
}
where rail.weight <= 0

View File

@@ -0,0 +1,35 @@
{
"task": "G0021",
"mutants": [
{
"object": "{{P}}I_SHIPMENT",
"mutant": "line 13: > -> <= (rel)",
"status": "killed",
"hidden": "3/8",
"failed_tests": [
"LIGHT_SHIPMENTS_HIDDEN",
"ROAD_CUSTOMER",
"ROAD_ROWS",
"ROAD_WEIGHT",
"ROW_COUNT"
]
},
{
"object": "{{P}}I_SHIPMENT",
"mutant": "line 23: > -> <= (rel)",
"status": "killed",
"hidden": "3/8",
"failed_tests": [
"LIGHT_SHIPMENTS_HIDDEN",
"RAIL_COST",
"RAIL_CUSTOMER",
"RAIL_ROWS",
"ROW_COUNT"
]
}
],
"valid": 2,
"killed": 2,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,85 @@
CLASS {{p}}expense_validator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
METHODS validate
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
PRIVATE SECTION.
CONSTANTS:
c_receipt_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '100.00',
c_cc_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '1000.00'.
METHODS check_amount
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_currency
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_date
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_receipt
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_cost_center
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS is_supported_currency
IMPORTING iv_currency TYPE {{p}}if_expense_claim=>ty_currency
RETURNING VALUE(rv_supported) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}expense_validator IMPLEMENTATION.
METHOD validate.
check_amount( is_claim ).
check_currency( is_claim ).
check_date( is_claim ).
check_receipt( is_claim ).
check_cost_center( is_claim ).
ENDMETHOD.
METHOD check_amount.
IF is_claim-amount <= 0.
RAISE EXCEPTION TYPE {{p}}cx_claim_amount
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD check_currency.
IF is_supported_currency( is_claim-currency ) <> abap_false.
RAISE EXCEPTION TYPE {{p}}cx_claim_currency
EXPORTING iv_currency = is_claim-currency.
ENDIF.
ENDMETHOD.
METHOD check_date.
IF is_claim-claim_date > sy-datum.
RAISE EXCEPTION TYPE {{p}}cx_claim_date
EXPORTING iv_claim_date = is_claim-claim_date.
ENDIF.
ENDMETHOD.
METHOD check_receipt.
IF is_claim-amount >= c_receipt_limit AND is_claim-has_receipt = abap_false.
RAISE EXCEPTION TYPE {{p}}cx_claim_receipt
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD check_cost_center.
IF is_claim-amount >= c_cc_limit AND is_claim-cost_center IS INITIAL.
RAISE EXCEPTION TYPE {{p}}cx_claim_costcenter
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD is_supported_currency.
rv_supported = xsdbool( iv_currency = 'EUR' OR iv_currency = 'USD'
OR iv_currency = 'GBP' OR iv_currency = 'CHF' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,85 @@
CLASS {{p}}expense_validator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
METHODS validate
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
PRIVATE SECTION.
CONSTANTS:
c_receipt_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '100.00',
c_cc_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '1000.00'.
METHODS check_amount
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_currency
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_date
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_receipt
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_cost_center
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS is_supported_currency
IMPORTING iv_currency TYPE {{p}}if_expense_claim=>ty_currency
RETURNING VALUE(rv_supported) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}expense_validator IMPLEMENTATION.
METHOD validate.
check_amount( is_claim ).
check_currency( is_claim ).
check_date( is_claim ).
check_receipt( is_claim ).
check_cost_center( is_claim ).
ENDMETHOD.
METHOD check_amount.
IF is_claim-amount <= 0.
RAISE EXCEPTION TYPE {{p}}cx_claim_amount
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD check_currency.
IF is_supported_currency( is_claim-currency ) = abap_true.
RAISE EXCEPTION TYPE {{p}}cx_claim_currency
EXPORTING iv_currency = is_claim-currency.
ENDIF.
ENDMETHOD.
METHOD check_date.
IF is_claim-claim_date > sy-datum.
RAISE EXCEPTION TYPE {{p}}cx_claim_date
EXPORTING iv_claim_date = is_claim-claim_date.
ENDIF.
ENDMETHOD.
METHOD check_receipt.
IF is_claim-amount >= c_receipt_limit AND is_claim-has_receipt = abap_false.
RAISE EXCEPTION TYPE {{p}}cx_claim_receipt
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD check_cost_center.
IF is_claim-amount >= c_cc_limit AND is_claim-cost_center IS INITIAL.
RAISE EXCEPTION TYPE {{p}}cx_claim_costcenter
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD is_supported_currency.
rv_supported = xsdbool( iv_currency = 'EUR' OR iv_currency = 'USD'
OR iv_currency = 'GBP' OR iv_currency = 'CHF' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,85 @@
CLASS {{p}}expense_validator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
METHODS validate
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
PRIVATE SECTION.
CONSTANTS:
c_receipt_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '100.00',
c_cc_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '1000.00'.
METHODS check_amount
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_currency
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_date
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_receipt
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_cost_center
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS is_supported_currency
IMPORTING iv_currency TYPE {{p}}if_expense_claim=>ty_currency
RETURNING VALUE(rv_supported) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}expense_validator IMPLEMENTATION.
METHOD validate.
check_amount( is_claim ).
check_currency( is_claim ).
check_date( is_claim ).
check_receipt( is_claim ).
check_cost_center( is_claim ).
ENDMETHOD.
METHOD check_amount.
IF is_claim-amount <= 0.
RAISE EXCEPTION TYPE {{p}}cx_claim_amount
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD check_currency.
IF is_supported_currency( is_claim-currency ) = abap_false.
RAISE EXCEPTION TYPE {{p}}cx_claim_currency
EXPORTING iv_currency = is_claim-currency.
ENDIF.
ENDMETHOD.
METHOD check_date.
IF is_claim-claim_date <= sy-datum.
RAISE EXCEPTION TYPE {{p}}cx_claim_date
EXPORTING iv_claim_date = is_claim-claim_date.
ENDIF.
ENDMETHOD.
METHOD check_receipt.
IF is_claim-amount >= c_receipt_limit AND is_claim-has_receipt = abap_false.
RAISE EXCEPTION TYPE {{p}}cx_claim_receipt
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD check_cost_center.
IF is_claim-amount >= c_cc_limit AND is_claim-cost_center IS INITIAL.
RAISE EXCEPTION TYPE {{p}}cx_claim_costcenter
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD is_supported_currency.
rv_supported = xsdbool( iv_currency = 'EUR' OR iv_currency = 'USD'
OR iv_currency = 'GBP' OR iv_currency = 'CHF' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,85 @@
CLASS {{p}}expense_validator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
METHODS validate
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
PRIVATE SECTION.
CONSTANTS:
c_receipt_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '100.00',
c_cc_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '1000.00'.
METHODS check_amount
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_currency
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_date
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_receipt
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS check_cost_center
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
RAISING {{p}}cx_claim_error.
METHODS is_supported_currency
IMPORTING iv_currency TYPE {{p}}if_expense_claim=>ty_currency
RETURNING VALUE(rv_supported) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}expense_validator IMPLEMENTATION.
METHOD validate.
check_amount( is_claim ).
check_currency( is_claim ).
check_date( is_claim ).
check_receipt( is_claim ).
check_cost_center( is_claim ).
ENDMETHOD.
METHOD check_amount.
IF is_claim-amount <= 0.
RAISE EXCEPTION TYPE {{p}}cx_claim_amount
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD check_currency.
IF is_supported_currency( is_claim-currency ) = abap_false.
RAISE EXCEPTION TYPE {{p}}cx_claim_currency
EXPORTING iv_currency = is_claim-currency.
ENDIF.
ENDMETHOD.
METHOD check_date.
IF is_claim-claim_date > sy-datum.
RAISE EXCEPTION TYPE {{p}}cx_claim_date
EXPORTING iv_claim_date = is_claim-claim_date.
ENDIF.
ENDMETHOD.
METHOD check_receipt.
IF is_claim-amount >= c_receipt_limit AND is_claim-has_receipt <> abap_false.
RAISE EXCEPTION TYPE {{p}}cx_claim_receipt
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD check_cost_center.
IF is_claim-amount >= c_cc_limit AND is_claim-cost_center IS INITIAL.
RAISE EXCEPTION TYPE {{p}}cx_claim_costcenter
EXPORTING iv_amount = is_claim-amount.
ENDIF.
ENDMETHOD.
METHOD is_supported_currency.
rv_supported = xsdbool( iv_currency = 'EUR' OR iv_currency = 'USD'
OR iv_currency = 'GBP' OR iv_currency = 'CHF' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,80 @@
{
"task": "G0022",
"mutants": [
{
"object": "{{P}}EXPENSE_VALIDATOR",
"mutant": "line 54: = -> <> (eq)",
"status": "killed",
"hidden": "3/12",
"failed_tests": [
"COST_CENTER_NOT_REQUIRED",
"COST_CENTER_REQUIRED",
"FUTURE_DATE_REJECTED",
"RECEIPT_NOT_REQUIRED_BELOW",
"RECEIPT_REQUIRED",
"RECEIPT_RULE_HAS_PRIORITY",
"TODAY_IS_ACCEPTED",
"UNKNOWN_CURRENCY_REJECTED",
"VALID_CLAIM_PASSES"
]
},
{
"object": "{{P}}EXPENSE_VALIDATOR",
"mutant": "line 54: abap_false -> abap_true (bool)",
"status": "killed",
"hidden": "3/12",
"failed_tests": [
"COST_CENTER_NOT_REQUIRED",
"COST_CENTER_REQUIRED",
"FUTURE_DATE_REJECTED",
"RECEIPT_NOT_REQUIRED_BELOW",
"RECEIPT_REQUIRED",
"RECEIPT_RULE_HAS_PRIORITY",
"TODAY_IS_ACCEPTED",
"UNKNOWN_CURRENCY_REJECTED",
"VALID_CLAIM_PASSES"
]
},
{
"object": "{{P}}EXPENSE_VALIDATOR",
"mutant": "line 61: > -> <= (rel)",
"status": "killed",
"hidden": "4/12",
"failed_tests": [
"COST_CENTER_NOT_REQUIRED",
"COST_CENTER_REQUIRED",
"FUTURE_DATE_REJECTED",
"RECEIPT_NOT_REQUIRED_BELOW",
"RECEIPT_REQUIRED",
"RECEIPT_RULE_HAS_PRIORITY",
"TODAY_IS_ACCEPTED",
"VALID_CLAIM_PASSES"
]
},
{
"object": "{{P}}EXPENSE_VALIDATOR",
"mutant": "line 68: = -> <> (eq)",
"status": "killed",
"hidden": "6/12",
"failed_tests": [
"COST_CENTER_NOT_REQUIRED",
"COST_CENTER_REQUIRED",
"RECEIPT_REQUIRED",
"RECEIPT_RULE_HAS_PRIORITY",
"TODAY_IS_ACCEPTED",
"VALID_CLAIM_PASSES"
]
},
{
"object": "{{P}}EXPENSE_VALIDATOR",
"mutant": "line 83: OR -> AND (logic)",
"status": "survived",
"hidden": "12/12",
"failed_tests": []
}
],
"valid": 5,
"killed": 4,
"kill_rate": 0.8,
"ok": true
}

View File

@@ -0,0 +1,62 @@
CLASS {{p}}freight_calculator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_freight_calc.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_rate,
zone TYPE {{p}}if_freight_calc=>ty_zone,
base TYPE {{p}}if_freight_calc=>ty_amount,
per_kg TYPE {{p}}if_freight_calc=>ty_amount,
minimum TYPE {{p}}if_freight_calc=>ty_amount,
surcharge TYPE p LENGTH 4 DECIMALS 3,
END OF ty_rate,
tt_rate TYPE SORTED TABLE OF ty_rate WITH UNIQUE KEY zone.
CONSTANTS:
c_heavy_limit TYPE {{p}}if_freight_calc=>ty_weight VALUE '1000.000',
c_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '0.95'.
METHODS rates RETURNING VALUE(rt_rate) TYPE tt_rate.
ENDCLASS.
CLASS {{p}}freight_calculator IMPLEMENTATION.
METHOD {{p}}if_freight_calc~calculate.
DATA(lt_rate) = rates( ).
READ TABLE lt_rate INTO DATA(ls_rate) WITH TABLE KEY zone = iv_zone.
IF sy-subrc <> 0.
rv_cost = 0.
RETURN.
ENDIF.
DATA lv_charge TYPE {{p}}if_freight_calc=>ty_amount.
lv_charge = ls_rate-per_kg / iv_weight.
DATA lv_freight TYPE {{p}}if_freight_calc=>ty_amount.
lv_freight = ls_rate-base + lv_charge.
IF lv_freight < ls_rate-minimum.
lv_freight = ls_rate-minimum.
ENDIF.
DATA lv_surcharge TYPE {{p}}if_freight_calc=>ty_amount.
lv_surcharge = lv_freight * ls_rate-surcharge.
DATA lv_total TYPE {{p}}if_freight_calc=>ty_amount.
lv_total = lv_freight + lv_surcharge.
IF iv_weight > c_heavy_limit.
lv_total = lv_total * c_discount.
ENDIF.
rv_cost = lv_total.
ENDMETHOD.
METHOD rates.
rt_rate = VALUE #(
( zone = 'DE' base = '12.50' per_kg = '0.85' minimum = '25.00' surcharge = '0.065' )
( zone = 'FR' base = '15.00' per_kg = '1.10' minimum = '30.00' surcharge = '0.075' )
( zone = 'NL' base = '10.00' per_kg = '0.75' minimum = '20.00' surcharge = '0.055' )
( zone = 'US' base = '20.00' per_kg = '1.40' minimum = '45.00' surcharge = '0.085' )
( zone = 'CN' base = '25.00' per_kg = '1.25' minimum = '50.00' surcharge = '0.095' ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,62 @@
CLASS {{p}}freight_calculator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_freight_calc.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_rate,
zone TYPE {{p}}if_freight_calc=>ty_zone,
base TYPE {{p}}if_freight_calc=>ty_amount,
per_kg TYPE {{p}}if_freight_calc=>ty_amount,
minimum TYPE {{p}}if_freight_calc=>ty_amount,
surcharge TYPE p LENGTH 4 DECIMALS 3,
END OF ty_rate,
tt_rate TYPE SORTED TABLE OF ty_rate WITH UNIQUE KEY zone.
CONSTANTS:
c_heavy_limit TYPE {{p}}if_freight_calc=>ty_weight VALUE '1000.000',
c_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '0.95'.
METHODS rates RETURNING VALUE(rt_rate) TYPE tt_rate.
ENDCLASS.
CLASS {{p}}freight_calculator IMPLEMENTATION.
METHOD {{p}}if_freight_calc~calculate.
DATA(lt_rate) = rates( ).
READ TABLE lt_rate INTO DATA(ls_rate) WITH TABLE KEY zone = iv_zone.
IF sy-subrc <> 0.
rv_cost = 0.
RETURN.
ENDIF.
DATA lv_charge TYPE {{p}}if_freight_calc=>ty_amount.
lv_charge = ls_rate-per_kg * iv_weight.
DATA lv_freight TYPE {{p}}if_freight_calc=>ty_amount.
lv_freight = ls_rate-base - lv_charge.
IF lv_freight < ls_rate-minimum.
lv_freight = ls_rate-minimum.
ENDIF.
DATA lv_surcharge TYPE {{p}}if_freight_calc=>ty_amount.
lv_surcharge = lv_freight * ls_rate-surcharge.
DATA lv_total TYPE {{p}}if_freight_calc=>ty_amount.
lv_total = lv_freight + lv_surcharge.
IF iv_weight > c_heavy_limit.
lv_total = lv_total * c_discount.
ENDIF.
rv_cost = lv_total.
ENDMETHOD.
METHOD rates.
rt_rate = VALUE #(
( zone = 'DE' base = '12.50' per_kg = '0.85' minimum = '25.00' surcharge = '0.065' )
( zone = 'FR' base = '15.00' per_kg = '1.10' minimum = '30.00' surcharge = '0.075' )
( zone = 'NL' base = '10.00' per_kg = '0.75' minimum = '20.00' surcharge = '0.055' )
( zone = 'US' base = '20.00' per_kg = '1.40' minimum = '45.00' surcharge = '0.085' )
( zone = 'CN' base = '25.00' per_kg = '1.25' minimum = '50.00' surcharge = '0.095' ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,62 @@
CLASS {{p}}freight_calculator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_freight_calc.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_rate,
zone TYPE {{p}}if_freight_calc=>ty_zone,
base TYPE {{p}}if_freight_calc=>ty_amount,
per_kg TYPE {{p}}if_freight_calc=>ty_amount,
minimum TYPE {{p}}if_freight_calc=>ty_amount,
surcharge TYPE p LENGTH 4 DECIMALS 3,
END OF ty_rate,
tt_rate TYPE SORTED TABLE OF ty_rate WITH UNIQUE KEY zone.
CONSTANTS:
c_heavy_limit TYPE {{p}}if_freight_calc=>ty_weight VALUE '1000.000',
c_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '0.95'.
METHODS rates RETURNING VALUE(rt_rate) TYPE tt_rate.
ENDCLASS.
CLASS {{p}}freight_calculator IMPLEMENTATION.
METHOD {{p}}if_freight_calc~calculate.
DATA(lt_rate) = rates( ).
READ TABLE lt_rate INTO DATA(ls_rate) WITH TABLE KEY zone = iv_zone.
IF sy-subrc <> 0.
rv_cost = 0.
RETURN.
ENDIF.
DATA lv_charge TYPE {{p}}if_freight_calc=>ty_amount.
lv_charge = ls_rate-per_kg * iv_weight.
DATA lv_freight TYPE {{p}}if_freight_calc=>ty_amount.
lv_freight = ls_rate-base + lv_charge.
IF lv_freight >= ls_rate-minimum.
lv_freight = ls_rate-minimum.
ENDIF.
DATA lv_surcharge TYPE {{p}}if_freight_calc=>ty_amount.
lv_surcharge = lv_freight * ls_rate-surcharge.
DATA lv_total TYPE {{p}}if_freight_calc=>ty_amount.
lv_total = lv_freight + lv_surcharge.
IF iv_weight > c_heavy_limit.
lv_total = lv_total * c_discount.
ENDIF.
rv_cost = lv_total.
ENDMETHOD.
METHOD rates.
rt_rate = VALUE #(
( zone = 'DE' base = '12.50' per_kg = '0.85' minimum = '25.00' surcharge = '0.065' )
( zone = 'FR' base = '15.00' per_kg = '1.10' minimum = '30.00' surcharge = '0.075' )
( zone = 'NL' base = '10.00' per_kg = '0.75' minimum = '20.00' surcharge = '0.055' )
( zone = 'US' base = '20.00' per_kg = '1.40' minimum = '45.00' surcharge = '0.085' )
( zone = 'CN' base = '25.00' per_kg = '1.25' minimum = '50.00' surcharge = '0.095' ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,62 @@
CLASS {{p}}freight_calculator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_freight_calc.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_rate,
zone TYPE {{p}}if_freight_calc=>ty_zone,
base TYPE {{p}}if_freight_calc=>ty_amount,
per_kg TYPE {{p}}if_freight_calc=>ty_amount,
minimum TYPE {{p}}if_freight_calc=>ty_amount,
surcharge TYPE p LENGTH 4 DECIMALS 3,
END OF ty_rate,
tt_rate TYPE SORTED TABLE OF ty_rate WITH UNIQUE KEY zone.
CONSTANTS:
c_heavy_limit TYPE {{p}}if_freight_calc=>ty_weight VALUE '1000.000',
c_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '0.95'.
METHODS rates RETURNING VALUE(rt_rate) TYPE tt_rate.
ENDCLASS.
CLASS {{p}}freight_calculator IMPLEMENTATION.
METHOD {{p}}if_freight_calc~calculate.
DATA(lt_rate) = rates( ).
READ TABLE lt_rate INTO DATA(ls_rate) WITH TABLE KEY zone = iv_zone.
IF sy-subrc <> 0.
rv_cost = 0.
RETURN.
ENDIF.
DATA lv_charge TYPE {{p}}if_freight_calc=>ty_amount.
lv_charge = ls_rate-per_kg * iv_weight.
DATA lv_freight TYPE {{p}}if_freight_calc=>ty_amount.
lv_freight = ls_rate-base + lv_charge.
IF lv_freight < ls_rate-minimum.
lv_freight = ls_rate-minimum.
ENDIF.
DATA lv_surcharge TYPE {{p}}if_freight_calc=>ty_amount.
lv_surcharge = lv_freight * ls_rate-surcharge.
DATA lv_total TYPE {{p}}if_freight_calc=>ty_amount.
lv_total = lv_freight - lv_surcharge.
IF iv_weight > c_heavy_limit.
lv_total = lv_total * c_discount.
ENDIF.
rv_cost = lv_total.
ENDMETHOD.
METHOD rates.
rt_rate = VALUE #(
( zone = 'DE' base = '12.50' per_kg = '0.85' minimum = '25.00' surcharge = '0.065' )
( zone = 'FR' base = '15.00' per_kg = '1.10' minimum = '30.00' surcharge = '0.075' )
( zone = 'NL' base = '10.00' per_kg = '0.75' minimum = '20.00' surcharge = '0.055' )
( zone = 'US' base = '20.00' per_kg = '1.40' minimum = '45.00' surcharge = '0.085' )
( zone = 'CN' base = '25.00' per_kg = '1.25' minimum = '50.00' surcharge = '0.095' ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,62 @@
CLASS {{p}}freight_calculator DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_freight_calc.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_rate,
zone TYPE {{p}}if_freight_calc=>ty_zone,
base TYPE {{p}}if_freight_calc=>ty_amount,
per_kg TYPE {{p}}if_freight_calc=>ty_amount,
minimum TYPE {{p}}if_freight_calc=>ty_amount,
surcharge TYPE p LENGTH 4 DECIMALS 3,
END OF ty_rate,
tt_rate TYPE SORTED TABLE OF ty_rate WITH UNIQUE KEY zone.
CONSTANTS:
c_heavy_limit TYPE {{p}}if_freight_calc=>ty_weight VALUE '1000.000',
c_discount TYPE p LENGTH 3 DECIMALS 2 VALUE '0.95'.
METHODS rates RETURNING VALUE(rt_rate) TYPE tt_rate.
ENDCLASS.
CLASS {{p}}freight_calculator IMPLEMENTATION.
METHOD {{p}}if_freight_calc~calculate.
DATA(lt_rate) = rates( ).
READ TABLE lt_rate INTO DATA(ls_rate) WITH TABLE KEY zone = iv_zone.
IF sy-subrc <> 0.
rv_cost = 0.
RETURN.
ENDIF.
DATA lv_charge TYPE {{p}}if_freight_calc=>ty_amount.
lv_charge = ls_rate-per_kg * iv_weight.
DATA lv_freight TYPE {{p}}if_freight_calc=>ty_amount.
lv_freight = ls_rate-base + lv_charge.
IF lv_freight < ls_rate-minimum.
lv_freight = ls_rate-minimum.
ENDIF.
DATA lv_surcharge TYPE {{p}}if_freight_calc=>ty_amount.
lv_surcharge = lv_freight * ls_rate-surcharge.
DATA lv_total TYPE {{p}}if_freight_calc=>ty_amount.
lv_total = lv_freight + lv_surcharge.
IF iv_weight > c_heavy_limit.
lv_total = lv_total / c_discount.
ENDIF.
rv_cost = lv_total.
ENDMETHOD.
METHOD rates.
rt_rate = VALUE #(
( zone = 'DE' base = '12.50' per_kg = '0.85' minimum = '25.00' surcharge = '0.065' )
( zone = 'FR' base = '15.00' per_kg = '1.10' minimum = '30.00' surcharge = '0.075' )
( zone = 'NL' base = '10.00' per_kg = '0.75' minimum = '20.00' surcharge = '0.055' )
( zone = 'US' base = '20.00' per_kg = '1.40' minimum = '45.00' surcharge = '0.085' )
( zone = 'CN' base = '25.00' per_kg = '1.25' minimum = '50.00' surcharge = '0.095' ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,78 @@
{
"task": "G0023",
"mutants": [
{
"object": "{{P}}FREIGHT_CALCULATOR",
"mutant": "line 34: * -> / (arith)",
"status": "killed",
"hidden": "3/9",
"failed_tests": [
"ALL_ZONES_ARE_RATED",
"DISCOUNT_ROUNDS_HALF_UP",
"HEAVY_DISCOUNT_ON_TOTAL",
"NO_DISCOUNT_AT_EXACTLY_1000",
"SURCHARGE_USES_MINIMUM",
"WEIGHT_CHARGE_ROUNDS_HALF_UP"
]
},
{
"object": "{{P}}FREIGHT_CALCULATOR",
"mutant": "line 37: + -> - (arith)",
"status": "killed",
"hidden": "4/9",
"failed_tests": [
"ALL_ZONES_ARE_RATED",
"DISCOUNT_ROUNDS_HALF_UP",
"HEAVY_DISCOUNT_ON_TOTAL",
"NO_DISCOUNT_AT_EXACTLY_1000",
"WEIGHT_CHARGE_ROUNDS_HALF_UP"
]
},
{
"object": "{{P}}FREIGHT_CALCULATOR",
"mutant": "line 38: < -> >= (rel)",
"status": "killed",
"hidden": "1/9",
"failed_tests": [
"ALL_ZONES_ARE_RATED",
"DISCOUNT_ROUNDS_HALF_UP",
"HEAVY_DISCOUNT_ON_TOTAL",
"MINIMUM_APPLIES_AFTER_CHARGE",
"NO_DISCOUNT_AT_EXACTLY_1000",
"SMALL_WEIGHT_USES_MINIMUM",
"SURCHARGE_USES_MINIMUM",
"WEIGHT_CHARGE_ROUNDS_HALF_UP"
]
},
{
"object": "{{P}}FREIGHT_CALCULATOR",
"mutant": "line 46: + -> - (arith)",
"status": "killed",
"hidden": "1/9",
"failed_tests": [
"ALL_ZONES_ARE_RATED",
"DISCOUNT_ROUNDS_HALF_UP",
"HEAVY_DISCOUNT_ON_TOTAL",
"MINIMUM_APPLIES_AFTER_CHARGE",
"NO_DISCOUNT_AT_EXACTLY_1000",
"SMALL_WEIGHT_USES_MINIMUM",
"SURCHARGE_USES_MINIMUM",
"WEIGHT_CHARGE_ROUNDS_HALF_UP"
]
},
{
"object": "{{P}}FREIGHT_CALCULATOR",
"mutant": "line 48: * -> / (arith)",
"status": "killed",
"hidden": "7/9",
"failed_tests": [
"DISCOUNT_ROUNDS_HALF_UP",
"HEAVY_DISCOUNT_ON_TOTAL"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,15 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales per product in a period'
define view entity {{P}}I_SALES_REPORT
with parameters
p_from : abap.dats,
p_to : abap.dats
as select from {{p}}sales as sale
{
key sale.product as product,
max( sale.quantity ) as total_qty,
sum( cast( sale.quantity as abap.dec( 15, 2 ) ) * sale.price ) as total_amount
}
where sale.sold_on >= $parameters.p_from
and sale.sold_on <= $parameters.p_to
group by sale.product

View File

@@ -0,0 +1,15 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales per product in a period'
define view entity {{P}}I_SALES_REPORT
with parameters
p_from : abap.dats,
p_to : abap.dats
as select from {{p}}sales as sale
{
key sale.product as product,
sum( sale.quantity ) as total_qty,
max( cast( sale.quantity as abap.dec( 15, 2 ) ) * sale.price ) as total_amount
}
where sale.sold_on >= $parameters.p_from
and sale.sold_on <= $parameters.p_to
group by sale.product

View File

@@ -0,0 +1,15 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales per product in a period'
define view entity {{P}}I_SALES_REPORT
with parameters
p_from : abap.dats,
p_to : abap.dats
as select from {{p}}sales as sale
{
key sale.product as product,
sum( sale.quantity ) as total_qty,
sum( cast( sale.quantity as abap.dec( 15, 2 ) ) * sale.price ) as total_amount
}
where sale.sold_on < $parameters.p_from
and sale.sold_on <= $parameters.p_to
group by sale.product

View File

@@ -0,0 +1,15 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales per product in a period'
define view entity {{P}}I_SALES_REPORT
with parameters
p_from : abap.dats,
p_to : abap.dats
as select from {{p}}sales as sale
{
key sale.product as product,
sum( sale.quantity ) as total_qty,
sum( cast( sale.quantity as abap.dec( 15, 2 ) ) * sale.price ) as total_amount
}
where sale.sold_on >= $parameters.p_from
or sale.sold_on <= $parameters.p_to
group by sale.product

View File

@@ -0,0 +1,15 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales per product in a period'
define view entity {{P}}I_SALES_REPORT
with parameters
p_from : abap.dats,
p_to : abap.dats
as select from {{p}}sales as sale
{
key sale.product as product,
sum( sale.quantity ) as total_qty,
sum( cast( sale.quantity as abap.dec( 15, 2 ) ) * sale.price ) as total_amount
}
where sale.sold_on >= $parameters.p_from
and sale.sold_on > $parameters.p_to
group by sale.product

View File

@@ -0,0 +1,68 @@
{
"task": "G0024",
"mutants": [
{
"object": "{{P}}I_SALES_REPORT",
"mutant": "line 10: sum( -> max( (agg)",
"status": "killed",
"hidden": "6/7",
"failed_tests": [
"SUMS_QUANTITY"
]
},
{
"object": "{{P}}I_SALES_REPORT",
"mutant": "line 11: sum( -> max( (agg)",
"status": "killed",
"hidden": "6/7",
"failed_tests": [
"SUMS_AMOUNT"
]
},
{
"object": "{{P}}I_SALES_REPORT",
"mutant": "line 13: >= -> < (rel)",
"status": "killed",
"hidden": "2/7",
"failed_tests": [
"BOUNDS_INCLUSIVE",
"EXCLUDES_BEFORE_FROM",
"ROW_PER_PRODUCT",
"SUMS_AMOUNT",
"SUMS_QUANTITY"
]
},
{
"object": "{{P}}I_SALES_REPORT",
"mutant": "line 14: and -> or (logic)",
"status": "killed",
"hidden": "2/7",
"failed_tests": [
"BOUNDS_INCLUSIVE",
"EMPTY_PERIOD",
"EXCLUDES_AFTER_TO",
"EXCLUDES_BEFORE_FROM",
"ROW_PER_PRODUCT"
]
},
{
"object": "{{P}}I_SALES_REPORT",
"mutant": "line 14: <= -> > (rel)",
"status": "killed",
"hidden": "0/7",
"failed_tests": [
"BOUNDS_INCLUSIVE",
"EMPTY_PERIOD",
"EXCLUDES_AFTER_TO",
"EXCLUDES_BEFORE_FROM",
"ROW_PER_PRODUCT",
"SUMS_AMOUNT",
"SUMS_QUANTITY"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,19 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'All partners'
@Metadata.ignorePropagatedAnnotations: true
define view entity {{P}}I_PARTNER_ALL
as select from {{p}}part_a as a
{
key a.partner_id as partner_id,
a.name as name,
a.city as city,
cast('Z' as abap.char(1)) as source
}
union all
select from {{p}}part_b as b
{
key b.partner_id as partner_id,
b.name as name,
b.city as city,
cast('B' as abap.char(1)) as source
}

View File

@@ -0,0 +1,19 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'All partners'
@Metadata.ignorePropagatedAnnotations: true
define view entity {{P}}I_PARTNER_ALL
as select from {{p}}part_a as a
{
key a.partner_id as partner_id,
a.name as name,
a.city as city,
cast('A' as abap.char(1)) as source
}
union all
select from {{p}}part_b as b
{
key b.partner_id as partner_id,
b.name as name,
b.city as city,
cast('Z' as abap.char(1)) as source
}

View File

@@ -0,0 +1,32 @@
{
"task": "G0025",
"mutants": [
{
"object": "{{P}}I_PARTNER_ALL",
"mutant": "line 10: 'A' -> 'Z' (lit)",
"status": "killed",
"hidden": "4/7",
"failed_tests": [
"ONLY_IN_A",
"SAME_ID_TWICE",
"SOURCE_A_ROWS"
]
},
{
"object": "{{P}}I_PARTNER_ALL",
"mutant": "line 18: 'B' -> 'Z' (lit)",
"status": "killed",
"hidden": "3/7",
"failed_tests": [
"NAME_AND_CITY",
"ONLY_IN_B",
"SAME_ID_TWICE",
"SOURCE_B_ROWS"
]
}
],
"valid": 2,
"killed": 2,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,158 @@
CLASS {{p}}cl_rent DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_class TYPE string.
TYPES ty_money TYPE decfloat34.
TYPES ty_err_code TYPE c LENGTH 1.
CONSTANTS: BEGIN OF c_err,
ok TYPE ty_err_code VALUE ' ',
duration TYPE ty_err_code VALUE 'D',
distance TYPE ty_err_code VALUE 'K',
bad_class TYPE ty_err_code VALUE 'C',
END OF c_err.
TYPES: BEGIN OF ty_request,
vehicle_class TYPE ty_class,
minutes TYPE i,
km TYPE i,
member TYPE abap_bool,
weekend TYPE abap_bool,
END OF ty_request.
TYPES: BEGIN OF ty_result,
err_code TYPE ty_err_code,
time_fee TYPE ty_money,
distance_fee TYPE ty_money,
surcharge TYPE ty_money,
discount TYPE ty_money,
total TYPE ty_money,
END OF ty_result.
CLASS-METHODS calculate
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rs_result) TYPE ty_result.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_block_price,
small TYPE ty_money VALUE '3.00',
medium TYPE ty_money VALUE '5.00',
large TYPE ty_money VALUE '8.00',
END OF c_block_price.
CONSTANTS c_block_minutes TYPE i VALUE 15.
CONSTANTS c_free_km TYPE i VALUE 10.
CONSTANTS c_km_price TYPE ty_money VALUE '0.25'.
CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'.
CONSTANTS c_member_share TYPE ty_money VALUE '0.15'.
CONSTANTS c_min_total TYPE ty_money VALUE '5.00'.
CONSTANTS c_decimals TYPE i VALUE 2.
CLASS-METHODS validate
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_err_code) TYPE ty_err_code.
CLASS-METHODS time_fee
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_fee) TYPE ty_money.
CLASS-METHODS distance_fee
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_fee) TYPE ty_money.
CLASS-METHODS block_price
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_price) TYPE ty_money.
CLASS-METHODS block_count
IMPORTING iv_minutes TYPE i
RETURNING VALUE(rv_blocks) TYPE i.
CLASS-METHODS round_money
IMPORTING iv_value TYPE ty_money
RETURNING VALUE(rv_value) TYPE ty_money.
ENDCLASS.
CLASS {{p}}cl_rent IMPLEMENTATION.
METHOD calculate.
rs_result-err_code = validate( is_request ).
IF rs_result-err_code <> c_err-ok.
RETURN.
ENDIF.
rs_result-time_fee = time_fee( is_request ).
rs_result-distance_fee = distance_fee( is_request ).
IF is_request-weekend <> abap_true.
rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ).
ELSE.
rs_result-surcharge = 0.
ENDIF.
DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge.
IF is_request-member = abap_true.
rs_result-discount = round_money( lv_gross * c_member_share ).
ELSE.
rs_result-discount = 0.
ENDIF.
rs_result-total = round_money( lv_gross - rs_result-discount ).
IF rs_result-total < c_min_total.
rs_result-total = c_min_total.
ENDIF.
ENDMETHOD.
METHOD validate.
IF is_request-minutes < 1.
rv_err_code = c_err-duration.
ELSEIF is_request-km < 0.
rv_err_code = c_err-distance.
ELSEIF is_request-vehicle_class <> 'S'
AND is_request-vehicle_class <> 'M'
AND is_request-vehicle_class <> 'L'.
rv_err_code = c_err-bad_class.
ELSE.
rv_err_code = c_err-ok.
ENDIF.
ENDMETHOD.
METHOD time_fee.
rv_fee = block_count( is_request-minutes ) * block_price( is_request ).
ENDMETHOD.
METHOD distance_fee.
DATA(lv_chargeable_km) = is_request-km - c_free_km.
IF lv_chargeable_km > 0.
rv_fee = lv_chargeable_km * c_km_price.
ELSE.
rv_fee = 0.
ENDIF.
ENDMETHOD.
METHOD block_price.
CASE is_request-vehicle_class.
WHEN 'S'.
rv_price = c_block_price-small.
WHEN 'M'.
rv_price = c_block_price-medium.
WHEN 'L'.
rv_price = c_block_price-large.
WHEN OTHERS.
rv_price = 0.
ENDCASE.
ENDMETHOD.
METHOD block_count.
rv_blocks = ( iv_minutes + c_block_minutes - 1 ) DIV c_block_minutes.
ENDMETHOD.
METHOD round_money.
rv_value = round( val = iv_value
dec = c_decimals
mode = cl_abap_math=>round_half_up ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,158 @@
CLASS {{p}}cl_rent DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_class TYPE string.
TYPES ty_money TYPE decfloat34.
TYPES ty_err_code TYPE c LENGTH 1.
CONSTANTS: BEGIN OF c_err,
ok TYPE ty_err_code VALUE ' ',
duration TYPE ty_err_code VALUE 'D',
distance TYPE ty_err_code VALUE 'K',
bad_class TYPE ty_err_code VALUE 'C',
END OF c_err.
TYPES: BEGIN OF ty_request,
vehicle_class TYPE ty_class,
minutes TYPE i,
km TYPE i,
member TYPE abap_bool,
weekend TYPE abap_bool,
END OF ty_request.
TYPES: BEGIN OF ty_result,
err_code TYPE ty_err_code,
time_fee TYPE ty_money,
distance_fee TYPE ty_money,
surcharge TYPE ty_money,
discount TYPE ty_money,
total TYPE ty_money,
END OF ty_result.
CLASS-METHODS calculate
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rs_result) TYPE ty_result.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_block_price,
small TYPE ty_money VALUE '3.00',
medium TYPE ty_money VALUE '5.00',
large TYPE ty_money VALUE '8.00',
END OF c_block_price.
CONSTANTS c_block_minutes TYPE i VALUE 15.
CONSTANTS c_free_km TYPE i VALUE 10.
CONSTANTS c_km_price TYPE ty_money VALUE '0.25'.
CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'.
CONSTANTS c_member_share TYPE ty_money VALUE '0.15'.
CONSTANTS c_min_total TYPE ty_money VALUE '5.00'.
CONSTANTS c_decimals TYPE i VALUE 2.
CLASS-METHODS validate
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_err_code) TYPE ty_err_code.
CLASS-METHODS time_fee
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_fee) TYPE ty_money.
CLASS-METHODS distance_fee
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_fee) TYPE ty_money.
CLASS-METHODS block_price
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_price) TYPE ty_money.
CLASS-METHODS block_count
IMPORTING iv_minutes TYPE i
RETURNING VALUE(rv_blocks) TYPE i.
CLASS-METHODS round_money
IMPORTING iv_value TYPE ty_money
RETURNING VALUE(rv_value) TYPE ty_money.
ENDCLASS.
CLASS {{p}}cl_rent IMPLEMENTATION.
METHOD calculate.
rs_result-err_code = validate( is_request ).
IF rs_result-err_code <> c_err-ok.
RETURN.
ENDIF.
rs_result-time_fee = time_fee( is_request ).
rs_result-distance_fee = distance_fee( is_request ).
IF is_request-weekend = abap_true.
rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ).
ELSE.
rs_result-surcharge = 0.
ENDIF.
DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge.
IF is_request-member = abap_true.
rs_result-discount = round_money( lv_gross * c_member_share ).
ELSE.
rs_result-discount = 0.
ENDIF.
rs_result-total = round_money( lv_gross - rs_result-discount ).
IF rs_result-total < c_min_total.
rs_result-total = c_min_total.
ENDIF.
ENDMETHOD.
METHOD validate.
IF is_request-minutes < 1.
rv_err_code = c_err-duration.
ELSEIF is_request-km >= 0.
rv_err_code = c_err-distance.
ELSEIF is_request-vehicle_class <> 'S'
AND is_request-vehicle_class <> 'M'
AND is_request-vehicle_class <> 'L'.
rv_err_code = c_err-bad_class.
ELSE.
rv_err_code = c_err-ok.
ENDIF.
ENDMETHOD.
METHOD time_fee.
rv_fee = block_count( is_request-minutes ) * block_price( is_request ).
ENDMETHOD.
METHOD distance_fee.
DATA(lv_chargeable_km) = is_request-km - c_free_km.
IF lv_chargeable_km > 0.
rv_fee = lv_chargeable_km * c_km_price.
ELSE.
rv_fee = 0.
ENDIF.
ENDMETHOD.
METHOD block_price.
CASE is_request-vehicle_class.
WHEN 'S'.
rv_price = c_block_price-small.
WHEN 'M'.
rv_price = c_block_price-medium.
WHEN 'L'.
rv_price = c_block_price-large.
WHEN OTHERS.
rv_price = 0.
ENDCASE.
ENDMETHOD.
METHOD block_count.
rv_blocks = ( iv_minutes + c_block_minutes - 1 ) DIV c_block_minutes.
ENDMETHOD.
METHOD round_money.
rv_value = round( val = iv_value
dec = c_decimals
mode = cl_abap_math=>round_half_up ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,158 @@
CLASS {{p}}cl_rent DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_class TYPE string.
TYPES ty_money TYPE decfloat34.
TYPES ty_err_code TYPE c LENGTH 1.
CONSTANTS: BEGIN OF c_err,
ok TYPE ty_err_code VALUE ' ',
duration TYPE ty_err_code VALUE 'D',
distance TYPE ty_err_code VALUE 'K',
bad_class TYPE ty_err_code VALUE 'C',
END OF c_err.
TYPES: BEGIN OF ty_request,
vehicle_class TYPE ty_class,
minutes TYPE i,
km TYPE i,
member TYPE abap_bool,
weekend TYPE abap_bool,
END OF ty_request.
TYPES: BEGIN OF ty_result,
err_code TYPE ty_err_code,
time_fee TYPE ty_money,
distance_fee TYPE ty_money,
surcharge TYPE ty_money,
discount TYPE ty_money,
total TYPE ty_money,
END OF ty_result.
CLASS-METHODS calculate
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rs_result) TYPE ty_result.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_block_price,
small TYPE ty_money VALUE '3.00',
medium TYPE ty_money VALUE '5.00',
large TYPE ty_money VALUE '8.00',
END OF c_block_price.
CONSTANTS c_block_minutes TYPE i VALUE 15.
CONSTANTS c_free_km TYPE i VALUE 10.
CONSTANTS c_km_price TYPE ty_money VALUE '0.25'.
CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'.
CONSTANTS c_member_share TYPE ty_money VALUE '0.15'.
CONSTANTS c_min_total TYPE ty_money VALUE '5.00'.
CONSTANTS c_decimals TYPE i VALUE 2.
CLASS-METHODS validate
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_err_code) TYPE ty_err_code.
CLASS-METHODS time_fee
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_fee) TYPE ty_money.
CLASS-METHODS distance_fee
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_fee) TYPE ty_money.
CLASS-METHODS block_price
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_price) TYPE ty_money.
CLASS-METHODS block_count
IMPORTING iv_minutes TYPE i
RETURNING VALUE(rv_blocks) TYPE i.
CLASS-METHODS round_money
IMPORTING iv_value TYPE ty_money
RETURNING VALUE(rv_value) TYPE ty_money.
ENDCLASS.
CLASS {{p}}cl_rent IMPLEMENTATION.
METHOD calculate.
rs_result-err_code = validate( is_request ).
IF rs_result-err_code <> c_err-ok.
RETURN.
ENDIF.
rs_result-time_fee = time_fee( is_request ).
rs_result-distance_fee = distance_fee( is_request ).
IF is_request-weekend = abap_true.
rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ).
ELSE.
rs_result-surcharge = 0.
ENDIF.
DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge.
IF is_request-member = abap_true.
rs_result-discount = round_money( lv_gross * c_member_share ).
ELSE.
rs_result-discount = 0.
ENDIF.
rs_result-total = round_money( lv_gross - rs_result-discount ).
IF rs_result-total < c_min_total.
rs_result-total = c_min_total.
ENDIF.
ENDMETHOD.
METHOD validate.
IF is_request-minutes < 1.
rv_err_code = c_err-duration.
ELSEIF is_request-km < 0.
rv_err_code = c_err-distance.
ELSEIF is_request-vehicle_class <> 'S'
OR is_request-vehicle_class <> 'M'
AND is_request-vehicle_class <> 'L'.
rv_err_code = c_err-bad_class.
ELSE.
rv_err_code = c_err-ok.
ENDIF.
ENDMETHOD.
METHOD time_fee.
rv_fee = block_count( is_request-minutes ) * block_price( is_request ).
ENDMETHOD.
METHOD distance_fee.
DATA(lv_chargeable_km) = is_request-km - c_free_km.
IF lv_chargeable_km > 0.
rv_fee = lv_chargeable_km * c_km_price.
ELSE.
rv_fee = 0.
ENDIF.
ENDMETHOD.
METHOD block_price.
CASE is_request-vehicle_class.
WHEN 'S'.
rv_price = c_block_price-small.
WHEN 'M'.
rv_price = c_block_price-medium.
WHEN 'L'.
rv_price = c_block_price-large.
WHEN OTHERS.
rv_price = 0.
ENDCASE.
ENDMETHOD.
METHOD block_count.
rv_blocks = ( iv_minutes + c_block_minutes - 1 ) DIV c_block_minutes.
ENDMETHOD.
METHOD round_money.
rv_value = round( val = iv_value
dec = c_decimals
mode = cl_abap_math=>round_half_up ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,158 @@
CLASS {{p}}cl_rent DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_class TYPE string.
TYPES ty_money TYPE decfloat34.
TYPES ty_err_code TYPE c LENGTH 1.
CONSTANTS: BEGIN OF c_err,
ok TYPE ty_err_code VALUE ' ',
duration TYPE ty_err_code VALUE 'D',
distance TYPE ty_err_code VALUE 'K',
bad_class TYPE ty_err_code VALUE 'C',
END OF c_err.
TYPES: BEGIN OF ty_request,
vehicle_class TYPE ty_class,
minutes TYPE i,
km TYPE i,
member TYPE abap_bool,
weekend TYPE abap_bool,
END OF ty_request.
TYPES: BEGIN OF ty_result,
err_code TYPE ty_err_code,
time_fee TYPE ty_money,
distance_fee TYPE ty_money,
surcharge TYPE ty_money,
discount TYPE ty_money,
total TYPE ty_money,
END OF ty_result.
CLASS-METHODS calculate
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rs_result) TYPE ty_result.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_block_price,
small TYPE ty_money VALUE '3.00',
medium TYPE ty_money VALUE '5.00',
large TYPE ty_money VALUE '8.00',
END OF c_block_price.
CONSTANTS c_block_minutes TYPE i VALUE 15.
CONSTANTS c_free_km TYPE i VALUE 10.
CONSTANTS c_km_price TYPE ty_money VALUE '0.25'.
CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'.
CONSTANTS c_member_share TYPE ty_money VALUE '0.15'.
CONSTANTS c_min_total TYPE ty_money VALUE '5.00'.
CONSTANTS c_decimals TYPE i VALUE 2.
CLASS-METHODS validate
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_err_code) TYPE ty_err_code.
CLASS-METHODS time_fee
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_fee) TYPE ty_money.
CLASS-METHODS distance_fee
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_fee) TYPE ty_money.
CLASS-METHODS block_price
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_price) TYPE ty_money.
CLASS-METHODS block_count
IMPORTING iv_minutes TYPE i
RETURNING VALUE(rv_blocks) TYPE i.
CLASS-METHODS round_money
IMPORTING iv_value TYPE ty_money
RETURNING VALUE(rv_value) TYPE ty_money.
ENDCLASS.
CLASS {{p}}cl_rent IMPLEMENTATION.
METHOD calculate.
rs_result-err_code = validate( is_request ).
IF rs_result-err_code <> c_err-ok.
RETURN.
ENDIF.
rs_result-time_fee = time_fee( is_request ).
rs_result-distance_fee = distance_fee( is_request ).
IF is_request-weekend = abap_true.
rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ).
ELSE.
rs_result-surcharge = 0.
ENDIF.
DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge.
IF is_request-member = abap_true.
rs_result-discount = round_money( lv_gross * c_member_share ).
ELSE.
rs_result-discount = 0.
ENDIF.
rs_result-total = round_money( lv_gross - rs_result-discount ).
IF rs_result-total < c_min_total.
rs_result-total = c_min_total.
ENDIF.
ENDMETHOD.
METHOD validate.
IF is_request-minutes < 1.
rv_err_code = c_err-duration.
ELSEIF is_request-km < 0.
rv_err_code = c_err-distance.
ELSEIF is_request-vehicle_class <> 'S'
AND is_request-vehicle_class <> 'M'
AND is_request-vehicle_class <> 'L'.
rv_err_code = c_err-bad_class.
ELSE.
rv_err_code = c_err-ok.
ENDIF.
ENDMETHOD.
METHOD time_fee.
rv_fee = block_count( is_request-minutes ) / block_price( is_request ).
ENDMETHOD.
METHOD distance_fee.
DATA(lv_chargeable_km) = is_request-km - c_free_km.
IF lv_chargeable_km > 0.
rv_fee = lv_chargeable_km * c_km_price.
ELSE.
rv_fee = 0.
ENDIF.
ENDMETHOD.
METHOD block_price.
CASE is_request-vehicle_class.
WHEN 'S'.
rv_price = c_block_price-small.
WHEN 'M'.
rv_price = c_block_price-medium.
WHEN 'L'.
rv_price = c_block_price-large.
WHEN OTHERS.
rv_price = 0.
ENDCASE.
ENDMETHOD.
METHOD block_count.
rv_blocks = ( iv_minutes + c_block_minutes - 1 ) DIV c_block_minutes.
ENDMETHOD.
METHOD round_money.
rv_value = round( val = iv_value
dec = c_decimals
mode = cl_abap_math=>round_half_up ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,158 @@
CLASS {{p}}cl_rent DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_class TYPE string.
TYPES ty_money TYPE decfloat34.
TYPES ty_err_code TYPE c LENGTH 1.
CONSTANTS: BEGIN OF c_err,
ok TYPE ty_err_code VALUE ' ',
duration TYPE ty_err_code VALUE 'D',
distance TYPE ty_err_code VALUE 'K',
bad_class TYPE ty_err_code VALUE 'C',
END OF c_err.
TYPES: BEGIN OF ty_request,
vehicle_class TYPE ty_class,
minutes TYPE i,
km TYPE i,
member TYPE abap_bool,
weekend TYPE abap_bool,
END OF ty_request.
TYPES: BEGIN OF ty_result,
err_code TYPE ty_err_code,
time_fee TYPE ty_money,
distance_fee TYPE ty_money,
surcharge TYPE ty_money,
discount TYPE ty_money,
total TYPE ty_money,
END OF ty_result.
CLASS-METHODS calculate
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rs_result) TYPE ty_result.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_block_price,
small TYPE ty_money VALUE '3.00',
medium TYPE ty_money VALUE '5.00',
large TYPE ty_money VALUE '8.00',
END OF c_block_price.
CONSTANTS c_block_minutes TYPE i VALUE 15.
CONSTANTS c_free_km TYPE i VALUE 10.
CONSTANTS c_km_price TYPE ty_money VALUE '0.25'.
CONSTANTS c_weekend_share TYPE ty_money VALUE '0.25'.
CONSTANTS c_member_share TYPE ty_money VALUE '0.15'.
CONSTANTS c_min_total TYPE ty_money VALUE '5.00'.
CONSTANTS c_decimals TYPE i VALUE 2.
CLASS-METHODS validate
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_err_code) TYPE ty_err_code.
CLASS-METHODS time_fee
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_fee) TYPE ty_money.
CLASS-METHODS distance_fee
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_fee) TYPE ty_money.
CLASS-METHODS block_price
IMPORTING is_request TYPE ty_request
RETURNING VALUE(rv_price) TYPE ty_money.
CLASS-METHODS block_count
IMPORTING iv_minutes TYPE i
RETURNING VALUE(rv_blocks) TYPE i.
CLASS-METHODS round_money
IMPORTING iv_value TYPE ty_money
RETURNING VALUE(rv_value) TYPE ty_money.
ENDCLASS.
CLASS {{p}}cl_rent IMPLEMENTATION.
METHOD calculate.
rs_result-err_code = validate( is_request ).
IF rs_result-err_code <> c_err-ok.
RETURN.
ENDIF.
rs_result-time_fee = time_fee( is_request ).
rs_result-distance_fee = distance_fee( is_request ).
IF is_request-weekend = abap_true.
rs_result-surcharge = round_money( rs_result-time_fee * c_weekend_share ).
ELSE.
rs_result-surcharge = 0.
ENDIF.
DATA(lv_gross) = rs_result-time_fee + rs_result-distance_fee + rs_result-surcharge.
IF is_request-member = abap_true.
rs_result-discount = round_money( lv_gross * c_member_share ).
ELSE.
rs_result-discount = 0.
ENDIF.
rs_result-total = round_money( lv_gross - rs_result-discount ).
IF rs_result-total < c_min_total.
rs_result-total = c_min_total.
ENDIF.
ENDMETHOD.
METHOD validate.
IF is_request-minutes < 1.
rv_err_code = c_err-duration.
ELSEIF is_request-km < 0.
rv_err_code = c_err-distance.
ELSEIF is_request-vehicle_class <> 'S'
AND is_request-vehicle_class <> 'M'
AND is_request-vehicle_class <> 'L'.
rv_err_code = c_err-bad_class.
ELSE.
rv_err_code = c_err-ok.
ENDIF.
ENDMETHOD.
METHOD time_fee.
rv_fee = block_count( is_request-minutes ) * block_price( is_request ).
ENDMETHOD.
METHOD distance_fee.
DATA(lv_chargeable_km) = is_request-km - c_free_km.
IF lv_chargeable_km > 0.
rv_fee = lv_chargeable_km * c_km_price.
ELSE.
rv_fee = 0.
ENDIF.
ENDMETHOD.
METHOD block_price.
CASE is_request-vehicle_class.
WHEN 'S'.
rv_price = c_block_price-small.
WHEN 'M'.
rv_price = c_block_price-medium.
WHEN 'L'.
rv_price = c_block_price-large.
WHEN OTHERS.
rv_price = 0.
ENDCASE.
ENDMETHOD.
METHOD block_count.
rv_blocks = ( iv_minutes + c_block_minutes - 2 ) DIV c_block_minutes.
ENDMETHOD.
METHOD round_money.
rv_value = round( val = iv_value
dec = c_decimals
mode = cl_abap_math=>round_half_up ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,75 @@
{
"task": "G0026",
"mutants": [
{
"object": "{{P}}CL_RENT",
"mutant": "line 89: = -> <> (eq)",
"status": "killed",
"hidden": "5/10",
"failed_tests": [
"DISTANCE_FEE_FREE_KM",
"MEMBER_DISCOUNT",
"MINIMUM_TOTAL_MEMBER",
"WEEKDAY_NO_SURCHARGE",
"WEEKEND_SURCHARGE"
]
},
{
"object": "{{P}}CL_RENT",
"mutant": "line 112: < -> >= (rel)",
"status": "killed",
"hidden": "2/10",
"failed_tests": [
"DISTANCE_FEE_FREE_KM",
"INVALID_CLASS",
"INVALID_DISTANCE",
"MEMBER_DISCOUNT",
"MINIMUM_TOTAL",
"MINIMUM_TOTAL_MEMBER",
"TIME_FEE_BLOCKS",
"WEEKEND_SURCHARGE"
]
},
{
"object": "{{P}}CL_RENT",
"mutant": "line 115: AND -> OR (logic)",
"status": "killed",
"hidden": "4/10",
"failed_tests": [
"DISTANCE_FEE_FREE_KM",
"MEMBER_DISCOUNT",
"MINIMUM_TOTAL",
"MINIMUM_TOTAL_MEMBER",
"TIME_FEE_BLOCKS",
"WEEKEND_SURCHARGE"
]
},
{
"object": "{{P}}CL_RENT",
"mutant": "line 124: * -> / (arith)",
"status": "killed",
"hidden": "4/10",
"failed_tests": [
"DISTANCE_FEE_FREE_KM",
"MEMBER_DISCOUNT",
"MINIMUM_TOTAL",
"MINIMUM_TOTAL_MEMBER",
"TIME_FEE_BLOCKS",
"WEEKEND_SURCHARGE"
]
},
{
"object": "{{P}}CL_RENT",
"mutant": "line 150: 1 -> 2 (const)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"TIME_FEE_BLOCKS"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}