Preface
This blog posting deals with a specific limitation related to the material assignment to networks and the activation of requirements business processes in the Project Systems component of the SAP system. For a broader overview of these processes please visit the following links:
Introduction
Purchase requisitions generated by material components assigned to network activities in PS carries a big limitation in a certain condition. If a requisition belongs to a material that is subcontracted (i.e. special procurement type 30) and has a Bill of Material (BOM) then this BOM is not exploded at the time of purchase requisition creation, but only at the time of purchase order creation. For long leading items that have to be ordered as soon as possible, this could be a problem.
The purpose of the current blog posting is to propose some system modifications in order to overcome the aforementioned limitation. This blog posting is not intended to go through other solutions like the project MRP or the BOM transfer (transactions MD51 and CN33, respectively) that could lead to similar results. The reason is simply because sometimes customers are just not willing to accept these solutions.
There are some screen shots from a SAP test system with a proof of concept at the end of the posting.
SAP Note 102595
Concerning the aforementioned limitation SAP states in note 102595 that “This is due to technical reasons. The function module ME_REQUISITION_EXT, which generates the purchase requisitions, cannot manage components. BOM explosions and changes of existing components are not provided”. It also states that “As of SAP ERP 6.05 (SAP ERP 6.00 with Enhancement Package 5), purchase requisitions with the 'Subcontracting' item category can be created using the sales order and a BOM explosion is carried out”. Nothing is clearly stated nevertheless about the limitation of purchase requisitions created using PS.
System modifications
It is not difficult to find inside function module ME_REQUISITION_EXT the spots enhanced by SAP in version 6.05 in order to provide the BOM explosion in purchase requisitions from sales orders. They are usually wrapped inside IF statements involving fields PSTYP and ESTKZ of structure EBAN and attributes PSTYP_3 and ESTKZ_V of class CL_MMPUR_CONSTANTS (e.g. IF eban-pstyp EQ cl_mmpur_constants=>pstyp_3 AND eban-estkz EQ cl_mmpur_constants=>estkz_v). As function module ME_REQUISITION_EXT is also used by the system in cases of purchase requisitions creation from projects these very same spots could be used in order extend the BOM explosion also to these cases.
All of the proposed systems modifications are dependent on a class called ZCLPS_0001 which has one static public method called caufvd_from_ps. This method returns a parameter called re_caufvd_from_ps of type char1. The purpose of this method is to ensure that the modifications are called only for PS networks and not for other type of orders (e.g. Plant Maintenance orders). Its coding is below:
METHOD caufvd_from_ps.
CONSTANTS:
c_autyp TYPE auftyp VALUE 20.
FIELD-SYMBOLS:
<s_caufvd> TYPE caufvd.
ASSIGN ('(SAPLCOZF)CAUFVD') TO <s_caufvd>.
IF <s_caufvd> IS ASSIGNED.
IF <s_caufvd>-autyp = c_autyp.
re_caufvd_from_ps = abap_true.
ENDIF.
ENDIF.
ENDMETHOD.
The required system modifications are as follows:
*&--------------------------------------------------------------------*
*& Object REPS LEBNEF0F
*& Object Header FUGR EBNE
*&--------------------------------------------------------------------*
...
* BOM explosion in case of SubContracting out of Sales Order
if eban-pstyp eq cl_mmpur_constants=>pstyp_3 and eban-rsnum is initial
and i_bapi_call is initial and sy-batch is initial "1844596
and eban-estkz eq cl_mmpur_constants=>estkz_v. "<--DELETE
*\ AND eban-estkz EQ cl_mmpur_constants=>estkz_v. "<-- INSERT
and ( eban-estkz eq cl_mmpur_constants=>estkz_v "<-- INSERT
or ( eban-estkz eq cl_mmpur_constants=>estkz_f "<-- INSERT
and zclps_0001=>caufvd_from_ps( ) eq abap_true ) ). "<-- INSERT
perform mdpm_maintain using 'H' "new BOM explosion
changing eban.
endif.
...
*&--------------------------------------------------------------------*
*& Object REPS LEBNEF0C
*& Object Header FUGR EBNE
*&--------------------------------------------------------------------*
...
* Subcontracting item updates
if eban-pstyp eq cl_mmpur_constants=>pstyp_3
and eban-estkz eq cl_mmpur_constants=>estkz_v. "<--DELETE
*\ AND eban-estkz EQ cl_mmpur_constants=>estkz_v. "<-- INSERT
and ( eban-estkz eq cl_mmpur_constants=>estkz_v "<-- INSERT
or ( eban-estkz eq cl_mmpur_constants=>estkz_f "<-- INSERT
and zclps_0001=>caufvd_from_ps( ) eq abap_true ) ). "<-- INSERT
* change of material -> set M, all other cases -> C
if eban-matnr ne *eban-matnr.
lv_vorga = 'M'.
else.
lv_vorga = 'C'.
endif.
...
*&--------------------------------------------------------------------*
*& Object REPS LEBNEF0F
*& Object Header FUGR EBNE
*&--------------------------------------------------------------------*
...
"--> START OF DELETION
call function 'ME_COMPONENTS_MAINTAIN'
exporting
i_ebelp = cs_eban-bnfpo
i_mdpa = ls_mdpa
i_mdpa_old = ls_old_mdpa
i_txz01 = cs_eban-txz0
i_vorga = iv_vorga
importing
e_rcode = lv_code
e_verid = cs_eban-verid
e_updkz = lv_updkz.
"<-- END OF DELETION
"--> START OF INSERTION
* CALL FUNCTION 'ME_COMPONENTS_MAINTAIN'
* EXPORTING
* i_ebelp = cs_eban-bnfpo
* i_mdpa = ls_mdpa
* i_mdpa_old = ls_old_mdpa
* i_txz01 = cs_eban-txz01
* i_vorga = iv_vorga
* IMPORTING
* e_rcode = lv_code
* e_verid = cs_eban-verid
* e_updkz = lv_updkz.
if cs_eban-estkz eq cl_mmpur_constants=>estkz_f
and zclps_0001=>caufvd_from_ps( ) eq abap_true.
call function 'ME_COMPONENTS_MAINTAIN'
exporting
i_ebeln = cs_eban-banfn
i_ebelp = cs_eban-bnfpo
i_mdpa = ls_mdpa
i_mdpa_old = ls_old_mdpa
i_txz01 = cs_eban-txz0
i_vorga = iv_vorga
importing
e_rcode = lv_code
e_verid = cs_eban-verid
e_updkz = lv_updkz.
else.
call function 'ME_COMPONENTS_MAINTAIN'
exporting
i_ebelp = cs_eban-bnfpo
i_mdpa = ls_mdpa
i_mdpa_old = ls_old_mdpa
i_txz01 = cs_eban-txz01
i_vorga = iv_vorga
importing
e_rcode = lv_code
e_verid = cs_eban-verid
e_updkz = lv_updkz.
endif.
"<--END OF INSERTION
if lv_updkz is not initial.
vb_updkz = cl_mmpur_constants=>yes.
posaend = cl_mmpur_constants=>yes.
cs_eban-fixkz = cl_mmpur_constants=>yes.
endif.
...
*&--------------------------------------------------------------------*
*& Object REPS LEBNEF0F
*& Object Header FUGR EBNE
*&--------------------------------------------------------------------*
...
form mdpm_verbuchen.
* define local data objects
data: lt_mdlb type standard table of mdlb,
ls_mdlb type mdlb.
field-symbols:
<ls_bsn> like bsn,
<ls_bsc> like bsc.
"-->START OF INSERTION
if eban-estkz eq cl_mmpur_constants=>estkz_f
and zclps_0001=>caufvd_from_ps( ) eq abap_true.
data: lt_bsn_aux like table of bsn.
field-symbols: <ls_ebannumall> like line of t_ebannumall.
lt_bsn_aux = bsn[].
sort lt_bsn_aux by banfn.
loop at lt_bsn_aux assigning <ls_bsn>.
clear ls_mdlb.
read table t_ebannumall assigning <ls_ebannumall> with key orgbanfn = <ls_bsn>-banfn.
ls_mdlb-ebeln = <ls_ebannumall>-intbanfn.
ls_mdlb-ebelp = <ls_bsn>-bnfpo.
ls_mdlb-lifnr = <ls_bsn>-flief.
read table bsc assigning <ls_bsc>
with key banfn = <ls_bsn>-banfn bnfpo = <ls_bsn>-bnfpo.
if sy-subrc eq 0.
ls_mdlb-kdauf = <ls_bsc>-vbeln.
ls_mdlb-kdpos = <ls_bsc>-vbelp.
ls_mdlb-kdein = <ls_bsc>-veten.
ls_mdlb-pspel = <ls_bsc>-ps_psp_pnr.
ls_mdlb-kzbws = <ls_bsn>-kzbws.
endif.
insert ls_mdlb into table lt_mdlb.
at end of banfn.
call function 'ME_COMPONENTS_UPDATE_PREPARE'
exporting
i_ebeln_old = <ls_ebannumall>-intbanfn
i_number = <ls_bsn>-banfn
tables
t_mdlb = lt_mdlb.
clear lt_mdlb.
endat.
endloop.
else.
"<--END OF INSERTION
loop at bsn assigning <ls_bsn>.
clear ls_mdlb.
ls_mdlb-ebeln = eban-banfn.
ls_mdlb-ebelp = bsn-bnfpo.
ls_mdlb-lifnr = bsn-flief.
read table bsc assigning <ls_bsc>
with key bnfpo = <ls_bsn>-bnfpo.
if sy-subrc eq 0.
ls_mdlb-kdauf = <ls_bsc>-vbeln.
ls_mdlb-kdpos = <ls_bsc>-vbelp.
ls_mdlb-kdein = <ls_bsc>-veten.
ls_mdlb-pspel = <ls_bsc>-ps_psp_pnr.
ls_mdlb-kzbws = <ls_bsn>-kzbws.
endif.
insert ls_mdlb into table lt_mdlb.
endloop.
call function 'ME_COMPONENTS_UPDATE_PREPARE'
exporting
i_number = xeban-banfn
tables
t_mdlb = lt_mdlb.
"-->START OF INSERTION
endif.
"<--END OF INSERTION
endform. "mdpm_verbuchen
*&--------------------------------------------------------------------*
*& Object REPS LEBNEF0L
*& Object Header FUGR EBNE
*&--------------------------------------------------------------------*
...
* Update Subcontracting Components
if eban-pstyp eq cl_mmpur_constants=>pstyp_3
and eban-estkz eq cl_mmpur_constants=>estkz_v. "<-- DELETE
*\ AND eban-estkz EQ cl_mmpur_constants=>estkz_v. "<-- INSERT
and ( eban-estkz eq cl_mmpur_constants=>estkz_v "<-- INSERT
or ( eban-estkz eq cl_mmpur_constants=>estkz_f "<-- INSERT
and zclps_0001=>caufvd_from_ps( ) eq abap_true ) ). "<-- INSERT
perform mdpm_maintain using 'C'
changing eban.
endif.
endform. "bezugsquelle_3
*&--------------------------------------------------------------------*
*& Object REPS LEBNEF19
*& Object Header FUGR EBNE
*&--------------------------------------------------------------------*
...
* change deletion indicator -> update SubContracting Components
if eban-pstyp eq cl_mmpur_constants=>pstyp_3
and eban-estkz eq cl_mmpur_constants=>estkz_v. "<-- DELETE
*\ AND eban-estkz EQ cl_mmpur_constants=>estkz_v. "<-- INSERT
and ( eban-estkz eq cl_mmpur_constants=>estkz_v "<-- INSERT
or ( eban-estkz eq cl_mmpur_constants=>estkz_f "<-- INSERT
and zclps_0001=>caufvd_from_ps( ) eq abap_true ) ). "<-- INSERT
if eban-loekz is initial and *eban-loekz is not initial.
if eban-ebakz is initial.
perform mdpm_maintain using 'E' changing eban.
endif.
endif.
if eban-loekz is not initial and *eban-loekz is initial.
perform mdpm_maintain using 'L' changing eban.
endif.
if eban-ebakz is initial and *eban-ebakz is not initial.
perform mdpm_maintain using 'E' changing eban.
endif.
if eban-ebakz is not initial and *eban-ebakz is initial.
perform mdpm_maintain using 'L' changing eban.
endif.
endif.
* Only delete the entry in bsn when loekz = X. Old IF eban-loekz NE space AND
if eban-loekz eq 'X' and
bsn-update eq 'I'.
if eban-pstyp eq cl_mmpur_constants=>pstyp_3
and eban-estkz eq cl_mmpur_constants=>estkz_v "<-- DELETE
*\ AND eban-estkz EQ cl_mmpur_constants=>estkz_v "<-- INSERT
and ( eban-estkz eq cl_mmpur_constants=>estkz_v "<-- INSERT
or ( eban-estkz eq cl_mmpur_constants=>estkz_f "<-- INSERT
and zclps_0001=>caufvd_from_ps( ) eq abap_true ) ) "<-- INSERT
and eban-rsnum is initial.
perform mdpm_maintain using 'D' changing eban.
endif.
perform bsn_loeschen using indexa.
else.
...
*&--------------------------------------------------------------------*
*& Object REPS LEBNEI06
*& Object Header FUGR EBNE
*&--------------------------------------------------------------------*
...
* subcontracting: New BOM explosion
when scex.
if eban-pstyp eq cl_mmpur_constants=>pstyp_3
and eban-estkz eq cl_mmpur_constants=>estkz_v. "<-- DELETE
*\ AND eban-estkz EQ cl_mmpur_constants=>estkz_v. "<-- INSERT
and ( eban-estkz eq cl_mmpur_constants=>estkz_v "<-- INSERT
or ( eban-estkz eq cl_mmpur_constants=>estkz_f "<-- INSERT
and zclps_0001=>caufvd_from_ps( ) eq abap_true ) ). "<-- INSERT
perform mdpm_maintain using 'S'
changing eban.
endif.
*- Änderungen in *eban Übernehmen ------------------------- HW 780552 -*
when others.
*eban = eban.
...
*&--------------------------------------------------------------------*
*& Object FUNC ME_CREATE_REQUISITION_EXT
*& Object Header FUGR EBNE
*&--------------------------------------------------------------------*
...
* swap document number for subcontracting PRs
if bsn-pstyp eq cl_mmpur_constants=>pstyp_3
and bsn-rsnum is initial
and bsn-estkz eq cl_mmpur_constants=>estkz_v. "1756558
call function 'ME_COMPONENTS_NUMBER'
exporting
i_ebelp = bsn-bnfpo
importing
e_rsnum = bsn-rsnum.
endif.
"-->START OF INSERTION
if bsn-pstyp eq cl_mmpur_constants=>pstyp_3
and bsn-rsnum is initial
and bsn-estkz eq cl_mmpur_constants=>estkz_f
and zclps_0001=>caufvd_from_ps( ) eq abap_true.
call function 'ME_COMPONENTS_NUMBER'
exporting
i_ebeln = i_banfn
i_ebelp = bsn-bnfpo
importing
e_rsnum = bsn-rsnum.
endif.
"<--END OF INSERTION
move-corresponding bsn to xeban.
xeban-kz = bsn-update.
Important final notes
System modifications are for sure the last option in the list of possibilities for enhancing the system. In the case above they are unfortunately necessary because the chunk of codes to be modified or influenced are always located in the middle of the standard SAP coding. Implicit enhancement implementations would then not be possible. Therefore any attempt of implementing the suggested system modification should be done with extreme caution and thoroughly tested. Preferably the modifications and the testings should be performed first in a secondary system outside the standard landscape (i.e. DEVELOPMENT -> QUALITY -> PRODUCTION).
Proof of concept
Below some screen shots taken from a test system showing the material component in PS and its respective purchase requisition. In the example material ZTEST has a BOM with material ZTEST2 as single item. Screen shots of transaction MD04 are also taken in order to show the generated requirements.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
6 | |
2 | |
2 | |
2 | |
2 | |
2 | |
2 | |
1 | |
1 |