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": "G0015",
"pool": "eval",
"object_type": "PROG",
"category": "B",
"attempts": [
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0
}
],
"accepted": true
}

View File

@@ -0,0 +1,120 @@
CLASS {{p}}bill_age_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES tt_customer TYPE RANGE OF {{p}}bill-customer.
METHODS run
IMPORTING iv_date TYPE d
it_customer TYPE tt_customer OPTIONAL
RETURNING VALUE(rr_data) TYPE REF TO data.
METHODS value_of
IMPORTING ir_data TYPE REF TO data
iv_row TYPE i
iv_col TYPE string
RETURNING VALUE(rv_value) TYPE string.
METHODS lines_of
IMPORTING ir_data TYPE REF TO data
RETURNING VALUE(rv_lines) TYPE i.
METHODS only_open_invoices FOR TESTING.
METHODS paid_invoices_excluded FOR TESTING.
METHODS sorted_by_open_amount FOR TESTING.
METHODS count_and_amount FOR TESTING.
METHODS overdue_amount FOR TESTING.
METHODS no_overdue_amount FOR TESTING.
METHODS customer_filter FOR TESTING.
METHODS customer_filter_multiple FOR TESTING.
ENDCLASS.
CLASS {{p}}bill_age_test IMPLEMENTATION.
METHOD run.
cl_salv_bs_runtime_info=>set( display = abap_false metadata = abap_false data = abap_true ).
SUBMIT {{p}}bill_age WITH p_date = iv_date WITH s_cust IN it_customer AND RETURN.
TRY.
cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = rr_data ).
CATCH cx_salv_bs_sc_runtime_info.
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
ENDMETHOD.
METHOD lines_of.
FIELD-SYMBOLS <lt_data> TYPE STANDARD TABLE.
IF ir_data IS BOUND.
ASSIGN ir_data->* TO <lt_data>.
rv_lines = lines( <lt_data> ).
ENDIF.
ENDMETHOD.
METHOD value_of.
FIELD-SYMBOLS <lt_data> TYPE STANDARD TABLE.
ASSIGN ir_data->* TO <lt_data>.
ASSIGN <lt_data>[ iv_row ] TO FIELD-SYMBOL(<ls_line>).
ASSIGN COMPONENT iv_col OF STRUCTURE <ls_line> TO FIELD-SYMBOL(<lv_value>).
cl_abap_unit_assert=>assert_subrc( exp = 0 msg = |Column { iv_col } is missing| ).
rv_value = condense( CONV string( <lv_value> ) ).
ENDMETHOD.
METHOD only_open_invoices.
cl_abap_unit_assert=>assert_equals( exp = 4 act = lines_of( run( '20260101' ) ) ).
ENDMETHOD.
METHOD paid_invoices_excluded.
DATA(lr_data) = run( '20260101' ).
cl_abap_unit_assert=>assert_equals( exp = `C002`
act = value_of( ir_data = lr_data iv_row = 2 iv_col = `CUSTOMER` ) ).
cl_abap_unit_assert=>assert_equals( exp = `300.00`
act = value_of( ir_data = lr_data iv_row = 2 iv_col = `OPEN_AMOUNT` ) ).
ENDMETHOD.
METHOD sorted_by_open_amount.
DATA(lr_data) = run( '20260101' ).
cl_abap_unit_assert=>assert_equals( exp = `C004`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `CUSTOMER` ) ).
cl_abap_unit_assert=>assert_equals( exp = `C003`
act = value_of( ir_data = lr_data iv_row = 4 iv_col = `CUSTOMER` ) ).
ENDMETHOD.
METHOD count_and_amount.
DATA(lr_data) = run( '20260101' ).
cl_abap_unit_assert=>assert_equals( exp = `C001`
act = value_of( ir_data = lr_data iv_row = 3 iv_col = `CUSTOMER` ) ).
cl_abap_unit_assert=>assert_equals( exp = `2`
act = value_of( ir_data = lr_data iv_row = 3 iv_col = `OPEN_COUNT` ) ).
cl_abap_unit_assert=>assert_equals( exp = `150.00`
act = value_of( ir_data = lr_data iv_row = 3 iv_col = `OPEN_AMOUNT` ) ).
ENDMETHOD.
METHOD overdue_amount.
DATA(lr_data) = run( '20260301' ).
cl_abap_unit_assert=>assert_equals( exp = `100.00`
act = value_of( ir_data = lr_data iv_row = 3 iv_col = `OVERDUE_AMOUNT` ) ).
cl_abap_unit_assert=>assert_equals( exp = `300.00`
act = value_of( ir_data = lr_data iv_row = 2 iv_col = `OVERDUE_AMOUNT` ) ).
ENDMETHOD.
METHOD no_overdue_amount.
DATA(lr_data) = run( '20260101' ).
cl_abap_unit_assert=>assert_equals( exp = `0.00`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `OVERDUE_AMOUNT` ) ).
cl_abap_unit_assert=>assert_equals( exp = `0.00`
act = value_of( ir_data = lr_data iv_row = 3 iv_col = `OVERDUE_AMOUNT` ) ).
ENDMETHOD.
METHOD customer_filter.
DATA(lr_data) = run( iv_date = '20260101'
it_customer = VALUE #( ( sign = 'I' option = 'EQ' low = 'C001' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals( exp = `150.00`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `OPEN_AMOUNT` ) ).
ENDMETHOD.
METHOD customer_filter_multiple.
DATA(lr_data) = run( iv_date = '20260101'
it_customer = VALUE #( ( sign = 'I' option = 'EQ' low = 'C001' )
( sign = 'I' option = 'EQ' low = 'C002' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals( exp = `C002`
act = value_of( ir_data = lr_data iv_row = 1 iv_col = `CUSTOMER` ) ).
cl_abap_unit_assert=>assert_equals( exp = `C001`
act = value_of( ir_data = lr_data iv_row = 2 iv_col = `CUSTOMER` ) ).
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,13 @@
@EndUserText.label : 'Invoices'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}bill {
key client : abap.clnt not null;
key bill_id : abap.int4 not null;
customer : abap.char(10);
due_date : abap.dats;
amount : abap.dec(15,2);
paid : abap.char(1);
}

View File

@@ -0,0 +1,19 @@
CLASS {{p}}bill_seed DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS {{p}}bill_seed IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DELETE FROM {{p}}bill.
INSERT {{p}}bill FROM TABLE @( VALUE #(
( bill_id = 1 customer = 'C001' due_date = '20260210' amount = '100.00' paid = ' ' )
( bill_id = 2 customer = 'C001' due_date = '20260410' amount = '50.00' paid = ' ' )
( bill_id = 3 customer = 'C002' due_date = '20260105' amount = '300.00' paid = ' ' )
( bill_id = 4 customer = 'C002' due_date = '20260501' amount = '200.00' paid = 'X' )
( bill_id = 5 customer = 'C003' due_date = '20260320' amount = '75.50' paid = ' ' )
( bill_id = 6 customer = 'C001' due_date = '20260101' amount = '25.00' paid = 'X' )
( bill_id = 7 customer = 'C004' due_date = '20260615' amount = '500.00' paid = ' ' ) ) ).
out->write( sy-dbcnt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,42 @@
# 1. Goal
Show the open invoice amounts for each customer in an ALV list. The accounting
team uses the list to find the customers that owe money and to see how much of
the money is overdue.
# 2. Open questions
None.
# 3. Context
- The table {{P}}BILL exists in package $TMP. It contains data.
Fields: BILL_ID (INT4, key), CUSTOMER (CHAR 10), DUE_DATE (DATS),
AMOUNT (DEC 15,2), PAID (CHAR 1).
- PAID is 'X' if the customer paid the invoice. PAID is ' ' if the invoice is
still open.
# 4. Contract
- Create the executable program {{P}}BILL_AGE in package $TMP.
- Selection screen:
- Parameter P_DATE, type DATS, mandatory: the date that you compare with the
due date.
- Select-option S_CUST for the customer.
- Show the result with CL_SALV_TABLE. The output table has these columns, with
these names: CUSTOMER, OPEN_COUNT, OPEN_AMOUNT, OVERDUE_AMOUNT.
# 5. Business rules
1. Include an invoice only if PAID is not 'X' and CUSTOMER is in S_CUST.
2. Show one line for each customer that has at least one included invoice.
3. OPEN_COUNT is the number of included invoices of the customer.
4. OPEN_AMOUNT is the sum of AMOUNT of the included invoices of the customer.
5. OVERDUE_AMOUNT is the sum of AMOUNT of the included invoices of the customer
whose DUE_DATE is before P_DATE.
6. Sort the lines by OPEN_AMOUNT, the highest amount first.
# 6. Constraints
- Release target: 7.58.
- Coding standards: Clean ABAP. Read the invoice data with one database access.
- Out of scope: do not change {{P}}BILL.
# 7. Acceptance
- The program is active and has no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests as local test classes in the program.

View File

@@ -0,0 +1,60 @@
{
"id": "G0015",
"category": "B",
"object_type": "PROG",
"difficulty": 2,
"release_target": "v758",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 40,
"max_activations": 10
},
"seed": [
{
"type": "TABL",
"name": "{{P}}BILL",
"file": "seed/bill.tabl.asabap",
"description": "Invoices with due date and paid flag"
},
{
"type": "CLAS",
"name": "{{P}}BILL_SEED",
"file": "seed/bill_seed.clas.abap",
"description": "Invoice seed data",
"run": true
}
],
"contract": [
{
"type": "PROG",
"name": "{{P}}BILL_AGE",
"parameters": [
"p_date",
"s_cust"
]
}
],
"out_of_scope": [
"{{P}}BILL"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}BILL_AGE_TEST",
"file": "hidden/bill_age_test.clas.abap",
"description": "Hidden tests for the open invoice report"
}
],
"reference": [
{
"type": "PROG",
"name": "{{P}}BILL_AGE",
"file": "reference/bill_age.prog.abap",
"description": "Open invoice amounts per customer"
}
],
"craft_checks": [
"db_operation_in_loop",
"method_length"
]
}