Skip to Content
Technical Articles
Author's profile photo Maximilian von Liechtenstein

Migration of PO release strategy framework to SD

Sometimes it is necessary to implement a release strategy for sales orders in SD in a similar fashion than the release strategy framework which comes as part of the standard with MM. There are no principal reasons why the MM release strategy framework could not be migrated to SD because the release concept is largely module-independent by design. Hence we set out to migrate the MM release strategy framework across modules to SD.

 

As a first step extend VBAK with the following Append-Structure in order to migrate the release-relevant fields from EKKO to VBAK:

 

 

Because we have extended VBAK, we now need to ensure that the sales order BAPI can update the new custom fields. Therefore we need to add Append structures with the new custom fields to VBAKKOZ,VBAKKOZX,BAPE_VBAK,BAPE_VBAKX. Below is an illustrative example regarding BAPE_VBAK. The other structures which I have mentioned need to be extended in the same way.

 

 

Now we need to copy function group EBNF to ZBNF and copy function modules ME_REL_EVENT_EKKO to Z_SD_REL_EVENT_VBAK and ME_REL_GET_REPONSIBLE to Z_SD_REL_GET_RESPONSIBLE.

After migration the coding in these function modules is as follows:

FUNCTION Z_SD_REL_EVENT_VBAK.
*"----------------------------------------------------------------------
*"*"Verbuchungsfunktionsbaustein:
*"
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(I_FRGCO) LIKE  T16FC-FRGCO OPTIONAL
*"     VALUE(I_WFVKB) LIKE  VBAK-VBELN OPTIONAL
*"     VALUE(I_ERNAM) LIKE  VBAK-ERNAM OPTIONAL
*"     VALUE(I_COMPL) LIKE  BAPIMMPARA-SELECTION OPTIONAL
*"     VALUE(I_NVBAK) LIKE  VBAK STRUCTURE  VBAK OPTIONAL
*"     VALUE(I_OVBAK) LIKE  VBAK STRUCTURE  VBAK OPTIONAL
*"----------------------------------------------------------------------
  INCLUDE <cntain>.
  FIELD-SYMBOLS: <f1>.
  DATA:  xfrg1 LIKE VBAK-frgzu,
         xfrg2 LIKE VBAK-frgzu.
  DATA: objtype LIKE swetypecou-objtype,
        event   LIKE swetypecou-event,
        objkey  LIKE sweinstcou-objkey,
        eventid LIKE swedumevid-evtid.
  REFRESH wfce.
  DATA BEGIN OF applicant.
          INCLUDE STRUCTURE swhactor.
  DATA  END OF applicant.
*-- Prüfen des Einkaufsbelegs -----------------------------------------*
*-- Prüfen freigaberelevante Änderungen -------------------------------*

  CHECK i_nVBAK-frggr NE i_oVBAK-frggr OR
        i_nVBAK-frgsx NE i_oVBAK-frgsx OR
        i_nVBAK-frgzu NE i_oVBAK-frgzu .

*---- Relevante Codes ermitteln für neuen Zustand----------------------*
  IF i_nVBAK-frggr NE space AND
     i_nVBAK-frgsx NE space.
    PERFORM read_t16fv USING i_nVBAK-frggr i_nVBAK-frgsx.
    LOOP AT xt16fv WHERE frggr EQ i_nVBAK-frggr
                     AND frgsx EQ i_nVBAK-frgsx
                     AND frgwf NE space.
      xfrg1 = xt16fv+9(8).
      xfrg2 = i_nVBAK-frgzu.
      TRANSLATE xfrg2 USING 'X  +'.
      OVERLAY xfrg1 WITH xfrg2 ONLY '+'.
*---- Keine Freigabezuständigkeit -------------------------------------*
      SEARCH xfrg1 FOR 'X'.
      CHECK sy-subrc EQ 0.
      ASSIGN xfrg2+sy-fdpos(1) TO <f1>.
*---- Keine Freigabezuständigkeit -------------------------------------*
      SEARCH xfrg1 FOR '+'.
      CHECK sy-subrc NE 0.
*---- Relevante Codes merken ------------------------------------------*
      CLEAR wfce.
      wfce-VBELN = i_nVBAK-VBELN.
      wfce-ernam = i_nVBAK-ernam.
      wfce-frgco = xt16fv-frgco.
*---- Freigabe bereits erfolgt ----------------------------------------*
      IF <f1> EQ space.
        wfce-delkz = 'F'.
      ELSE.
        IF <f1> CA '+' AND i_nVBAK-frgrl EQ space.
          wfce-delkz = 'X'.
        ENDIF.
      ENDIF.
      APPEND wfce.
    ENDLOOP.
    SORT wfce.
  ENDIF.

*- alter Zustand ------------------------------------------------------*
  IF  i_oVBAK-frggr NE space AND
      i_oVBAK-frgsx NE space. "rejected
*---- Relevante Codes ermitteln ---------------------------------------*
    PERFORM read_t16fv USING i_oVBAK-frggr i_oVBAK-frgsx.
    LOOP AT xt16fv WHERE frggr EQ i_oVBAK-frggr
                     AND frgsx EQ i_oVBAK-frgsx
                     AND frgwf NE space.
      xfrg1 = xt16fv+9(8).
      xfrg2 = i_oVBAK-frgzu.
      TRANSLATE xfrg2 USING 'X  +'.
      OVERLAY xfrg1 WITH xfrg2 ONLY '+'.
*---- Keine Freigabezuständigkeit -------------------------------------*
      SEARCH xfrg1 FOR 'X'.
      CHECK sy-subrc EQ 0.
*---- Freigabe bereits erfolgt ----------------------------------------*
      ASSIGN xfrg2+sy-fdpos(1) TO <f1>.
*---- Keine Freigabezuständigkeit -------------------------------------*
      SEARCH xfrg1 FOR '+'.
      CHECK sy-subrc NE 0.
*---- Relevante Codes merken ------------------------------------------*
      CLEAR wfcekey.
      wfcekey-VBELN = i_oVBAK-VBELN.
      wfcekey-frgco = xt16fv-frgco.
      READ TABLE wfce WITH KEY wfcekey BINARY SEARCH.
*---- Code nicht mehr relevant ----------------------------------------*
      IF sy-subrc NE 0.
        CHECK <f1> NE space.
        MOVE-CORRESPONDING wfcekey TO wfce.
        wfce-ernam = i_oVBAK-ernam.
        wfce-delkz = 'X'.
        INSERT wfce INDEX sy-tabix.
*---- Code vorher schon relevant --------------------------------------*
      ELSE.
*---- EKBeleg neu nicht freigegeben -----------------------------------*
        IF wfce-delkz EQ space.
*---- EkBeleg alt nicht freigegeben -> keine Änderung -----------------*
          IF <f1> NE space AND i_oVBAK-frgrl NE space.
            IF i_nVBAK-frgsx EQ i_oVBAK-frgsx
               AND i_nVBAK-frggr EQ i_oVBAK-frggr.
              DELETE wfce INDEX sy-tabix.
            ELSE.
              CLEAR wfce.
              wfce-VBELN = i_oVBAK-VBELN.
              wfce-ernam = i_oVBAK-ernam.
              wfce-frgco = xt16fv-frgco.
              wfce-delkz = 'X'.
              APPEND wfce.
            ENDIF.
          ENDIF.
*---- EKBeleg neu freigegeben -----------------------------------------*
        ELSE.
*---- EKBeleg alt freigegeben -> keine Änderung -----------------------*
          IF <f1> EQ space.
            DELETE wfce INDEX sy-tabix.
          ENDIF.
        ENDIF.
      ENDIF.
    ENDLOOP.
  ENDIF.



  objtype = 'ZBUS2032'.

*- ReleaseStepCreated -------------------------------------------------*
  objtype = objtype.
  event   = 'RELEASESTEPCREATED'.
  swc_container VBAK_container.
  LOOP AT wfce WHERE delkz EQ space OR
                     delkz EQ 'Z'.
    swc_clear_container VBAK_container.
    swc_create_container VBAK_container.
    swc_set_element VBAK_container 'ReleaseCode' wfce-frgco.
    objkey(10) = wfce-VBELN.
    applicant-otype = 'US'.
    applicant-objid = wfce-ernam.

    CALL FUNCTION 'SWE_EVENT_CREATE'
         EXPORTING
              objtype           = objtype
              objkey            = objkey
              event             = event
              creator           = applicant
              start_with_delay  = ' '
*    IMPORTING
*         EVENT_ID          = EVENTID
         TABLES
              event_container   = VBAK_container
         EXCEPTIONS
              objtype_not_found = 01.
  ENDLOOP.
*- Workflows beenden --------------------------------------------------*
*- SignificantlyChanged -----------------------------------------------*
  event   = 'SIGNIFICANTLYCHANGED'.
  LOOP AT wfce WHERE delkz EQ 'X'.
    swc_clear_container VBAK_container.
    swc_create_container VBAK_container.
    swc_set_element VBAK_container 'ReleaseCode' wfce-frgco.
    objkey(10) = wfce-VBELN.
    applicant-otype = 'US'.
    applicant-objid = sy-uname.                                     "GF

    CALL FUNCTION 'SWE_EVENT_CREATE'
         EXPORTING
              objtype           = objtype
              objkey            = objkey
              event             = event
              creator           = applicant
              start_with_delay  = ' '
*    IMPORTING
*         EVENT_ID          = EVENTID
         TABLES
              event_container   = VBAK_container
         EXCEPTIONS
              objtype_not_found = 01.
  ENDLOOP.

*- Released - ---------------------------------------------------------*
  event   = 'RELEASED'.
  LOOP AT wfce WHERE delkz EQ 'F'.
    swc_clear_container VBAK_container.
    swc_create_container VBAK_container.
    swc_set_element VBAK_container 'ReleaseCode' wfce-frgco.
    objkey(10) = wfce-VBELN.
    applicant-otype = 'US'.
    applicant-objid = sy-uname.                                    "GF

    CALL FUNCTION 'SWE_EVENT_CREATE'
         EXPORTING
              objtype           = objtype
              objkey            = objkey
              event             = event
              creator           = applicant
              start_with_delay  = ' '
*    IMPORTING
*         EVENT_ID          = EVENTID
         TABLES
              event_container   = VBAK_container
         EXCEPTIONS
              objtype_not_found = 01.
  ENDLOOP.



ENDFUNCTION.

 

 

FUNCTION Z_SD_REL_GET_RESPONSIBLE .
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  TABLES
*"      ACTOR_TAB STRUCTURE  SWHACTOR
*"      AC_CONTAINER STRUCTURE  SWCONT
*"  EXCEPTIONS
*"      NOBODY_FOUND
*"----------------------------------------------------------------------

  INCLUDE <cntain>.
  TABLES: vbak, t16fw.
*data: eban-object type swc_object.
  DATA: object TYPE swc_object.
  DATA: h_object_ext LIKE rhobjects-object.                 "108391
*  DATA: BEGIN OF ebankey,
*           banfn LIKE eban-banfn,
*           bnfpo LIKE eban-bnfpo,
*        END OF ebankey.

  DATA: BEGIN OF vbakkey,
           vbeln LIKE vbak-vbeln,
        END OF vbakkey.
* Initialisieren der Tabelle ACTOR_TAB
  REFRESH actor_tab.
  CLEAR actor_tab.
  swc_get_element ac_container 'ReleaseCode' rm06b-frgab.
*  swc_get_element ac_container 'requisition' object.


    PERFORM get_object TABLES ac_container
                       CHANGING object.
*   swc_get_element ac_container 'purchaseorder' object.
* Objectschlüssel in das Anwendungsfeld bringen
    swc_get_object_key object vbakkey.
* Freigabeverantwortlicher für Einkaufsbeleg
    SELECT SINGLE * FROM vbak WHERE vbeln EQ vbakkey-vbeln.
    IF sy-subrc > 0.
      RAISE nobody_found.
    ENDIF.

* Code lesen
    SELECT SINGLE * FROM t16fc WHERE frggr EQ vbak-frggr
                                 AND frgco EQ rm06b-frgab.
* Typ der Ermittlung des Verantwortlichen
    CASE t16fc-frgwf.
* keine Ermittlung
      WHEN space.
        RAISE nobody_found.
* Ermittlung über T16fW
      WHEN '1'.
        SELECT SINGLE * FROM t16fw WHERE frggr = vbak-frggr
                                     AND frgco = rm06b-frgab
                                     AND werks = space.
        IF sy-subrc NE 0.
          RAISE nobody_found.
        ELSE.
          actor_tab-otype = t16fw-otype.
          actor_tab-objid = t16fw-objid.
          APPEND actor_tab.
        ENDIF.
* Ermittlung über User-exit
      WHEN '9'.
        CALL CUSTOMER-FUNCTION '005'
           EXPORTING i_vbak    = vbak
                     i_frgco   = t16fc-frgco
           TABLES actor_tab    = actor_tab
                  ac_container = ac_container.              "H91758

* keine Ermittlung
      WHEN OTHERS.
        RAISE nobody_found.
    ENDCASE.


* Verprobung der ermittelten Verantwortlichen.                 "108391

  LOOP AT actor_tab.                                        "108391
    h_object_ext = actor_tab.

    CALL FUNCTION 'RH_WF_OBJID_UNPACK'                      "160606
         EXPORTING
              act_object_ext = h_object_ext
         IMPORTING
              act_object_ext = h_object_ext.
    actor_tab = h_object_ext.
    MODIFY actor_tab.

    CALL FUNCTION 'RH_CHECK_ORG_OBJECT_EXISTS'              "108391
         EXPORTING
              act_object_ext       = h_object_ext
              authority_check      = ' '
     EXCEPTIONS
          no_active_plvar      = 1
          no_org_object        = 2
          org_object_not_found = 3
          OTHERS               = 4.

    IF sy-subrc <> 0.
      RAISE nobody_found.
    ENDIF.
  ENDLOOP.
ENDFUNCTION.

*---------------------------------------------------------------------*
*       FORM GET_OBJECT                                               *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
*  -->  AC_CONTAINER                                                  *
*  -->  OBJECT                                                        *
*---------------------------------------------------------------------*
FORM get_object TABLES ac_container STRUCTURE swcont
                CHANGING object.
  swc_get_element ac_container 'salesorder' object.

ENDFORM.                    "get_object

 

 

The next step involves copying function group GDWF to ZGDWF and copy function module BAPI_PO_RELEASE to ZBAPI_SO_RELEASE. After migration the new function module has the following coding:

FUNCTION ZBAPI_SO_RELEASE.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(SALESORDER) TYPE  VBELN
*"     VALUE(REL_CODE) LIKE  BAPIMMPARA-PO_REL_COD
*"     VALUE(USE_EXCEPTIONS) LIKE  BAPIMMPARA-SELECTION DEFAULT 'X'
*"     VALUE(NO_COMMIT) TYPE  BAPIMMPARA-SELECTION DEFAULT ' '
*"  EXPORTING
*"     VALUE(REL_STATUS_NEW) LIKE  BAPIMMPARA-REL_STATUS
*"     VALUE(REL_INDICATOR_NEW) LIKE  BAPIMMPARA-PO_REL_IND
*"     VALUE(RET_CODE) TYPE  SY-SUBRC
*"  TABLES
*"      RETURN STRUCTURE  BAPIRETURN OPTIONAL
*"  EXCEPTIONS
*"      AUTHORITY_CHECK_FAIL
*"      DOCUMENT_NOT_FOUND
*"      ENQUEUE_FAIL
*"      PREREQUISITE_FAIL
*"      RELEASE_ALREADY_POSTED
*"      RESPONSIBILITY_FAIL
*"----------------------------------------------------------------------

  DATA: e_frgrl LIKE VBAK-frgrl,                            "#EC *
        l_tcode LIKE sy-tcode,
        lo_buffer TYPE REF TO cl_mmbsi_srm_ctr_buffer.      "1527696

* BAPIRETURN additionally filled with release 4.0A
  CLEAR return.
  REFRESH return.


** read document
*  CALL FUNCTION 'ME_VBAK_SINGLE_READ'
*    EXPORTING
*      pi_ebeln            = purchaseorder
*      pi_bypassing_buffer = 'X'
*      pi_refresh_buffer   = 'X'
*    IMPORTING
*      po_VBAK             = VBAK
*    EXCEPTIONS
*      no_records_found    = 1
*      OTHERS              = 2.

CALL FUNCTION 'SD_VBAK_SINGLE_READ'
  EXPORTING
    I_VBELN                  = SALESORDER
*   I_BYPASSING_BUFFER       = ' '
*   I_REFRESH_BUFFER         =
 IMPORTING
   E_VBAK                   = vbak
 EXCEPTIONS
   RECORD_NOT_FOUND         = 1
   OTHERS                   = 2
          .



  IF sy-subrc NE 0.
    PERFORM fill_bapireturn TABLES return
                            USING  sy-msgty
                                   sy-msgid
                                   sy-msgno
                                   sy-msgv1
                                   sy-msgv2
                                   sy-msgv3
                                   sy-msgv4   .
    IF use_exceptions NE space.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
              RAISING  document_not_found.
    ENDIF.
    EXIT.
  ENDIF.



*- Authority-check ----------------------------------------------------*
  AUTHORITY-CHECK OBJECT 'M_EINK_FRG'
    ID 'FRGGR' FIELD vbak-frggr
    ID 'FRGCO' FIELD rel_code.
  IF sy-subrc NE 0.
    PERFORM fill_bapireturn TABLES return
                            USING  'E'
                                   'W5'
                                   '100'
                                   space
                                   space
                                   space
                                   space.
    IF use_exceptions NE space.
      MESSAGE e100 RAISING authority_check_fail.
    ENDIF.
    EXIT.
  ENDIF.



*-- Set release -------------------------------------------------------*
  CLEAR yvbak.
  MOVE vbak TO yvbak.

  CALL FUNCTION 'ME_REL_SET'
    EXPORTING
      i_frgrl                = yVBAK-frgrl
      i_frgco                = rel_code
      i_frgkz                = yVBAK-frgke
      i_frggr                = yVBAK-frggr
      i_frgst                = yVBAK-frgsx
      i_frgzu                = yVBAK-frgzu
      i_frgot                = '2'
    IMPORTING
      e_frgkz                = VBAK-frgke
      e_frgzu                = VBAK-frgzu
      e_frgrl                = VBAK-frgrl
    EXCEPTIONS
      prerequisite_fail      = 1
      release_already_posted = 2
      responsibility_fail    = 3
      error_message          = 0                            "n_947945
      OTHERS                 = 4.

  CASE sy-subrc.
    WHEN 1.
      PERFORM fill_bapireturn TABLES return
                              USING  'E'
                                     'ME'
                                     '102'
                                     space
                                     space
                                     space
                                     space.
      IF use_exceptions NE space.
        MESSAGE e102(me) RAISING prerequisite_fail.
      ENDIF.
      EXIT.
    WHEN 2.
      PERFORM fill_bapireturn TABLES return
                              USING  'E'
                                     'ME'
                                     '103'
                                     salesorder
                                     space
                                     space
                                     space.
      IF use_exceptions NE space.
        MESSAGE e103(me) WITH salesorder
                         RAISING release_already_posted.
      ENDIF.
      EXIT.
    WHEN 3.
      PERFORM fill_bapireturn TABLES return
                              USING  'E'
                                     'ME'
                                     '104'
                                     space
                                     space
                                     space
                                     space.
      IF use_exceptions NE space.
        MESSAGE e104(me) RAISING responsibility_fail.
      ENDIF.
      EXIT.
    WHEN 4.
      PERFORM fill_bapireturn TABLES return
                              USING  syst-msgty
                                     syst-msgid
                                     syst-msgno
                                     syst-msgv1
                                     syst-msgv2
                                     syst-msgv3
                                     syst-msgv4.
      EXIT.
  ENDCASE.




    DATA: ls_header_inx TYPE bapisdh1x,
    ls_header_in TYPE bapisdh1.

*    DATA lt_ext like BAPIPAREX occurs 0 with header line.

    data: lt_return type standard table of bapiret2.



    TYPES : BEGIN OF lty_valuepartx,

           valuepart1 TYPE valuepart,

           valuepart2 TYPE valuepart,

           valuepart3 TYPE valuepart,

           valuepart4 TYPE valuepart,

         END OF lty_valuepartx.

DATA : lt_extensionin TYPE TABLE OF bapiparex,

        lt_extensioninx TYPE TABLE OF bapiparex.

    DATA : ls_valuepart   TYPE lty_valuepartx,

            ls_bape_vbak   TYPE bape_vbak,

            ls_bape_vbakx  TYPE bape_vbakx,

            ls_extensionin TYPE bapiparex.




    ls_bape_vbak-vbeln        = SALESORDER.      " Sales Document Number

  IF VBAK-frgke NE yVBAK-frgke.
    ls_bape_vbak-FRGRL      = vbak-FRGRL.
  ENDIF.

  IF VBAK-frgrl NE yVBAK-frgrl.
    ls_bape_vbak-FRGRL      = vbak-FRGRL.
  ENDIF.


  IF VBAK-frgzu NE yVBAK-frgzu.
    ls_bape_vbak-FRGZU      = vbak-FRGZU.
  ENDIF.

    ls_valuepart              = ls_bape_vbak.

    ls_extensionin-structure  = 'BAPE_VBAK'.

    ls_extensionin-valuepart1 = ls_valuepart-valuepart1.

    ls_extensionin-valuepart2 = ls_valuepart-valuepart2.

    ls_extensionin-valuepart3 = ls_valuepart-valuepart3.

    ls_extensionin-valuepart4 = ls_valuepart-valuepart4.

    APPEND ls_extensionin TO lt_extensionin.

    CLEAR : ls_extensionin,

         ls_bape_vbak,

         ls_valuepart.

* Same way for BAPE_VBAPX also, populate extensionx information

  ls_bape_vbakx-vbeln       = SALESORDER.

*  ls_bape_vbak-FRGGR      = abap_true.
  IF VBAK-frgke NE yVBAK-frgke.
    ls_bape_vbak-FRGKE      = abap_true.
  ENDIF.

  IF VBAK-frgrl NE yVBAK-frgrl.
    ls_bape_vbak-FRGRL      = abap_true.
  ENDIF.

*  ls_bape_vbak-FRGSX      = abap_true.

  IF VBAK-frgzu NE yVBAK-frgzu.
    ls_bape_vbak-FRGZU      = abap_true.
  ENDIF.


  ls_valuepart              = ls_bape_vbakx.

  ls_extensionin-structure  = 'BAPE_VBAKX'.

  ls_extensionin-valuepart1 = ls_valuepart-valuepart1.

  ls_extensionin-valuepart2 = ls_valuepart-valuepart2.

  ls_extensionin-valuepart3 = ls_valuepart-valuepart3.

  ls_extensionin-valuepart4 = ls_valuepart-valuepart4.

  APPEND ls_extensionin TO lt_extensioninx.


    DATA ls_order_header_in TYPE BAPISDH1.
    DATA ls_order_header_inx TYPE BAPISDH1X.

    ls_order_header_inx-UPDATEFLAG = 'U'.


    CALL FUNCTION 'BAPI_SALESORDER_CHANGE'
    EXPORTING
    salesdocument = SALESORDER
    order_header_in = ls_order_header_in
    order_header_inx = ls_order_header_inx
    TABLES
     extensionin      = lt_extensionin
     extensionex      = lt_extensioninx
     return = lt_return.

*     check for errors.
    LOOP AT lt_return transporting no fields WHERE type = 'A' Or type = 'E'.
      EXIT.
    ENDLOOP.

    If sy-subrc = 0.
      write: / 'Error in updating'.
    ELSE.
      commit work and wait.
    endif.

    IF VBAK-frgzu EQ ABAP_FALSE.

      CALL FUNCTION 'Z_SD_REL_EVENT_VBAK'
       EXPORTING
         I_FRGCO       = REL_CODE
         I_WFVKB       = vbak-vbeln
         I_ERNAM       = vbak-ERNAM
*         I_COMPL       =
*         I_NVBAK       =
*         I_OVBAK       =
                .

    ENDIF.


*- Sichern Daten  -----------------------------------------------------*
  rel_status_new = VBAK-frgzu.
  rel_indicator_new = VBAK-frgke.


ENDFUNCTION.

 

For the next steps we have to extend the standard BOR object for sales orders BUS2032 with the release-specific attributes, events and methods of purchase order BOR object BUS2012. Hence we define ZBUS2032 as follows:

 

 

The object methods are implemented as follows:

 

*****           Implementation of object type ZBUS2032             *****
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,
      SALESDOCUMENT LIKE VBAK-VBELN,
  END OF KEY.
END_DATA OBJECT. " Do not change.. DATA is generated

begin_method singlerelease changing container.
DATA: releasecode LIKE t16fc-frgco.
swc_get_element container 'ReleaseCode' releasecode.

CALL FUNCTION 'ZBAPI_SO_RELEASE'
    EXPORTING
      SALESORDER                = object-key-salesdocument
      REL_CODE                  = releasecode
*     USE_EXCEPTIONS               = 'X'
*     NO_COMMIT                    = ' '
*   IMPORTING
*     REL_STATUS_NEW               =
*     REL_INDICATOR_NEW            =
*     RET_CODE                     =
*   TABLES
*     RETURN                       =
*   EXCEPTIONS
*     AUTHORITY_CHECK_FAIL         = 1
*     DOCUMENT_NOT_FOUND           = 2
*     ENQUEUE_FAIL                 = 3
*     PREREQUISITE_FAIL            = 4
*     RELEASE_ALREADY_POSTED       = 5
*     RESPONSIBILITY_FAIL          = 6
*     OTHERS                       = 7
            .

IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
end_method.

BEGIN_METHOD CHANGEUSERSTATUS CHANGING CONTAINER.


DATA ls_vbak TYPE VBAK.

  CALL FUNCTION 'SD_VBAK_SINGLE_READ'
    EXPORTING
      I_VBELN                  = object-key-salesdocument
*     I_BYPASSING_BUFFER       = ' '
*     I_REFRESH_BUFFER         =
   IMPORTING
     E_VBAK                   = ls_vbak
   EXCEPTIONS
     RECORD_NOT_FOUND         = 1
     OTHERS                   = 2
            .



  CALL FUNCTION 'STATUS_CHANGE_EXTERN'
    EXPORTING
      CHECK_ONLY = ' '
      CLIENT = SY-MANDT
      OBJNR = ls_vbak-OBJNR
      USER_STATUS = 'FREI'
      SET_INACT = ' '
*      SET_CHGKZ =
      NO_CHECK = ' '
*    IMPORTING
*      STONR =
    EXCEPTIONS
      OBJECT_NOT_FOUND = 01
      STATUS_INCONSISTENT = 02
      STATUS_NOT_ALLOWED = 03
      OTHERS = 04.
  CASE SY-SUBRC.
    WHEN 0.            " OK
    WHEN 01.    " to be implemented
    WHEN 02.    " to be implemented
    WHEN 03.    " to be implemented
    WHEN OTHERS.       " to be implemented
  ENDCASE.
END_METHOD.

BEGIN_METHOD CREATERELEASESTEP CHANGING CONTAINER.


CALL FUNCTION 'Z_SD_REL_EVENT_VBAK'
 EXPORTING
*   I_FRGCO       =
    I_WFVKB       = object-key-salesdocument
*   I_ERNAM       =
*   I_COMPL       =
*   I_NVBAK       =
*   I_OVBAK       =
          .


END_METHOD.

 

Since we are blocking the release of a sales order by making use of user status, we now need to define a status profile in transaction BS02:

 

Basically when a sales order is initially created it is in status INIT, which is associated with blocking all the functions which require release. The status FREI then unblocks these functions after relase has been successfully effected.

 

Now we have successfully migrated the basic release framework across modules.

The framework can be used in many ways, however as an illustration we will next show a basic sales order release workflow, which is equivalent to the standard PO release workflow WF_PO_REL.

 

First we define a task which kicks of the release process once a sales order has been created:

 

 

Next we define a workflow pattern similar to the following:

 

 

This workflow is triggered like so:

 

 

The user decision regarding release approval is defined as follows:

 

 

What is a crucial aspect of the decision step is rule-based agent determination:

 

 

The third task in our workflow pattern is that of actual release following release approval by the agent:

The only thing which is still missing in the big picture is changing the user status of the sales order after successful release, so that all blocking is disabled. To achieve this objective we define a new task which is triggered by the RELEASED event of ZBUS2032:

 

All we have to do after receiving the RELEASED event is to set a user status on the sales order which removes blocking:

 

 

Now that we have successfully migrated the release framework and that we have also set up a basic sales order release workflow, all that is left to do is to customize the actual release strategies using the standard SPRO customizing in module MM.

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.