Skip to Content

Introduction

When customer pricing requirements exceed the robust standard pricing functionality provided by SAP, we can code routines for requirement check, condition base value, and condition value maintained in transaction VOFM. This provides a great help, but they are old fashioned procedural, require registration each time as repairs, and do not have the rich memory management and other functionality provided in the object oriented context. This document describes a one-time setup for any SD implementation to provide a flexible way of enhancing your pricing with the new OO context.

Setup

  1. Create a BADI definition in SE18/SE80.

You may need to create an enhancement spot first.

ScreenHunter_01 Dec. 06 21.41.gif

ScreenHunter_02 Dec. 06 21.46.gif

Short Text

Check requirement and calculate base and condition values with formula

Use

This BADI gives more flexibility to the routines found in transaction VOFM and assigned in the pricing procedure. The BADI contains three methods which are called from requirement check routine 900, condition base value formula 900, and condition value formula 900.

The BADI is filter dependent on condition type.

Requirements

The condition type must be created and assigned in the pricing procedure. The relevant number 900 routines must also be assigned in the procedure. If the BADI implementation is not active and the requirement check routine 900 is assigned in the pricing procedure, the condition will not be created.

Standard settings

When a new condition type needs either a custom requirement, base value, or total value, create an implementation with filter equal to the condition type. Implement all three methods to keep the implementation consistent. In the price procedure for the condition type, assign routine 900 in the appropriate place. If only the requirement check method is needed, only assign the 900 routine in the check column, but leave the formula and base value columns empty.

   *”* components of interface ZIF_PRICE_COND_CALC
interface ZIF_PRICE_COND_CALC
  public .

  interfaces IF_BADI_INTERFACE .

  methods VALUE_CALCULATE
    importing
      !I_KOMK type KOMK
      !I_KOMP type KOMP
      !I_KOMT1 type KOMT1
      !I_KOMT2 type KOMT2
      !I_XKOMV_TAB type CPET_KOMV_INDEX_TAB
      !I_XWORKD type KWERT
      !I_XWORKE type KWERT
      !I_XWORKF type KWERT
      !I_XWORKG type KWERT
      !I_XWORKH type KWERT
      !I_XWORKI type KWERT
      !I_XWORKJ type KWERT
      !I_XWORKK type KOMVKBETR
      !I_XWORKL type KOMVKBETR
      !I_XWORKM type KOMVKBETR
      !I_PREISFINDUNGSART type CHAR1
    changing
      !C_XKOMV_LINE type KOMV_INDEX .
  methods BASE_CALCULATE
    importing
      !I_KOMK type KOMK
      !I_KOMP type KOMP
      !I_KOMT1 type KOMT1
      !I_KOMT2 type KOMT2
      !I_XKOMV_TAB type CPET_KOMV_INDEX_TAB
      !I_XWORKD type KWERT
      !I_XWORKE type KWERT
      !I_XWORKF type KWERT
      !I_XWORKG type KWERT
      !I_XWORKH type KWERT
      !I_XWORKI type KWERT
      !I_XWORKJ type KWERT
      !I_XWORKK type KOMVKBETR
      !I_XWORKL type KOMVKBETR
      !I_XWORKM type KOMVKBETR
      !I_XKOMV_LINE type KOMV_INDEX
    changing
      !C_XKAWRT type KAWRT
      !C_KOMV_BASE type ZSD_KOMV_BASE
    exceptions
      NO_CHANGE .
  methods REQUIREMENT_CHECK
    importing
      !I_KOMK type KOMK
      !I_KOMP type KOMP
      !I_KOMT2 type KOMT2
      !I_XKOMV_TAB type CPET_KOMV_INDEX_TAB
      !I_XWORKD type KWERT
      !I_XWORKE type KWERT
      !I_XWORKF type KWERT
      !I_XWORKG type KWERT
      !I_XWORKH type KWERT
      !I_XWORKI type KWERT
      !I_XWORKJ type KWERT
      !I_XWORKK type KOMVKBETR
      !I_XWORKL type KOMVKBETR
      !I_XWORKM type KOMVKBETR
      !I_XKOMV_LINE type KOMV_INDEX
      !I_XVBAPU type VBAPU_TTY
    changing
      !C_KOMT1 type KOMT1
    exceptions
      NO_COND .
endinterface.

2. Add the code to call BADI’s in VOFM routines

Enhance LV61ATOP to add this data declaration:

   DATA: ZBADI_PRICE_COND_CALC TYPE REF TO ZBADI_PRICE_COND_CALC.

Register a requirement routine 900 (or another available in customer namespace), condition base value routine 900, and condition formula routine 900 in VOFM and add the below code:

Requirement Code:

Include          RV61A900

FORM.

   *This BADI is also called from base formula 900 and condition value formula 900.

  GET BADI ZBADI_PRICE_COND_CALC
    FILTERS
    kschl = komt1kschl.

* If not implemented, exclude
  IF ZBADI_PRICE_COND_CALC->IMPS IS INITIAL.
    sysubrc = 4.
    EXIT.
  ENDIF.

  CALL BADI ZBADI_PRICE_COND_CALC->REQUIREMENT_CHECK
    EXPORTING
      I_XVBAPU     = xvbapu[]
      I_KOMK       = komk
      I_KOMP       = komp
      I_KOMT2      = komt2
      I_XKOMV_TAB  = xkomv[]
      I_XWORKD     = xworkd
      I_XWORKE     = xworke
      I_XWORKF     = xworkf
      I_XWORKG     = xworkg
      I_XWORKH     = xworkh
      I_XWORKI     = xworki
      I_XWORKJ     = xworkj
      I_XWORKK     = xworkk
      I_XWORKL     = xworkl
      I_XWORKM     = xworkm
      I_XKOMV_LINE = xkomv
    CHANGING
      C_KOMT1      = komt1
    EXCEPTIONS
      NO_COND      = 1
      others       = 2.

ENDFORM.

Condition base value code:

Include          RV63A900

   FORM FRM_KOND_BASIS_900.
*{   INSERT         DEVK907971                                        1
DATA zkomv_base TYPE zsd_komv_base.

GET BADI ZBADI_PRICE_COND_CALC
  FILTERS
  kschl = xkomvkschl.

CALL BADI ZBADI_PRICE_COND_CALC->BASE_CALCULATE
  EXPORTING
    I_KOMK       = komk
    I_KOMP       = komp
    I_KOMT1      = komt1
    I_KOMT2      = komt2
    I_XKOMV_TAB  = xkomv[]
    I_XWORKD     = xworkd
    I_XWORKE     = xworke
    I_XWORKF     = xworkf
    I_XWORKG     = xworkg
    I_XWORKH     = xworkh
    I_XWORKI     = xworki
    I_XWORKJ     = xworkj
    I_XWORKK     = xworkk
    I_XWORKL     = xworkl
    I_XWORKM     = xworkm
    I_XKOMV_LINE = xkomv
  CHANGING
    C_XKAWRT     = xkawrt
    c_komv_base  = zkomv_base
  EXCEPTIONS
    NO_CHANGE    = 1
    others       = 2.

IF zkomv_base IS NOT INITIAL.
   MOVE-CORRESPONDING zkomv_base TO xkomv.
ENDIF.
*}   INSERT
ENDFORM.

Condition Value code:

Include          RV64A900

   FORM FRM_KONDI_WERT_900.
*{   INSERT         DEVK907971                                        1
GET BADI ZBADI_PRICE_COND_CALC
  FILTERS
  kschl = xkomvkschl.

CALL BADI ZBADI_PRICE_COND_CALC->VALUE_CALCULATE
  EXPORTING
    I_KOMK             = komk
    I_KOMP             = komp
    I_KOMT1            = komt1
    I_KOMT2            = komt2
    I_XKOMV_TAB        = xkomv[]
    I_XWORKD           = xworkd
    I_XWORKE           = xworke
    I_XWORKF           = xworkf
    I_XWORKG           = xworkg
    I_XWORKH           = xworkh
    I_XWORKI           = xworki
    I_XWORKJ           = xworkj
    I_XWORKK           = xworkk
    I_XWORKL           = xworkl
    I_XWORKM           = xworkm
    I_PREISFINDUNGSART = preisfindungsart
  CHANGING
    C_XKOMV_LINE       = xkomv.
  xkwert = xkomvkwert.

ENDFORM.

Implementation

Now when you need a new condition type with code, you can easily create a new implementation of the BADI in SE19/SE80. In the pricing procedure, you assign these routines.

ScreenHunter_03 Dec. 06 22.07.gif

It is now easier for me to create new pricing functionality with all the benefits of object oriented classes. I do not need to bother basis for registration keys either. I hope this makes your life easier too. 🙂

To report this post you need to login first.

3 Comments

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

  1. Patrick Fichtner

    Hi Karl,

    thanks a lot for the detailed step-by-step guide. I have a question regarding zsd_komv_base. How is it declared (type komv_index ?) and what is it used for?

    Thanks

    Patrick

    (0) 
    1. Karl Rockwell

      Hello Patrick,

      Sorry for such a late reply, but I did not get notice of your question. This is a custom structure I created defining which fields in KOMV should be changed via condition base value formula. I think I only defined KAWRT in that system, but you can test which other fields are successfully and safely updated via CBV routine. I recall it being more limited than what you can change in condition value formula.

      (0) 
      1. Patrick Fichtner

        Hi Karl,

        thanks for your answer on zsd_komv_base.

        I have successfully implemented this pricing technique in some systems already. From implementation to implementation I have refined the setup so that I now have following situation:

        • I ripped apart the BAdIs for value, base value, requirement etc. so that I can easier share e.g. requirements between condition types without having to use e.g. the same value formula. It can happen that condition A & B should have the same requirement, but not the same value formula (whereas conditions B & C could share the same formula)….
        • I created an aditional BAdI for the scale base formula with following interface:

        INTERFACE zif_pr_scale_base
          PUBLIC .

          TYPE-POOLS abap .

          INTERFACES if_badi_interface .

          METHODS scale_base_calculate
           IMPORTING
             !i_komk TYPE komk
             !i_komp TYPE komp
             !i_komt1 TYPE komt1
             !i_komt2 TYPE komt2
             !i_xkomv_tab TYPE cpet_komv_index_tab
             !i_xworkd TYPE kwert
             !i_xworke TYPE kwert
             !i_xworkf TYPE kwert
             !i_xworkg TYPE kwert
             !i_xworkh TYPE kwert
             !i_xworki TYPE kwert
             !i_xworkj TYPE kwert
             !i_xworkk TYPE komv-kbetr
             !i_xworkl TYPE komv-kbetr
             !i_xworkm TYPE komv-kbetr
             !i_xkomv TYPE komv_index
           CHANGING
             !c_xkwert TYPE kwert
           EXCEPTIONS
             no_change .
        ENDINTERFACE.                    “ZIF_PR_SCALE_BASE

        The VOFM routine is following:

        GET BADI zbadi_pr_scale_base
            FILTERS
              kschl = xkomv-kschl
              kalsm = komk-kalsm.

          CALL BADI zbadi_pr_scale_base->scale_base_calculate
            EXPORTING
              i_komk      = komk
              i_komp      = komp
              i_komt1     = komt1
              i_komt2     = komt2
              i_xkomv_tab = xkomv[]
              i_xworkd    = xworkd
              i_xworke    = xworke
              i_xworkf    = xworkf
              i_xworkg    = xworkg
              i_xworkh    = xworkh
              i_xworki    = xworki
              i_xworkj    = xworkj
              i_xworkk    = xworkk
              i_xworkl    = xworkl
              i_xworkm    = xworkm
              i_xkomv     = xkomv
            CHANGING
              c_xkwert    = xkwert
            EXCEPTIONS
              no_change   = 1
              OTHERS      = 2.

        • As you can see I have also introduced another filter –> KALSM. So for all the different BAdIs I can use the combination of KALSM and KSCHL or only one of them (of course KALSM as a single filter doesn’t make sense). By doing so I could differentiate between the same KSCHL in different KALSMs.
        • I have differentiated the Requirements BAdI into KOBEV and KOBED with following interface:

        INTERFACE zif_pr_requirement

          PUBLIC .

          TYPE-POOLS abap .

          INTERFACES if_badi_interface .

          METHODS requirement_check_kobed

            IMPORTING

              !i_komk TYPE komk

              !i_komp TYPE komp

              !i_komt1 TYPE komt1

              !i_komt2 TYPE komt2

              !i_xkomv_tab TYPE cpet_komv_index_tab

              !i_xworkd TYPE kwert

              !i_xworke TYPE kwert

              !i_xworkf TYPE kwert

              !i_xworkg TYPE kwert

              !i_xworkh TYPE kwert

              !i_xworki TYPE kwert

              !i_xworkj TYPE kwert

              !i_xworkk TYPE komv-kbetr

              !i_xworkl TYPE komv-kbetr

              !i_xworkm TYPE komv-kbetr

              !i_xkomv TYPE komv_index

              !i_xvbapu TYPE vbapu_tty

            CHANGING

              !c_komt1 TYPE komt1

              !c_subrc TYPE sysubrc

            EXCEPTIONS

              no_cond .

          METHODS requirement_check_kobev

            IMPORTING

              !i_komk TYPE komk

              !i_komp TYPE komp

              !i_komt1 TYPE komt1

              !i_komt2 TYPE komt2

              !i_xkomv_tab TYPE cpet_komv_index_tab

              !i_xworkd TYPE kwert

              !i_xworke TYPE kwert

              !i_xworkf TYPE kwert

              !i_xworkg TYPE kwert

              !i_xworkh TYPE kwert

              !i_xworki TYPE kwert

              !i_xworkj TYPE kwert

              !i_xworkk TYPE komv-kbetr

              !i_xworkl TYPE komv-kbetr

              !i_xworkm TYPE komv-kbetr

              !i_xkomv TYPE komv_index

              !i_xvbapu TYPE vbapu_tty

            CHANGING

              !c_komt1 TYPE komt1

              !c_subrc TYPE sysubrc

            EXCEPTIONS

              no_cond .

        ENDINTERFACE.                    “ZIF_PR_REQUIREMENT

        The VOFM routine is following:


        form kobed_999.

          DATA: lf_subrc TYPE sysubrc,

                ls_komt2 TYPE komt2.

          GET BADI zbadi_pr_requirement

            FILTERS

              kschl = komt1-kschl

              kalsm = komk-kalsm.

          CALL BADI zbadi_pr_requirement->requirement_check_kobed

            EXPORTING

              i_xvbapu    = xvbapu[]

              i_komk      = komk

              i_komp      = komp

              i_komt1     = komt1

              i_komt2     = komt2

              i_xkomv_tab = xkomv[]

              i_xworkd    = xworkd

              i_xworke    = xworke

              i_xworkf    = xworkf

              i_xworkg    = xworkg

              i_xworkh    = xworkh

              i_xworki    = xworki

              i_xworkj    = xworkj

              i_xworkk    = xworkk

              i_xworkl    = xworkl

              i_xworkm    = xworkm

              i_xkomv     = xkomv

            CHANGING

              c_komt1     = komt1

              c_subrc     = lf_subrc

            EXCEPTIONS

              no_cond     = 1

              OTHERS      = 2.

          sy-subrc = lf_subrc.

        ENDFORM.                    “KOBED_999

        *&———————————————————————*

        *&      Form  KOBEV_999

        *&———————————————————————*

        *       text

        *———————————————————————-*

        FORM kobev_999.

          DATA: lf_subrc TYPE sysubrc,

              ls_komt2 TYPE komt2.

          GET BADI zbadi_pr_requirement

            FILTERS

              kschl = komt1-kschl

              kalsm = komk-kalsm.

          CALL BADI zbadi_pr_requirement->requirement_check_kobev

            EXPORTING

              i_xvbapu    = xvbapu[]

              i_komk      = komk

              i_komp      = komp

              i_komt1     = komt1

              i_komt2     = komt2

              i_xkomv_tab = xkomv[]

              i_xworkd    = xworkd

              i_xworke    = xworke

              i_xworkf    = xworkf

              i_xworkg    = xworkg

              i_xworkh    = xworkh

              i_xworki    = xworki

              i_xworkj    = xworkj

              i_xworkk    = xworkk

              i_xworkl    = xworkl

              i_xworkm    = xworkm

              i_xkomv     = xkomv

            CHANGING

              c_komt1     = komt1

              c_subrc     = lf_subrc

            EXCEPTIONS

              no_cond     = 1

              OTHERS      = 2.

          sy-subrc = lf_subrc.

        ENDFORM.                    “KOBEV_999

        Hope this helps you or someone else who is reading this post…

        Regards

        Patrick

        (0) 

Leave a Reply