Skip to Content
SAP Electronic Invoicing for Brazil (SAP Nota Fiscal Eletronica)

Sample ABAP Coding for Enhancing the Logistics Workplace

Tags:

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 processo Prepare 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 de Prepare 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ção BAPI_DELIVERY_GETLIST. A tabela de output relevante, que retorna os dados de item da ID é et_delivery_item com estrutura BAPIDLVITEM (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 node NODE_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:

Former Member