on 2021 Oct 05 1:34 PM
Hi Experts,
I have done my first RAP implementation which is an unmanaged implementation and the service is responsible to update Business Partner Name and Address data. I want to send, a message back upon successful update or failed. I am able to do the same using the structures "mapped" for success and "reported" for failure from within the FINALIZE( ) method for BAPI_BUPA_CENTRAL_CHANGE. However while trying to update the Address using BAPI_BUPA_ADDRESS_CHANGE, it gives a dump like following,
-------------------------------------------------------------------------------------------------------------------------------------------------------------
BEHAVIOR_ILLEGAL_STATEMENT
Short Text
Statement "CALL FUNCTION .. IN UPDATE TASK" is not allowed with this status.
There is probably an error in the program "SAPLSZA0". A BEHAVIOR implementation is active for "ZC_UPD_BP_FROM_XXX". While this is the case, the following ABAP statements are illegal:
The following statement is only allowed in the "Save” phase: - CALL FUNCTION IN UPDATE TASK Quitting the BEHAVIOR implementation with RAISE EXCEPTION is illegal.
-------------------------------------------------------------------------------------------------------------------------------------------------------------
However the same doesn't happen if the implementation is done within SAVE( ) method. But, save( ) doesn't have parameters to send back any message.
Request for your support in resolving this issue and help me knowing how can I send back a message either using save( ) or avoid the dump using finalize( ).
Interface View:
@AbapCatalog.sqlViewName: 'ZI_XXX_UPD_BP'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Int. view to update BP data'
@VDM.viewType: #BASIC
define view zi_upd_bp_from_xxx
as select from but000
left outer join but020 on but000.partner = but020.partner
left outer join adrc on but020.addrnumber = adrc.addrnumber
{
key but000.partner as bpNum,
key but000.type as bpType,
but000.partner_guid as bpGuid,
adrc.addrnumber as addressNo,
but000.title as title,
but000.name_last as lastName,
but000.name_first as firstName,
but000.name_org1 as nameI,
but000.name_org2 as nameII,
but000.name_org3 as nameIII,
adrc.city1 as city,
adrc.street as street,
adrc.country as country,
adrc.post_code1 as postalCode,
adrc.house_num1 as houseNumber
}
where
adrc.nation is initial
Consumption View:
@AbapCatalog.sqlViewName: 'ZC_XXX_UPD_BP'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Cons. view to update BP data'
define root view ZC_UPD_BP_FROM_XXX
as select from zi_upd_bp_from_xxx
{
key bpNum,
bpType,
bpGuid,
addressNo,
title,
lastName,
firstName,
nameI,
nameII,
nameIII,
nameAffix,
academicTitle1,
academicTitle2,
city,
street,
country,
postalCode,
houseNumber
}
Behavior Definition:
unmanaged implementation in class zcl_upd_bp_from_xxx unique;
define behavior for ZC_UPD_BP_FROM_XXX alias XxxUpdBP
//late numbering
//lock master
//authorization master
//etag <field_name>
{
field ( mandatory ) bpNum, bpType;
update;
}
Service Definition:
@EndUserText.label: 'Service Definition to update BP'
define service ZUI_XXX_UPD_BP {
expose ZC_UPD_BP_FROM_XXX;
}
Behavior Implementation:
CLASS lcl_buffer DEFINITION .
PUBLIC SECTION .
TYPES: BEGIN OF tys_control,
cid TYPE abp_behv_cid,
msg TYPE REF TO if_abap_behv_message,
END OF tys_control .
CLASS-DATA gs_buffer TYPE zc_upd_bp_from_xxx .
CLASS-DATA gs_control TYPE tys_control .
ENDCLASS.
CLASS lcl_XxxUpdBP DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS update FOR MODIFY
IMPORTING entities FOR UPDATE XXXUpdBP.
METHODS read FOR READ
IMPORTING keys FOR READ XXXUpdBP RESULT result.
ENDCLASS.
CLASS lcl_xxxUpdBP IMPLEMENTATION.
METHOD update.
ENDMETHOD.
METHOD read.
ENDMETHOD.
ENDCLASS.
CLASS lcl_ZC_UPD_BP_FROM_XXX DEFINITION INHERITING FROM cl_abap_behavior_saver.
PROTECTED SECTION.
METHODS check_before_save REDEFINITION.
METHODS finalize REDEFINITION.
METHODS save REDEFINITION.
METHODS fill_address
IMPORTING !is_entities TYPE zc_upd_bp_from_xxx
EXPORTING !es_address TYPE bapibus1006_address .
METHODS fill_address
IMPORTING !is_entities TYPE zc_upd_bp_from_xxx
EXPORTING !es_address TYPE bapibus1006_address .
METHODS gt_bp_data
IMPORTING !iv_partner TYPE bu_partner
EXPORTING !ev_bptype TYPE bu_type
!ev_bpguid TYPE bu_partner_guid
!ev_bpadrnr TYPE ad_addrnum
!ev_bpaddrguid TYPE ad_uuid .
METHODS call_bapi
IMPORTING
!is_buffer TYPE zc_upd_bp_from_xxx .
ENDCLASS.
CLASS lcl_ZC_UPD_BP_FROM_XXX IMPLEMENTATION.
METHOD check_before_save.
ENDMETHOD.
METHOD finalize.
me->call_bapi( EXPORTING is_buffer = lcl_buffer=>gs_buffer ) .
** DATA ls_message TYPE symsg.
** DATA: li_mapper_symsg TYPE REF TO if_rap_plmi_sy_msg_convert,
** li_message_behv TYPE REF TO if_abap_behv_message.
*
** ls_message = VALUE #( msgid = ' ' msgty = 'E' msgno = ' ' msgv1 = ' ' ).
** CALL METHOD li_mapper_symsg->map_symsg_to_behv_message
** EXPORTING
** is_message_symsg = ls_message
** RECEIVING
** ro_message_behv = li_message_behv.
** INSERT VALUE #( %msg = li_message_behv bpnum = '2200000045' ) INTO TABLE reported-xxxupdbp.
ENDMETHOD.
METHOD save.
ENDMETHOD.
METHOD fill_address .
es_address-city = is_entities-city .
es_address-room_no = is_entities-room .
es_address-floor = is_entities-floor .
es_address-po_box = is_entities-poBox .
es_address-c_o_name = is_entities-coName .
es_address-region = is_entities-region .
es_address-street = is_entities-street .
es_address-location = is_entities-co2Name .
es_address-country = is_entities-country .
es_address-po_w_o_no = is_entities-poWoNum .
es_address-str_suppl1 = is_entities-street2 .
es_address-str_suppl3 = is_entities-street4 .
es_address-building = is_entities-building .
es_address-district = is_entities-district .
es_address-postl_cod1 = is_entities-postalCode .
es_address-house_no = is_entities-houseNumber .
es_address-postl_cod2 = is_entities-poBoxPostalCode .
es_address-house_no2 = is_entities-houseNumberSuppl .
es_address-postl_cod3 = is_entities-companyPostalCode .
es_address-dont_use_p = is_entities-unDeliverablePoBox .
es_address-dont_use_s = is_entities-unDeliverableStreet .
ENDMETHOD .
METHOD call_bapi.
DATA: ls_address TYPE bapibus1006_address,
ls_entities TYPE zc_upd_bp_from_xxx.
ls_entities = CORRESPONDING #( lcl_buffer=>gs_buffer ) .
me->fill_address( EXPORTING is_entities = ls_entities IMPORTING es_address = ls_address ) .
DATA(lo_execute) = NEW zcl_rap_crud_operation( ) .
DATA(lt_ret) = lo_execute->change( EXPORTING iv_partner = lcl_buffer=>gs_buffer-bpNum
iv_adrnrguid = lv_addrguid
is_address = ls_address ) .
ENDMETHOD.
CLASS zcl_rap_crud_operation DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES: tyt_person TYPE bapibus1006_central_person,
tyt_organisation TYPE bapibus1006_central_organ,
tyt_telephone TYPE bapibus1006_adtel_tty,
tyt_smtp TYPE bapibus1006_adsmtp_tty,
BEGIN OF tys_central,
person TYPE tyt_person,
organisation TYPE tyt_organisation,
END OF tys_central,
tyt_central TYPE TABLE OF tys_central WITH EMPTY KEY,
BEGIN OF tys_comm,
telephone TYPE tyt_telephone,
smtp TYPE tyt_smtp,
END OF tys_comm,
tyt_comm TYPE TABLE OF tys_comm WITH EMPTY KEY.
METHODS:
constructor,
change
IMPORTING
!iv_partner TYPE bu_partner
!iv_adrnrguid TYPE ad_uuid OPTIONAL
!is_central TYPE bapibus1006_central OPTIONAL
!is_name TYPE tyt_central OPTIONAL
!is_address TYPE bapibus1006_address OPTIONAL
!it_comm TYPE tyt_comm OPTIONAL
RETURNING VALUE(rt_return) TYPE bapiret2_t.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_rap_crud_operation IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD change.
DATA: lt_persaddr TYPE bapiad1vd_t,
lt_persaddr_x TYPE bapiad1vdx_t,
lt_orgaddr TYPE bapiad2vd_t,
lt_orgaddr_x TYPE bapiad2vdx_t,
ls_address_x TYPE bapibus1006_address_x,
ls_org TYPE bapibus1006_central_organ,
ls_pers TYPE bapibus1006_central_person,
ls_org_x TYPE bapibus1006_central_organ_x,
ls_pers_x TYPE bapibus1006_central_person_x,
lt_return TYPE bapiret2_t.
CLEAR: ls_org, ls_org_x, ls_pers, ls_pers_x, lt_return .
IF NOT is_name IS INITIAL .
IF NOT is_name[ 1 ]-organisation IS INITIAL .
ls_org-name1 = is_name[ 1 ]-organisation-name1 .
ls_org-name2 = is_name[ 1 ]-organisation-name2 .
ls_org-name3 = is_name[ 1 ]-organisation-name3 .
ls_org_x-name1 = COND #( WHEN is_name[ 1 ]-organisation-name1 IS NOT INITIAL THEN abap_true ELSE abap_false ) .
ls_org_x-name2 = COND #( WHEN is_name[ 1 ]-organisation-name2 IS NOT INITIAL THEN abap_true ELSE abap_false ) .
ls_org_x-name3 = COND #( WHEN is_name[ 1 ]-organisation-name3 IS NOT INITIAL THEN abap_true ELSE abap_false ) .
ELSEIF NOT is_name[ 1 ]-person IS INITIAL .
ls_pers-firstname = is_name[ 1 ]-person-firstname .
ls_pers-lastname = is_name[ 1 ]-person-lastname .
ls_pers_x-firstname = COND #( WHEN is_name[ 1 ]-person-firstname IS NOT INITIAL THEN abap_true ELSE abap_false ) .
ls_pers_x-lastname = COND #( WHEN is_name[ 1 ]-person-lastname IS NOT INITIAL THEN abap_true ELSE abap_false ) .
ENDIF.
CALL FUNCTION 'BAPI_BUPA_CENTRAL_CHANGE'
EXPORTING
businesspartner = iv_partner
centraldata = is_central
centraldataperson = ls_pers
centraldataorganization = ls_org
centraldataperson_x = ls_pers_x
centraldataorganization_x = ls_org_x
valid_date = sy-datlo
TABLES
return = rt_return.
IF rt_return IS INITIAL .
ENDIF.
ENDIF.
IF NOT is_address IS INITIAL .
ls_address_x-city = COND #( WHEN is_address-city IS NOT INITIAL THEN abap_true ELSE abap_false ) .
ls_address_x-street = COND #( WHEN is_address-street IS NOT INITIAL THEN abap_true ELSE abap_false ) .
ls_address_x-postl_cod1 = COND #( WHEN is_address-postl_cod1 IS NOT INITIAL THEN abap_true ELSE abap_false ) .
ls_address_x-country = COND #( WHEN is_address-country IS NOT INITIAL THEN abap_true ELSE abap_false ) .
ls_address_x-house_no = COND #( WHEN is_address-house_no IS NOT INITIAL THEN abap_true ELSE abap_false ) .
CALL FUNCTION 'BAPI_BUPA_ADDRESS_CHANGE'
EXPORTING
businesspartner = iv_partner
addressdata = is_address
addressdata_x = ls_address_x
TABLES
return = rt_return.
IF NOT line_exists( rt_return[ type = 'E' ] ) OR NOT line_exists( rt_return[ type = 'A' ] ) .
ENDIF.
ENDIF.
ENDMETHOD.
JSON URL: /sap/opu/odata/sap/ZUI_XXX_UPD_BP/ZC_UPD_BP_FROM_XXX
JSON Payload:
{
"d": {
"results": [
{
"bpNum": "11",
"bpType": "1",
"bpGuid": "xxxx-xxxx-xxxx-xxxx-xxxx",
"addressNo": "xxxx",
"title": "",
"lastName": "Banerjee",
"firstName": "Shubham",
"nameI": "",
"nameII": "",
"nameIII": "",
"nameAffix": "",
"academicTitle1": "",
"academicTitle2": "",
"city": "Berlin",
"street": "Straße",
"country": "DE",
"postalCode": "10000",
"houseNumber": "19",
} ]
}
Thanks in advance.
Request clarification before answering.
Hi Shubham,
the problem seems to be the BAPI BAPI_BUPA_ADDRESS_CHANGE since it seems to register a Save via Update Task.
During the Finalize / Check_before_save phases it is only allowed to run code that does something similar as a validation or a determination.
Persisting data to the database in this early part of the SAVE sequence is not allowed.
Using a workaround such as trying to call the BAPI via an RFC destination is NOT recommended since it could cause inconsistencies in your data.
See also our documentation:
Saver Classes - SAP Help Portal
So you would have to try to develop code that would check if the data can be updated successfully (a validation). If the validation is successful you could call the above mentioned BAPI in the method save( ).
If such validations can be built and if you would be able to build appropriate CDS views to read the data it might be an option to try out to build a managed app with unmanaged save. Because then you would be able to perform validations and determinations and would only use your legacy API to persist the data for which the consistency has been checked beforehand.
Kind regards,
Andre
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 29 | |
| 14 | |
| 14 | |
| 6 | |
| 5 | |
| 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.