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