Idocs error handling agents

Soady, Phil phil.soady at sap.com
Mon Jan 12 21:09:07 EST 2004


Some reading for your scenic tour. (nice one Mike...)
 
A workflow can easily check the IDOC type.
 
As soon as you start doing much with IDOCs and workflows
it is very useful to have your own ZZIDOCAPPL. ;-)
A delegated version of IDOCAPPL.
The ALE and Workflow topic is getting a bit of press at the moment
so I thought this might be of interest.
 
ABAP CODE FOLLOWS for 3 OBJECTS
ZZIDOCAPPL, ZZEDIDS and ZZEDIDC  (IDOC SEGEMENTS and Control Records)
 
If you have more goodies in this this area, please share the POST !
 
Cheers
Phil Soady.
 
************************************************************************
*****           Implementation of object type ZIDOCAPPL            *****
************************************************************************
 
INCLUDE <OBJECT>.
 
 "IDOC constants
constants:
      C_IDOC_STATUS_DELETE LIKE EDI_DS-STATUS VALUE '68',
      c_wf_result_delete_idoc LIKE BDWF_PARAM-RESULT VALUE '99998',
      C_WF_PAR_RESULT LIKE BDWFRETVAR-WF_PARAM VALUE 'Result'.
 
BEGIN_DATA OBJECT. " Do not change.. DATA is generated
* only private members may be inserted into structure private
DATA:
" begin of private,
"   to declare private attributes remove comments and
"   insert private attributes here ...
" end of private,
  BEGIN OF KEY,
      IDOCNUMBER LIKE EDIDC-DOCNUM,
  END OF KEY,
      LASTSTATUS TYPE SWC_OBJECT,
      IDOCCONTROLRECORD TYPE SWC_OBJECT.
END_DATA OBJECT. " Do not change.. DATA is generated
 
GET_PROPERTY LASTSTATUS CHANGING CONTAINER.
SWC_CONTAINER l_container.
DATA: O_ZEDIDS TYPE SWC_OBJECT.
 
SWC_CREATE_OBJECT o_zedids 'ZEDIDS'    ' '.
 
SWC_SET_ELEMENT l_Container 'IdocNumber' object-key.
SWC_CALL_METHOD o_zedids 'GetLastStatus' l_CONTAINER.
SWC_GET_ELEMENT l_Container 'LastStatus' o_zedids.
 
SWC_SET_ELEMENT CONTAINER 'LastStatus' o_zedids.
END_PROPERTY.
 
BEGIN_METHOD DELETE CHANGING CONTAINER.
  DATA: BEGIN OF T_IDOC_STATUS OCCURS 0.
          INCLUDE STRUCTURE BDIDOCSTAT.
  DATA: END OF T_IDOC_STATUS.
 
data: l_docnumber like  EDIDC-DOCNUM.
data: edidc type edidc.
data: edp21 type edp21.
data: tbd52 type tbd52.
 
* This method emulates a part of IDOC_MANUAL_INPUT.
* Inparticular the section regarding deletion of IDOCs.
*
* get the IDOC number
swc_get_property self 'IDOCNUMBER' l_docnumber.
* get the control record.
 
select single * from edidc where docnum = l_docnumber.
* Auth check
AUTHORITY-CHECK OBJECT 'S_IDOCMONI'
             ID 'ACTVT'   FIELD '02'         "change for delete
             ID 'EDI_DIR' FIELD edidc-direct
             ID 'EDI_MES' FIELD edidc-mestyp
             ID 'EDI_PRN' FIELD edidc-sndprn
             ID 'EDI_PRT' FIELD edidc-sndprt
             ID 'EDI_TCD' DUMMY.
 
if sy-subrc <> 0.
  exit_return 1000 l_docnumber 'Delete'   ' '   ' '.
endif.
 
SELECT SINGLE * FROM edp21 WHERE sndprn = edidc-sndprn
                             AND sndprt = edidc-sndprt
                             AND sndpfc = edidc-sndpfc
                             AND mestyp = edidc-mestyp
                             AND mescod = edidc-mescod
                             AND mesfct = edidc-mesfct
                             AND test   = edidc-test.
 
  SELECT SINGLE * FROM tbd52 WHERE evcode = edp21-evcode.
  refresh T_IDOC_STATUS.
* Set IDOC's status to "ready for deletion".............................
  T_IDOC_STATUS-DOCNUM = l_DOCNUMBER.
  T_IDOC_STATUS-STATUS = C_IDOC_STATUS_DELETE.
  APPEND T_IDOC_STATUS.
 
CALL FUNCTION 'IDOC_STATUS_WRITE_TO_DATABASE'
  EXPORTING
    IDOC_NUMBER                     = l_docnumber
    IDOC_OPENED_FLAG                = ' '
    NO_DEQUEUE_FLAG                 = ' '
*  IMPORTING
*   IDOC_CONTROL                    =
  TABLES
    IDOC_STATUS                     = T_IDOC_STATUS
  EXCEPTIONS
    IDOC_FOREIGN_LOCK               = 1
    OTHERS                          = 2
          .
 
case sy-subrc.
   when 1. exit_return 1001 l_DOCNUMBER ' '   ' '   ' '.
   when 2. exit_return 1002 l_docnumber ' '   ' '   ' '.
endcase.
 
PERFORM start_event USING   l_docnumber
                            tbd52-event_end
                            tbd52-idocobjtyp
                            c_wf_result_delete_idoc.
 
commit work.
 
 
END_METHOD.
 
 
*---------------------------------------------------------------------*
*       FORM START_EVENT                                              *
*---------------------------------------------------------------------*
*  This routine triggers the event in PI_EVENT.                       *
*---------------------------------------------------------------------*
*  -->  PI_IDOC_NUMBER           IDOC number                          *
*  -->  PI_EVENT                 Event number                         *
*  -->  PI_EVENT_OBJECT_TYPE     IDOC object type                     *
*  -->  PI_RESULT                Result parameter in event-container  *
*---------------------------------------------------------------------*
FORM START_EVENT USING PI_IDOC_NUMBER LIKE EDIDC-DOCNUM
                       PI_EVENT LIKE SWETYPECOU-EVENT
                       PI_EVENT_OBJECT_TYPE LIKE SWETYPECOU-OBJTYPE
                       PI_RESULT LIKE BDWF_PARAM-RESULT.
 
  DATA: BEGIN OF T_CONTAINER OCCURS 0.
          INCLUDE STRUCTURE SWCONT.
  DATA: END OF T_CONTAINER.
 
* These variables are used for the event function.
  DATA: EVENT_OBJECT_KEY  LIKE SWEINSTCOU-OBJKEY,
        EVENT_ID LIKE SWEDUMEVID-EVTID.
 
 
  EVENT_OBJECT_KEY = PI_IDOC_NUMBER.
* Set the Result parameter of the event's container
  SWC_SET_ELEMENT T_CONTAINER C_WF_PAR_RESULT PI_RESULT.
 
  check not PI_EVENT is initial.
  check not PI_EVENT_OBJECT_TYPE is initial.
 
*   Trigger event.......................................................
    CALL FUNCTION 'SWE_EVENT_CREATE'
         EXPORTING
              OBJTYPE           = PI_EVENT_OBJECT_TYPE
              OBJKEY            = EVENT_OBJECT_KEY
              EVENT             = PI_EVENT
*         CREATOR           = ' '
         IMPORTING
              EVENT_ID          = EVENT_ID
         TABLES
              EVENT_CONTAINER   = T_CONTAINER.
*    EXCEPTIONS
*         OBJTYPE_NOT_FOUND = 01.
*   Event triggered.....................................................
 
 
ENDFORM.
 
BEGIN_METHOD PROCESSIDOCINERROR CHANGING CONTAINER.
* Special version of error process
*  so that the WI will go away without deletion of IDOC
* THIS METHOD is SYNCHRONOUS, the standard Method is NOT !
DATA: dialog_flag(1),
      execute_multiply(1) TYPE c.
* Check whether all marked workitems should be processed without
* dialog
swc_get_element container '_WI_EXECUTI_MULTI' execute_multiply.
 
IF execute_multiply = space.
  dialog_flag = 'X'.
ELSE.
  dialog_flag = ' '.
ENDIF.
 
CALL FUNCTION 'IDOC_PROCESS_ERROR'
     EXPORTING
          idoc_number = object-key-idocnumber
          dialog_flag = dialog_flag.
 
 
END_METHOD.
 
BEGIN_METHOD EXISTENCECHECK CHANGING CONTAINER.
data: l_idocnumber like edidc-docnum.
data: edidc type edidc.
SWC_GET_OBJECT_KEY self  l_idocnumber.
 
select single docnum from EDIDC into edidc-docnum
       where docnum = l_idocnumber.
if sy-subrc <> 0.
EXIT_RETURN 0001 SPACE SPACE SPACE SPACE.
endif.
END_METHOD.
 
BEGIN_METHOD GETIDOC CHANGING CONTAINER.
DATA:
      l_idocnumber like edidc-docnum,
      o_IDOC TYPE SWC_OBJECT.
 
  swc_get_element container 'IdocNumber' l_idocnumber.
 
  SWC_CREATE_OBJECT o_idoc 'ZIDOCAPPL' l_idocnumber.
 
  SWC_SET_ELEMENT CONTAINER RESULT o_IDOC.
 
 
 
END_METHOD.
 
GET_PROPERTY IDOCCONTROLRECORD CHANGING CONTAINER.
data l_idocnumber like edidc-docnum.
data o_zedidc type  SWC_OBJECT.
  swc_get_object_key self   l_idocnumber.
  SWC_CREATE_OBJECT o_zedidc 'ZEDIDc' l_idocnumber.
  SWC_SET_ELEMENT CONTAINER 'IDOCControlRecord'   o_zedidc .
 
END_PROPERTY.
 
BEGIN_METHOD GETINVOICREFFIELDS CHANGING CONTAINER.
data: t_idoc_data like edidd occurs 0 with header line.
data: t_idoc_control like edidc occurs 0 with header line.
 
DATA: e1edk02            like E1EDK02,
      e1edp02            like e1edp02,
      docnum             like edid4-docnum,
      PURCHASINGDOCUMENT LIKE EKPO-EBELN,
      POITEM             LIKE EKPO-EBELP,
      YOURDOCUMENT       LIKE E1EDK02-BELNR,
      YOURDOCUMENTITEM   LIKE E1EDK02-POSNR.
 
refresh: t_idoc_control,
         t_idoc_data.
 
  swc_get_object_key self docnum.
  t_idoc_control-docnum =  docnum.
  append t_idoc_control.
 
  CALL FUNCTION 'ALE_FTCH_DATA_SEGMENTS_OF_IDOC'
    TABLES
      T_IDOC_CONTROL       =  t_idoc_control
      T_IDOC_DATA          =  t_idoc_data .
 
  loop at t_idoc_data.
  case t_idoc_data-segnam.
  when 'E1EDK02'.
       e1edk02 = t_idoc_data-sdata.
       if e1edk02-qualf = '009'.   "Sender invoice ref
          YOURDOCUMENT = e1edk02-belnr.
          YOURDOCUMENTITEM = e1edk02-posnr.
       endif.
   when 'E1EDP02'.
      e1edp02 = t_idoc_data-sdata.
      if e1edp02-qualf = '001'.   " our PO number
         PURCHASINGDOCUMENT = e1edp02-belnr.
         POITEM             = e1edp02-zeile.
      endif.
  endcase.
  endloop.
 
 
  SWC_SET_ELEMENT CONTAINER 'PurchasingDocument' PURCHASINGDOCUMENT.
  SWC_SET_ELEMENT CONTAINER 'POItem' POITEM.
  SWC_SET_ELEMENT CONTAINER 'YourDocument' YOURDOCUMENT.
  SWC_SET_ELEMENT CONTAINER 'YourDocumentItem' YOURDOCUMENTITEM.
 
END_METHOD.
 
BEGIN_METHOD GETIDOCDATASEGMENTS CHANGING CONTAINER.
data: t_idoc_data like edidd occurs 0 with header line.
data: t_idoc_control like edidc occurs 0 with header line.
data: sdata_tab like dfbnt-string occurs 0 with header line.
 
Data:      docnum             like edid4-docnum.
 
refresh :  t_idoc_data,
          t_idoc_control.
  swc_get_object_key self docnum.
  t_idoc_control-docnum =  docnum.
  append t_idoc_control.
 
  CALL FUNCTION 'ALE_FTCH_DATA_SEGMENTS_OF_IDOC'
    TABLES
      T_IDOC_CONTROL       =  t_idoc_control
      T_IDOC_DATA          =  t_idoc_data .
 
  loop at t_idoc_data.
    sdata_tab = t_idoc_data.   "-sdata.  full record or just sdata?
    append sdata_tab.
 
  endloop.
 
  swc_set_table container 'DATASEGMENT' sdata_tab.
 
END_METHOD.
 
BEGIN_METHOD INPUTBACKGROUNDSYNC CHANGING CONTAINER.
* Constants - these must have the same values as in the report MBDCONWF
DATA: c_true(1) TYPE c VALUE 'X',
      c_false(1) TYPE c VALUE ' '.
* End of constants......................................................
 
* These tables are not used; needed for interface to Function IDOC_INPUT
DATA: BEGIN OF t_idoc_control OCCURS 0.
        INCLUDE STRUCTURE edidc.
DATA: END OF t_idoc_control.
 
DATA: BEGIN OF t_idoc_data OCCURS 0.
        INCLUDE STRUCTURE edidd.
DATA: END OF t_idoc_data.
* End of tables that are not needen.....................................
 
DATA BEGIN OF t_unprocessed_idocs OCCURS 0.
        INCLUDE STRUCTURE bdidocs.
DATA END OF t_unprocessed_idocs.
 
DATA no_of_retries LIKE bdwf_param-retries.
 
* Fill UNPROCESSED_IDOC.................................................
* Move the number of the unprocessed IDOC from container to parameter
* UNPROCESSED_IDOC.
 
t_unprocessed_idocs-docnum = object-key-idocnumber.
APPEND t_unprocessed_idocs.
* UNPROCESSED_IDOC filled...............................................
 
 
* Get NO_OF_RETRIES from container
* SWC_GET_ELEMENT CONTAINER C_WF_PAR_NO_OF_RETRIES NO_OF_RETRIES.
* The parameter name must be identical to that in the variable
* C_WF_PAR_NO_OF_RETRIES in the report MBDCONWF.
swc_get_element container 'No_of_retries' no_of_retries.    "#EC NOTEXT
 
CALL FUNCTION 'IDOC_INPUT'
     EXPORTING
          no_of_retries            = no_of_retries
          mass_processing          = c_false
          idoc_start_event_enabled = c_false
          end_event_enabled        = c_true
          end_event_always         = c_true
     TABLES
          unprocessed_idocs        = t_unprocessed_idocs
          idoc_data                = t_idoc_data
          idoc_control             = t_idoc_control
     EXCEPTIONS
          OTHERS                   = 1.
END_METHOD.
 
 
 
 
**************************************************************************
*****           Implementation of object type ZEDIDC               *****
INCLUDE <OBJECT>.
BEGIN_DATA OBJECT. " Do not change.. DATA is generated
* only private members may be inserted into structure private
DATA:
" begin of private,
"   to declare private attributes remove comments and
"   insert private attributes here ...
" end of private,
  BEGIN OF KEY,
      IDOCNUMBER LIKE EDIDC-DOCNUM,
  END OF KEY,
      _EDIDC LIKE EDIDC.
END_DATA OBJECT. " Do not change.. DATA is generated
 
BEGIN_METHOD EXISTENCECHECK CHANGING CONTAINER.
data: l_idocnumber like edidc-docnum.
data: edidc type edidc.
SWC_GET_OBJECT_KEY self  l_idocnumber.
 
select single docnum from EDIDC into edidc-docnum
       where docnum = l_idocnumber.
if sy-subrc <> 0.
EXIT_RETURN 0001 SPACE SPACE SPACE SPACE.
endif.
END_METHOD.
 
TABLES EDIDC.
*
GET_TABLE_PROPERTY EDIDC.
DATA SUBRC LIKE SY-SUBRC.
* Fill TABLES EDIDC to enable Object Manager Access to Table Properties
  PERFORM SELECT_TABLE_EDIDC USING SUBRC.
  IF SUBRC NE 0.
    EXIT_OBJECT_NOT_FOUND.
  ENDIF.
END_PROPERTY.
*
* Use Form also for other(virtual) Properties to fill TABLES EDIDC
FORM SELECT_TABLE_EDIDC USING SUBRC LIKE SY-SUBRC.
* Select single * from EDIDC, if OBJECT-_EDIDC is initial
  IF OBJECT-_EDIDC-MANDT IS INITIAL
  AND OBJECT-_EDIDC-DOCNUM IS INITIAL.
    SELECT SINGLE * FROM EDIDC CLIENT SPECIFIED
        WHERE MANDT = SY-MANDT
        AND DOCNUM = OBJECT-KEY-IDOCNUMBER.
    SUBRC = SY-SUBRC.
    IF SUBRC NE 0. EXIT. ENDIF.
    OBJECT-_EDIDC = EDIDC.
  ELSE.
    SUBRC = 0.
    EDIDC = OBJECT-_EDIDC.
  ENDIF.
ENDFORM.
 
BEGIN_METHOD GETCONTROLRECORD CHANGING CONTAINER.
DATA:
 
      o_edidc TYPE SWC_OBJECT.
data: l_IDOCNUMBER LIKE EDIDc-DOCNUM.
 
data: l_edidc type edidc.
data:  BEGIN OF l_KEY,
      IDOCNUMBER LIKE EDIDS-DOCNUM,
  END OF l_KEY.
 
SWC_GET_ELEMENT CONTAINER 'IdocNumber' l_idocnumber.
 
select single * from edidc into l_edidc
       where docnum = l_idocnumber .
 
 
if sy-subrc <> 0.
* when not found exception
  EXIT_RETURN 1000 l_idocnumber ' '  ' '  ' '.
else.
 
 
  l_KEY-IDOCNUMBER       = l_EDIDc-DOCNUM.
 
  SWC_CREATE_OBJECT o_edidc 'ZEDIDC' l_key.
 
  SWC_SET_ELEMENT CONTAINER RESULT o_edidc.
endif.
 
END_METHOD.
 
 
 
*********************************************************************
*****           Implementation of object type ZEDIDS               *****
INCLUDE <OBJECT>.
BEGIN_DATA OBJECT. " Do not change.. DATA is generated
* only private members may be inserted into structure private
DATA:
" begin of private,
"   to declare private attributes remove comments and
"   insert private attributes here ...
" end of private,
  BEGIN OF KEY,
      IDOCNUMBER LIKE EDIDS-DOCNUM,
      DATESTATUSERROR LIKE EDIDS-LOGDAT,
      TIMESTATUSERROR LIKE EDIDS-LOGTIM,
      STATUSCOUNTER LIKE EDIDS-COUNTR,
  END OF KEY,
      MESSAGECODE LIKE EDIDS-SEGFLD,
      _EDIDS LIKE EDIDS.
END_DATA OBJECT. " Do not change.. DATA is generated
 
TABLES EDIDS.
*
GET_TABLE_PROPERTY EDIDS.
DATA SUBRC LIKE SY-SUBRC.
* Fill TABLES EDIDS to enable Object Manager Access to Table Properties
PERFORM SELECT_TABLE_EDIDS USING SUBRC.
IF SUBRC NE 0.
  EXIT_OBJECT_NOT_FOUND.
ENDIF.
END_PROPERTY.
*
* Use Form also for other(virtual) Properties to fill TABLES EDIDS
FORM SELECT_TABLE_EDIDS USING SUBRC LIKE SY-SUBRC.
* Select single * from EDIDS, if OBJECT-_EDIDS is initial
  IF OBJECT-_EDIDS-MANDT IS INITIAL
  AND OBJECT-_EDIDS-DOCNUM IS INITIAL
  AND OBJECT-_EDIDS-LOGDAT IS INITIAL
  AND OBJECT-_EDIDS-LOGTIM IS INITIAL
  AND OBJECT-_EDIDS-COUNTR IS INITIAL.
    SELECT SINGLE * FROM EDIDS CLIENT SPECIFIED
        WHERE MANDT = SY-MANDT
        AND DOCNUM = OBJECT-KEY-IDOCNUMBER
        AND LOGDAT = OBJECT-KEY-DATESTATUSERROR
        AND LOGTIM = OBJECT-KEY-TIMESTATUSERROR
        AND COUNTR = OBJECT-KEY-STATUSCOUNTER.
    SUBRC = SY-SUBRC.
    IF SUBRC NE 0. EXIT. ENDIF.
    OBJECT-_EDIDS = EDIDS.
  ELSE.
    SUBRC = 0.
    EDIDS = OBJECT-_EDIDS.
  ENDIF.
ENDFORM.
 
BEGIN_METHOD GETLASTSTATUS CHANGING CONTAINER.
data: l_IDOCNUMBER LIKE EDIDS-DOCNUM.
DATA l_statrec TYPE SWC_OBJECT.
data: l_edids type edids.
data:  BEGIN OF l_KEY,
      IDOCNUMBER LIKE EDIDS-DOCNUM,
      DATESTATUSERROR LIKE EDIDS-LOGDAT,
      TIMESTATUSERROR LIKE EDIDS-LOGTIM,
      STATUSCOUNTER LIKE EDIDS-COUNTR,
  END OF l_KEY.
 
SWC_GET_ELEMENT CONTAINER 'IdocNumber' l_idocnumber.
 
select * from edids into l_edids up to 1 rows
       where docnum = l_idocnumber
       order by LOGDAT descending
                LOGTIM descending
                COUNTR descending.
 
endselect.
if sy-subrc <> 0.
* when not found exception
  EXIT_RETURN 1000 l_idocnumber ' '  ' '  ' '.
else.
 
 
  l_KEY-IDOCNUMBER       = l_EDIDS-DOCNUM.
  l_key-DATESTATUSERROR  = L_EDIDS-LOGDAT.
  l_key-TIMESTATUSERROR  = l_EDIDS-LOGTIM.
  l_key-STATUSCOUNTER    = l_EDIDS-COUNTR.
 
  SWC_CREATE_OBJECT l_statrec 'ZEDIDS' l_key.
  SWC_SET_ELEMENT CONTAINER 'LastStatus' l_statrec.
 
endif.
 
END_METHOD.
 
GET_PROPERTY MESSAGECODE CHANGING CONTAINER.
data l_messagecode like edids-segfld.
DATA SUBRC LIKE SY-SUBRC.
* Fill TABLES EDIDS to enable Object Manager Access to Table Properties
PERFORM SELECT_TABLE_EDIDS USING SUBRC.
IF SUBRC NE 0.
  EXIT_OBJECT_NOT_FOUND.
ENDIF.
  concatenate edids-stamid edids-stamno into l_messagecode.
 
  SWC_SET_ELEMENT CONTAINER 'MessageCode' l_messagecode.
END_PROPERTY.
 


More information about the SAP-WUG mailing list