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 t685INTO @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_kozgfTABLES
t682ia_tab = lt_t682iaEXCEPTIONS
OTHERS = 1.
SELECT * FROM t681INTO 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_t681iv_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>.
• 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_t682zEXCEPTIONS
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~knumhkonp~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 . "BGO01ENDIF.APPEND ls_data TO gt_data.ENDSELECT.ENDLOOP.SORT gt_data BY knumh kstbm.
ENDMETHOD.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
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_vbrkvbrp_i = ls_vbrpIMPORTING
komk_e = ls_komkkomp_e = ls_kompTABLES
xkomfk = lt_komfkxvbfs = lt_vbfsxvbpa = lt_xvbpaxvbrk = lt_xvbrkxvbrp = lt_xvbrpEXCEPTIONS
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_kozgfTABLES
t682ia_tab = lt_t682iaEXCEPTIONS
OTHERS = 1.
IF lt_t682ia IS NOT INITIAL.SELECT * FROM t681INTO 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 !