Skip to Content

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


To report this post you need to login first.

2 Comments

You must be Logged on to comment or reply to a post.

    1. Marcos TEIXEIRA Post author

      Hi Vinay,

      Thank you for your feedback.

      I must say I was a little bit worried about publishing this blog post because it suggests some audacious system changes that are not always very well seen.

      I have decided to post it anyhow because this limitation on the BOM explosion on purchase requisitions created out of PS has already costed me a lot of work in the past.

      Regards,

      (0) 

Leave a Reply