on 2024 Apr 10 11:58 AM
Hello everyone,
we are currently in process of setting up new SAP S/4HANA 2023 SP1 as greenfield on premise. We are moving there from old ECC system. In previous system we used MB_RESERVATION_BADI to do checks when manual reservations are created/changed using MB21/MB22 transactions.
We see that this BADI is still present in S/4 system and can be used for MB* transactions. However there is also now available Fiori applicaton F4839 "Manage Manual Reservations" that allows user to create reservations manually. As our main intent is to shift to Fiori usage as much as possbile we would like to use the Fiori application for business users. Unfortunatelly when creating reservations via the Fiori app BADI that is called for MB* transactions is not executed.
Could anyone help us to resolve the issue? Is there any other BADI to be used. We did not find any. And we would like to avoid to have a difference between SAPGUI and Fiori behavior for same process.
Thank you very much.
Request clarification before answering.
For anyone dealing with this problem we managed to solved it in following way using new RAP objects. By using Eclipse ADT tools:
We have found out that Manual Reservations Fiori applications is using entity R_ReservationDocumentHeaderTP. This entity has in its behavior definition on our release enabled extension for validations and determinations.
Therefore we have created our own Behavior Definition extension:
extension implementation in class /XXX/bp_mmim_r_reservation unique;
extend behavior for ReservationDocHeader
{
validation /XXX/mmimValidateHeaderBAPI on save { field GoodsRecipientName; }
extend draft determine action Prepare {
validation /XXX/mmimValidateHeaderBAPI;
validation ReservationDocItem~/XXX/mmimValidateItemBAPI;
}
}
extend behavior for ReservationDocItem
{
validation /XXX/mmimValidateItemBAPI on save { create; update; }
determination /XXX/mmimDetermineItemBAPI on modify { field plant; field product; }
}We have created three methods:
Implementation of reservation header validation: The method simply call same method that we call in MB_RESERVATION_BADI->DATA_CHECK. In our situation we have our validation functionality enveloped in custom BADI so we can filter validations by WERKS but BADI in this implementation can be ommited and any method/FM can be called here.
LV_ERROR_ELEMENT is string defining which FIORI UI field should indicate error. Names of fields are taken from entity R_ReservationDocumentHeaderTP (i.e. "GoodsRecipientName")
METHOD /xxx/mmimvalidateheaderbapi.
DATA:
lo_reservation_badi TYPE REF TO /xxx/mmim_reservation_badi_def,
lt_changable TYPE tdtab_c132,
ls_resb TYPE resb,
ls_rkpf TYPE rkpf,
lv_error_element TYPE string.
READ ENTITIES OF r_reservationdocumentheadertp IN LOCAL MODE ##EML_READ_IN_LOCAL_MODE_OK
ENTITY reservationdocheader
FIELDS ( goodsrecipientname resvnverificationcompanycode ) WITH CORRESPONDING #( keys )
RESULT DATA(lt_reservations).
LOOP AT lt_reservations INTO DATA(ls_reservation).
APPEND VALUE #( %tky = ls_reservation-%tky
%state_area = 'VALIDATE_WEMPF' ) TO reported-reservationdocheader.
GET BADI lo_reservation_badi FILTERS werks = ls_reservation-resvnverificationcompanycode lgort = ''.
ls_rkpf-wempf = ls_reservation-goodsrecipientname.
CALL BADI lo_reservation_badi->data_check
EXPORTING
is_rkpf = ls_rkpf
CHANGING
cv_bo_entity_error_field = lv_error_element
EXCEPTIONS
external_message = 1.
IF sy-subrc <> 0.
IF lv_error_element IS NOT INITIAL.
APPEND VALUE #( %tky = ls_reservation-%tky
%state_area = 'VALIDATE_WEMPF'
%msg = new_message( id = sy-msgid number = sy-msgno severity = if_abap_behv_message=>severity-error v1 = sy-msgv1 v2 = sy-msgv2 v3 = sy-msgv3 v4 = sy-msgv4 )
) TO reported-reservationdocheader ASSIGNING FIELD-SYMBOL(<ls_reservationdocheader>).
ASSIGN COMPONENT lv_error_element OF STRUCTURE <ls_reservationdocheader>-%element TO FIELD-SYMBOL(<lv_behv>).
IF sy-subrc = 0.
<lv_behv> = if_abap_behv=>mk-on.
ENDIF.
ELSE.
APPEND VALUE #( %tky = ls_reservation-%tky
%state_area = 'VALIDATE_WEMPF'
%msg = new_message( id = sy-msgid number = sy-msgno severity = if_abap_behv_message=>severity-error v1 = sy-msgv1 v2 = sy-msgv2 v3 = sy-msgv3 v4 = sy-msgv4 )
) TO reported-reservationdocheader.
ENDIF.
ENDIF.
ENDLOOP.
ENDMETHOD.Implementation of reservation item is practiacly same as the one for reservation header. We are calling same code as in MB_RESERVATION_BADI->DATA_CHECK. Again our own custom checks are enveloped in our own BADI for WERKS filtering. And error handling differs if UI element can be pointed out on the screen or no.
METHOD /xxx/mmimvalidateitembapi.
DATA:
lo_reservation_badi TYPE REF TO /xxx/mmim_reservation_badi_def,
lt_changable TYPE tdtab_c132,
ls_resb TYPE resb,
ls_rkpf TYPE rkpf,
lv_error_element TYPE string.
READ ENTITIES OF r_reservationdocumentheadertp IN LOCAL MODE ##EML_READ_IN_LOCAL_MODE_OK
ENTITY reservationdocitem
FIELDS ( reservation
reservationitem
goodsrecipientname
goodsmovementtype
issuingorreceivingplant
reservationitmismarkedfordeltn
resvnitmwithdrawnqtyinbaseunit
resvnitmrequiredqtyinentryunit
baseunit
entryunit
product
plant
storagelocation
unloadingpointname
batch
matlcomprequirementdate )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_res_items)
BY \_reservationdocumentheadertp
FIELDS ( reservation
goodsmovementtype
goodsrecipientname )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_reservation).
LOOP AT lt_res_items INTO DATA(ls_res_item).
APPEND VALUE #( %tky = ls_res_item-%tky
%state_area = 'VALIDATE_ITEM'
%path-reservationdocheader-%is_draft = ls_res_item-%is_draft
%path-reservationdocheader-reservation = ls_res_item-reservation
) TO reported-reservationdocitem.
GET BADI lo_reservation_badi FILTERS werks = ls_res_item-plant lgort = ls_res_item-storagelocation.
ls_rkpf = CORRESPONDING #( lt_reservation[ KEY entity COMPONENTS reservation = ls_res_item-reservation ] MAPPING rsnum = reservation wempf = goodsrecipientname ).
ls_resb = CORRESPONDING #( ls_res_item MAPPING wempf = goodsrecipientname matnr = product bdter = matlcomprequirementdate
lgort = storagelocation werks = plant rsnum = reservation rspos = reservationitem xloek = reservationitmismarkedfordeltn enmng = resvnitmwithdrawnqtyinbaseunit
erfmg = resvnitmrequiredqtyinentryunit meins = baseunit erfme = entryunit ablad = unloadingpointname ).
CALL BADI lo_reservation_badi->data_check
EXPORTING
is_rkpf = ls_rkpf
is_resb = ls_resb
ib_rap_call = abap_true
CHANGING
cv_bo_entity_error_field = lv_error_element
EXCEPTIONS
external_message = 1.
IF sy-subrc <> 0.
IF lv_error_element IS NOT INITIAL .
APPEND VALUE #( %tky = ls_res_item-%tky
%state_area = 'VALIDATE_ITEM'
%msg = new_message( id = sy-msgid number = sy-msgno severity = if_abap_behv_message=>severity-error v1 = sy-msgv1 v2 = sy-msgv2 v3 = sy-msgv3 v4 = sy-msgv4 )
%path-reservationdocheader-%is_draft = ls_res_item-%is_draft
%path-reservationdocheader-reservation = ls_res_item-reservation
) TO reported-reservationdocitem ASSIGNING FIELD-SYMBOL(<ls_reservationdocitem>).
ASSIGN COMPONENT lv_error_element OF STRUCTURE <ls_reservationdocitem>-%element TO FIELD-SYMBOL(<lv_behv>).
IF sy-subrc = 0.
<lv_behv> = if_abap_behv=>mk-on.
ENDIF.
ELSE.
APPEND VALUE #( %tky = ls_res_item-%tky
%state_area = 'VALIDATE_ITEM'
%msg = new_message( id = sy-msgid number = sy-msgno severity = if_abap_behv_message=>severity-error v1 = sy-msgv1 v2 = sy-msgv2 v3 = sy-msgv3 v4 = sy-msgv4 )
%path-reservationdocheader-%is_draft = ls_res_item-%is_draft
%path-reservationdocheader-reservation = ls_res_item-reservation
) TO reported-reservationdocitem.
ENDIF.
ENDIF.
ENDLOOP.
ENDMETHOD.Last method that we implemented was for reservation item determination. Doing the same as we do in MB_RESERVATION_BADI->DATA_MODIFY In this method we are filling value to LGORT based on our custom logic (again enveloped in custom BADI) if it differs from the one on the screen.
METHOD /xxx/mmimdetermineitembapi.
DATA:
lo_reservation_badi TYPE REF TO /xxx/mmim_reservation_badi_def,
lt_reservationdocitem_update TYPE TABLE FOR UPDATE r_reservationdocumentitemtp,
ls_resb TYPE resb.
READ ENTITIES OF r_reservationdocumentheadertp IN LOCAL MODE ##EML_READ_IN_LOCAL_MODE_OK
ENTITY reservationdocitem
FIELDS ( reservation
plant
reservationitem
goodsrecipientname
unloadingpointname
product )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_res_items).
LOOP AT lt_res_items INTO DATA(ls_res_item).
IF ls_res_item-plant IS INITIAL OR ls_res_item-product IS INITIAL.
CONTINUE.
ENDIF.
GET BADI lo_reservation_badi FILTERS werks = ls_res_item-plant lgort = ls_res_item-storagelocation.
ls_resb = CORRESPONDING #( ls_res_item MAPPING matnr = product
lgort = storagelocation werks = plant ).
CALL BADI lo_reservation_badi->data_modify
CHANGING
cs_resb = ls_resb.
IF ls_resb-lgort <> ls_res_item-storagelocation.
APPEND VALUE #( %tky = ls_res_item-%tky storagelocation = ls_resb-lgort ) TO lt_reservationdocitem_update.
ENDIF.
ENDLOOP.
IF lt_reservationdocitem_update IS NOT INITIAL.
MODIFY ENTITIES OF r_reservationdocumentheadertp IN LOCAL MODE
ENTITY reservationdocitem
UPDATE FIELDS ( storagelocation ) WITH lt_reservationdocitem_update
FAILED DATA(ls_failed_modify)
MAPPED DATA(ls_mapped_modify)
REPORTED DATA(ls_reported_modify).
ENDIF.
ENDMETHOD.We have tested it and it works nicely. Therefore we achieved same level of validations and determinations from SAP GUI transaction MB21 and Fiori F4839 for reservations.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 36 | |
| 27 | |
| 21 | |
| 5 | |
| 4 | |
| 4 | |
| 4 | |
| 3 | |
| 3 | |
| 2 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.