Enterprise Resource Planning Blogs by Members
Gain new perspectives and knowledge about enterprise resource planning in blog posts from community members. Share your own comments and ERP insights today!
cancel
Showing results for 
Search instead for 
Did you mean: 
Sandra_Rossi
Active Contributor
2,293
This is just an executable program to help developers quickly duplicate an existing reservation (transaction codes MB21, MB22, MB23), and see how parameters are filled. Just used it in ECC 6.0.

EDIT: the code is proposed in this GitHub repository. If you want to improve the code below, please contribute in GitHub.

EDIT: by default the custom fields are not considered (EXTENSIONOUT and EXTENSIONIN), I have added a chapter at the end to explain how to consider them.
REPORT zbapi_reservation_copy.

PARAMETERS p_rsnum TYPE rkpf-rsnum.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_rsnum.
CALL FUNCTION 'MB_SELECT_RESERVATION'
EXPORTING
hilfe = 'HLPR'
IMPORTING
rsnum = p_rsnum.

START-OF-SELECTION.

DATA: sl_header_detail TYPE bapi2093_res_head_detail,
tl_postes_detail TYPE TABLE OF bapi2093_res_item_detail,
tl_return TYPE TABLE OF bapiret2,
tl_extensionout TYPE TABLE OF bapiparex.

CALL FUNCTION 'BAPI_RESERVATION_GETDETAIL1'
EXPORTING
reservation = p_rsnum
IMPORTING
reservation_header = sl_header_detail
TABLES
reservation_items = tl_postes_detail
return = tl_return
extensionout = tl_extensionout.

IF 0 = REDUCE i( INIT i = 0 FOR <m> IN tl_return WHERE ( type CA 'AEX' ) NEXT i = i + 1 ).

DATA: sl_header TYPE bapi2093_res_head,
tl_postes TYPE TABLE OF bapi2093_res_item,
tl_segments TYPE TABLE OF bapi_profitability_segment,
tl_extensionin TYPE TABLE OF bapiparex,
vl_reservation TYPE bapi2093_res_key-reserv_no.

sl_header = CORRESPONDING #( sl_header_detail ).
tl_postes = CORRESPONDING #( tl_postes_detail MAPPING entry_qnt = quantity ).
tl_extensionin = tl_extensionout.
CALL FUNCTION 'BAPI_RESERVATION_CREATE1'
EXPORTING
reservationheader = sl_header
IMPORTING
reservation = vl_reservation
TABLES
reservationitems = tl_postes
profitabilitysegment = tl_segments " <======= ?
return = tl_return
extensionin = tl_extensionin.
IF 0 = REDUCE i( INIT i = 0 FOR <m> IN tl_return WHERE ( type CA 'AEX' ) NEXT i = i + 1 ).

DATA: sl_return TYPE bapiret2.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'
IMPORTING
return = sl_return.

ENDIF.
ENDIF.

DATA(result) = COND string( WHEN 0 = REDUCE i( INIT i = 0 FOR <m> IN tl_return WHERE ( type CA 'AEX' ) NEXT i = i + 1 )
THEN |Created: { vl_reservation }|
ELSE 'Failed' ).

cl_demo_output=>new( )->write_data( result )->write_data( tl_return )->write_data( sl_return )->display( ).

 

Custom fields (EXTENSIONOUT and EXTENSIONIN)


I'm talking about the custom fields you may add in the tables RKPF and RESB.

So that BAPI_RESERVATION_GETDETAIL1 returns the custom fields, I think that the BAdI MB_RES_BAPI_DETAIL1 was planned to implement that, but it doesn't work in my ECC version, so I did an enhancement at the end of BAPI_RESERVATION_GETDETAIL1.

So that BAPI_RESERVATION_CREATE1 transfers the custom fields to the table, you must implement the BAdI MB_RES_BAPI_CREATE1.

The code below requires that you create the DDIC structures ZBAPI_TE_RKPF and ZBAPI_TE_RESB, with the custom columns that you have defined in the tables RKPF and RESB, and they should have the same names.

Be careful, when calling BAPI_RESERVATION_CREATE1, the sequence of the lines "ZBAPI_TE_RESB" in EXTENSIONIN must be the same as the sequence of the lines in RESERVATIONITEMS, it's the only criteria I could find to make the match (RSPOS field is missing in RESERVATIONITEMS).

You can adapt the code if you want to work only with either RKPF or RESB.

Code at the end of BAPI_RESERVATION_GETDETAIL1:
TYPES: BEGIN OF zz_ty_valueparts,
structure TYPE te_struc,
BEGIN OF parts,
_1 TYPE valuepart,
_2 TYPE valuepart,
_3 TYPE valuepart,
_4 TYPE valuepart,
END OF parts,
END OF zz_ty_valueparts.
DATA: zz_zbapi_te_rkpf TYPE zbapi_te_rkpf,
zz_table_zbapi_te_resb TYPE TABLE OF zbapi_te_resb.

SELECT SINGLE *
FROM rkpf
WHERE rsnum = @reservation
INTO CORRESPONDING FIELDS OF @zz_zbapi_te_rkpf.
IF sy-subrc = 0.
" ORDER BY is used to make "ZBAPI_TE_RESB" lines in EXTENSIONOUT ordered as
" RESERVATION_ITEMS lines, so that it's aligned with BAPI_RESERVATION_CREATE1 whose lines
" "ZBAPI_TE_RESB" of EXTENSIONIN and RESERVATIONITEMS must respect the same logic.
SELECT *
FROM resb
WHERE rsnum = @reservation
ORDER BY PRIMARY KEY
INTO CORRESPONDING FIELDS OF TABLE @zz_table_zbapi_te_resb.
IF sy-subrc = 0.
extensionout[] = VALUE #(
( CONV #( VALUE zz_ty_valueparts(
structure = 'ZBAPI_TE_RKPF'
parts = CONV #( CORRESPONDING zbapi_te_rkpf( zz_zbapi_te_rkpf ) ) ) ) )
( LINES OF VALUE bapiparextab(
FOR <zz_zbapi_te_resb> IN zz_table_zbapi_te_resb
( CONV #( VALUE zz_ty_valueparts(
structure = 'ZBAPI_TE_RESB'
parts = CONV #( CORRESPONDING zbapi_te_resb( <zz_zbapi_te_resb> ) ) ) ) ) ) ) ).
ENDIF.
ENDIF.

Implement the method EXTENSIONIN_TO_RESB of BAdI MB_RES_BAPI_CREATE1 with this code:
TYPES: BEGIN OF zz_ty_valueparts,
structure TYPE te_struc,
BEGIN OF parts,
_1 TYPE valuepart,
_2 TYPE valuepart,
_3 TYPE valuepart,
_4 TYPE valuepart,
END OF parts,
END OF zz_ty_valueparts.
DATA(resb_index) = 0.
LOOP AT it_extension_in ASSIGNING FIELD-SYMBOL(<extensionin>).
CASE <extensionin>-structure.
WHEN 'ZBAPI_TE_RKPF'.
DATA(zbapi_te_rkpf) = CONV zbapi_te_rkpf( LET aux_valueparts = CONV zz_ty_valueparts( <extensionin> ) IN aux_valueparts-parts ).
MOVE-CORRESPONDING zbapi_te_rkpf TO cs_rkpf.
WHEN 'ZBAPI_TE_RESB'.
DATA(zbapi_te_resb) = CONV zbapi_te_resb( LET aux_valueparts = CONV zz_ty_valueparts( <extensionin> ) IN aux_valueparts-parts ).
ADD 1 TO resb_index.
ASSIGN resb[ resb_index ] TO FIELD-SYMBOL(<resb>).
IF sy-subrc = 0.
MOVE-CORRESPONDING zbapi_te_resb TO <resb>.
ENDIF.
ENDCASE.
ENDLOOP.

 
9 Comments
Labels in this area