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.


Picture1.png

Picture2.png


New NetWeaver Information at SAP.com

Very Helpfull

User Rating: Be the first one !