Enterprise Resource Planning Blogs by Members
Gain new perspectives and knowledge about enterprise resource planning in blog posts from community members. Share your own comments and ERP insights today!
cancel
Showing results for 
Search instead for 
Did you mean: 
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.
Labels in this area