To print this page properly - use Print icon located on the page.
Please note that JavaScript has to be enabled.

SAP BW/BI Blog

Using BOM for Vendor Split

19-Nov-09 18:53 | Sergei Peleshuk (administrator)

Bill of Materials can play a crucial role in identifying relevant vendors for articles sold in retail. Let us imagine we are selling a product that is assembled or produced in the shop or in the warehouse. A typical example can be steak sold in a supermarket. It is obvious a steak is not purchased from vendors in the packaging it is sold. From a technical point of view it may be challenging assigning steak sales to vendors. To solve this we have to use Bill Of Materials (BOM). In the post below I will give examples how BOM for product articles can be extracted from SAP Retail and how it can be used in the vendor split logic for Vendor P&L reporting.

 

Vendor Split for Fresh Food

There are numerous ways for assigning vendor codes to sales and stock movements. When we want to construct a Profit & Loss Statement by vendor we have to have business logic on how to allocate sales by vendor. For example we may want to use the following logic for fresh food products:

  • Look up for purchases for the article during last 2 months 
  • If not found look up all parent articles in BOM 
  • Look up for purchases for all parent articles during last 2 months
  • Look up for purchases for the article during last 3 months 
  •  … 
  • Look up for purchases for the article during last 12 months 
  • If not found look up for purchases for all parent articles during last 12 months 
  • If no purchases found apply Main vendor

Here is a data flow example where BOM may be used in the vendor split logic:

image001.jpg

 

Extract BOM from Retail

Bill of Material is stored in three tables in SAP Retail:

  • MAST 
  • STAS 
  • STPO

We can design a database view (Transaction SE11) where these three tables are linked. The link between MAST & STAS: stlnr+stlal; the link between STAS & STPO : stlty+stlnr+stlkn. If we want to extract BOM for articles only we have to apply filter: STPO-STLTY = ‘M’.

The view may have the following fields (columns):

MATNR CHAR   18         Article Number

IDNRK  CHAR   18         BOM component

MANDT CLNT    3          Client

WERKS CHAR  4          Site

STLAN  CHAR   1          BOM Usage

STLNR  CHAR   8          Bill of material

STLAL  CHAR   2          Alternative BOM

STLTY  CHAR   1          BOM category

STLKN  NUMC   8          BOM item node number

STPOZ  NUMC   8          Internal counter

It is a matter of just a few button clicks for designing a generic extractor based on the view defined above (Transaction RSO2). Selection fields for the extractor can be Article Number and BOM component.

Masterdata tables used in the view usually contain a few hundred thousand records or less, therefore running full load for the complete BOM should not pose performance issues.

Apply BOM in Vendor Split

We have to store article BOM in BW in order to access it from a transformation. I suggest using a DSO with two key fields:

  • Article Parent
  • Article Child

With this we can identify parent articles for a child and apply vendor split for children based on parent article purchases.

We can use a full load to the DSO containing BOM: O_ARTBOM. Therefore, BOM relationships can be used in other transformations containing vendor split logic.

Below is an ABAP code example in the start routine of a transformation connecting source and the “P&L by vendor” DSO:

  REFRESH et_target.

  LOOP AT SOURCE_PACKAGE ASSIGNING <ls>.

    REFRESH vspl.

        READ TABLE vspl_all WITH TABLE KEY MATERIAL =

        <ls>-/BIC/CHARTICLE

        CALMONTH = pto TRANSPORTING NO FIELDS.

        IF sy-subrc <> 0.

          READ TABLE vspl_all WITH TABLE KEY MATERIAL =

          <ls>-/BIC/CHARTICLE

          CALMONTH = pfr TRANSPORTING NO FIELDS.

        ENDIF.

*   --- Find last period with purchases for this product & BOM

DATA: tmon TYPE n length 3. tmon = '11'.

TYPES: t_bom TYPE /BIC/AO_ARTBOM00, tsbom TYPE STANDARD TABLE OF t_bom.

FIELD-SYMBOLS: <bom> TYPE t_bom.

DATA : tab_bom TYPE tsbom, tb2 TYPE tsbom.

* --- If purchases not found Build list of articles from BOM

        IF sy-subrc <> 0.

          SELECT * FROM /BIC/AO_ARTBOM00 INTO TABLE tab_bom

          WHERE MATERIAL = <ls>-/BIC/CHARTICLE.

          IF sy-subrc = 0.

            LOOP AT tab_bom ASSIGNING <bom>.

              SELECT * FROM /BIC/AO_ARTBOM00 INTO TABLE tb2

              WHERE MATERIAL = <bom>-/BIC/CHARTICLE.

              IF sy-subrc = 0. APPEND LINES OF tb2 TO tab_bom. ENDIF.

            ENDLOOP.

          ELSE.

            found_vs = 'm'.

          ENDIF.

          WHILE ( found_vs = 'n' OR found_vs = 'm' ) AND tmon > 0.

            IF found_vs <> 'm'. " If there is BOM

              SELECT * FROM /BIC/AO_VENSPL00

              INTO CORRESPONDING FIELDS OF TABLE vspl

              FOR ALL ENTRIES IN tab_bom WHERE

              MATERIAL = tab_bom-/BIC/CHARTICLE AND

              CALMONTH >= pfr AND CALMONTH <= pto.

              IF sy-subrc = 0. found_vs = 'b'. ENDIF.

            ENDIF.

            IF found_vs <> 'b'. " Check for original article

              pfr = pfr - 1.

              IF pfr+4(2) = '00'. pfr = pfr(4) - 1.

                CONCATENATE pfr+2(4) '12' INTO pfr.

              ENDIF.

              READ TABLE vspl_all WITH TABLE KEY MATERIAL =

              <ls>-/BIC/CHARTICLE

              CALMONTH = pfr TRANSPORTING NO FIELDS.

              IF sy-subrc = 0. found_vs = 'y'. ENDIF.

              tmon = tmon - 1.

            ENDIF.

          ENDWHILE.

        ELSE.

          found_vs = 'y'.

        ENDIF.

      ELSE.

      ENDIF.

* Select all relevant purchases for vendor split

      IF found_vs = 'n' OR found_vs = 'y'.

        LOOP AT vspl_all ASSIGNING <vs> WHERE MATERIAL =

          <ls>-/BIC/CHARTICLE.

          IF <vs>-CALMONTH >= pfr AND <vs>-CALMONTH <= pto.

            APPEND <vs> TO vspl.

            found_vs = 'y'.

          ENDIF.

        ENDLOOP.

      ENDIF.

      IF found_vs = 'y' OR found_vs = 'b'.

* Calculate total article purchased AND Group by vendor

        tot = vtot = 0. curv = 'uno'. REFRESH vs_comp.

        SORT vspl BY VENDOR ASCENDING.

        LOOP AT vspl INTO cvl.

          IF cvl-VENDOR <> curv AND curv <> 'uno'.

            lastv-/BIC/KFQTRCUB = vtot.

            APPEND lastv TO vs_comp.

            vtot = 0.

          ENDIF.

          lastv = cvl.

          curv = cvl-VENDOR.

          vtot = vtot + cvl-/BIC/KFQTRCUB.

          tot = tot + cvl-/BIC/KFQTRCUB.

        ENDLOOP.

        lastv-/BIC/KFQTRCUB = vtot.

        APPEND lastv TO vs_comp.

* Distribute value in proportion to Qty purchased

DATA: t1 TYPE /BIC/OIKFVALSTCK, t2 TYPE /BIC/OIKFVALSTQ.

        t1 = <ls>-/BIC/KFVALSTCK.  t2 = <ls>-/BIC/KFVALSTQ.

        LOOP AT vs_comp ASSIGNING <vs>.

          <ls>-VENDOR = <vs>-VENDOR.

          IF tot <> 0.

            <ls>-/BIC/KFVALSTCK = t1 * <vs>-/BIC/KFQTRCUB / tot.

            <ls>-/BIC/KFVALSTQ = t2 * <vs>-/BIC/KFQTRCUB / tot.

          ENDIF.

          APPEND <ls> TO et_target.

        ENDLOOP.

      ELSE.

* If no relevant articles purchased assign main vendor
        
READ TABLE art WITH TABLE KEY
        /BIC/CHARTICLE = <ls>-/BIC/CHARTICLE 
ASSIGNING <art>.
        
IF sy-subrc = 0. <ls>-
VENDOR = <art>-vendor.
        
ELSE. <ls>-
VENDOR' '.  ENDIF.
        
APPEND <ls> TO et_target.

      ENDIF.

  ENDLOOP.

Focus On Performance

In order to address performance we have to make sure we process only records required in the business process: In P&L processing filter out balance GL accounts and all non P&L entries. When we process relevant entries the most time consuming operation is SELECT statement from external database tables (DSOs). We should minimize usage of SELECT statements in the loops and use internal tables wherever possible. However, if we do have to read database tables in the loops in order to improve performance we have to read data using key fields in the proper order sequence (Read more in the post: Key Fields Order Does Matter ).

 

 

Powered by Wild Apricot                                                                                                                                                       Copyright BI Portal.ORG