If we want to valuate inhouse product through costing run in a way which is not provided by SAP standards (all the priorities / strategies provided),
we need to use the user exit EXIT_SAPLCK21_002.
A product costing of such nature is detailed here; We tried to gather and finalize the requirements and how it could be achieved :
Following parameters need to be achieved when costing run takes place:
- A. For any bought out item indigenous ,
ØSystem should look into all PO s containing that material.
ØSuch PO s should be restricted to whose delivery date falls within last 365 days of costing run date.
ØSystem will consider only PO s released and line item is not deleted.
ØSystem will then pick the highest price from the PO s; the price is net effective price.
ØIf the purchasing unit of material is different from BOM unit, the price needs to be converted to BOM unit.
ØThis net effective price will be compared to MAP of the material and higher of two will be taken into valuation.
ØIncase system could not find any such PO for the abovementioned period then the MAP will be picked up for cost estimate.
B. For any bought out item imported,
ØTo encounter the High Seas sale issue, which contain only the basic price, system will find the basic price of all import PO s;
then the highest basic price will be picked up.
ØAll modvatable items will be deducted from the effective price to arrive at the basic price .
- For exchange rate ,
ØFor all imported bought out items, the above mentioned price will be multiplied by exchange rate as on most recent date the costing run date
ØTo achieve this, a separate exchange rate type will be maintained in the exchange rate table ; which must be different from classical "M" or "P"
To achieve point no 1 A:
We need to join EKKO & EKPO table to get the PO s relevant for the material & plant.
Standard SAP join table WB2_V_EKKO_EKPO will be used.
Delivery Date we will get from EKET-EINDT, this should be restricted to last 365 days of costing run date. This can be achieved by calling a FM.
Effective Price we will get from EKPO-EFFWR; this to be divided by EKPO-MENGE (quantity); currency we will get from EKKO-WAERS.
So with the material no (EKPO-MATNR) PO s will be sorted first; then the highest price will be picked up.
To convert the price from purchasing UOM to BOM UOM, a FM will be called.
This will be compared with (MBEW-VERPR) field of the MM.
The MAP is set as 2nd priority, in case system fails to find any PO in the above period.
To achieve point no 1 B:
System will recognize the high seas sale with a unique purchasing group “XXX”.
For all import PO s from net effective price the landing charge, CVD modvatable, additional duty of customs will be deducted to arrive at basic price.
This basic price will be inflated by say 1.1205 times to arrive at net effective price. ( this 1.1205 factor is applicable for India)
To achieve point no 2:
As mentioned, system will check the currency and will multiply with the unique exchange rate type maintained.
A new exchange rate type Y1 is configured for quotation costing; only this exchange rate type and corresponding exchange rates will be called in the user exit.
Relevant field is TCURR-GDATU (most recent date to costing runs date) & TCURR-UKURS (exchange rate as on that date).
The details of ABAP code written
FUNCTION EXIT_SAPLCK21_002.
INCLUDE ZXCKAU08
TYPES: BEGIN OF lty_ekpo,
ebeln TYPE ebeln,
ebelp TYPE ebelp,
bukrs TYPE bukrs,
waers TYPE waers,
matnr TYPE matnr,
menge TYPE bstmg,
effwr TYPE effwr,
bprme TYPE bprme,
knumv type knumv,
ekgrp type ekgrp,
mengec TYPE bstmg,
eindt TYPE eindt,
END OF lty_ekpo.
TYPES: BEGIN OF lty_eket,
ebeln TYPE ebeln,
ebelp TYPE ebelp,
eindt TYPE eindt,
END OF lty_eket.
TYPES: BEGIN OF lty_ins,
menge TYPE bstmg,
END OF lty_ins.
DATA: lt_ekpo TYPE STANDARD TABLE OF lty_ekpo,
lw_ekpo TYPE lty_ekpo.
DATA: lt_eket TYPE STANDARD TABLE OF lty_eket,
lw_eket TYPE lty_eket.
DATA: lw_ins TYPE lty_ins.
DATA: lv_date TYPE p0001-begda,
lv_verpr TYPE verpr,
lv_vprsv TYPE vprsv,
lv_value TYPE ukurs_curr,
lv_meins TYPE meins,
tmeins LIKE t006-msehi,
tbprme LIKE t006-msehi,
tmgvgw LIKE plfh-mgvgw,
tkwert like konv-kwert,
tkschl like konv-kschl.
REFRESH: lt_eket,lt_ekpo.CLEAR: lv_date,lv_verpr,lv_vprsv,lv_value.SELECT SINGLE meins
INTO lv_meins
FROM mara
WHERE matnr = f_matbw-matnr.SELECT SINGLE verpr vprsv
INTO (lv_verpr,lv_vprsv)
FROM mbew
WHERE matnr = f_matbw-matnr
AND bwkey = f_matbw-werks.
IF lv_vprsv = 'V'.
SELECT ebeln ebelp_i bukrs waers
matnr_i menge_i effwr_i
bprme_i knumv ekgrp
FROM wb2_v_ekko_ekpo2 INTO TABLE lt_ekpo
WHERE bukrs = '1000' (the company code =1000)
AND matnr_i = f_matbw-matnr
and ( frgke = 'A' or
frgke = 'C' )
and LOEKZ_I = ' '.
IF sy-subrc = 0.
SORT lt_ekpo BY ebeln ebelp.
ENDIF.
IF lt_ekpo IS NOT INITIAL.
SELECT ebeln ebelp eindt FROM eket INTO TABLE lt_eket
FOR ALL ENTRIES IN lt_ekpo
WHERE ebeln = lt_ekpo-ebeln
AND ebelp = lt_ekpo-ebelp
AND etenr = '0001'.
IF sy-subrc = 0.
SORT lt_eket BY ebeln ebelp.
ENDIF.
IF lt_eket IS NOT INITIAL.
LOOP AT lt_ekpo INTO lw_ekpo.
if lw_ekpo-ekgrp = '946'.(the purchasing group for high seas sale = 946)
lw_ekpo-effwr = lw_ekpo-effwr * 11205 / 10000.
endif.
if lw_ekpo-waers ne 'INR'.
select kwert kschl
into (tkwert, tkschl)
from konv
where knumv = lw_ekpo-knumv
and kposn = lw_ekpo-ebelp.
if sy-subrc eq 0.
if tkschl = 'ZLC1'.
lw_ekpo-effwr = lw_ekpo-effwr - tkwert.
elseif tkschl = 'ZCV1'.
lw_ekpo-effwr = lw_ekpo-effwr - tkwert.
elseif tkschl = 'JADC'.
lw_ekpo-effwr = lw_ekpo-effwr - tkwert.
endif. (the condition types to be deducted are identified as ZLC1 / ZCV1 / JADC)
endif.
clear : tkwert, tkschl.
endselect.
endif.
READ TABLE lt_eket INTO lw_eket WITH KEY ebeln = lw_ekpo-ebeln
ebelp = lw_ekpo-ebelp BINARY SEARCH.
IF sy-subrc = 0.
CALL FUNCTION 'CF_UT_UNIT_CONVERSION'
EXPORTING
matnr_imp = f_matbw-matnr
meins_imp = lv_meins
unit_new_imp = lv_meins
unit_old_imp = lw_ekpo-bprme
value_old_imp = 1000
IMPORTING
value_new_exp = tmgvgw.* ENDIF.
lw_ekpo-menge = tmgvgw * lw_ekpo-menge / 1000.
CLEAR : tmgvgw.
lw_ekpo-eindt = lw_eket-eindt.
IF lw_ekpo-menge > 0.
lw_ekpo-mengec = ( lw_ekpo-effwr / lw_ekpo-menge ).
ELSE.
lw_ekpo-mengec = lw_ekpo-effwr.
ENDIF.
IF lw_ekpo-waers NE 'INR'.
CALL FUNCTION 'READ_EXCHANGE_RATE'
EXPORTING
client = sy-mandt
date = sy-datum
foreign_currency = lw_ekpo-waers
local_currency = 'INR'
type_of_rate = 'Y1'
IMPORTING
exchange_rate = lv_value
EXCEPTIONS
no_rate_found = 1
no_factors_found = 2
no_spread_found = 3
derived_2_times = 4
overflow = 5
zero_rate = 6
OTHERS = 7.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
lw_ekpo-mengec = lw_ekpo-mengec * lv_value.
ENDIF.
MODIFY lt_ekpo FROM lw_ekpo.
CLEAR: lw_ekpo,lw_eket.
ENDIF.
ENDLOOP.
CALL FUNCTION 'RP_CALC_DATE_IN_INTERVAL'
EXPORTING
date = sy-datum
days = '00'
months = '00'
signum = '-'
years = '01'
IMPORTING
calc_date = lv_date.
IF lv_date IS NOT INITIAL.
DELETE lt_ekpo WHERE eindt LT lv_date.
ENDIF.
SORT lt_ekpo BY mengec DESCENDING.
DELETE ADJACENT DUPLICATES FROM lt_ekpo COMPARING matnr.
READ TABLE lt_ekpo INTO lw_ekpo INDEX 1.
IF sy-subrc = 0.
IF lv_verpr IS NOT INITIAL.
IF lv_verpr GE lw_ekpo-mengec.
lw_ins-menge = lv_verpr.
ELSEIF lv_verpr LE lw_ekpo-mengec.
lw_ins-menge = lw_ekpo-mengec.
ENDIF.
exp_preis = lw_ins-menge.
ENDIF.* else. "IF PO Not Found* exp_preis = lv_verpr.
ENDIF.
clear lv_verpr.
ENDIF.
ENDIF.
ENDIF.
==========================================================================