Sample ABAP coding for enhancing the Logistics Workplace in NF-e Inbound


This blog will provide a sample coding for the implementation of BAdI Determination of Custom UI for Logistics Workplace for Inbound NF-e’s. You use this BAdI to replace the existing user interface (UI) of the process step Prepare Goods Receipt Posting with a custom Web Dynpro UI.


Implementing the BAdI ‘Determination of Custom UI for Logistics Workplace’


The BAdI uses interface /XNFE/IF_BADI_GET_CUSTOM_UI. The system calls this interface with the GET_CUSTOM_UI method and here you can make known your custom UI component to the NFE Framework. You can determine different UI components depending on the import parameters

  • CNPJ,
  • process type, or
  • process step.


Although we only support one step (Prepare Goods Receipt Posting) at the moment, the process step is import parameter of the BAdI (because maybe in future we support other steps).


The following is an example of this method in the implementing class of the enhancement implementation; let us call our component Z_INBOUND_DELIV:


METHOD /xnfe/if_badi_get_custom_ui~get_custom_ui.
*  use this UI only for process type ‘Normal Purchasing’
IF iv_procstep = ‘GRMMCHCK’ AND iv_proctyp  = ‘NORMPRCH’.
ev_component = ‘Z_INBOUND_DELIV’.
ev_component_window = ‘MAIN’.
ev_component_plug = ‘DEFAULT’.





Enhancing the NF-e Logistics Workplace


On the Logistics Workplace screen you can select a NF-e and choose Execute Process Step > Prepare Goods Receipt Posting, if the NF-e processing status allows it. On the Prepare Goods Receipt Posting screen you can set the status for the NF-e and return to the NF-e Logistics Workplace. With our custom UI (below the Set Status buttons) we want to offer the possibility to change data of the inbound delivery in ERP before setting the status of the step:



Create a new Web Dynpro component


To visualize the data of the inbound delivery from the ERP data base we will use an editable ALV table. The implementation presented here uses a copy of the sample component WDT_FLIGHTLIST_EDIT in package SWDP_DEMO_TUTORIALS as starting point.


To read the delivery data from the ERP data base we use function BAPI_DELIVERY_GETLIST. The relevant output table, which returns the item data of the deliveries, is et_delivery_item with structure BAPIDLVITEM (we use the copy structure INBOUND_DELIV_STY).


To store the delivery data create node NODE_DELIVERY_ITEM based on dictionary structure INBOUND_DELIV_STY in the context of the component controller and choose the fields which you want to show in the ALV table:


Set table editable


Then this ALV is configured to make column Shelf Life Expiration or Best-Before Date (VFDAT) editable. Therefore we need to enhance method WDDOINIT of view ResultView:


METHOD wddoinit .
lo_cmp_usage TYPE REF TO if_wd_component_usage,
lo_interfacecontroller TYPE REF TO iwci_salv_wd_table,
lv_value TYPE REF TO cl_salv_wd_config_table,
lr_column TYPE REF TO cl_salv_wd_column,
lr_column_settings TYPE REF TO if_salv_wd_column_settings,
lr_input_field TYPE REF TO cl_salv_wd_uie_input_field.

lo_cmp_usage =   wd_this->wd_cpuse_alv( ).
IF lo_cmp_usage->has_active_component( ) IS INITIAL.
lo_cmp_usage->create_component( ).
lo_interfacecontroller =   wd_this->wd_cpifc_alv( ).
lv_value = lo_interfacecontroller->get_model( ).
lv_value->if_salv_wd_table_settings~set_read_only( abap_false ).
lv_value->if_salv_wd_table_settings~set_selection_mode( cl_wd_table=>e_selection_mode-none ).
lv_value->if_salv_wd_table_settings~set_visible_row_count( ‘5’ ).
lv_value->if_salv_wd_table_settings~set_fixed_table_layout( abap_true ).
lv_value->if_salv_wd_std_functions~set_pdf_allowed( abap_false ).
lv_value->if_salv_wd_std_functions~set_export_allowed( abap_false ).
lv_value->if_salv_wd_std_functions~set_edit_append_row_allowed( abap_false ).
lv_value->if_salv_wd_std_functions~set_edit_check_available( abap_false ).
lv_value->if_salv_wd_std_functions~set_edit_delete_row_allowed( abap_false ).
lv_value->if_salv_wd_std_functions~set_edit_insert_row_allowed( abap_false ).
lv_value->if_salv_wd_std_functions~set_filter_complex_allowed( abap_false ).
lv_value->if_salv_wd_std_functions~set_filter_filterline_allowed( abap_false ).

lr_column_settings ?= lv_value.
lr_column = lr_column_settings->get_column( ‘VFDAT’ ).
CREATE OBJECT lr_input_field
value_fieldname = ‘VFDAT’.
lr_column->set_cell_editor( lr_input_field ).



Create a method to get the data from ERP


Your custom Web Dynpro component needs to implement the Web Dynpro interface /XNFE/IF_CUSTOM_UI with the 3 methods:

  1. STEP_DATA. This method transfers the step-relevant import parameters
  • IS_INNFEHD – NF-e header,
  • IT_NFEASSIGN – the corresponding assignment table,
  • IV_XML – the XML data

into your custom UI. The method is called by the NFE Framework every time the custom UI is loaded.


We use this method in the component controller to fill node NODE_DELIVERY_ITEM:


METHOD step_data .

BEGIN OF bapidlvbuffercontrol,
bypassing_buffer  TYPE  char1,
head_status TYPE  xfeld,
head_partner  TYPE  xfeld,
item  TYPE  xfeld,
item_status TYPE  xfeld,
doc_flow  TYPE  xfeld,
ft_data TYPE  xfeld,
hu_data TYPE  xfeld,
serno TYPE  xfeld,
END OF bapidlvbuffercontrol,
BEGIN OF bapidlv_range_vbeln,
sign  TYPE  bapisign,
option  TYPE  bapioption,
deliv_numb_low  TYPE  char10,
deliv_numb_high TYPE  char10,
END OF bapidlv_range_vbeln.

lo_nd_node_delivery_item  TYPE REF TO if_wd_context_node,
lt_delivery_item          TYPE TABLE OF inbound_deliv_sty,

ls_range_vbeln            TYPE bapidlv_range_vbeln,
lt_range_vbeln            TYPE TABLE OF bapidlv_range_vbeln,
ls_dlv_data_control       TYPE bapidlvbuffercontrol,
ls_nfeassign              LIKE LINE OF it_nfeassign,
lv_delnumber              TYPE /xnfe/delnum,
lt_return                 TYPE bapiret2_tab,
ls_return                 LIKE LINE OF lt_return.

wd_this->ms_innfehd = is_innfehd.
wd_this->mt_nfeassign = it_nfeassign.
wd_this->mv_xml = iv_xml.
*— Get system for RFC call



iv_logsys     = is_innfehd-logsys


ev_rfcdest    = wd_this->mv_rfcdest


no_dest_found = 1.

IF sy-subrc = 1.




READ TABLE it_nfeassign INTO ls_nfeassign INDEX 1.
IF sy-subrc = 0.
lv_delnumber = ls_nfeassign-delnumber.
ls_dlv_data_control-bypassing_buffer = ‘X’.
ls_dlv_data_control-item = ‘X’.
ls_range_vbeln-sign = ‘I’.
ls_range_vbeln-option = ‘EQ’.
ls_range_vbeln-deliv_numb_low = lv_delnumber.
COLLECT ls_range_vbeln INTO lt_range_vbeln.

* read the delivery data from the data base
is_dlv_data_control   = ls_dlv_data_control
it_vbeln              = lt_range_vbeln

et_delivery_item      = lt_delivery_item
return                = lt_return
communication_failure = 1
system_failure        = 2.
IF lt_return IS NOT INITIAL.
LOOP AT lt_return INTO ls_return
WHERE type EQ ‘E’ OR type EQ ‘A’ OR type EQ ‘X’.

* fill ALV
lo_nd_node_delivery_item = wd_context->get_child_node( name = wd_this->wdctx_node_delivery_item ).
lo_nd_node_delivery_item->bind_table( lt_delivery_item ).



  1. ACTION_BACK_IS_ALLOWED. If you managed to recognize that there are unsaved data on the UI you can enter this status in the return parameter RV_IS_ALLOWED (“Navigation Allowed?”).

But at least you should return True, the worst that can happen is that unsaved data are lost and the user has to enter them again.


METHOD action_back_is_allowed .
rv_is_allowed = ‘X’.


  1. ACTION_SET_STATUS_IS_ALLOWD. Here you should return True with the return parameter RV_IS_ALLOWED (“Navigation Allowed?”), if the last update of ERP was successful, otherwise False.

Remark: It is advisable with ‘Set status to OK’ to call ERP to check that the ID is complete, i.e. Sloc entered, batch, manufacturing date. Otherwise, when Goods Receipt fails, the user cannot go back to ‘Prepare Goods Receipt’.

So the proposal is, to just call the functionality of method ONACTIONSAVE again in this Interface method and return the result:


METHOD action_set_status_is_allowd .
rv_is_allowed =  wd_this->save( ).




Save Changes

Now we can see the delivery data and change the expiration date in the editable column of VFDAT. So implement a save button called Change Data to save the user changes to the database in view ResultView.

Implement method ONACTIONSAVE

Implement an event handler method ONACTIONSAVE for the Change Data button with the following functionality:

  • Get actual/changed content of the delivery table
  • Update DB
  • Display a success message.

To update the existing delivery we use function WS_DELIVERY_UPDATE in ERP. The relevant input table for confirming the data from delivery item is VBPOK_TAB of structure VBPOK. The error or success message is displayed in the message area.

METHOD onactionsave .
wd_comp_controller->save( ).

METHOD save .

DATA: node_node_deliverytab TYPE REF TO if_wd_context_node,
elem_node_deliverytab TYPE REF TO if_wd_context_element,
lt_sdelivery          TYPE if_layoutview=>elements_node_delivery_item,
ls_sdelivery          LIKE LINE OF lt_sdelivery,
lv_rfcdest            TYPE rfcdest,
lv_out                TYPE string,
vbkok_ls              TYPE vbkok_sty,
vbpok_ls              TYPE vbpok_sty,
vbpok_lt              TYPE TABLE OF vbpok_sty INITIAL SIZE 0,
prot_ls               TYPE prott_sty,
prot_lt               TYPE TABLE OF prott_sty INITIAL SIZE 0,
ls_error              TYPE string.

* get error message manager
DATA: l_current_controller TYPE REF TO if_wd_controller,
l_message_manager    TYPE REF TO if_wd_message_manager.
l_current_controller ?= wd_this->wd_get_api( ).
CALL METHOD l_current_controller->get_message_manager
message_manager = l_message_manager.

* navigate from <CONTEXT> to <NODE_deliveryTAB> via lead selection
= wd_context->get_child_node( name = `NODE_DELIVERY_ITEM` ).

* save data to database
lv_rfcdest = wd_comp_controller->mv_rfcdest.

* get data from context node <NODE_deliveryTAB>
IMPORTING table = lt_sdelivery ).
* read the changed data
CLEAR: vbpok_lt.
LOOP AT lt_sdelivery INTO ls_sdelivery.
vbkok_ls-vbeln_vl     = ls_sdelivery-vbeln.
vbkok_ls-vbeln        = ls_sdelivery-vbeln.

* Positions
vbpok_ls-vbeln_vl = ls_sdelivery-vbeln.
vbpok_ls-posnr_vl = ls_sdelivery-posnr.
vbpok_ls-vbeln    = ls_sdelivery-vbeln.
vbpok_ls-posnn    = ls_sdelivery-posnr.
vbpok_ls-lfimg    = ls_sdelivery-lfimg.
vbpok_ls-vfdat    = ls_sdelivery-vfdat.
vbpok_ls-kzvfdat  = ‘X’.
APPEND vbpok_ls TO vbpok_lt. CLEAR vbpok_ls.

**** update the existing delivery …
vbkok_wa                 = vbkok_ls                   “#EC ENHOK
commit                   = ‘X’
delivery                 = ls_sdelivery-vbeln
vbpok_tab                = vbpok_lt                   “#EC ENHOK
prot                     = prot_lt                    “#EC ENHOK
error_message            = 1
OTHERS                   = 2.

IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
INTO ls_error.
CALL METHOD l_message_manager->report_error_message
message_text = ls_error.
CLEAR prot_ls.
LOOP AT prot_lt INTO prot_ls.
MESSAGE ID prot_ls-msgid TYPE prot_ls-msgty NUMBER prot_ls-msgno
WITH prot_ls-msgv1 prot_ls-msgv2 prot_ls-msgv3 prot_ls-msgv4
INTO ls_error.
CALL METHOD l_message_manager->report_error_message
message_text = ls_error.
IF prot_ls IS INITIAL.
rv_is_allowed  = ‘X’.
CONCATENATE ‘Data has been modified successfully in system’ lv_rfcdest INTO lv_out SEPARATED BY space. “#EC NOTEXT
CALL METHOD l_message_manager->report_success
message_text = lv_out.



Test the Web Dynpro Application

The result will look like the following:

Display the changed inbound delivery in the ERP system with transaction VL33N:

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply