Preamble -
Consider a scenario where a standard costing (S) is used for raw material pricing.
Purchase Orders are generated for raw materials and the standard cost of raw material is captured in condition type ZI01 as per PO pricing procedure.
The freight related to procurement is captured in condition type ZCFR which is also available in the PO pricing procedure.
The freight cost is calculated as a percentage of the standard cost condition ZI01 and captured in the PO pricing procedure.
Issue description -
The issue faced here relates to changes in the standard cost and the effects of that in the freight calculation.
Currently, once the PO is created, the freight cost (condition type ZCFR) gets calculated on raw material standard cost (condition type Z101).
Material master Accounting View for Material 41.
In ME23N, standard price is 120 USD.
Post creation of PO, if material standard cost is changed through standard cost estimation cycle (yearly / half yearly), it does not automatically update the condition type Z101 & hence during GRN freight cost( condition type ZCFR) gets calculated on old material standard cost.
Eg.
Before GR (MIGO) , Using the TCODE MR21, standard price of the material 41 is changed from 120 USD to 150 USD.
After pressing Save, same price of 150 USD is available in Material master.
Now, all the pricing calculation should occur with respect to this latest price of 150 USD. However, this recently changed price is not updated in PO. It still shows old price i.e. 120 USD which is incorrect.
Solution -
To overcome this, the new standard cost that has been released for a material should be updated in all open PO for that material (condition type ZI01) so that during GRN the new standard cost (condition type ZI01) and freight (condition type ZCFR) will be posted at latest cost.
The requirement is also to ensure that the changes for new standard cost need not be done manually by the business user and a solution which would dynamically update the standard cost of an existing PO.
While doing good’s receipt using MIGO, In order to update latest Statistical price (MBEW-STPRS) to PO line items, BADI ‘MB_MIGO_BADI’ will be implemented. Method ‘LINE_MODIFY’ of BADI will use BAPI ‘BAPI_PO_CHANGE’ to update latest Statistical price (MBEW-STPRS) to PO line items.
Code to update Statistical Price should execute only for Goods Receipt process for the POs other than Stock Transfer POs.
Once the PO is updated with latest Statistical Price, message ‘Latest Cost updated in PO’ will be displayed.
In order to execute this price updating logic only once, internal table GT_PROCESSED is used. All the processed PO# for that particular session will be marked as 'X' initially so that when control comes again to method LINE_MODIFY, it will not execute the price updating logic again and thus will improve the performance. Finally, all the memory IDs will be flushed when user posts the document using method POST_DOCUMENT.
Pre-requisite –
Go to configuration settings through path SPRO – Ref IMG - Material Management – Purchasing – Conditions – Define price determination process – Define condition type – Select condition “Z101” – click on Details tab
Table V_T685A in condition type “Z101” should have status “No limitations”
Code Snippets :
------------------------------------------------------------------------------------------------------------------------
1. Method LINE_MODIFY :
------------------------------------------------------------------------------------------------------------------------
METHOD IF_EX_MB_MIGO_BADI~LINE_MODIFY.
TYPES: BEGIN OF LTY_KONV,
KNUMV TYPE KONV-KNUMV,
KSCHL TYPE KONV-KSCHL,
KWERT TYPE KONV-KWERT,
END OF LTY_KONV.
TYPES :BEGIN OF TY_PROCESSED,
PO_NUM TYPE EBELN,
PROC TYPE CHAR1,
END OF TY_PROCESSED.
TYPES :BEGIN OF TY_MBEW,
BWKEY TYPE MBEW-BWKEY,
MATNR TYPE MBEW-MATNR,
STPRS TYPE MBEW-STPRS,
END OF TY_MBEW.
DATA : GT_MBEW TYPE STANDARD TABLE OF TY_MBEW,
GW_MBEW TYPE TY_MBEW.
DATA: GT_PROCESSED TYPE STANDARD TABLE OF TY_PROCESSED,
WA_PROCESSED TYPE TY_PROCESSED.
DATA :GW_HEADER TYPE BAPIEKKOL,
GT_RETURN TYPE TABLE OF BAPIRET2,
GW_RETURN TYPE BAPIRET2,
GT_ITEMS TYPE TABLE OF BAPIEKPO,
GW_ITEMS TYPE BAPIEKPO,
GT_COND TYPE TABLE OF BAPIMEPOCOND,
GW_COND TYPE BAPIMEPOCOND,
GT_CONDX TYPE TABLE OF BAPIMEPOCONDX,
LT_POCONDX TYPE STANDARD TABLE OF BAPIMEPOCONDX,
LS_POCONDX TYPE BAPIMEPOCONDX,
GT_POSCHEDULE TYPE TABLE OF BAPIMEPOSCHEDULE,
GW_POSCHEDULE TYPE BAPIMEPOSCHEDULE,
GT_POSCHEDULX TYPE TABLE OF BAPIMEPOSCHEDULX,
GW_POSCHEDULX TYPE BAPIMEPOSCHEDULX.
DATA : LV_SPRICE TYPE MBEW-STPRS,
LV_KNUMV TYPE EKKO-KNUMV,
LV_MES TYPE CHAR100.
DATA: LW_KONV TYPE LTY_KONV.
DATA: LV_CALC_AMT TYPE MBEW-STPRS,
LV_WERKS TYPE EKPO-WERKS,
GT_BAPI_POITEM TYPE STANDARD TABLE OF BAPIMEPOITEM,
GW_BAPI_POITEM TYPE BAPIMEPOITEM,
GT_BAPI_POITEMX TYPE STANDARD TABLE OF BAPIMEPOITEMX,
GW_BAPI_POITEMX TYPE BAPIMEPOITEMX.
DATA : LV_DONE TYPE CHAR1,
LV_MODE TYPE CHAR1.
DATA : LV_LINE TYPE CHAR4.
DATA : LV_VSTEL TYPE EKPV-VSTEL,
LV_VSBED TYPE EKPV-VSBED,
LV_LADGR TYPE EKPV-LADGR.
CONSTANTS : LC_X TYPE CHAR1 VALUE 'X'.
CONSTANTS : LC_Z101 TYPE BAPIMEPOCOND-COND_TYPE VALUE 'Z101',
LC_U TYPE BAPIMEPOCOND-CHANGE_ID VALUE 'U',
LC_3 TYPE BAPIMEPOITEM-PRICEDATE VALUE '3',
LC_C TYPE BAPIMEPOITEM-CALCTYPE VALUE 'C'.
CONSTANTS : LC_E TYPE BAPIRET2-TYPE VALUE 'E',
LC_S TYPE BAPIRET2-TYPE VALUE 'S',
LC_ME TYPE BAPIRET2-ID VALUE 'ME',
LC_06 TYPE BAPIRET2-ID VALUE '06',
LC_006 TYPE BAPIRET2-NUMBER VALUE '006',
LC_023 TYPE BAPIRET2-NUMBER VALUE '023'.
* Execute only for Goods Receipt
IMPORT LV_MODE TO LV_MODE FROM MEMORY ID 'MODE'.
CHECK LV_MODE = LC_X.
* Execute only Once.This Memory ID GET Export from below code
IMPORT GT_PROCESSED TO GT_PROCESSED FROM MEMORY ID 'PROCESSED'.
READ TABLE GT_PROCESSED INTO WA_PROCESSED WITH KEY PO_NUM = CS_GOITEM-EBELN.
CHECK WA_PROCESSED-PROC NE LC_X.
WA_PROCESSED-PROC = LC_X.
WA_PROCESSED-PO_NUM = CS_GOITEM-EBELN.
APPEND WA_PROCESSED TO GT_PROCESSED.
CLEAR WA_PROCESSED.
EXPORT GT_PROCESSED FROM GT_PROCESSED TO MEMORY ID 'PROCESSED'.
* Restrict the logic from Execution for Stock Transfer PO
CLEAR : LV_VSTEL,LV_VSBED, LV_LADGR.
SELECT SINGLE VSTEL
VSBED
LADGR
FROM EKPV
INTO (LV_VSTEL,LV_VSBED, LV_LADGR)
WHERE EBELN = CS_GOITEM-EBELN.
IF LV_VSTEL IS NOT INITIAL OR
LV_VSBED IS NOT INITIAL OR
LV_LADGR IS NOT INITIAL .
EXIT.
ENDIF.
* Get Condition Record Number
CLEAR LV_KNUMV.
SELECT SINGLE KNUMV FROM EKKO
INTO LV_KNUMV
WHERE EBELN = CS_GOITEM-EBELN.
* Get PO details
CALL FUNCTION 'BAPI_PO_GETDETAIL'
EXPORTING
PURCHASEORDER = CS_GOITEM-EBELN
ITEMS = LC_X
IMPORTING
PO_HEADER = GW_HEADER
TABLES
PO_ITEMS = GT_ITEMS.
IF GT_ITEMS[] IS NOT INITIAL.
* Get Std Price
SELECT BWKEY MATNR STPRS
FROM MBEW
INTO TABLE GT_MBEW
FOR ALL ENTRIES IN GT_ITEMS
WHERE BWKEY EQ GT_ITEMS-PLANT AND
MATNR EQ GT_ITEMS-MATERIAL.
ENDIF.
* Sort Material Valuation details
SORT GT_MBEW ASCENDING BY BWKEY MATNR STPRS.
LOOP AT GT_ITEMS INTO GW_ITEMS.
REFRESH : GT_BAPI_POITEMX, GT_BAPI_POITEM.
REFRESH : GT_RETURN[],GT_POSCHEDULE[],GT_POSCHEDULX,GT_COND[].
READ TABLE GT_MBEW INTO GW_MBEW WITH KEY BWKEY = GW_ITEMS-PLANT
MATNR = GW_ITEMS-MATERIAL BINARY SEARCH.
IF SY-SUBRC EQ 0 .
* Assign Current Standard Price
IF GW_MBEW-STPRS IS NOT INITIAL .
LV_CALC_AMT = GW_MBEW-STPRS / 10 .
ENDIF.
ENDIF.
* Delivery Complition Flag is marked,do not process the Item
IF GW_ITEMS-DEL_COMPL = LC_X.
CLEAR:GW_MBEW,GW_ITEMS,LV_CALC_AMT.
CONTINUE.
ENDIF.
* Condition Records
GW_COND-CONDITION_NO = LV_KNUMV.
GW_COND-ITM_NUMBER = GW_ITEMS-PO_ITEM.
GW_COND-COND_TYPE = LC_Z101.
GW_COND-COND_VALUE = LV_CALC_AMT.
GW_COND-CHANGE_ID = LC_U.
APPEND GW_COND TO GT_COND.
LS_POCONDX-ITM_NUMBER = GW_ITEMS-PO_ITEM.
LS_POCONDX-COND_TYPE = LC_X.
LS_POCONDX-COND_VALUE = LC_X.
LS_POCONDX-CHANGE_ID = LC_U.
APPEND LS_POCONDX TO LT_POCONDX.
GW_BAPI_POITEM-PO_ITEM = GW_ITEMS-PO_ITEM.
GW_BAPI_POITEM-MATERIAL = GW_ITEMS-MATERIAL.
GW_BAPI_POITEM-NET_PRICE = LV_CALC_AMT .
GW_BAPI_POITEM-CALCTYPE = LC_C. " Reprice it
GW_BAPI_POITEM-PRICEDATE = LC_3. " Reprice it based on current date
APPEND GW_BAPI_POITEM TO GT_BAPI_POITEM.
GW_BAPI_POITEMX-PO_ITEM = GW_ITEMS-PO_ITEM.
GW_BAPI_POITEMX-PO_ITEMX = LC_X.
GW_BAPI_POITEMX-CALCTYPE = LC_X.
GW_BAPI_POITEMX-PRICEDATE = LC_X.
APPEND GW_BAPI_POITEMX TO GT_BAPI_POITEMX.
* Schedule Line
GW_POSCHEDULE-PO_ITEM = GW_ITEMS-PO_ITEM.
* Supress Leading zeros
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
INPUT = GW_ITEMS-PO_ITEM
IMPORTING
OUTPUT = LV_LINE.
GW_POSCHEDULE-PO_ITEM = GW_ITEMS-PO_ITEM.
GW_POSCHEDULE-SCHED_LINE = LV_LINE.
APPEND GW_POSCHEDULE TO GT_POSCHEDULE.
GW_POSCHEDULX-PO_ITEM = GW_ITEMS-PO_ITEM.
GW_POSCHEDULX-PO_ITEMX = LC_X.
APPEND GW_POSCHEDULX TO GT_POSCHEDULX.
* Update PO with latest Pricing
CALL FUNCTION 'BAPI_PO_CHANGE'
EXPORTING
PURCHASEORDER = CS_GOITEM-EBELN
TABLES
RETURN = GT_RETURN
POITEM = GT_BAPI_POITEM
POITEMX = GT_BAPI_POITEMX
POSCHEDULE = GT_POSCHEDULE
POSCHEDULEX = GT_POSCHEDULX
POCOND = GT_COND
POCONDX = LT_POCONDX.
* When PO is open in change mode, show error message
LOOP AT GT_RETURN INTO GW_RETURN WHERE TYPE = LC_E AND
ID = LC_ME AND
NUMBER = LC_006 .
MESSAGE GW_RETURN-MESSAGE TYPE 'S' DISPLAY LIKE 'E'. "PO is being edited by some user
LEAVE TO TRANSACTION 'MIGO'.
ENDLOOP.
* Display Success message
LOOP AT GT_RETURN INTO GW_RETURN WHERE TYPE = LC_S AND
ID = LC_06 AND
NUMBER = LC_023 .
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
WAIT = LC_X.
IF SY-SUBRC EQ 0.
MESSAGE TEXT-002 TYPE 'S'. " Latest Cost updated in PO
ENDIF.
ENDLOOP.
CLEAR: GW_ITEMS,GW_POSCHEDULE,GW_POSCHEDULX.
CLEAR: GW_BAPI_POITEMX, GW_BAPI_POITEM,GW_COND,LV_CALC_AMT.
ENDLOOP.
ENDMETHOD.
------------------------------------------------------------------------------------------------------------------------
2. Method MODE_SET.
------------------------------------------------------------------------------------------------------------------------
method IF_EX_MB_MIGO_BADI~MODE_SET.
*Local Constants
DATA : LC_A01 TYPE GOACTION VALUE 'A01', " Goods Receipt
LV_MODE TYPE CHAR1.
FREE MEMORY ID 'MODE'.
IF I_ACTION EQ LC_A01 .
LV_MODE = 'X'.
EXPORT LV_MODE FROM LV_MODE TO MEMORY ID 'MODE'.
ENDIF.
endmethod.
------------------------------------------------------------------------------------------------------------------------
3. Method POST_DOCUMENT
------------------------------------------------------------------------------------------------------------------------
method IF_EX_MB_MIGO_BADI~POST_DOCUMENT.
FREE MEMORY ID 'DONE'.
FREE MEMORY ID 'PROCESSED'.
endmethod.
Conclusion :
During GR when User enters the PO in MIGO.
Once the user hits Enter button after entering PO# in MIGO, in the background BADI ‘MB_MIGO_BADI’ implementation changes the PO Pricing conditions with new material standard price ($150 in this case).
Finally Success message is shown.
Now, if we check the PO 4500264840 in ME23N, we see latest cost for condition type 'Z101'.
Post GRN : Financial document :
Freight will be calculated on new material price in GRN that resulting in posting correct PPV.
Test Cases:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
2 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |