Shared Top Border

Enterprise Resource
Planning Portal

 

Advertise | Founder BLOG

ERPGenie.COM ABAP Tips and Tricks Database

THE ultimate
ERP website

 

Forums | Vote for us |

Google    Other Search Options

Login

Login to view more content!!!





Lost Password?
No account yet? Register

Related Items

Home arrow Sample Code arrow IDocs / BDocs arrow Error IDoc status and send to workflow
Error IDoc status and send to workflow PDF Print E-mail
User Rating: / 1
PoorBest 
Written by Kevin Wilson   
Saturday, 17 February 2007
This program checks all INVOIC MM IDocs in status 64 and 66 to determine if they have been received. Those IDocs older than 10 days that have still not been goods receipted are given error status 51.

REPORT ZIDOCERROR message-id ZS7 .

*______________________________________________________________________

 
*/ Program Name: Process invoice IDocs with Goods Receipt

*/ Description : This program checks all INVOIC MM IDocs in status 64

*                and 66 to determine if they have been received. Those

*                IDocs older than 10 days that have still not been

*                goods receipted are given error status 51.

*/ Transaction : N/A - run via scheduled job

*______________________________________________________________________

 

tables: edidc,

        mkpf,

        ekpo,

        rbkp,

        e1edk01,

        e1edka1,

        e1edk02,

        e1edp02.

 

data: iedidc   like edidc occurs 1 with header line,

      data_rec like edidd occurs 1 with header line.

 

data: c_docnum(16) type c,

      c_mblnr(10)  type c,

      c_invoic(10) type c,

      rc(1)        type c,

      lead_time    like lfm1-plifz,

      gr_qty       like mseg-erfmg,

      test_date    like sy-datum,

      gr_required  like ekpo-webre,

      po_number(10)    type n,

      po_lineno    like ekpo-ebelp,

      n_vend(10)   type n,

      vendor_id    like lfa1-lifnr.

 

data: begin of itab_gr occurs 0,

        mblnr like mkpf-mblnr,

        bwart like mseg-bwart,

        erfmg like mseg-erfmg,

      end of itab_gr.

 

constants:

* name of container element (workitem object id)

  C_ELEMENT_WI_OBJ_ID      LIKE SWCONT-ELEMENT VALUE '_WI_OBJECT_ID',

* name of container element (NumberPlusEventcode)

  C_ELEMENT_NO_PLUS_INFO   LIKE SWCONT-ELEMENT

                           VALUE 'NumberPlusEventcode'.

 

ranges: r_status for edidc-status.

 

TYPE-POOLS:

* general idoc type pool

  TIDOC.

 

************************************************************************

* INCLUDES                                                             *

************************************************************************

* include for workflow programming

INCLUDE <CNTN01>.

 

************************************************************************

* INNITIALIZATION                                                      *

************************************************************************

initialization.

* create IDoc status selection table.

  clear r_status. refresh r_status.

 

  MOVE: 'EQ'      TO r_status-OPTION,   "equals

        'I'       TO r_status-SIGN,     "include

        '64'      TO r_status-LOW.

  APPEND r_status.

  MOVE: '66'      TO r_status-LOW.

  APPEND r_status.

 

************************************************************************

* START-OF-SELECTION

************************************************************************

start-of-selection.

 

  select * from edidc into table iedidc

    where status in r_status and

          direct = '2' and      "inbound

          mestyp = 'INVOIC' and

          mescod = 'MM'.

 

  loop at iedidc.

    clear rc.

 

    CALL FUNCTION 'EDI_DOCUMENT_OPEN_FOR_READ'

         EXPORTING

              DOCUMENT_NUMBER         = iedidc-docnum

         IMPORTING

              IDOC_CONTROL            = IEDIDC

         EXCEPTIONS

              DOCUMENT_FOREIGN_LOCK   = 01

              DOCUMENT_NOT_EXIST      = 02

              DOCUMENT_NUMBER_INVALID = 03

              ERROR_MESSAGE           = 04

              OTHERS                  = 05.

 

    IF NOT SY-SUBRC IS INITIAL.

      c_docnum = iedidc-docnum.

      shift c_docnum left deleting leading '0'.

* 'Cannot open INVOIC IDoc & for Goods Receipt processing'

      message w025 with c_docnum.

      continue.

    ENDIF.

 

    call function 'EDI_SEGMENTS_GET_ALL'

        exporting

         document_number         = iedidc-docnum

        tables

         idoc_containers         = data_rec

        exceptions

         document_number_invalid = 1

         end_of_document         = 2

         others                  = 3.

 

    if not sy-subrc is initial.

      CALL FUNCTION 'EDI_DOCUMENT_CLOSE_READ'

          EXPORTING

            DOCUMENT_NUMBER         =  iedidc-docnum

          IMPORTING

            IDOC_CONTROL            =  iedidc

 

      c_docnum = iedidc-docnum.

      shift c_docnum left deleting leading '0'.

* 'Cannot retrieve data for INVOIC IDoc & (Goods Receipt processing)'

      message w030 with c_docnum.

      continue.

    else.

      CALL FUNCTION 'EDI_DOCUMENT_CLOSE_READ'

          EXPORTING

            DOCUMENT_NUMBER         =  iedidc-docnum

          IMPORTING

            IDOC_CONTROL            =  iedidc.

* If this is a change or modify IDoc, change status to 51 (error).

* One & only one K01 segment should exist -

      read table data_rec with key segnam = 'E1EDK01'.

      if sy-subrc is initial.

        move data_rec-sdata to e1edk01.

        case e1edk01-action.

          when '000'.  "original data

* OK - do nothing

          when '002'.  "modified data

* 'Invoice & - IDoc for Review Only'

            perform idoc_status_update using '51' '028'

                                             'Modification' ' '.

          when '002'.  "modified data

* 'Invoice & - IDoc for Review Only'

            perform idoc_status_update using '51' '028'

                                             'Cancellation' ' '.

        endcase.

      endif.

      check rc is initial.

* get the vendor no.

      clear vendor_id.

      loop at data_rec where segnam = 'E1EDKA1'.

        move data_rec-sdata to e1edka1.

        check: e1edka1-parvw = 'LF',

               e1edka1-partn co ' 0123456789',

               e1edka1-partn <> ' '.

        n_vend = e1edka1-partn.

        vendor_id = n_vend.

      endloop.

* if this is a new IDoc, check to make sure it even needs the GR test

      clear gr_required.

      loop at data_rec where segnam = 'E1EDP02'.

        move data_rec-sdata to e1edp02.

        check: e1edp02-qualf = '001',

               e1edp02-belnr <> ' ',

               e1edp02-zeile <> ' '.

* Note that a missing PO number / line number is NOT an error here -

* the IDoc will error in the standard SAP processing in RBDAPP01

        shift e1edp02-belnr left deleting leading '0'.

        clear: po_number, po_lineno.

        if e1edp02-belnr co ' 0123456789'.

          po_number = e1edp02-belnr.

        endif.

        if e1edp02-zeile co ' 0123456789'.

          po_lineno = e1edp02-zeile.

        endif.

        select single webre from ekpo into gr_required

            where ebeln = po_number

              and ebelp = po_lineno.

        if ( sy-subrc is initial and gr_required = 'X' ).

          exit.

        endif.

      endloop.  "E1EDP02 segments

* if any line item on this invoice requires a goods receipt, continue

* receipt evaluation. Otherwise, status the IDoc to go to standard SAP

* processing. (Assumption is made that if an IDoc has status 66, the GR

* flag was turned "on" at some point and has since been removed.)

      if gr_required is initial.  "no goods receipt required

        if iedidc-status = '66'.

* 'Goods Receipt no longer required'

          perform idoc_status_update using '64' '026' ' ' ' '.

        endif.

        continue. "next IDoc

      endif.

 

* Should be only one K02, but loop just in case...

      loop at data_rec where segnam = 'E1EDK02'.

        move data_rec-sdata to e1edk02.

        if e1edk02-qualf = '009'.

* if an invoice already exists for this ref. no., give the IDoc

* an error status

          select single belnr from rbkp into rbkp-belnr

            where xblnr = e1edk02-belnr(16)

              and blart = 'KR' "invoice

              and stblg = ' '. "no reversal

          if sy-subrc is initial.

*'Invoice & already exists for ref.no. &'

            c_invoic = rbkp-belnr.

            shift c_invoic left deleting leading '0'.

            perform idoc_status_update using '51' '027'

                             c_invoic e1edk02-belnr(16).

            exit. "exit loop on data recs for this IDoc

          endif.

          clear: itab_gr, gr_qty.

          refresh: itab_gr.

          select a~mblnr

                 b~bwart b~erfmg

            into corresponding fields of table itab_gr

              from mkpf as a

                 inner join mseg as b

                    on a~mblnr = b~mblnr

              where a~vgart = 'WE' "goods receipt for PO

                and a~blart = 'WE' "goods receipt

                and a~xblnr = e1edk02-belnr(16).

          loop at itab_gr.

            case itab_gr-bwart.

              when '101'. "receipt

                gr_qty = gr_qty + itab_gr-erfmg.

              when '102'. "reversal

                gr_qty = gr_qty - itab_gr-erfmg.

            endcase.

          endloop.

* if no goods receipt

          if gr_qty <= 0.

           case iedidc-status.

* if new IDoc, status to '66'

             when '64'.

* 'Waiting for Goods Receipt'

               perform idoc_status_update using '66' '022' ' ' ' '.

* if reprocessed IDoc, check length of delay and status to 51

* (late receipt) if > 10 days.

             when '66'.

               clear lead_time.

               select single plifz from lfm1 into lead_time

                   where lifnr = vendor_id

                     and ekorg = '7100'.

               if lead_time is initial.

                 lead_time = 10.

               endif.

               test_date = iedidc-credat + lead_time.

**TEST

**               if test_date > sy-datum.

**TEST

               if test_date <= sy-datum.

 

* 'Goods Receipt Overdue'

                 perform idoc_status_update using '51' '024' ' ' ' '.

               else.

* do nothing - IDoc stays in status 66 and gets tested for GR in next

* job run

               endif.

            endcase.

          else. "goods receipt exists

* if this is a reprocess of an IDoc for which a goods receipt now

* exists, give the IDoc status 64, so it is processed by RBDAPP01

* in the next job step.

            if iedidc-status = '66'.

              c_mblnr = mkpf-mblnr.

              shift c_mblnr left deleting leading '0'.

* 'Goods Receipt found for ref.no. &'

              perform idoc_status_update

                            using '64' '023' e1edk02-belnr(16) ' '.

            endif.

          endif.

        else.  "wrong K02 qualifier

* do nothing - IDoc will try to post and be handled manually

        endif.  "QUALF='009'

      endloop.  "data_rec

    endif.  "successful retrieval of IDoc data segments > data_rec

 

  endloop.  "iedidc

 

end-of-selection.

 

*-----------------------------------------------------------------------

*  FORM IDOC_STATUS_UPDATE

*  Creates status records for the selected IDocs.

*-----------------------------------------------------------------------

FORM IDOC_STATUS_UPDATE using value(i_stat)

                              value(i_msgno)

                              value(i_msgv1)

                              value(i_msgv2).

tables: edi_ds, tede2.

 

DATA: MESS like EDIMESSAGE.

 

data:

    l_commit_counter        LIKE ediglodata-comcount value '00000001',

    inbsync                 LIKE ediglodata-inbsync,

    t_couple_to_process     LIKE ediinbound OCCURS 0 WITH HEADER LINE.

 

  CALL FUNCTION 'EDI_DOCUMENT_OPEN_FOR_PROCESS'

         EXPORTING

              DOCUMENT_NUMBER         = iedidc-docnum

         IMPORTING

              IDOC_CONTROL            = IEDIDC

         EXCEPTIONS

              DOCUMENT_FOREIGN_LOCK   = 01

              DOCUMENT_NOT_EXIST      = 02

              DOCUMENT_NUMBER_INVALID = 03

              ERROR_MESSAGE           = 04

              OTHERS                  = 05.

 

  IF NOT SY-SUBRC IS INITIAL.

      c_docnum = iedidc-docnum.

      shift c_docnum left deleting leading '0'.

* 'Cannot open INVOIC IDoc & for Goods Receipt processing'

      message w025 with c_docnum.

      rc = 'X'.

      exit.

  ENDIF.

 

  CLEAR EDI_DS.

  EDI_DS-DOCNUM      = iedidc-DOCNUM.

  EDI_DS-STATUS      = i_stat.

  EDI_DS-REPID       = 'ZS7BM000007'.

  EDI_DS-TABNAM      = 'EDI_DS'.

  EDI_DS-MANDT       = SY-MANDT.

  EDI_DS-STAMQU      = 'SAP'.

  EDI_DS-STAMID      = 'ZS7'.

  EDI_DS-STAMNO      = i_msgno.

  EDI_DS-STAPA1      = i_msgv1.

  EDI_DS-STAPA2      = i_msgv2.

  GET TIME.

  EDI_DS-LOGDAT      = SY-DATUM.

  EDI_DS-LOGTIM      = SY-UZEIT.

 

  CALL FUNCTION 'EDI_DOCUMENT_STATUS_SET'

    EXPORTING

      DOCUMENT_NUMBER               = iedidc-DOCNUM

      IDOC_STATUS                   = edi_ds

    IMPORTING

      IDOC_CONTROL                  = iedidc

    EXCEPTIONS

      DOCUMENT_NUMBER_INVALID       = 1

      OTHER_FIELDS_INVALID          = 2

      STATUS_INVALID                = 3

      OTHERS                        = 4

            .

  IF NOT SY-SUBRC IS INITIAL.

    c_docnum = iedidc-docnum.

    shift c_docnum left deleting leading '0'.

* IDoc no. & failed status update to &

    message w021 with c_docnum i_stat.

  ENDIF.

 

  CALL FUNCTION 'EDI_DOCUMENT_CLOSE_PROCESS'

        EXPORTING

          DOCUMENT_NUMBER     =  iedidc-DOCNUM.

 

  if i_stat = '51'.

 

      clear: t_couple_to_process.

      refresh: t_couple_to_process.

 

      select single * from tede2 into tede2

         where evcode = 'INVL'.

      if sy-subrc is initial.

        t_couple_to_process(16) = iedidc-docnum.

        t_couple_to_process+16(138) = tede2.

        append t_couple_to_process.

 

        PERFORM analyzing_event_create

                TABLES

                   t_couple_to_process

                USING

                   l_commit_counter

                   inbsync.

        if sy-subrc is initial.

 

          MESS-MSGID = 'ZS7'.

          MESS-MSGTY = 'E'.

          MESS-MSGNO = i_msgno.

          MESS-MSGV1 = i_msgv1.

          MESS-MSGV2 = i_msgv2.

          CALL FUNCTION 'IDOC_ERROR_WORKFLOW_START'

            EXPORTING

              DOCNUM                        = 0

              EVENTCODE                     = 'EDIM'

              MESS                          = mess

              STATUSMESS                    = mess

            EXCEPTIONS

              NO_ENTRY_IN_TEDE5             = 1

              ERROR_IN_START_WORKFLOW       = 2

              OTHERS                        = 3.

 

          COMMIT WORK.

        endif.  "link created

      endif.  "tede2 found

 

  endif.

 

* Set return code to stop further processing of this IDoc

  rc = 'X'.

 

ENDFORM.

 

 

*-----------------------------------------------------------------------

*  FORM ANALYZING_EVENT_CREATE

*  Creates link between IDoc and workflow container.

*  SAP code stolen from LEDINF01

*-----------------------------------------------------------------------

FORM analyzing_event_create

                TABLES

                   t_couple_to_process_in  STRUCTURE ediinbound

                USING

                   commit_counter_in       LIKE      ediglodata-comcount

                   start_recfb_synchron_in LIKE      ediglodata-inbsync.

* local variables

  DATA:

* instance that is created

    l_object               TYPE swc_object,

* object key, e.g IDoc number

    l_object_key           LIKE swotobjid-objkey,

* id of wf event

    l_event_id             LIKE swedumevid-evtid,

* status record for case of error

    l_status_record        TYPE tidoc_status_record_ext,

* flag indicating whether subscribed task is started synchronously

    l_start_recfb_synchron LIKE sweflags-syncflag VALUE ' ',

* idoc number (needed because of type checking)

    l_idoc_number          LIKE edidc-docnum.

* local constants

  CONSTANTS:

* object type 'IDOC'

    c_object_type          LIKE swetypecou-objtype VALUE 'IDOCINVOIC',

* name of event to be created

    c_idc_evt     LIKE swetypecou-event VALUE 'INPUTERROROCCURREDMM'

.

 

 if t_couple_to_process_in[] is initial.

    COMMIT WORK.

    CALL FUNCTION 'DEQUEUE_ALL'.

    CLEAR commit_counter_in.

    exit.

  endif.

 

* cast

  l_start_recfb_synchron = start_recfb_synchron_in.

* declaration of container

  swc_container       l_t_ev_container.

* initialize container

  swc_clear_container l_t_ev_container.

 

* dequeue all idocs at the same time

  LOOP AT t_couple_to_process_in.

* cast

    l_idoc_number = t_couple_to_process_in(16).

    CALL FUNCTION 'EDI_DOCUMENT_DEQUEUE_LATER'

         EXPORTING

              docnum = l_idoc_number

         EXCEPTIONS

              OTHERS = 0.

  ENDLOOP.

 

* get first idoc number in table in order to create an object

  READ TABLE t_couple_to_process_in INDEX 1.

* set object key in variable of correct type (casting)

  l_object_key = t_couple_to_process_in(16).

 

* create an object, i.e. an IDoc

  swc_create_object l_object c_object_type l_object_key.

 

* fill container: work item object id (idoc)

  swc_set_element l_t_ev_container     "EC *

                  c_element_wi_obj_id  "EC *

                  l_object.            "EC *

* fill container:  NumberPlusEventcode (table of couples)

  swc_set_table l_t_ev_container

                c_element_no_plus_info

                t_couple_to_process_in.

 

* fire event that will trigger the idoc inbound processing

  CALL FUNCTION 'SWE_EVENT_CREATE'

       EXPORTING

            objtype              = c_object_type

            objkey               = l_object_key

            event                = c_idc_evt

*           CREATOR              = ' '

*           START_WITH_DELAY     = ' '

            start_recfb_synchron = l_start_recfb_synchron

       IMPORTING

            event_id             = l_event_id

       TABLES

            event_container      = l_t_ev_container

       EXCEPTIONS

            objtype_not_found    = 1

            OTHERS               = 2.

 

  IF   ( sy-subrc <> 0 )

* event was not created => error handling for this idoc (EDIM)

    OR ( l_event_id = 0 ).

* stop processing, no commit

    MESSAGE ID      'E0'

            TYPE    'A'

            NUMBER  '374'

            WITH    l_status_record-docnum

                    c_idc_evt

            RAISING event_create_failed.

  ELSE.

* do commit and reset counter

* the commit will get the idocs to the database and at the same time

* activate the event that was created

    COMMIT WORK.

* dequeue all unprocessed IDocs to avoid log-overflow

    CALL FUNCTION 'DEQUEUE_ALL'.

    CLEAR commit_counter_in.

* reset table of idocs that need to be processed

    CLEAR   t_couple_to_process_in.

    REFRESH t_couple_to_process_in.

  ENDIF.

 

ENDFORM.                               " ANALYZING_EVENT_CREATE


Related Items:

 
Next >

Google Seach

Google Ads

Shared Bottom Border

Contact Us | Polls | Add URL | Contribute | Privacy | Terms | Feedback

Discussion Forum | BLOG | Consultants: Post your resume | Companies: Advertise on ERPGenie.COM | Post Job
Financials Consultant | Consultant Review | Gallia Consulting | Supply Chain Project | SAP Financials Forum
GenieHoldings.COM, Inc. | Genie Press | WorkflowGenie | ESAGenie | ERPTopSites | ABAP Tips and Tricks | SAP Solutions Database

EDIGenie | Searching Survivor