O objetivo desse artigo é fornecer um exemplo de código ABAP para implementação da BAdI Determination of Custom UI for Logistics Workplace for Inbound NF-es. Você usará essa BAdI para substituir a atual interface (UI) do processoPrepare Goods Receipt Posting com um UI Web Dynpro customizada.
Implementing the BAdI ‘Determination of Custom UI for Logistics Workplace’
A BAdI usa a interface /XNFE/IF_BADI_GET_CUSTOM_UI. O sistema realiza a chamada dessa interfac com o método GET_CUSTOM_UI. Use essa interface para transferir seu UI component customizado para o NFE Framework. É possível determinar diferentes UI components dependendo dos parâmetros de importação:
- CNPJ
- Process Type
- Process Step.
Embora apenas um processo (Prepare Goods Receipt Posting) seja suportado até o momento, o processo é um parâmetro de importação da BAdI (no futuro, outros processos podem ser suportados).
A seguir, um exemplo desse método na classe de implementação do enhancement implementation. Nesse exemplo, o nome dado ao componente foi 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'.
ENDIF.
ENDMETHOD.
Enhancing the NF-e Logistics Workplace
Na tela no Monitor Logístico, você poderá selecionar uma NF-e e clicar em Execute Process Step -> Prepare Goods Receipt Posting (se o status da NF-e permitir). Na tela dePrepare Goods Receipt Posting, você poderá definir o status para a NF-e e retornar para o Monitor Logístico. Com essa UI customizada (abaixo os botões de Definir Status), a ideia é oferecer a opção de alterar dados da inbound delivery no ERP antes de definir o status da etapa do processo:
Create a New Web Dynpro Component
Para visualizar os dados da inbound delivery da banco de dados do ERP, é usado uma tabela ALV modificável. A implementação apresentada aqui usa uma cópia de um componente WDT_FLIGHTLIST_EDIT no package SWDP_DEMO_TUTORIALS como ponto de partida.
Para ler os dados da inbound delivery do ERP, foi usado a funçãoBAPI_DELIVERY_GETLIST. A tabela de output relevante, que retorna os dados de item da ID éet_delivery_item com estruturaBAPIDLVITEM (nós usamos a copy-structure INBOUND_DELIV_STY).
Para armazenar os dados da ID, é necessário criar um node NODE_DELIVERY_ITEM baseado no estrutura do dicionário INBOUND_DELIV_STY no contexto do controller do componente e escolher os campos que você deseja mostrar na tabela ALV:
Set Table to “Editable”
Feito isso, a tabela ALV é configurada para fazer a coluna Shelf Life Expiration ou Best-Before Date (VFDAT) modificável. Portanto, é necessário melhorar o método WDDOINIT da view ResultView:
METHOD wddoinit.
DATA:
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( ).
ENDIF.
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
EXPORTING
value_fieldname = 'VFDAT'.
lr_column->set_cell_editor( lr_input_field ).
ENDMETHOD.
Create a Method to Receive the Data from ERP
Seu componente Web Dynpro customizado precisa implementar a interface Web Dynpro interface /XNFE/IF_CUSTOM_UI com o método STEP_DATA. Esse método transfere os parâmetros de importação da etapa relevante
- IS_INNFEHD - NF-e header,
- IT_NFEASSIGN - the corresponding assignment table,
- IV_XML - the XML data
na sua UI. O método é chamado pelo NFE Framework toda vez que sua UI customizada for carregada.
Esse método é usado no controller do componente para preencher o nodeNODE_DELIVERY_ITEM:
METHOD step_data.
TYPES:
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.
DATA:
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
CALL FUNCTION '/XNFE/READ_RFC_DESTINATION'
EXPORTING
iv_logsys = is_innfehd-logsys
IMPORTING
ev_rfcdest = wd_this->mv_rfcdest
EXCEPTIONS
no_dest_found = 1.
IF sy-subrc = 1.
RETURN.
ENDIF.
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
CALL FUNCTION 'BAPI_DELIVERY_GETLIST' DESTINATION wd_this->mv_rfcdest
EXPORTING
is_dlv_data_control = ls_dlv_data_control
TABLES
it_vbeln = lt_range_vbeln
et_delivery_item = lt_delivery_item
return = lt_return
EXCEPTIONS
communication_failure = 1
system_failure = 2.
IF sy-subrc IS NOT INITIAL.
RETURN.
ENDIF.
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'.
EXIT.
ENDLOOP.
ENDIF.
ENDIF.
* 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 ).
ENDMETHOD.
Save Changes
Agora é possível visualizar os dados da ID e alterar o expiration date na coluna editável do VFDAT. Criar um botão chamado "Editar Dados" para salvar no banco de dados as alterações do usuário na view ResultView.
Implement Method ONACTIONSAVE
Implementar um método event handler ONACTIONSAVE para o botão "Editar Dados" com as seguintes funções:
- Pegar o conteúdo atual/alterado da tabela da ID;
- Atualizar o Banco de Dados;
- Exibir uma mensagem de sucesso;
Para atualizar a inbound delivery existente, é usado a função WS_DELIVERY_UPDATE in ERP. A tabela de input relevant para confirmar os dados de item da ID é VBPOK_TAB da estrutura VBPOK. O mensagem de erro ou de sucesso é mostrado na área de mensagens.
METHOD onactionsave.
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
RECEIVING
message_manager = l_message_manager.
* navigate from <CONTEXT> to <NODE_deliveryTAB> via lead selection
node_node_deliverytab = 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>
node_node_deliverytab->get_static_attributes_table(
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.
ENDLOOP.
**** update the existing delivery ...
CALL FUNCTION 'WS_DELIVERY_UPDATE' DESTINATION lv_rfcdest
EXPORTING
vbkok_wa = vbkok_ls "#EC ENHOK
commit = 'X'
delivery = ls_sdelivery-vbeln
TABLES
vbpok_tab = vbpok_lt "#EC ENHOK
prot = prot_lt "#EC ENHOK
EXCEPTIONS
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
EXPORTING
message_text = ls_error.
ELSE.
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
EXPORTING
message_text = ls_error.
ENDLOOP.
IF prot_ls IS INITIAL.
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
EXPORTING
message_text = lv_out.
ENDIF.
ENDIF.
ENDMETHOD.
Test the Web Dynpro Application
O resultado ficaria, basicamente, assim:
Exibir a inbound delivery modificado no ERP, acessando a transação VL33N: