
CLASS zcl_amdp_unit_of_measurement DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb.
TYPES: BEGIN OF ty_data,
matnr TYPE matnr,
menge_from TYPE menge_d,
uom_from TYPE meins,
menge_to TYPE menge_d,
uom_to TYPE meins,
END OF ty_data,
tty_data TYPE TABLE OF ty_data.
CLASS-METHODS marm_convert_material_unit IMPORTING VALUE(it_data) TYPE tty_data
EXPORTING VALUE(et_result) TYPE tty_data.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_amdp_unit_of_measurement IMPLEMENTATION.
METHOD marm_convert_material_unit BY DATABASE PROCEDURE FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING mara
marm.
* The standard SAP AMDP CL_CS_BOM_AMDP=>MAT_CONVERT_UOM_TO_BASE_UOM does not factor in MARM-MESUB.
* Therefore, calculation will be incomplete if MESUB is used.
*
* EXAMPLE: material with base UoM PCE and the following UoM conversion rules
* 1 PCE = 1 PCE
* 1 CS = 4 MP (MESUB = MP)
* 1 MP = 10 PCE
*
* When using CL_CS_BOM_AMDP=>MAT_CONVERT_UOM_TO_BASE_UOM the result is:
* 1 MP => 10 PCE
* 1 CS => 4 PCE
*
* This is not correct and should be:
* 1 CS = 4 MP and 1 MP = 10 PCE thus 1 CS = 4*10 PCE = 40 PCE
* Since all UoM conversions rules are stored in MARM in relation to the base UoM (even with MESUB), with a simple formula we
* can make sure the correct calculation is performed and get a converted quantity just like using function MD_CONVERT_MATERIAL_UNIT:
* Formula to convert quantity unit_from = > unit_to
* converted quantity = quantity * ( ( denominator uom_from / nominator uom_from ) / ( denominator uom_to / nominator uom_to ) )
tmp_from =
select marm.mandt as mandt,
marm.matnr as matnr,
marm.meinh as uom,
marm.umrez as umrez,
marm.umren as umren
from :it_data as data_source
inner join mara as mara on mara.mandt = session_context( 'CLIENT' ) and
mara.matnr = data_source.matnr
inner join marm as marm on marm.mandt = mara.mandt and
marm.matnr = data_source.matnr and
marm.meinh = data_source.uom_from;
tmp_to =
select marm.mandt as mandt,
marm.matnr as matnr,
marm.meinh as uom,
marm.umrez as umrez,
marm.umren as umren
from :it_data as data_source
inner join mara as mara on mara.mandt = session_context( 'CLIENT' ) and
mara.matnr = data_source.matnr
inner join marm as marm on marm.mandt = mara.mandt and
marm.matnr = data_source.matnr and
marm.meinh = data_source.uom_to;
* Convert original quantity to requested unit
* converted quantity = quantity * ( ( denominator uom_from / nominator uom_from ) / ( denominator uom_to / nominator uom_to ) )
et_result =
select data_source.matnr,
data_source.menge_from,
data_from.uom as uom_from,
ROUND( ( data_source.menge_from * ( ( data_from.umrez / data_from.umren ) / ( data_to.umrez / data_to.umren) ) ), 3, ROUND_HALF_EVEN) as menge_to,
data_to.uom as uom_to
from :it_data as data_source
left join :tmp_from as data_from on data_from.matnr = data_source.matnr and
data_from.uom = data_source.uom_from
left join :tmp_to as data_to on data_to.matnr = data_source.matnr and
data_to.uom = data_source.uom_to;
ENDMETHOD.
ENDCLASS.
METHOD marm_convert_material_unit BY DATABASE PROCEDURE FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING marm.
* The standard SAP AMDP CL_CS_BOM_AMDP=>MAT_CONVERT_UOM_TO_BASE_UOM does not factor in MARM-MESUB.
* Therefore, calculation will be incomplete if MESUB is used.
*
* EXAMPLE: material with base UoM PCE and the following UoM conversion rules
* 1 PCE = 1 PCE
* 1 CS = 4 MP (MESUB = MP)
* 1 MP = 10 PCE
*
* When using CL_CS_BOM_AMDP=>MAT_CONVERT_UOM_TO_BASE_UOM the result is:
* 1 MP => 10 PCE
* 1 CS => 4 PCE
*
* This is not correct and should be:
* 1 CS = 4 MP and 1 MP = 10 PCE thus 1 CS = 4*10 PCE = 40 PCE
* Since all UoM conversions rules are stored in MARM in relation to the base UoM (even with MESUB), with a simple formula we
* can make sure the correct calculation is performed and get a converted quantity just like using function MD_CONVERT_MATERIAL_UNIT:
* Formula to convert quantity unit_from = > unit_to
* converted quantity = quantity * ( ( denominator uom_from / nominator uom_from ) / ( denominator uom_to / nominator uom_to ) )
et_result =
select data_source.matnr,
data_source.menge_from,
data_source.uom_from,
case when marm_to.umren = 0 or marm_to.umren is NULL then 0.000
when marm_from.umren = 0 or marm_from.umren is NULL then 0.000
when marm_to.umren is NOT NULL and marm_from.umren is NOT NULL then
ROUND( ( data_source.menge_from * ( ( marm_from.umrez / marm_from.umren ) / ( marm_to.umrez / marm_to.umren) ) ), 3, ROUND_HALF_EVEN)
end as menge_to,
marm_to.meinh as uom_to
from :it_data as data_source
left outer join marm as marm_from on marm_from.mandt = session_context( 'CLIENT' ) and
marm_from.matnr = data_source.matnr and
marm_from.meinh = data_source.uom_from
left outer join marm as marm_to on marm_to.mandt = session_context( 'CLIENT' ) and
marm_to.matnr = data_source.matnr and
marm_to.meinh = data_source.uom_to;
ENDMETHOD.
METHOD marm_convert_material_unit BY DATABASE PROCEDURE FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING marm.
* The standard SAP AMDP CL_CS_BOM_AMDP=>MAT_CONVERT_UOM_TO_BASE_UOM does not factor in MARM-MESUB.
* Therefore, calculation will be incomplete if MESUB is used.
*
* EXAMPLE: material with base UoM PCE and the following UoM conversion rules
* 1 PCE = 1 PCE
* 1 CS = 4 MP (MESUB = MP)
* 1 MP = 10 PCE
*
* When using CL_CS_BOM_AMDP=>MAT_CONVERT_UOM_TO_BASE_UOM the result is:
* 1 MP => 10 PCE
* 1 CS => 4 PCE
*
* This is not correct and should be:
* 1 CS = 4 MP and 1 MP = 10 PCE thus 1 CS = 4*10 PCE = 40 PCE
* Since all UoM conversions rules are stored in MARM in relation to the base UoM (even with MESUB), with a simple formula we
* can make sure the correct calculation is performed and get a converted quantity just like using function MD_CONVERT_MATERIAL_UNIT:
* Formula to convert quantity unit_from = > unit_to
* converted quantity = quantity * ( ( denominator uom_from / nominator uom_from ) / ( denominator uom_to / nominator uom_to ) )
tmp_result =
select data_source.matnr,
data_source.menge_from,
data_source.uom_from,
case when marm_to.umren = 0 or marm_to.umren is NULL then 0.000
when marm_from.umren = 0 or marm_from.umren is NULL then 0.000
when marm_to.umren is NOT NULL and marm_from.umren is NOT NULL then
ROUND( ( data_source.menge_from * ( ( marm_from.umrez / marm_from.umren ) / ( marm_to.umrez / marm_to.umren) ) ), 3, ROUND_HALF_EVEN)
end as menge_to,
marm_to.meinh as uom_to
from :it_data as data_source
left outer join marm as marm_from on marm_from.mandt = session_context( 'CLIENT' ) and
marm_from.matnr = data_source.matnr and
marm_from.meinh = data_source.uom_from
left outer join marm as marm_to on marm_to.mandt = session_context( 'CLIENT' ) and
marm_to.matnr = data_source.matnr and
marm_to.meinh = data_source.uom_to;
* If no conversion could be carried out, retry with standard CONVERT_UNIT
et_result =
select matnr,
menge_from,
uom_from,
menge_to,
uom_to
from :tmp_result
where menge_to <> 0 and menge_to is NOT NULL
union all
select no_cnv.matnr,
no_cnv.menge_from,
no_cnv.uom_from,
CONVERT_UNIT("QUANTITY"=>no_cnv.menge_from,
"SOURCE_UNIT_COLUMN"=>no_cnv.uom_from,
"SCHEMA"=>'SAPSR3',
"TARGET_UNIT_COLUMN"=>data_source.uom_to,
"ERROR_HANDLING"=>'set to null',
"CLIENT"=>session_context('CLIENT')) AS menge_to,
data_source.uom_to
from :tmp_result as no_cnv
inner join :it_data as data_source on no_cnv.matnr = data_source.matnr
where no_cnv.menge_to = 0 or no_cnv.menge_to is NULL;
ENDMETHOD.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
9 | |
6 | |
6 | |
5 | |
5 | |
5 | |
5 | |
5 | |
4 | |
4 |