Cerca nel blog

martedì 11 ottobre 2022

Creazione di un IDOC custom che richiama un WS di tipo REST ed invia un file Json

 

Creazione di un IDOC custom che richiama un WS di tipo REST ed invia un file Json


Dopo aver creato un nostro Idoc ( Vedere post: ABAP - IDoc Definizione), passiamo alle varie configurazioni:

STEP NR. 1: Configuriamo il sistema esterno

Richiamiamo la transazione OMKY, e definiamo un nome per il sistema esterno




STEP NR. 2: Definiamo la porta

Richiamiamo la transazione WE21, e definiamo la porta ZTEST e il FM ZFM_TEST_IDOC_TO_WS_REST associato per gestire l’Idoc

STEP NR. 3: Definiamo la porta

Richiamiamo la transazione WE20, e definiamo gli accordi partner e associato la porta definita in precedenza

STEP NR. 3: Creiamo Il FM ZFM_TEST_IDOC_TO_WS_REST (di tipo RFC) che richiama il FM che richiama a sua volta IL WS di tipo REST 

FUNCTION ZFM_TEST_IDOC_TO_WS_REST .

  
TABLES: edidc, edi_ds.

  
DATA: BEGIN OF i_edidd OCCURS 0.
      
INCLUDE STRUCTURE edidd.
  
DATA: END OF i_edidd.

  
DATA: error(1).
  
DATA lv_tech_error. "X=set 02 status

  
LOOP AT i_edidc.

    
CALL FUNCTION 'EDI_DOCUMENT_OPEN_FOR_PROCESS'
      
EXPORTING
*       DB_READ_OPTION           = DB_READ
        document_number          
= i_edidc-docnum
*       ENQUEUE_OPTION           = SYNCHRONOUS
      
IMPORTING
        idoc_control             
= edidc
      
EXCEPTIONS
        document_foreign_lock    
= 1
        document_not_exist       
= 2
        document_number_invalid  
= 3
        document_is_already_open 
= 4
        
OTHERS                   = 5.
    
IF sy-subrc <> 0.
      
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    
ENDIF.

    
CLEAR i_edidd.
    
REFRESH i_edidd.

    
CALL FUNCTION 'EDI_SEGMENTS_GET_ALL'
      
EXPORTING
        document_number         
= i_edidc-docnum
      
TABLES
        idoc_containers         
= i_edidd
      
EXCEPTIONS
        document_number_invalid 
= 1
        end_of_document         
= 2
        
OTHERS                  = 3.
    
IF sy-subrc <> 0.
      
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    
ENDIF.

*ho trovato la function da lanciare
      
DATA lt_ret TYPE bapiret2_tab WITH HEADER LINE.

      
CALL FUNCTION 'ZFM_TEST_WS_DA_IDOC_WMTOID01'
        
EXPORTING
          i_docnum     
= i_edidc-docnum
        
IMPORTING
          ot_ret       
= lt_ret[]
          o_tech_error 
= lv_tech_error.

      
READ TABLE lt_ret WITH KEY type = 'E' TRANSPORTING NO FIELDS.
      
IF sy-subrc = 0.
        error 
= 'Y'.
        
CLEAR edi_ds.
      
ENDIF.

IF error = 'Y'.

      
IF edi_ds IS NOT INITIAL.
        edi_ds
-docnum = i_edidc-docnum.
        edi_ds
-tabnam = 'EDI_DS'.
        edi_ds
-logdat = sy-datum.
        edi_ds
-logtim = sy-uzeit.
        edi_ds
-repid = 'ZFM_TEST_IDOC_TO_WS_REST'.
        
IF lv_tech_error = 'X'.
          edi_ds
-status = '02'. "Error passing data to port
        
ELSE.
          edi_ds
-status = '29'. " Error in ALE service
        
ENDIF.
        edi_ds
-stamqu = 'SAP'.

        
CALL FUNCTION 'EDI_DOCUMENT_STATUS_SET'
          
EXPORTING
            document_number         
= i_edidc-docnum
            idoc_status             
= edi_ds
          
EXCEPTIONS
            document_number_invalid 
= 1
            other_fields_invalid    
= 2
            status_invalid          
= 3
            
OTHERS                  = 4.
        
IF sy-subrc <> 0.
          
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                  
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
        
ENDIF.
      
ENDIF.

      
LOOP AT   lt_ret .
        
CLEAR edi_ds .
        edi_ds
-docnum = i_edidc-docnum.
        edi_ds
-tabnam = 'EDI_DS'.
        edi_ds
-logdat = sy-datum.
        edi_ds
-logtim = sy-uzeit.
        edi_ds
-repid = 'ZFM_TEST_IDOC_TO_WS_REST'.
        
IF lv_tech_error = 'X'.
          edi_ds
-status = '02'. "Error passing data to port
        
ELSE.
          edi_ds
-status = '29'. " Error in ALE service
        
ENDIF.
        edi_ds
-stamqu = 'SAP'.
        edi_ds
-stamid = lt_ret-id.
        edi_ds
-stamno = lt_ret-number.
        edi_ds
-stapa1 = lt_ret-message_v1.
        edi_ds
-stapa2 = lt_ret-message_v2.
        edi_ds
-stapa3 = lt_ret-message_v3.
        edi_ds
-stapa4 = lt_ret-message_v4.

        
CALL FUNCTION 'EDI_DOCUMENT_STATUS_SET'
          
EXPORTING
            document_number         
= i_edidc-docnum
            idoc_status             
= edi_ds
          
EXCEPTIONS
            document_number_invalid 
= 1
            other_fields_invalid    
= 2
            status_invalid          
= 3
            
OTHERS                  = 4.
        
IF sy-subrc <> 0.
          
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                  
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
        
ENDIF.
      
ENDLOOP.
    
ELSE.
      
CLEAR edi_ds .
      edi_ds
-docnum = i_edidc-docnum.
      edi_ds
-tabnam = 'EDI_DS'.
      edi_ds
-logdat = sy-datum.
      edi_ds
-logtim = sy-uzeit.
      edi_ds
-repid = 'ZFM_TEST_IDOC_TO_WS_REST'.
      edi_ds
-status = '12'.
      edi_ds
-stamqu = 'SAP'.

      
CALL FUNCTION 'EDI_DOCUMENT_STATUS_SET'
        
EXPORTING
          document_number         
= i_edidc-docnum
          idoc_status             
= edi_ds
        
EXCEPTIONS
          document_number_invalid 
= 1
          other_fields_invalid    
= 2
          status_invalid          
= 3
          
OTHERS                  = 4.
      
IF sy-subrc <> 0.
        
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      
ENDIF.
    
ENDIF.

    
CALL FUNCTION 'EDI_DOCUMENT_CLOSE_PROCESS'
      
EXPORTING
        document_number     
= i_edidc-docnum
*       BACKGROUND          = NO_BACKGROUND
*       NO_DEQUEUE          = ' '
*      IMPORTING
*       IDOC_CONTROL        =
      
EXCEPTIONS
        document_not_open   
= 1
        failure_in_db_write 
= 2
        parameter_error     
= 3
        status_set_missing  
= 4
        
OTHERS              = 5.
    
IF sy-subrc <> 0.
      
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    
ENDIF.

  
ENDLOOP.
ENDFUNCTION.

STEP NR. 4: CREAIMO IL SECONDO FM ZFM_TEST_WS_DA_IDOC_WMTOID01 che richiama IL WS di tipo REST

FUNCTION ZFM_TEST_WS_DA_IDOC_WMTOID01.

*dati idoc
  
DATA ls_idoc_control  LIKE  edidc .
  
DATA lt_edidd TYPE edidd OCCURS 0 WITH HEADER LINE.
  
DATA: wa           LIKE LINE OF lt_edidd.

  
DATA: wa_e1ltorh     TYPE e1ltorh,
        wa_e1ltori     
TYPE e1ltori.

  
DATA: http_client          TYPE REF TO if_http_client,
        http_url             
TYPE string,
        p_content            
TYPE string,
        lv_json              
TYPE string,
        ls_to_create         
TYPE z_test_s_to_create,
        ls_imp_ordini_righe  
TYPE zwm_test_s_to_create_item,
        ls_imp_ordini_header 
TYPE zwm_test_s_to_create_header,
        lv_tanum             
TYPE tanum,
        lsret                
LIKE LINE OF ot_ret,
        lv_text
(255),
        oref_exception       
TYPE REF TO cx_root,
        lv_status            
TYPE i.


  
WAIT UP TO 3 SECONDS. 
  
SET LANGUAGE 'I'.
  
SET LOCALE LANGUAGE 'I'.

  
CALL FUNCTION 'IDOC_READ_COMPLETELY'
    
EXPORTING
      document_number         
= i_docnum
    
IMPORTING
      idoc_control            
= ls_idoc_control
    
TABLES
      int_edidd               
= lt_edidd
    
EXCEPTIONS
      document_not_exist      
= 1
      document_number_invalid 
= 2
      
OTHERS                  = 3.
  
IF lt_edidd[] IS INITIAL.
    lsret
-type = 'E'.
    lsret
-id = 'ZCL_MSG'.
    lsret
-number = '007'.
    lsret
-message_v1 = i_docnum.
    lsret
-message_v2 = ''.
    lsret
-message_v3 = ''.
    lsret
-message_v4 = ''.
    
APPEND lsret TO ot_ret.

    
EXIT.
  
ENDIF.

  
SORT lt_edidd BY docnum segnum.

  
CLEAR ls_to_create.

  
READ TABLE lt_edidd INTO wa WITH KEY segnam = 'E1LTORH'.
  
MOVE wa-sdata TO wa_e1ltorh.
  lv_tanum 
= wa_e1ltorh-tanum.

    
LOOP AT lt_edidd INTO wa.
      
CASE wa-segnam.
        
WHEN 'E1LTORH'.
* Header segment
          
MOVE wa-sdata TO wa_e1ltorh.
* Map header seg field to MOD JSON structure
          
CLEAR ls_imp_ordini_header.
          
MOVE wa_e1ltorh-lgnum TO ls_imp_ordini_header-ord_attr1.
          
MOVE wa_e1ltorh-tanum TO ls_imp_ordini_header-ord_ordine.
          lv_tanum 
= wa_e1ltorh-tanum.

          
APPEND ls_imp_ordini_header TO ls_to_create-imp_ordini.

        
WHEN 'E1LTORI'.
* Item segment
          
MOVE wa-sdata TO wa_e1ltori.
* Map Item seg field to MOD JSON structure
          
CLEAR ls_imp_ordini_righe.
          
MOVE wa_e1ltori-tapos TO ls_imp_ordini_righe-rig_hostinf.
          
MOVE wa_e1ltori-matnr TO ls_imp_ordini_righe-rig_articolo.
          
MOVE wa_e1ltori-charg TO ls_imp_ordini_righe-rig_sub1.
          
APPEND ls_imp_ordini_righe TO ls_to_create-imp_ordini_righe.
      
ENDCASE.
    
ENDLOOP.

* chiamata webservice
    
TRY.
* ABAP to JSON Serializer
        lv_json 
= /ui2/cl_json=>serialize( data = ls_to_create ).

        
CALL METHOD cl_http_client=>create_by_destination
          
EXPORTING
            destination              
= 'Z_TEST_TO_CREATE'
          
IMPORTING
            
client                   = http_client
          
EXCEPTIONS
            argument_not_found       
= 1
            destination_not_found    
= 2
            destination_no_authority 
= 3
            plugin_not_active        
= 4
            internal_error           
= 5
            
OTHERS                   = 6.

        
IF sy-subrc <> 0.
* Gestione Errori
          lsret
-type = 'E'.
          lsret
-id = 'ZCL_MSG'.
          
CASE sy-subrc.
            
WHEN '1'. lsret-number = '018'.
            
WHEN '2'. lsret-number = '019'.
            
WHEN '3'. lsret-number = '020'.
            
WHEN OTHERS. lsret-number = '009'.
          
ENDCASE.
          
APPEND lsret TO ot_ret.
* Gestione  o_tech_error
          o_tech_error 
= 'X'.

          
EXIT.
        
ENDIF.

        
CALL METHOD http_client->request->set_method
          
EXPORTING
            
method = 'POST'.

        http_client
->request->set_content_type(
         
EXPORTING
         content_type 
= if_rest_media_type=>gc_appl_json ).

        
CALL METHOD http_client->request->set_cdata
          
EXPORTING
            
data = lv_json.

        
CALL METHOD http_client->send
          
EXCEPTIONS
            http_communication_failure 
= 1
            http_invalid_state         
= 2
            http_processing_failed     
= 3
            http_invalid_timeout       
= 4.

        
IF sy-subrc <> 0.
* Gestione Errori
          lsret
-type = 'E'.
          lsret
-id = 'ZCL_MSG'.
          lsret
-number = '008'.
          
CASE sy-subrc.
            
WHEN '1'. lsret-number = '025'.
            
WHEN '2'. lsret-number = '026'.
            
WHEN '3'. lsret-number = '027'.
            
WHEN '4'. lsret-number = '028'.
            
WHEN OTHERS. lsret-number = '010'.
          
ENDCASE.
          
APPEND lsret TO ot_ret.
* Gestione  o_tech_error
          o_tech_error 
= 'X'.
          
EXIT.
        
ENDIF.

        
CALL METHOD http_client->receive
          
EXCEPTIONS
            http_communication_failure 
= 1
            http_invalid_state         
= 2
            http_processing_failed     
= 3
            
OTHERS                     = 4.

        
IF sy-subrc <> 0.
* Gestione Errori
          lsret
-type = 'E'.
          lsret
-id = 'ZCL_MSG'.
          
CASE sy-subrc.
            
WHEN '1'. lsret-number = '021'.
            
WHEN '2'. lsret-number = '022'.
            
WHEN '3'. lsret-number = '023'.
            
WHEN OTHERS. lsret-number = '010'.
          
ENDCASE.
          
APPEND lsret TO ot_ret.
* Gestione  o_tech_error
          o_tech_error 
= 'X'.
          
EXIT.
        
ENDIF.

        p_content 
= http_client->response->get_cdata( ).

        
CALL METHOD http_client->response->get_status
          
IMPORTING
            
code = lv_status.

        
IF lv_status NE '200'.
          
EXIT.
        
ENDIF.

        
CALL METHOD http_client->close
          
EXCEPTIONS
            http_invalid_state 
= 1
            
OTHERS             = 2.
        
IF sy-subrc <> 0.
* Gestione Errori
          lsret
-type = 'E'.
          lsret
-id = 'ZCL_MSG'.
          
CASE sy-subrc.
            
WHEN '1'. lsret-number = '022'.
            
WHEN OTHERS. lsret-number = '010'.
          
ENDCASE.
          
APPEND lsret TO ot_ret.
* Gestione  o_tech_error
          o_tech_error 
= 'X'.

          
EXIT.
        
ENDIF.

      
CATCH cx_root INTO oref_exception.
* Gestione Errori
        lv_text 
= oref_exception->get_text( ).
        lsret
-type = 'E'.
        lsret
-id = 'ZCL_MSG'.
        lsret
-number = '016'.
        lsret
-message_v1 = lv_text+000(50).
        lsret
-message_v2 = lv_text+050(50).
        lsret
-message_v3 = lv_text+100(50).
        lsret
-message_v4 = lv_text+150(50).
        
APPEND lsret TO ot_ret.
* Gestione  o_tech_error
        o_tech_error 
= 'X'.

        
EXIT.
    
ENDTRY.

ENDFUNCTION.

STEP NR. 5: Creare la destinazione dove passare il file json Z_TEST_TO_CREATE

Transazione SM59: In collegamenti http a serve est. Creare il collegamento