Reading price conditions dynamically from condition tables

作者:郑德鼎 约 6 分钟阅读 更新日期:2024-02-22 2 年前更新 标签:SD, 销售分销
目录

François Henrotte

Posted onAugust 28, 2018 4 minute read

Reading price conditions dynamically from condition tables

FollowRSS feedLike

10 Likes 11,373 Views 9 Comments

It is not easy to get price conditions as they can be stored into different condition tables based on the needs of each customer. The condition tables are generated and the fields used inside the tables are not always the same.

Here is a solution to get the price linked to a condition LV_KSCHL. We assume that the usage and application (keys from table T685) are fixed into constants – respectively ‘A’ and ‘V’ for Sales.

Step 1 : get access sequence

This is needed in order to retrieve the list of condition tables linked to the condition type.

SELECT SINGLE * FROM t685

INTO @gs_t685

WHERE kvewe EQ @gc_kvewe

AND kappl EQ @gc_kappl

AND kschl EQ @lv_kschl.

IF sy-subrc EQ 0.
lv_kozgf = gs_t685-kozgf.
ENDIF.

Step 2 : get the list of condition tables linked to the access sequence

DATA: lt_t682ia TYPE TABLE OF t682ia.

CLEAR: gt_t681.

CALL FUNCTION 'COND_READ_ACCESSES'

EXPORTING

i_kvewe = gc_kvewe

i_kappl = gc_kappl

i_kozgf = lv_kozgf

TABLES

t682ia_tab = lt_t682ia

EXCEPTIONS

OTHERS = 1.

SELECT * FROM t681

INTO TABLE gt_t681

FOR ALL ENTRIES IN lt_t682ia

WHERE kvewe EQ gc_kvewe

AND kotabnr EQ lt_t682ia-kotabnr.

Step 3 : for each condition table, get the data of the condition type

We follow the access sequence, and if some data is found, then we exit the loop. We could also collect all the data from the different condition tables, if needed. The date PRSDT can be also defined externally to some other value than the current date.

LOOP AT gt_t681 INTO DATA(ls_t681).

"Retrieve data from condition tables

get_data_from_condition_table( is_t681 = ls_t681

iv_prsdt = sy-datum ).

IF gt_data IS NOT INITIAL.

EXIT.

ENDIF.
ENDLOOP.

Now let’s look at the dynamical reading of the data. As we have the structures T685 and T681, we have almost all information needed to do so. The only missing part is about the fields to be used for the selection of the table. This will be easily retrieved using function module WCB_GET_CONDITION_TABLE_KEYS. So the coding to retrieve the data will be like this :

METHOD GET_DATA_FROM_CONDITION_TABLE.
DATA: lt_t682z TYPE wcb_t682z_tab.
DATA: lv_datum TYPE datum,

ls_where TYPE string.

DATA: ls_data TYPE ty_data.
DATA: ob_rec TYPE REF TO data.

FIELD-SYMBOLS: <lt_rec> TYPE STANDARD TABLE,

<lv_field> TYPE any,

<lv_knumh> TYPE knumh.

CREATE DATA ob_rec TYPE STANDARD TABLE OF (is_t681-kotab) WITH NON-UNIQUE DEFAULT KEY.

ASSIGN ob_rec->* TO <lt_rec>.

* Pay attention to this

• Method GET_ACCESS_SEQUENCE should be called first in order to fill structure GS_T685

CALL FUNCTION 'WCB_GET_CONDITION_TABLE_KEYS'

EXPORTING

i_use = gc_kvewe

i_application = gc_kappl

i_condition_type = gs_t685-kschl

i_con_tab = is_t681-kotabnr

i_access = gs_t685-kozgf

IMPORTING

et_t682z = lt_t682z

EXCEPTIONS

OTHERS = 1.

IF sy-subrc NE 0.

RETURN.

ENDIF.
LOOP AT lt_t682z INTO DATA(ls_t682z).

ASSIGN COMPONENT ls_t682z-zifna OF STRUCTURE gs_komg TO <lv_field>.

IF sy-subrc EQ 0.
IF ls_where IS INITIAL.
ls_where = |{ ls_t682z-zifna } EQ '{ <lv_field> }'|.

ELSE.

ls_where = ls_where && | AND { ls_t682z-zifna } EQ '{ <lv_field> }'|.
ENDIF.
ENDIF.
ENDLOOP.
IF is_t681-ksdat IS INITIAL.
SELECT * INTO TABLE <lt_rec>

FROM (is_t681-kotab)

WHERE kappl EQ gc_kappl

AND kschl EQ gs_t685-kschl

AND (ls_where).

ELSE.

IF iv_prsdt IS INITIAL.
lv_datum = sy-datum.

ELSE.

lv_datum = iv_prsdt.
ENDIF.
SELECT * INTO TABLE <lt_rec>

FROM (is_t681-kotab)

WHERE kappl EQ gc_kappl

AND kschl EQ gs_t685-kschl

AND datbi GE lv_datum

AND datab LE lv_datum

AND (ls_where).

ENDIF.
LOOP AT <lt_rec> ASSIGNING FIELD-SYMBOL(<ls_line>).

ASSIGN COMPONENT 'KNUMH' OF STRUCTURE <ls_line> TO <lv_knumh>.

SELECT konp~knumh

konp~kbetr AS kbetr_1

konp~konwa

konp~kpein

konp~kmein

konm~kstbm

konp~konms

konm~kbetr AS kbetr_2

INTO ls_data

FROM konp

LEFT OUTER JOIN konm ON konm~knumh = konp~knumh

WHERE konp~knumh EQ <lv_knumh>

AND konp~loevm_ko EQ ' '.

IF ls_data-konwa CA '%'.
ls_data-kbetr_1 = ls_data-kbetr_1 / 10 .
ls_data-kbetr_2 = ls_data-kbetr_2 / 10 . "BGO01
ENDIF.
APPEND ls_data TO gt_data.
ENDSELECT.
ENDLOOP.

SORT gt_data BY knumh kstbm.

ENDMETHOD.

Notes

the parameters are trivial : IS_T681 TYPE T681 and IV_PRSDT TYPE PRSDT.

the field T681-KSDAT indicates if the condition table is time-dependent.

depending on your needs you define the table GT_DATA to contain data from tables KONP / KONM

those two tables are always read with the key KNUMH coming from the condition tables

Prerequisite

Now you should have noticed that we compare the values of the condition tables with the values from segment GS_KOMG. This one is of type KOMG and contains all the possible fields to be used in the key fields of condition tables. Of course you have to fill this segment before starting to read the condition tables. Here is some sample code to do it quite easily for a Billing document.

CALL FUNCTION 'RV_INVOICE_PRICING_PREPARE'

EXPORTING

vbrk_i = ls_vbrk
vbrp_i = ls_vbrp

IMPORTING

komk_e = ls_komk
komp_e = ls_komp

TABLES

xkomfk = lt_komfk
xvbfs = lt_vbfs
xvbpa = lt_xvbpa
xvbrk = lt_xvbrk
xvbrp = lt_xvbrp

EXCEPTIONS

OTHERS = 1.

"Fill source fields for condition tables

MOVE-CORRESPONDING ls_komk TO gs_komg.

MOVE-CORRESPONDING ls_komp TO gs_komg.

As you probably noticed, this was extracted from a class that I made to read the condition tables dynamically. I extracted the important parts of the code and removed the Z tables and such things that are not generic so that you can see how this works from a global point of view.

Alert Moderator

Assigned tags

ABAP Development

condition

dynamic

price

table

Similar Blog Posts

Getting Sales Conditions using ABAP

By Alexandre Dambrowski, Jun 19, 2015

When “For All Entries(FAE)” gone for a Toss

By Siva rama Krishna Pabbraju, Apr 17, 2018

Extra sub segment E1EDP05 for Idoc Type ORDERS05

By Jigang Zhang 张吉刚, Mar 10, 2021

Related Questions

How to get Purchace Order price conditions with a function module

By Former Member, Sep 06, 2010

Sales Order Pricing - changing XKOMV in code

By sapuser SAP, Apr 19, 2019

PO net value incl tax

By rangerlet mesee, May 07, 2019

9 Comments

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

Jesús Antonio Santos Giraldo

August 28, 2018 at 2:40 pm

Nice !

Like(0)

ROBERTO Forti Santos

August 28, 2018 at 3:17 pm

Thanks for sharing it! Regards

Like(0)

Shai Sinai

August 28, 2018 at 9:29 pm

Thanks for sharing.

In case you are interested just in the condition value (and not in complete analysis), you may use standard FM CONDITION_RECORD_READ.

FM CONDITION_RECORD_READ (and it seems that also your code) doesn't handle scale based conditions, For this you'll have to further process parameter pe_t_scale according to KOMP-KSTBS.

Like(2)

François Henrotte Post author

August 30, 2018 at 3:30 pm

Thank you for your input !

The coding I proposed is a basis that you can adapt in order to meet specific needs.

Based on KONP you can retrieve the scales using the function module CONDITION_SCALES_READ. This one is used also in CONDITION_RECORD_READ which leads me to think that it is well handling such conditions.

Like(1)

akira jain

August 29, 2018 at 8:20 am

Thanks for sharing.

The ABAP language was originally used by developers to develop the SAP R/3 platform. It was also intended to be used by SAP customers to enhance SAP applications – customers can develop custom reports and interfaces with ABAP programming.

Like(0)

Matthew Billingham

August 29, 2018 at 6:26 pm

Spammer, reported.

Like(1)

Akash Kanade

August 29, 2018 at 10:38 am

Thanks for sharing..! Helpful..!

Like(0)

Matthew Billingham

August 29, 2018 at 1:57 pm

You need to make an edit

CALL FUNCTION 'COND_READ_ACCESSES'

EXPORTING

i_kvewe = gc_kvewe

i_kappl = gc_kappl

i_kozgf = lv_kozgf

TABLES

t682ia_tab = lt_t682ia

EXCEPTIONS

OTHERS = 1.

IF lt_t682ia IS NOT INITIAL.
SELECT * FROM t681

INTO TABLE gt_t681

FOR ALL ENTRIES IN lt_t682ia

WHERE kvewe EQ gc_kvewe

AND kotabnr EQ lt_t682ia-kotabnr.

ENDIF.

If you don't have that check and lt_t682ia is empty, then you'll get everything in T681. Which you probably don't want.

Like(3)

François Henrotte Post author

August 30, 2018 at 3:16 pm

True, it is always needed to check if the table is empty before you use it in a FOR ALL ENTRIES statement. Thank you for your remark !

郑德鼎

关于作者:郑德鼎

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「Reading price conditions dynamically from condition tables.docx」整理生成,仅用于内部技术分享与学习交流。