开票定价例程

定价例程原理
先配置条件类型和定价例程的对应关系 (一个条件类型只会对应一个例程,一个例程可以配给多个条件)
一个行项目的定价数据存在内表xkomv中,程序loop xkomv,判断xkomv-kofrm,如果配置了例程,执行例程的处理逻辑。
对工作区xkomv的字段值修改后,最后修改内表xkomv,完成定价数据的修改
1.如果修改定价值,需要修改变量xkwet,因为执行完定价后会有执行一句xkomv-xkwet = xkwet。
2.如果修改单价和其他字段,直接修改工作区xkwet,注意不要loop xkwet再修改,因为例程本身就在loop中(触发时修改的工作区xkomv就是对应配置的条件类型),而且如果该行是外币,在进入例程之前会有汇率转换的逻辑,工作区中存放的是外币金额,而内表xkomv中存放的却是本位币金额。

定价例程增强步骤
vofm-公式-定价值
新建例程,比如901-双击,修改程序后,激活程序,激活例程(选中行,在菜单上有激活),业务配置条件类型和定价例程的对应关系就行。
常用变量:xkomv 内表、komk、komv、komp、xkbetr 。
例程没有固定点算术,所以计算和赋值时需要注意小数位。
一个例程只对应一种条件类型,所以修改的单价和总金额都是这种条件类型的
请求传输后需要在目标系统se38运行RV80HGEN重新生成所有的VOFM(会在 RV64ANNN中增加一行INCLUDE )。
定价例程在vf03时也会触发,但修改无效
可以在前台看到条件类型关联的例程
注意:当“条件控制”为E、F、H时(在copy control配置pricing type),在例程中修改金额是无效的。例程在另一个地方被调用了,执行完之后xkomv会被 RETTKOMV覆盖掉,
PREISFINDUNGSART = ‘E’时就会进入修改无效的地方调用例程,如果例程可能会被多次调用,只有PREISFINDUNGSART ne 'E'的时候修改才是有效的

例子(从600copy过来的改内表的应该都不规范)
最全的例子
FORM FRM_KONDI_WERT_917.
*{ INSERT DEVK900694 1
*计算NETW单价
case xkomv-kschl.
when 'ZFR1'.
read table xkomv into DATA(LS_xkomv1) WITH key kschl = 'Z001'.
read table xkomv into DATA(LS_xkomv2) WITH key kschl = 'ZA01'.
xkwert = LS_xkomv1-kwert + LS_xkomv2-kwert. "子越配置成负的了,直接加
when 'ZFR2'.
read table xkomv into LS_xkomv1 WITH key kschl = 'Z002'.
read table xkomv into LS_xkomv2 WITH key kschl = 'ZA02'.
xkwert = LS_xkomv1-kwert + LS_xkomv2-kwert. "子越配置成负的了,直接加
when 'ZFR3'.
read table xkomv into LS_xkomv1 with key kschl = 'Z003'.
read table xkomv into LS_xkomv2 with key kschl = 'ZA03'.
xkwert = LS_xkomv1-kwert + LS_xkomv2-kwert. "子越配置成负的了,直接加
when 'ZFR4'.
read table xkomv into LS_xkomv1 with key kschl = 'Z004'.
read table xkomv into LS_xkomv2 with key kschl = 'ZA04'.
xkwert = LS_xkomv1-kwert + LS_xkomv2-kwert. "子越配置成负的了,直接加
when 'ZFR5'.
read table xkomv into LS_xkomv1 WITH key kschl = 'Z005'.
read table xkomv into LS_xkomv2 WITH key kschl = 'ZA05'.
xkwert = LS_xkomv1-kwert + LS_xkomv2-kwert. "子越配置成负的了,直接加
when 'ZFR6'.
read table xkomv into LS_xkomv1 with key kschl = 'Z006'.
read table xkomv into LS_xkomv2 with key kschl = 'ZA06'.
xkwert = LS_xkomv1-kwert + LS_xkomv2-kwert. "子越配置成负的了,直接加
when 'ZFR7'.
read table xkomv into LS_xkomv1 with key kschl = 'Z007'.
read table xkomv into LS_xkomv2 with key kschl = 'ZA07'.
xkwert = LS_xkomv1-kwert + LS_xkomv2-kwert. "子越配置成负的了,直接加
when 'ZFR8'.
read table xkomv into LS_xkomv1 with key kschl = 'Z008'.
read table xkomv into LS_xkomv2 with key kschl = 'ZA08'.
xkwert = LS_xkomv1-kwert + LS_xkomv2-kwert. "子越配置成负的了,直接加
endcase.

xkomv-kbetr = 1000 * xkwert / komp-mglme.
*} INSERT
ENDFORM.


1.根据日期调整定价(更新单价和单位)
************************************************************
*** 注意: 复制的例程 ! *
*** 注意 : ***
*** 所有字符串 ?1 用?2 替换 ! ***
************************************************************

* value excluding tax
form frm_kondi_wert_901.
*{ INSERT HSDK901167 2

* XKOMV-KSTAT = 'X'.

DATA: lv_vkorg TYPE vkorg,
lv_knumh TYPE knumh,
ls_komk TYPE komk,
ls_komp TYPE komp,
ls_komv TYPE komv,
ls_ekko TYPE ekko.

IF komk-fkart = 'ZIV1' OR komk-fkart = 'ZIG'.
SELECT SINGLE ekko~bsart INTO CORRESPONDING FIELDS OF ls_ekko
FROM ekko
INNER JOIN lips on lips~vgbel = ekko~ebeln
WHERE lips~vbeln = komp-vgbel and lips~posnr = komp-vgpos.

if ls_ekko-BSART = 'EB'.

LOOP AT xkomv WHERE kschl = 'ZPB1'.

* SELECT SINGLE vkorg INTO ls_komp-werks
* FROM tvko
* WHERE kunnr = komk-kunnr.
* SELECT SINGLE lifnr INTO ls_komk-lifnr
* FROM t001w
* WHERE werks = komk-vkorg.

ls_komp-werks = '2600'.
ls_komk-lifnr = '0000010142'.

ls_komp-matkl = komp-matkl.
ls_komp-matnr = komp-matnr.
ls_komk-reswk = komk-vkorg. "发出工厂

CALL FUNCTION 'ZGET_CONDITION_KOMV'
EXPORTING
kschl = xkomv-kschl
datum = komk-fkdat "开票日期
kappl = 'M'
komk = ls_komk
komp = ls_komp
IMPORTING
komv = ls_komv
EXCEPTIONS
not_found = 1
value_init = 2
kschl_not_found = 3
OTHERS = 4.
IF sy-subrc = 0.
IF ls_komv-krech CA 'AHIKJ'. "百分比等
ls_komv-kbetr = ls_komv-kbetr * 10 .
ENDIF.
xkomv-kbetr = ls_komv-kbetr.
MODIFY xkomv.
ENDIF.
ENDLOOP.

xkomv-kstat = 'X'.
ENDIF.
endif.


*} INSERT
*{ DELETE HSDK901167 1
*\ xkwert = komp-netwr.
*} DELETE
endform.

FUNCTION zget_condition_komv.
*"----------------------------------------------------------------------
*"*"局部接口:
*" IMPORTING
*" VALUE(KSCHL) TYPE KSCHL
*" VALUE(DATUM) TYPE DATUM
*" VALUE(KAPPL) TYPE KAPPL
*" VALUE(KOMK) TYPE KOMK
*" VALUE(KOMP) TYPE KOMP
*" EXPORTING
*" VALUE(KOMV) TYPE KOMV
*" EXCEPTIONS
*" NOT_FOUND
*" VALUE_INIT
*" KSCHL_NOT_FOUND
*"----------------------------------------------------------------------
DATA: BEGIN OF lt_682 OCCURS 0,
kolnr LIKE t682i-kolnr,
kotabnr LIKE t682i-kotabnr, "表名
zifna LIKE t682z-zifna, "字段名
qustr LIKE t682z-qustr,
qufna LIKE t682z-qufna,
END OF lt_682.
DATA: BEGIN OF lt_talbes OCCURS 0,
kotabnr LIKE t682i-kotabnr,
tabname(4),"表名
knumh TYPE knumh,
END OF lt_talbes.
DATA: wa_t685 LIKE t685.
DATA: wherestr(1000).

IF kappl IS INITIAL .
kappl = 'V'.
ENDIF.

IF kschl IS INITIAL OR datum IS INITIAL OR kappl IS INITIAL OR
( komk IS INITIAL AND komp IS INITIAL ) .
RAISE value_init.
ELSE.
SELECT SINGLE * INTO wa_t685 FROM t685 "条件类型获取存取顺序
WHERE kvewe = 'A' AND
kappl = kappl AND
kschl = kschl.
IF sy-subrc <> 0.
RAISE kschl_not_found.
ENDIF.
ENDIF.

SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_682
FROM t682i INNER JOIN t682z ON t682i~kvewe = t682z~kvewe AND
t682i~kappl = t682z~kappl AND
t682i~kozgf = t682z~kozgf AND
t682i~kolnr = t682z~kolnr
WHERE t682i~kvewe = 'A' AND
t682i~kappl = kappl AND
t682i~kozgf = wa_t685-kozgf AND
t682z~qustr <> ''
ORDER BY t682i~kolnr.

LOOP AT lt_682.
lt_talbes-kotabnr = lt_682-kotabnr.
lt_talbes-tabname = 'A' && lt_682-kotabnr.
COLLECT lt_talbes.
ENDLOOP.

LOOP AT lt_talbes.
CLEAR wherestr.
LOOP AT lt_682 WHERE kotabnr = lt_talbes-kotabnr.
CONCATENATE wherestr ` ` lt_682-zifna ` = `
lt_682-qustr '-' lt_682-qufna ` AND `
INTO wherestr.
ENDLOOP.
* SHIFT wherestr RIGHT DELETING TRAILING 'AND ' .
wherestr = shift_right( val = wherestr sub = 'AND' ).

SELECT SINGLE knumh INTO lt_talbes-knumh
FROM (lt_talbes-tabname)
WHERE kappl = kappl AND
kschl = kschl AND
datbi >= datum AND
datab <= datum AND
(wherestr).
IF sy-subrc = 0.
SELECT SINGLE * INTO CORRESPONDING FIELDS OF komv
FROM konp
WHERE knumh = lt_talbes-knumh AND loevm_ko = ''.
IF sy-subrc = 0.
IF komv-krech CA 'AHIKJ'. "百分比等
komv-kbetr = komv-kbetr / 10 .
ENDIF.
EXIT.
ENDIF.
ENDIF.
ENDLOOP.

IF komv IS INITIAL.
RAISE not_found.
ENDIF.

ENDFUNCTION.

2.计算单价
FORM FRM_KONDI_WERT_916.
*{ INSERT DEVK900651 1
*计算NETW单价

xkomv-kbetr = 1000 * xkomv-KWERT / komp-mglme.

*} INSERT
ENDFORM.

3.更新定价值(总金额)
FORM FRM_KONDI_WERT_915.
*{ INSERT DEVK900554 1
*Z002写入金额

data:begin of lt_con occurs 0.
include structure bapikomv.
data:
vgbel like lips-vgbel,
vgpos like lips-vgpos,
end of lt_con.

import
lt_con = lt_con
from memory id 'ZFLG_VF01_MIRO'.

read table lt_con with key vgbel = komp-vgbel vgpos = komp-vgpos.
if sy-subrc = 0.
xkwert = lt_con-cond_value / 100. "没有固定点算术
endif.

*} INSERT
ENDFORM.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值