Generator: pilot analysis and fixes; G0002-G0021 tasks; handover notes merged

- Static bundle checks (name length, seed type, reserved words, contract test classes,
  testclasses_file), local abaplint parser check before SAP, max_tokens, robust JSON parse
- Runner: G2 for CDS views with parameters, contract_check detail in report
- G0020 and G0013 fixed by review and revalidated (oracle 100, null 0)
- Pilot results in docs/faz1-tasarim.md 11e; handover notes merged into CLAUDE.md and docs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-03 05:04:23 +02:00
parent 15eb9f1bb2
commit 5de5e2851c
162 changed files with 9943 additions and 23 deletions

View File

@@ -0,0 +1,19 @@
{
"id": "G0009",
"pool": "eval",
"object_type": "CLAS",
"category": "I",
"attempts": [
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0
}
],
"accepted": true
}

View File

@@ -0,0 +1,111 @@
CLASS {{p}}t02_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}if_shipping_cost.
METHODS setup.
METHODS zero_weight_is_free FOR TESTING.
METHODS light_parcel_gets_minimum FOR TESTING.
METHODS tier_limit_one_kg FOR TESTING.
METHODS tier_limit_five_kg FOR TESTING.
METHODS tier_limit_ten_kg FOR TESTING.
METHODS bulk_weight_limit FOR TESTING.
METHODS bulk_weight_started_kg FOR TESTING.
METHODS express_surcharge FOR TESTING.
METHODS express_below_minimum FOR TESTING.
METHODS bulk_express FOR TESTING.
METHODS assert_cost
IMPORTING iv_weight TYPE {{p}}if_shipping_cost=>ty_weight
iv_express TYPE abap_bool
iv_exp TYPE {{p}}if_shipping_cost=>ty_amount
iv_msg TYPE string.
ENDCLASS.
CLASS {{p}}t02_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}shipping_cost_calc( ).
ENDMETHOD.
METHOD assert_cost.
cl_abap_unit_assert=>assert_equals(
exp = iv_exp
act = mo_cut->calculate( iv_weight = iv_weight iv_express = iv_express )
msg = iv_msg ).
ENDMETHOD.
METHOD zero_weight_is_free.
assert_cost( iv_weight = '0.000' iv_express = abap_false
iv_exp = '0.00' iv_msg = `zero weight` ).
assert_cost( iv_weight = '-2.500' iv_express = abap_true
iv_exp = '0.00' iv_msg = `negative weight` ).
ENDMETHOD.
METHOD light_parcel_gets_minimum.
assert_cost( iv_weight = '0.100' iv_express = abap_false
iv_exp = '6.00' iv_msg = `0.100 kg` ).
assert_cost( iv_weight = '0.500' iv_express = abap_false
iv_exp = '6.00' iv_msg = `0.500 kg` ).
ENDMETHOD.
METHOD tier_limit_one_kg.
assert_cost( iv_weight = '1.000' iv_express = abap_false
iv_exp = '6.00' iv_msg = `1.000 kg` ).
assert_cost( iv_weight = '1.001' iv_express = abap_false
iv_exp = '8.50' iv_msg = `1.001 kg` ).
ENDMETHOD.
METHOD tier_limit_five_kg.
assert_cost( iv_weight = '5.000' iv_express = abap_false
iv_exp = '8.50' iv_msg = `5.000 kg` ).
assert_cost( iv_weight = '5.001' iv_express = abap_false
iv_exp = '12.00' iv_msg = `5.001 kg` ).
ENDMETHOD.
METHOD tier_limit_ten_kg.
assert_cost( iv_weight = '10.000' iv_express = abap_false
iv_exp = '12.00' iv_msg = `10.000 kg` ).
assert_cost( iv_weight = '10.001' iv_express = abap_false
iv_exp = '18.75' iv_msg = `10.001 kg` ).
ENDMETHOD.
METHOD bulk_weight_limit.
assert_cost( iv_weight = '31.500' iv_express = abap_false
iv_exp = '18.75' iv_msg = `31.500 kg` ).
assert_cost( iv_weight = '31.501' iv_express = abap_false
iv_exp = '19.40' iv_msg = `31.501 kg` ).
ENDMETHOD.
METHOD bulk_weight_started_kg.
assert_cost( iv_weight = '32.000' iv_express = abap_false
iv_exp = '19.40' iv_msg = `32.000 kg` ).
assert_cost( iv_weight = '33.000' iv_express = abap_false
iv_exp = '20.05' iv_msg = `33.000 kg` ).
assert_cost( iv_weight = '100.000' iv_express = abap_false
iv_exp = '63.60' iv_msg = `100.000 kg` ).
ENDMETHOD.
METHOD express_surcharge.
assert_cost( iv_weight = '2.000' iv_express = abap_true
iv_exp = '11.48' iv_msg = `2.000 kg express` ).
assert_cost( iv_weight = '20.000' iv_express = abap_true
iv_exp = '25.31' iv_msg = `20.000 kg express` ).
ENDMETHOD.
METHOD express_below_minimum.
assert_cost( iv_weight = '0.500' iv_express = abap_true
iv_exp = '6.62' iv_msg = `0.500 kg express` ).
assert_cost( iv_weight = '1.000' iv_express = abap_true
iv_exp = '6.62' iv_msg = `1.000 kg express` ).
ENDMETHOD.
METHOD bulk_express.
assert_cost( iv_weight = '32.000' iv_express = abap_true
iv_exp = '26.19' iv_msg = `32.000 kg express` ).
assert_cost( iv_weight = '100.000' iv_express = abap_true
iv_exp = '85.86' iv_msg = `100.000 kg express` ).
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,68 @@
CLASS ltc_shipping_cost_calc DEFINITION FINAL FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}if_shipping_cost.
METHODS setup.
METHODS zero_weight_is_free FOR TESTING.
METHODS minimum_charge FOR TESTING.
METHODS tier_limits FOR TESTING.
METHODS bulk_weight FOR TESTING.
METHODS express_surcharge FOR TESTING.
METHODS express_below_minimum FOR TESTING.
METHODS assert_cost
IMPORTING iv_weight TYPE {{p}}if_shipping_cost=>ty_weight
iv_express TYPE abap_bool
iv_exp TYPE {{p}}if_shipping_cost=>ty_amount
iv_msg TYPE string.
ENDCLASS.
CLASS ltc_shipping_cost_calc IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}shipping_cost_calc( ).
ENDMETHOD.
METHOD assert_cost.
cl_abap_unit_assert=>assert_equals(
exp = iv_exp
act = mo_cut->calculate( iv_weight = iv_weight iv_express = iv_express )
msg = iv_msg ).
ENDMETHOD.
METHOD zero_weight_is_free.
assert_cost( iv_weight = '0.000' iv_express = abap_true
iv_exp = '0.00' iv_msg = `zero weight` ).
ENDMETHOD.
METHOD minimum_charge.
assert_cost( iv_weight = '0.500' iv_express = abap_false
iv_exp = '6.00' iv_msg = `minimum charge` ).
ENDMETHOD.
METHOD tier_limits.
assert_cost( iv_weight = '1.000' iv_express = abap_false
iv_exp = '6.00' iv_msg = `1.000 kg` ).
assert_cost( iv_weight = '1.001' iv_express = abap_false
iv_exp = '8.50' iv_msg = `1.001 kg` ).
ENDMETHOD.
METHOD bulk_weight.
assert_cost( iv_weight = '31.500' iv_express = abap_false
iv_exp = '18.75' iv_msg = `31.500 kg` ).
assert_cost( iv_weight = '32.000' iv_express = abap_false
iv_exp = '19.40' iv_msg = `32.000 kg` ).
ENDMETHOD.
METHOD express_surcharge.
assert_cost( iv_weight = '2.000' iv_express = abap_true
iv_exp = '11.48' iv_msg = `2.000 kg express` ).
ENDMETHOD.
METHOD express_below_minimum.
assert_cost( iv_weight = '0.500' iv_express = abap_true
iv_exp = '6.62' iv_msg = `0.500 kg express` ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,17 @@
INTERFACE {{p}}if_shipping_cost PUBLIC.
TYPES ty_weight TYPE p LENGTH 13 DECIMALS 3.
TYPES ty_amount TYPE p LENGTH 15 DECIMALS 2.
CONSTANTS:
BEGIN OF c_rate,
min_charge TYPE ty_amount VALUE '6.00',
express_percent TYPE i VALUE 35,
bulk_weight TYPE ty_weight VALUE '31.500',
bulk_step TYPE ty_amount VALUE '0.65',
END OF c_rate.
METHODS calculate
IMPORTING iv_weight TYPE ty_weight
iv_express TYPE abap_bool
RETURNING VALUE(rv_cost) TYPE ty_amount.
ENDINTERFACE.

View File

@@ -0,0 +1,53 @@
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.
RETURN.
ENDIF.
rv_cost = base_rate( iv_weight ).
IF rv_cost < {{p}}if_shipping_cost=>c_rate-min_charge.
rv_cost = {{p}}if_shipping_cost=>c_rate-min_charge.
ENDIF.
IF iv_express = abap_true.
rv_cost = rv_cost + express_surcharge( rv_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 TYPE i.
lv_started_kg = 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,53 @@
CLASS {{p}}shipping_cost_legacy 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_legacy IMPLEMENTATION.
METHOD {{p}}if_shipping_cost~calculate.
IF iv_weight <= 0.
RETURN.
ENDIF.
rv_cost = base_rate( iv_weight ).
IF rv_cost < {{p}}if_shipping_cost=>c_rate-min_charge.
rv_cost = {{p}}if_shipping_cost=>c_rate-min_charge.
ENDIF.
IF iv_express = abap_true.
rv_cost = rv_cost + express_surcharge( rv_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 TYPE i.
lv_started_kg = 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,63 @@
# 1. Goal
Calculate the shipping cost of a parcel. A webshop calls the calculation before
it shows the total price to the customer. The cost depends on the weight of the
parcel and on an express flag. The class that the webshop uses today returns
wrong costs. A corrected class must replace it.
# 2. Open questions
None.
# 3. Context
- The interface {{P}}IF_SHIPPING_COST exists in package $TMP. It is active.
- The interface contains the types TY_WEIGHT (packed, 3 decimals) and TY_AMOUNT
(packed, 2 decimals), the constant structure C_RATE, and one method:
CALCULATE IMPORTING iv_weight TYPE ty_weight, iv_express TYPE abap_bool
RETURNING VALUE(rv_cost) TYPE ty_amount.
- C_RATE has the components MIN_CHARGE (6.00), EXPRESS_PERCENT (35),
BULK_WEIGHT (31.500), and BULK_STEP (0.65).
- The class {{P}}SHIPPING_COST_LEGACY exists in package $TMP. It is active and
it implements the interface, but the calculated costs are wrong.
- Reported symptoms of {{P}}SHIPPING_COST_LEGACY:
1. A parcel with a weight that is exactly on a weight limit is charged with
the rate of the next weight limit.
2. A parcel that is heavier than C_RATE-BULK_WEIGHT is charged as if its
weight were exactly C_RATE-BULK_WEIGHT.
3. An express parcel that is lighter than the minimum charge gets a total
that is too high.
# 4. Contract
- Create the class {{P}}SHIPPING_COST_CALC in package $TMP.
- The class is public and final and has a public constructor without parameters.
- The class implements {{P}}IF_SHIPPING_COST.
- Do not add other public methods.
- Do not change {{P}}IF_SHIPPING_COST and {{P}}SHIPPING_COST_LEGACY.
# 5. Business rules
Apply the rules in this sequence.
1. If iv_weight is zero or negative, the cost is 0. Stop.
2. Else calculate the base rate from the weight:
- weight up to and including 1.000 kg: 4.90
- weight up to and including 5.000 kg: 8.50
- weight up to and including 10.000 kg: 12.00
- weight up to and including 31.500 kg: 18.75
- weight above 31.500 kg: 18.75 plus 0.65 for each started kilogram above
31.500 kg. A started kilogram is a kilogram that is not complete.
Example: 31.501 kg is 0.001 kg above 31.500 kg, so there is one started
kilogram. 33.000 kg is 1.500 kg above 31.500 kg, so there are two started
kilograms.
3. If iv_express is abap_true, add 35 percent of the base rate to the base rate.
Round this surcharge to 2 decimals. Round a half away from zero.
4. If the result is below 6.00, the result is 6.00.
5. The result has 2 decimals.
# 6. Constraints
- Release target: 8.16.
- Coding standards: Clean ABAP. Methods below 40 statements. No global variables.
No comment that restates the code.
- Out of scope: do not change {{P}}IF_SHIPPING_COST and
{{P}}SHIPPING_COST_LEGACY.
# 7. Acceptance
- The class is active and has no syntax error.
- The hidden tests pass.
- Write your own ABAP Unit tests for the class.

View File

@@ -0,0 +1,59 @@
{
"id": "G0009",
"category": "I",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 50,
"max_activations": 12
},
"seed": [
{
"type": "INTF",
"name": "{{P}}IF_SHIPPING_COST",
"file": "seed/if_shipping_cost.intf.abap",
"description": "Shipping cost contract with the weight and amount types, the rate constants and the CALCULATE method"
},
{
"type": "CLAS",
"name": "{{P}}SHIPPING_COST_LEGACY",
"file": "seed/shipping_cost_legacy.clas.abap",
"description": "Active class that implements the interface but calculates wrong costs"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}SHIPPING_COST_CALC",
"implements": "{{P}}IF_SHIPPING_COST"
}
],
"out_of_scope": [
"{{P}}IF_SHIPPING_COST",
"{{P}}SHIPPING_COST_LEGACY"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T02_HIDDEN",
"file": "hidden/t02_hidden.clas.abap",
"description": "T02 hidden tests for the shipping cost calculation"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}SHIPPING_COST_CALC",
"file": "reference/shipping_cost_calc.clas.abap",
"description": "Correct shipping cost calculation",
"testclasses_file": "reference/shipping_cost_calc.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"cyclomatic_complexity",
"no_global_variables"
]
}