开发目的
本开发目的主要是用于促销活动期间,客户必须支付专项货款才能购买促销产品的情况。促销的专款需要和普通货款相区别,同时,根据客户提供的专款控制客户订货的金额。当活动结束,专款尚未使用完毕,需要转入普通货款。
开发目的
本开发目的主要是用于促销活动期间,客户必须支付专项货款才能购买促销产品的情况。促销的专款需要和普通货款相区别,同时,根据客户提供的专款控制客户订货的金额。当活动结束,专款尚未使用完毕,需要转入普通货款。
一、表结构
本平台主要有2个自定义表、1个日志报表以及相关逻辑构成
表1:ZKHD(专款专用活动报表):该表的主要目的就是保存专款专用的活动信息
专款项目号 | 专款项目描述 | 打款有效起始日期 | 打款有效结束日期 | 活动起始日期 | 活动结束日期 |
|
|
|
|
|
|
选择字段名称 | 选择字段对应SAP字段 | 录入方式 | 是否必输 | 字段类型 | 字段长度 | 主键 |
专款项目号 | ZKHD-NUMBE | 手工录入 | 是 | C | 10 | √ |
专款项目描述 | ZKHD-DSCRI | 手工录入 | 是 | C | 20 | X |
打款有效起始日期 | ZKHD-DKFRD | 手工录入 | 是 | D | 8 | X |
打款有效结束日期 | ZKHD-DKTOD | 手工录入 | 是 | D | 8 | X |
活动起始日期 | ZKHD-SYFRD | 手工录入 | 否 | D | 8 | X |
活动结束日期 | ZKHD-SYTOD | 手工录入 | 否 | D | 8 | X |
表2:ZKSY(专款使用信息表):本表主要记录活动期间专款的使用情况
专款项目号 | 专款项目描述 | 客户编码 | 客户描述 | 总金额 | 已经使用金额 | 剩余金额 |
选择字段名称 | 选择字段对应SAP字段 | 录入方式 | 是否必输 | 字段类型 | 字段长度 | 主键 |
专款项目号 | ZKSY-NUMBE | 单选 | 是 | C | 10 | √ |
专款项目描述 | ZKSY-DSCRI | 根据专款项目号带出 | 是 | C | 20 | X |
客户编码 | ZKSY-KUNNR | 单选 | 是 | D | 8 | √ |
客户描述 | ZKSY-KDSC | 根据客户编号带出 | 是 | D | 8 | X |
总金额 | ZKSY-ZZJE | 手工录入 | 是 | 货币型 | 15 | X |
已经使用金额 | ZKSY-ZSYJE | 根据订单金额计算 | 是 | 货币型 | 15 | X |
剩余金额 | ZKSY-ZWYJE | 总金额减去已经使用的金额 | 是 | 货币型 | 15 | X |
专款项目号:可选值,值从表ZKHD表中的ZKHD-NUMBE字段获得;
专款项目描述:不可输入,根据专款项目号,从表ZKHD-DSCRI中带出;
客户编码:可选值,从表KNA1中KNA1-KUNNR字段获得;
客户描述:不可输入,从表KNA1- NAME1中带出;
总金额:手工录入
已经使用的金额:根据销售订单的值累计计算得到,具体逻辑参见第三部分:程序逻辑
剩余金额:总金额减去已经使用的金额。
表3:ZKRZ日志报表
用户 | 日期 | 时间 | 操作类型 | 字段名 | 字段原值 | 字段新值 | 备注 |
选择字段名称 | 选择字段对应SAP字段 | 录入方式 | 是否必输 | 字段类型 | 字段长度 | 主键 |
用户 | ZKRZ-ZUSER |
| 是 | C | 15 |
|
日期 | ZKRZ-ZDATE |
| 是 | D | 8 |
|
时间 | ZKRZ-ZTIME |
| 是 | 时间类型 | 10 |
|
操作类型 | ZKRZ-ZTYPE |
| 是 | C | 8 |
|
字段名称 | ZKRZ-FIELD |
| 是 | C | 15 |
|
字段原值 | ZKRZ-ORGRI |
| 是 | C | 15 |
|
字段新值 | ZKRZ-UPDAT |
| 是 | C | 15 |
|
第二部分:屏幕
1. 专款使用统计的屏幕
由于专款专用的客户较多,针对第二张表ZKSY需要建立搜索查询的屏幕,具体屏幕格式如下:
选择字段名称 | 选择字段对应SAP字段 | 单选/多值 | 是否必输 | 默认值 | 其它要求 |
专款项目号 | ZKSY-NUMBE | 多选 | 否 |
|
|
客户号 | ZKSY-KUNNR | 多选 | 否 |
|
|
已经使用完毕为单元框,如果勾选,则表示将剩余金额为0的行业输出,否则就仅输出剩余金额不为0的行。
2. 日志报表查询的屏幕
选择字段名称 | 选择字段对应SAP字段 | 单选/多值 | 是否必输 | 默认值 | 其它要求 |
用户 |
|
|
|
|
|
日期 |
|
|
|
|
|
时间 |
|
|
|
|
|
操作类型 |
|
|
|
|
|
第三部分:程序逻辑
1. 已经使用金额的计算:
当销售订单保存的时候,系统会检查三个字段信息,检查逻辑需要写在销售订单保存的出口中。
① 判断订单类型是否为ZS04(促销订单)
② 判断客号VBAK-KUNNR在表ZKSY-KUNNR中是否能找到
③ 判断VBKD-IHREZ是否在表ZKSY-NUMBE中是否能找到
如果上述3个条件满足,则找到表ZKSY中对应行的字段ZKSY-ZSYJE将订单的值与原字段值进行累加并和总金额ZKSY-ZZJE进行比较,如果小于等于总金额的值则将累加值写入,否则销售订单不能保存,并输出提醒“ 超过专款使用额度,请调整订单货数量”。
2. 订单的值取值逻辑:KOMP-KZWI1
3. 返向逻辑
如果订单类型是ZS05(退货单),且同样能在表ZKSY找到对应的VBAK-KUNNR=ZKSY-KUNNR,VBKD-IHREZ=ZKSY-NUMBE,则将订单值和字段ZKSY-ZSYJE比较,如果订单值小于等于ZKSY-ZSYJE,则将ZKSY-ZSYJE的值减去订单值然后更新该字段,否则销售订单不能保存,并输出提醒“退货金额超出专款已经使用金额,不允许执行。”
4. 订单删除的情况:
该代码需要写入订单删除的出口中
① 如果字段VBKD-IHREZ中无值,则可以删除,否则需要进一步进行判断;
② 如果字段VBKD-IHREZ中有值,且在表中ZKSY-NUMBE找不到对应的值,则可以删除;
③ 如果根据VBKD-IHREZ以及客户名称VBAK-KUNNR在表中能够找到对应的记录,则需要检查销售订单的值KOMP-KZWI1和这条记录的值比较。如果已使用金额的字段的值小于销售订单的值则不允许删除,输出提醒“ 订单值与专款金额不匹配”;如果已使用金额的字段的值大于等于销售订单值,则将已使用金额变为原有的已使用金额减去销售订单值,同时更新剩余金额的值。此事销售订单可以删除。
5. 由于表ZKSY的金额字段可以手工调整,则每当修改完毕保存的时候,系统需要重新计算剩余金额的值,如果剩余金额为负数,则不允许保存。
6. 将字段“您的参考”VBKD-IHREZ的描述改为“活动号”
7. 以上订单都是考虑创建的情况,如果订单金额是修改,则不能直接进行价钱,程序首先要判断订单是新建,还是修改。如果是修改,则需要记录订单原值以及修改以后的值,将此部分的差异计入已使用金额:
对于ZS04的订单:
如果修改值大于原值,则已使用金额为=已经使用金额+(修改值-原值)
如果修改值小于等于原值,则已使用金额为=已经使用金额+(修改值-原值)
对于ZS05的订单:
如果修改值大于原值,则已使用金额为=已经使用金额-(修改值-原值)
如果修改值小于等于原值,则已使用金额为=已经使用金额-(修改值-原值)
第四部分:日志报表
1. 当ZKSY每次保存的时候,系统进行日志报表更新信息的记录。
第五部分:权限设定
本平台需要针对3个自定义表设定不同的Tcode及权限:
1. 专款活动信息维护表 (Tcode:由开发统一提供),需要提供(创建/修改,显示)两个事务码
2. 专款使用表 (Tcode:由开发统一提供),需要提供(创建/修改,显示)两个事务码
3. 日志报表维护表 (Tcode:由开发统一提供),需要提供显示事务码
使用增强:SE38:MV45AFZZ
<span style="font-size:10px;">FORM USEREXIT_SAVE_DOCUMENT_PREPARE.
*{ INSERT DEVK900108 1
"IF sy-uname = 'HANDZCY'.
" BREAK-POINT.
*-------------------------专款专用平台----------------------------------*
"数据校验
DATA lw_xvbap LIKE LINE OF xvbap.
DATA lw_yvbap LIKE LINE OF yvbap.
DATA lw_xvbkd LIKE LINE OF xvbkd.
DATA lw_yvbkd LIKE LINE OF yvbkd.
DATA lt_ztsd0030 TYPE STANDARD TABLE OF ztsd0030.
DATA lw_ztsd0020 TYPE ztsd0020.
DATA lw_xztsd0030 TYPE ztsd0030.
DATA lw_yztsd0030 TYPE ztsd0030.
READ TABLE xvbap INTO lw_xvbap INDEX 1."新
READ TABLE yvbap INTO lw_yvbap INDEX 1.
IF SY-subrc NE 0.
lw_yvbap = lw_xvbap.
ENDIF.
READ TABLE xvbkd INTO lw_xvbkd INDEX 1.
READ TABLE yvbkd INTO lw_yvbkd INDEX 1.
IF SY-subrc NE 0.
lw_yvbkd = lw_xvbkd.
ENDIF.
"校验
IF lw_xvbkd-ihrez IS NOT INITIAL AND ( yvbak-auart NE 'ZS04' AND yvbak-auart NE 'ZS05').
MESSAGE '该订单类型不能输入活动号' TYPE 'S' DISPLAY LIKE 'E'.
LEAVE TO SCREEN sy-dynnr.
ENDIF.
IF lw_xvbkd-ihrez IS INITIAL AND yvbak-auart = 'ZS04'.
MESSAGE '该类型订单必须输入活动号' TYPE 'S' DISPLAY LIKE 'E'.
LEAVE TO SCREEN sy-dynnr.
ENDIF.
IF lw_xvbkd-ihrez IS NOT INITIAL.
SELECT SINGLE * FROM ztsd0030 INTO lw_xztsd0030 WHERE kunnr = yvbak-kunnr AND numbe = lw_xvbkd-ihrez.
IF sy-subrc NE 0.
MESSAGE '活动号与客户不匹配,请检查' TYPE 'S' DISPLAY LIKE 'E'.
LEAVE TO SCREEN sy-dynnr.
ELSE.
SELECT SINGLE * FROM ztsd0020 INTO lw_ztsd0020 WHERE numbe = lw_xvbkd-ihrez.
IF yvbak-AUDAT > lw_ztsd0020-SYTOD OR yvbak-AUDAT < lw_ztsd0020-SYFRD.
MESSAGE '订单并不在录入的活动有效期' TYPE 'S' DISPLAY LIKE 'E'.
LEAVE TO SCREEN sy-dynnr.
ENDIF.
ENDIF.
ENDIF.
"金额处理
IF yvbak-auart = 'ZS04'.
IF lw_yvbkd-ihrez IS NOT INITIAL AND FCODE = 'LOES'."删除订单
CLEAR lt_ztsd0030.
CLEAR lw_yztsd0030.
SELECT SINGLE * FROM ztsd0030 INTO lw_yztsd0030 WHERE kunnr = yvbak-kunnr AND numbe = lw_yvbkd-ihrez.
IF SY-subrc = 0.
lw_yztsd0030-zsyje = lw_yztsd0030-zsyje - lw_yvbap-kzwi1 ."旧活动退还原金额
lw_yztsd0030-zwyje = lw_yztsd0030-zzje - lw_yztsd0030-zsyje.""计算剩余金额
APPEND lw_yztsd0030 TO lt_ztsd0030.
IF lt_ztsd0030 IS NOT INITIAL.
MODIFY ztsd0030 FROM TABLE lt_ztsd0030.
ENDIF.
CLEAR lt_ztsd0030.
ENDIF.
ELSE.
IF lw_xvbkd-ihrez IS INITIAL AND lw_yvbkd-ihrez IS INITIAL."活动无关订单
ELSEIF lw_xvbkd-ihrez IS NOT INITIAL AND lw_yvbkd-ihrez IS NOT INITIAL."修改金额
IF lw_yvbkd-ihrez = lw_xvbkd-ihrez AND lw_xvbap-kzwi1 NE lw_yvbap-kzwi1."相同活动号修改金额
lw_xztsd0030-zsyje = lw_xztsd0030-zsyje + lw_xvbap-kzwi1 - lw_yvbap-kzwi1."已经使用金额
IF lw_xztsd0030-zsyje > lw_xztsd0030-zzje.
MESSAGE '超过专款使用额度,请调整订单货数量' TYPE 'S' DISPLAY LIKE 'E'.
LEAVE TO SCREEN sy-dynnr.
ELSE.
lw_xztsd0030-zwyje = lw_xztsd0030-zzje - lw_xztsd0030-zsyje."计算剩余金额
ENDIF.
APPEND lw_xztsd0030 TO lt_ztsd0030.
ELSEIF lw_yvbkd-ihrez NE lw_xvbkd-ihrez .
SELECT SINGLE * FROM ztsd0030 INTO lw_yztsd0030 WHERE kunnr = yvbak-kunnr AND numbe = lw_yvbkd-ihrez.
lw_xztsd0030-zsyje = lw_xztsd0030-zsyje + lw_xvbap-kzwi1 ."新活动扣除现金额
IF lw_xztsd0030-zsyje > lw_xztsd0030-zzje.
MESSAGE '超过专款使用额度,请调整订单货数量' TYPE 'S' DISPLAY LIKE 'E'.
LEAVE TO SCREEN sy-dynnr.
ELSE.
lw_xztsd0030-zwyje = lw_xztsd0030-zzje - lw_xztsd0030-zsyje."计算剩余金额
ENDIF.
lw_yztsd0030-zsyje = lw_yztsd0030-zsyje - lw_yvbap-kzwi1 ."旧活动退还原金额
lw_yztsd0030-zwyje = lw_yztsd0030-zzje - lw_yztsd0030-zsyje.""计算剩余金额
APPEND lw_xztsd0030 TO lt_ztsd0030.
APPEND lw_yztsd0030 TO lt_ztsd0030.
ENDIF.
ELSEIF lw_xvbkd-ihrez IS NOT INITIAL AND lw_yvbkd-ihrez IS INITIAL."新建活动订单
lw_xztsd0030-zsyje = lw_xztsd0030-zsyje + lw_xvbap-kzwi1."新活动扣除现金额
IF lw_xztsd0030-zsyje > lw_xztsd0030-zzje.
MESSAGE '超过专款使用额度,请调整订单货数量' TYPE 'S' DISPLAY LIKE 'E'.
LEAVE TO SCREEN sy-dynnr.
ELSE.
lw_xztsd0030-zwyje = lw_xztsd0030-zzje - lw_xztsd0030-zsyje."计算剩余金额
ENDIF.
APPEND lw_xztsd0030 TO lt_ztsd0030.
ELSEIF lw_xvbkd-ihrez IS INITIAL AND lw_yvbkd-ihrez IS NOT INITIAL."删除活动订单
SELECT SINGLE * FROM ztsd0030 INTO lw_yztsd0030 WHERE kunnr = yvbak-kunnr AND numbe = lw_yvbkd-ihrez.
lw_yztsd0030-zsyje = lw_yztsd0030-zsyje - lw_yvbap-kzwi1 ."旧活动退还原金额
lw_yztsd0030-zwyje = lw_yztsd0030-zzje - lw_yztsd0030-zsyje.""计算剩余金额
APPEND lw_yztsd0030 TO lt_ztsd0030.
ENDIF.
IF lt_ztsd0030 IS NOT INITIAL.
MODIFY ztsd0030 FROM TABLE lt_ztsd0030.
ENDIF.
*ELSEIF yvbak-auart = 'ZS05'.
* IF lw_xvbkd-ihrez IS INITIAL AND lw_yvbkd-ihrez IS INITIAL."活动无关订单
* ELSEIF lw_xvbkd-ihrez IS NOT INITIAL AND lw_yvbkd-ihrez IS NOT INITIAL."修改活动订单
*
* IF lw_yvbkd-ihrez = lw_xvbkd-ihrez AND lw_xvbap-kzwi1 NE lw_yvbap-kzwi1. "相同活动号修改金额
* lw_xztsd0030-zsyje = lw_xztsd0030-zsyje - lw_xvbap-kzwi1 + lw_yvbap-kzwi1."已经使用金额
* IF lw_xztsd0030-zsyje > lw_xztsd0030-zzje.
* MESSAGE '超过专款使用额度,请调整订单货数量' TYPE 'S' DISPLAY LIKE 'E'.
* LEAVE TO SCREEN sy-dynnr.
* ELSE.
* lw_xztsd0030-zwyje = lw_xztsd0030-zzje + lw_xztsd0030-zsyje."计算剩余金额
* ENDIF.
* APPEND lw_xztsd0030 TO lt_ztsd0030.
* ELSEIF lw_yvbkd-ihrez NE lw_xvbkd-ihrez. "不同活动号修改
* SELECT SINGLE * FROM ztsd0030 INTO lw_yztsd0030 WHERE kunnr = yvbak-kunnr AND numbe = lw_yvbkd-ihrez.
* lw_xztsd0030-zsyje = lw_xztsd0030-zsyje - lw_xvbap-kzwi1 ."新活动退还现金额
* IF lw_xztsd0030-zsyje > lw_xztsd0030-zzje.
* MESSAGE '超过专款使用额度,请调整订单货数量' TYPE 'S' DISPLAY LIKE 'E'.
* LEAVE TO SCREEN sy-dynnr.
* ELSE.
* lw_xztsd0030-zwyje = lw_xztsd0030-zzje + lw_xztsd0030-zsyje."计算剩余金额
* ENDIF.
* lw_yztsd0030-zsyje = lw_yztsd0030-zsyje + lw_yvbap-kzwi1 ."旧活动扣除原金额
* lw_yztsd0030-zwyje = lw_yztsd0030-zzje + lw_yztsd0030-zsyje.""计算剩余金额
* APPEND lw_xztsd0030 TO lt_ztsd0030.
* APPEND lw_yztsd0030 TO lt_ztsd0030.
* ENDIF.
*
* ELSEIF lw_xvbkd-ihrez IS NOT INITIAL AND lw_yvbkd-ihrez IS INITIAL."新建活动订单
* lw_xztsd0030-zsyje = lw_xztsd0030-zsyje - lw_xvbap-kzwi1."新活动退还现金额
* IF lw_xztsd0030-zsyje > lw_xztsd0030-zzje.
* MESSAGE '超过专款使用额度,请调整订单货数量' TYPE 'S' DISPLAY LIKE 'E'.
* LEAVE TO SCREEN sy-dynnr.
* ELSE.
* lw_xztsd0030-zwyje = lw_xztsd0030-zzje + lw_xztsd0030-zsyje."计算剩余金额
* ENDIF.
* APPEND lw_xztsd0030 TO lt_ztsd0030.
* ELSEIF lw_xvbkd-ihrez IS INITIAL AND lw_yvbkd-ihrez IS NOT INITIAL."删除活动订单
* SELECT SINGLE * FROM ztsd0030 INTO lw_yztsd0030 WHERE kunnr = yvbak-kunnr AND numbe = lw_yvbkd-ihrez.
* lw_yztsd0030-zsyje = lw_yztsd0030-zsyje + lw_yvbap-kzwi1 ."旧活动扣除原金额
* lw_yztsd0030-zwyje = lw_yztsd0030-zzje + lw_yztsd0030-zsyje.""计算剩余金额
* APPEND lw_yztsd0030 TO lt_ztsd0030.
* ENDIF.
*
* IF lt_ztsd0030 IS NOT INITIAL.
* MODIFY ztsd0030 FROM TABLE lt_ztsd0030.
* ENDIF.
ENDIF.
"ENDIF.
*-------------------------专款专用平台----------------------------------*
ENDIF.</span>
<span style="font-size:10px;"><span class="L0S52">ENDFORM</span><span class="L0S55">.</span>
</span>