前言
作为乐老师的一位卑微粉丝,自从看了发出商品十种方案后,沉迷至今无法自拔,在一个月黑风高的夜晚,它初步问世了。
乐老师原帖地址奉上 能不能给我来个完美的发出商品方案-关于sap中发出商品的十个方案
Q:为什么发出商品会有拆分开票的场景?
A:活久见呗
Q:为什么不用其他替代方案?
A:通俗来说就是 今天就是天王老子来了,我也想要用这方案。同时,心细不细我不知道,但我胆大。
一、场景解释
POD确认:
POD确认后,数据存放在表TVPOD中,同时会更新LIKP、LIPS(S4已不更新VBUK/VBUP此处不做考虑),既然如此,对这三张表下手多次确认问题就能迎刃而解。
开票:
既然确认后是存在TVPOD中,那么开票的源数据是不是也是来源于TVPOD?答案是对的
初步思路:
POD确认时,清除TVPOD记录,数据存到Z表中为后面开票提供数据源;开票时,更新LIKP、LIPS
二、代码示例
1.VLPOD确认-FV50XF0B_BELEG_SICHERN
VLPOD时,将数据存放到Z表中,并清除标准表TVPOD
IF sy-tcode = 'VLPOD'.
DATA:gt_tvpod LIKE TABLE OF tvpod WITH HEADER LINE.
DATA:l_finish TYPE c.
DATA:l_count TYPE lfimg.
DATA:gt_ztsdpod LIKE TABLE OF ztsdpod WITH HEADER LINE.
DATA:gt_lips LIKE TABLE OF lips WITH HEADER LINE.
DATA:gt_likp LIKE TABLE OF likp WITH HEADER LINE.
DATA:gt_ztsdpod1 LIKE TABLE OF ztsdpod WITH HEADER LINE.
l_finish = 1.
LOOP AT xlips.
REFRESH gt_tvpod.
REFRESH gt_ztsdpod.
REFRESH gt_ztsdpod1.
CLEAR l_count.
SELECT * INTO TABLE gt_tvpod FROM tvpod WHERE vbeln = xlips-vbeln AND posnr = xlips-posnr..
MOVE-CORRESPONDING gt_tvpod[] TO gt_ztsdpod[].
LOOP AT gt_ztsdpod.
gt_ztsdpod-cdate = sy-datum.
gt_ztsdpod-ctime = sy-uzeit.
gt_ztsdpod-cuser = sy-uname.
DATA:g_message_id TYPE guid_32. "定义消息id
CALL FUNCTION 'GUID_CREATE' "调用方法创建信息id
IMPORTING
ev_guid_32 = g_message_id. "需要保存的信息id
gt_ztsdpod-guid = g_message_id.
MODIFY gt_ztsdpod.
l_count = l_count + gt_ztsdpod-podmg.
ENDLOOP.
DELETE gt_ztsdpod WHERE podmg = 0.
SELECT * INTO TABLE gt_ztsdpod1 FROM ztsdpod WHERE vbeln = xlips-vbeln AND posnr = xlips-posnr.
LOOP AT gt_ztsdpod1.
l_count = l_count + gt_ztsdpod1-podmg.
ENDLOOP.
MODIFY ztsdpod FROM TABLE gt_ztsdpod.
DELETE tvpod FROM TABLE gt_tvpod.
IF l_count <> xlips-lfimg.
l_finish = 0.
ENDIF.
ENDLOOP.
IF xlips[] IS NOT INITIAL AND l_finish = 0 AND l_count > 0.
SELECT SINGLE * INTO gt_likp FROM likp WHERE vbeln = xlikp-vbeln.
IF sy-subrc = 0.
gt_likp-pdstk = 'B'. "POD状态
gt_likp-gbstk = 'B'. "抬头总体状态
gt_likp-podat = '00000000'. "POD日期
gt_likp-potim = '000000'. "POD时间
gt_likp-uvall = 'B'. "开票状态
gt_likp-fkstk = 'B'. "抬头开票状态
MODIFY likp FROM gt_likp.
ENDIF.
LOOP AT xlips.
SELECT SINGLE * INTO gt_lips FROM lips WHERE vbeln = xlips-vbeln AND posnr = xlips-posnr.
IF sy-subrc = 0.
gt_lips-pdsta = 'B'. "POD状态
gt_lips-gbsta = 'B'. "项目总体状态
gt_lips-fksta = 'B'. "项目开票状态
MODIFY lips FROM gt_lips.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
2.开票数量校验 - LV60AA22
判断已做POD确认部分是否开票完成
data:gt_ztsdpod like table of ztsdpod WITH HEADER LINE.
"如果不允许进入vf01 判断ztsdpod是否有已开数量 有则进入
if sy-subrc = 4.
select SINGLE * into gt_ztsdpod from ztsdpod where vbeln = likp-vbeln.
if sy-subrc = 0.
sy-subrc = 0.
else.
sy-subrc = 4.
endif.
endif.
3.开票时更新Z表- SD_CIN_LV60AU02~EXCISE_INVOICE_CREATE
开票完成后更新Z表状态
*更新ZTSDPOD开票状态
data:l_xvbrp type VBRPVB.
loop at xvbrp into l_xvbrp.
data:gt_ztsdpod type table of ztsdpod .
refresh gt_ztsdpod.
select * into table gt_ztsdpod from ztsdpod where vbeln = l_xvbrp-vgbel and posnr = l_xvbrp-vgpos.
if sy-subrc = 0.
update ztsdpod set flag = 'X' where vbeln = l_xvbrp-vgbel and posnr = l_xvbrp-vgpos.
endif.
endloop.
三.测试数据
见下图,至于为什么是3月份的图,遇到了些技术性难题,代码仅供参考。
总结
该方案可以实现POD做拆分开票,但代码和逻辑都需要进一步优化。只要胆大心细!