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

View File

@@ -0,0 +1,186 @@
CLASS {{p}}t15_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES tt_matnr TYPE RANGE OF {{p}}move-material.
METHODS run
IMPORTING iv_from TYPE d
iv_to TYPE d
it_matnr TYPE tt_matnr OPTIONAL
RETURNING VALUE(rr_data) TYPE REF TO data.
METHODS lines_of
IMPORTING ir_data TYPE REF TO data
RETURNING VALUE(rv_lines) TYPE i.
METHODS text_of
IMPORTING ir_data TYPE REF TO data
iv_row TYPE i
iv_col TYPE string
RETURNING VALUE(rv_text) TYPE string.
METHODS qty_of
IMPORTING ir_data TYPE REF TO data
iv_row TYPE i
RETURNING VALUE(rv_qty) TYPE {{p}}move-quantity.
METHODS count_of
IMPORTING ir_data TYPE REF TO data
iv_row TYPE i
RETURNING VALUE(rv_count) TYPE i.
METHODS all_groups FOR TESTING.
METHODS sort_order FOR TESTING.
METHODS net_quantity FOR TESTING.
METHODS move_count FOR TESTING.
METHODS material_filter FOR TESTING.
METHODS date_from_filter FOR TESTING.
METHODS date_to_filter FOR TESTING.
METHODS no_matching_data FOR TESTING.
ENDCLASS.
CLASS {{p}}t15_hidden IMPLEMENTATION.
METHOD run.
cl_salv_bs_runtime_info=>set( display = abap_false metadata = abap_false data = abap_true ).
SUBMIT {{p}}stock_net
WITH p_from = iv_from
WITH p_to = iv_to
WITH s_matnr IN it_matnr
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 text_of.
FIELD-SYMBOLS <lt_data> TYPE STANDARD TABLE.
ASSIGN ir_data->* TO <lt_data>.
ASSIGN <lt_data>[ iv_row ] TO FIELD-SYMBOL(<ls_line>).
cl_abap_unit_assert=>assert_subrc( exp = 0 msg = |Row { iv_row } is missing| ).
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| ).
DATA lv_text TYPE string.
lv_text = <lv_value>.
rv_text = condense( lv_text ).
ENDMETHOD.
METHOD qty_of.
FIELD-SYMBOLS <lt_data> TYPE STANDARD TABLE.
ASSIGN ir_data->* TO <lt_data>.
ASSIGN <lt_data>[ iv_row ] TO FIELD-SYMBOL(<ls_line>).
cl_abap_unit_assert=>assert_subrc( exp = 0 msg = |Row { iv_row } is missing| ).
ASSIGN COMPONENT 'NET_QTY' OF STRUCTURE <ls_line> TO FIELD-SYMBOL(<lv_value>).
cl_abap_unit_assert=>assert_subrc( exp = 0 msg = 'Column NET_QTY is missing' ).
DATA lv_qty TYPE {{p}}move-quantity.
lv_qty = <lv_value>.
rv_qty = lv_qty.
ENDMETHOD.
METHOD count_of.
FIELD-SYMBOLS <lt_data> TYPE STANDARD TABLE.
ASSIGN ir_data->* TO <lt_data>.
ASSIGN <lt_data>[ iv_row ] TO FIELD-SYMBOL(<ls_line>).
cl_abap_unit_assert=>assert_subrc( exp = 0 msg = |Row { iv_row } is missing| ).
ASSIGN COMPONENT 'MOVE_COUNT' OF STRUCTURE <ls_line> TO FIELD-SYMBOL(<lv_value>).
cl_abap_unit_assert=>assert_subrc( exp = 0 msg = 'Column MOVE_COUNT is missing' ).
DATA lv_count TYPE i.
lv_count = <lv_value>.
rv_count = lv_count.
ENDMETHOD.
METHOD all_groups.
cl_abap_unit_assert=>assert_equals(
exp = 4
act = lines_of( run( iv_from = '20260101' iv_to = '20261231' ) ) ).
ENDMETHOD.
METHOD sort_order.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20261231' ).
cl_abap_unit_assert=>assert_equals(
exp = `MAT-001`
act = text_of( ir_data = lr_data iv_row = 1 iv_col = 'MATERIAL' ) ).
cl_abap_unit_assert=>assert_equals(
exp = `1000`
act = text_of( ir_data = lr_data iv_row = 1 iv_col = 'PLANT' ) ).
cl_abap_unit_assert=>assert_equals(
exp = `2000`
act = text_of( ir_data = lr_data iv_row = 2 iv_col = 'PLANT' ) ).
cl_abap_unit_assert=>assert_equals(
exp = `MAT-002`
act = text_of( ir_data = lr_data iv_row = 3 iv_col = 'MATERIAL' ) ).
cl_abap_unit_assert=>assert_equals(
exp = `MAT-002`
act = text_of( ir_data = lr_data iv_row = 4 iv_col = 'MATERIAL' ) ).
ENDMETHOD.
METHOD net_quantity.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20261231' ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}move-quantity( 120 )
act = qty_of( ir_data = lr_data iv_row = 1 ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}move-quantity( -40 )
act = qty_of( ir_data = lr_data iv_row = 2 ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}move-quantity( -15 )
act = qty_of( ir_data = lr_data iv_row = 4 ) ).
ENDMETHOD.
METHOD move_count.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20261231' ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = count_of( ir_data = lr_data iv_row = 1 ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = count_of( ir_data = lr_data iv_row = 2 ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = count_of( ir_data = lr_data iv_row = 4 ) ).
ENDMETHOD.
METHOD material_filter.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20261231'
it_matnr = VALUE #( ( sign = 'I' option = 'EQ' low = 'MAT-002' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals(
exp = `MAT-002`
act = text_of( ir_data = lr_data iv_row = 1 iv_col = 'MATERIAL' ) ).
cl_abap_unit_assert=>assert_equals(
exp = `1000`
act = text_of( ir_data = lr_data iv_row = 1 iv_col = 'PLANT' ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}move-quantity( 200 )
act = qty_of( ir_data = lr_data iv_row = 1 ) ).
ENDMETHOD.
METHOD date_from_filter.
DATA(lr_data) = run( iv_from = '20260201' iv_to = '20261231' ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals(
exp = `MAT-002`
act = text_of( ir_data = lr_data iv_row = 1 iv_col = 'MATERIAL' ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}move-quantity( 200 )
act = qty_of( ir_data = lr_data iv_row = 1 ) ).
ENDMETHOD.
METHOD date_to_filter.
DATA(lr_data) = run( iv_from = '20260101' iv_to = '20260131' ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}move-quantity( -15 )
act = qty_of( ir_data = lr_data iv_row = 3 ) ).
ENDMETHOD.
METHOD no_matching_data.
cl_abap_unit_assert=>assert_equals(
exp = 0
act = lines_of( run( iv_from = '20270101' iv_to = '20271231' ) ) ).
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,14 @@
@EndUserText.label : 'Stock movements'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}move {
key client : abap.clnt not null;
key mov_id : abap.int4 not null;
material : abap.char(10);
plant : abap.char(4);
move_date : abap.dats;
move_type : abap.char(2);
quantity : abap.dec(15,3);
}

View File

@@ -0,0 +1,20 @@
CLASS {{p}}seed_move DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS {{p}}seed_move IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DELETE FROM {{p}}move.
INSERT {{p}}move FROM TABLE @( 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 = '20260120' move_type = 'GR' quantity = '50.000' )
( mov_id = 3 material = 'MAT-001' plant = '1000' move_date = '20260115' move_type = 'GI' quantity = '30.000' )
( mov_id = 4 material = 'MAT-001' plant = '2000' move_date = '20260112' move_type = 'GI' quantity = '40.000' )
( mov_id = 5 material = 'MAT-002' plant = '1000' move_date = '20260201' move_type = 'GR' quantity = '200.000' )
( mov_id = 6 material = 'MAT-002' plant = '2000' move_date = '20260115' move_type = 'GR' quantity = '10.000' )
( mov_id = 7 material = 'MAT-002' plant = '2000' move_date = '20260116' move_type = 'GI' quantity = '25.000' )
( mov_id = 8 material = 'MAT-003' plant = '1000' move_date = '20251231' move_type = 'GR' quantity = '500.000' ) ) ).
out->write( sy-dbcnt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,82 @@
REPORT {{p}}stock_net.
TYPES: BEGIN OF ty_key,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
END OF ty_key,
BEGIN OF ty_out,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
net_qty TYPE {{p}}move-quantity,
move_count TYPE i,
END OF ty_out.
DATA: gv_matnr TYPE {{p}}move-material,
gv_from TYPE d,
gv_to TYPE d,
gv_gr TYPE {{p}}move-quantity,
gv_gi TYPE {{p}}move-quantity,
gv_cnt TYPE i,
gs_key TYPE ty_key,
gs_out TYPE ty_out,
gt_keys TYPE STANDARD TABLE OF ty_key,
gt_out TYPE STANDARD TABLE OF ty_out,
go_alv TYPE REF TO cl_salv_table,
gx_msg TYPE REF TO cx_salv_msg.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_matnr FOR gv_matnr.
START-OF-SELECTION.
gv_from = p_from.
gv_to = p_to.
SELECT DISTINCT material, plant
FROM {{p}}move
INTO TABLE gt_keys
WHERE move_date >= gv_from
AND move_date <= gv_to
AND material IN s_matnr
ORDER BY material, plant.
LOOP AT gt_keys INTO gs_key.
CLEAR: gv_gr, gv_gi, gv_cnt, gs_out.
SELECT SUM( quantity ) FROM {{p}}move INTO gv_gr
WHERE material = gs_key-material
AND plant = gs_key-plant
AND move_type = 'GR'
AND move_date >= gv_from
AND move_date <= gv_to.
SELECT SUM( quantity ) FROM {{p}}move INTO gv_gi
WHERE material = gs_key-material
AND plant = gs_key-plant
AND move_type = 'GI'
AND move_date >= gv_from
AND move_date <= gv_to.
SELECT COUNT(*) FROM {{p}}move INTO gv_cnt
WHERE material = gs_key-material
AND plant = gs_key-plant
AND move_date >= gv_from
AND move_date <= gv_to.
gs_out-material = gs_key-material.
gs_out-plant = gs_key-plant.
gs_out-net_qty = gv_gr - gv_gi.
gs_out-move_count = gv_cnt.
APPEND gs_out TO gt_out.
ENDLOOP.
TRY.
CALL METHOD cl_salv_table=>factory
IMPORTING
r_salv_table = go_alv
CHANGING
t_table = gt_out.
CALL METHOD go_alv->display.
CATCH cx_salv_msg INTO gx_msg.
MESSAGE gx_msg TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.

View File

@@ -0,0 +1,82 @@
REPORT {{p}}stock_net_old.
TYPES: BEGIN OF ty_key,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
END OF ty_key,
BEGIN OF ty_out,
material TYPE {{p}}move-material,
plant TYPE {{p}}move-plant,
net_qty TYPE {{p}}move-quantity,
move_count TYPE i,
END OF ty_out.
DATA: gv_matnr TYPE {{p}}move-material,
gv_from TYPE d,
gv_to TYPE d,
gv_gr TYPE {{p}}move-quantity,
gv_gi TYPE {{p}}move-quantity,
gv_cnt TYPE i,
gs_key TYPE ty_key,
gs_out TYPE ty_out,
gt_keys TYPE STANDARD TABLE OF ty_key,
gt_out TYPE STANDARD TABLE OF ty_out,
go_alv TYPE REF TO cl_salv_table,
gx_msg TYPE REF TO cx_salv_msg.
PARAMETERS: p_from TYPE d OBLIGATORY,
p_to TYPE d OBLIGATORY.
SELECT-OPTIONS: s_matnr FOR gv_matnr.
START-OF-SELECTION.
gv_from = p_from.
gv_to = p_to.
SELECT DISTINCT material plant
FROM {{p}}move
INTO TABLE gt_keys
WHERE move_date >= gv_from
AND move_date <= gv_to
AND material IN s_matnr.
SORT gt_keys BY material plant.
LOOP AT gt_keys INTO gs_key.
CLEAR: gv_gr, gv_gi, gv_cnt, gs_out.
SELECT SUM( quantity ) FROM {{p}}move INTO gv_gr
WHERE material = gs_key-material
AND plant = gs_key-plant
AND move_type = 'GR'
AND move_date >= gv_from
AND move_date <= gv_to.
SELECT SUM( quantity ) FROM {{p}}move INTO gv_gi
WHERE material = gs_key-material
AND plant = gs_key-plant
AND move_type = 'GI'
AND move_date >= gv_from
AND move_date <= gv_to.
SELECT COUNT(*) FROM {{p}}move INTO gv_cnt
WHERE material = gs_key-material
AND plant = gs_key-plant
AND move_date >= gv_from
AND move_date <= gv_to.
gs_out-material = gs_key-material.
gs_out-plant = gs_key-plant.
gs_out-net_qty = gv_gr - gv_gi.
gs_out-move_count = gv_cnt.
APPEND gs_out TO gt_out.
ENDLOOP.
TRY.
CALL METHOD cl_salv_table=>factory
IMPORTING
r_salv_table = go_alv
CHANGING
t_table = gt_out.
CALL METHOD go_alv->display.
CATCH cx_salv_msg INTO gx_msg.
MESSAGE gx_msg TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.

View File

@@ -0,0 +1,56 @@
# 1. Goal
The program {{P}}STOCK_NET_OLD is a legacy report. It shows the net stock
quantity for each material and plant in a period. The report is slow and hard
to read. Write the program {{P}}STOCK_NET. The new program has the same
selection screen and the same result as the legacy report, but the code is
clean and the movements are read with one database access.
# 2. Open questions
None.
# 3. Context
- The table {{P}}MOVE exists in package $TMP and contains data. Fields:
- MOV_ID (INT4, key): the movement number.
- MATERIAL (CHAR 10): the material number.
- PLANT (CHAR 4): the plant.
- MOVE_DATE (DATS): the movement date.
- MOVE_TYPE (CHAR 2): 'GR' for a goods receipt, 'GI' for a goods issue.
- QUANTITY (DEC 15,3): the movement quantity.
- The program {{P}}STOCK_NET_OLD exists in package $TMP. It is legacy code. It
gives the correct result.
- The class {{P}}SEED_MOVE fills the table {{P}}MOVE with data.
# 4. Contract
- Create the executable program {{P}}STOCK_NET in package $TMP.
- Selection screen:
- Parameter P_FROM, type DATS, mandatory: the first movement date to include.
- Parameter P_TO, type DATS, mandatory: the last movement date to include.
- Select-option S_MATNR for the material number.
- Show the result with CL_SALV_TABLE. The output table has these columns with
these names: MATERIAL, PLANT, NET_QTY, MOVE_COUNT.
# 5. Business rules
1. Include a movement only if MOVE_DATE is on or after P_FROM, MOVE_DATE is on
or before P_TO, and MATERIAL is in S_MATNR.
2. Group the included movements by MATERIAL and PLANT.
3. NET_QTY is the sum of QUANTITY of all included goods receipts in the group
minus the sum of QUANTITY of all included goods issues in the group.
4. MOVE_COUNT is the number of included movements in the group.
5. Show one line for each material and plant that has at least one included
movement.
6. Sort the lines by MATERIAL in ascending order and by PLANT in ascending
order.
7. The result of {{P}}STOCK_NET is the same as the result of
{{P}}STOCK_NET_OLD.
# 6. Constraints
- Release target: 8.16.
- Coding standards: Clean ABAP. Methods have less than 40 statements. Read the
movements with one database access. Do not use obsolete statements.
- Out of scope: do not change the table {{P}}MOVE, the class {{P}}SEED_MOVE and
the program {{P}}STOCK_NET_OLD.
# 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,70 @@
{
"id": "G0016",
"category": "E",
"object_type": "PROG",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 40,
"max_activations": 12
},
"seed": [
{
"type": "TABL",
"name": "{{P}}MOVE",
"file": "seed/move.tabl.asabap",
"description": "Stock movements"
},
{
"type": "CLAS",
"name": "{{P}}SEED_MOVE",
"file": "seed/seed_move.clas.abap",
"description": "Stock movement seed data",
"run": true
},
{
"type": "PROG",
"name": "{{P}}STOCK_NET_OLD",
"file": "seed/stock_net_old.prog.abap",
"description": "Legacy net stock report"
}
],
"contract": [
{
"type": "PROG",
"name": "{{P}}STOCK_NET",
"parameters": [
"p_from",
"p_to",
"s_matnr"
]
}
],
"out_of_scope": [
"{{P}}MOVE",
"{{P}}SEED_MOVE",
"{{P}}STOCK_NET_OLD"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T15_HIDDEN",
"file": "hidden/t15_hidden.clas.abap",
"description": "T15 hidden tests"
}
],
"reference": [
{
"type": "PROG",
"name": "{{P}}STOCK_NET",
"file": "reference/stock_net.prog.abap",
"description": "Refactored net stock report"
}
],
"craft_checks": [
"db_operation_in_loop",
"method_length",
"obsolete_statements"
]
}