一般销售业务中存在多次交货及多次开票的可能.这种情况在SAP中标准功能是实现不了的,所以需要进行增强。POD状态有:
货物移动状态、交货相关开票状态、公司间开票状态、交付证明状态,用来确定交货单目前所处的状态。POD确认之后完成销售开票允许再次POD,所以在销售开票之后需要修改POD的状态以及标准表TVPOD来达成。
整个逻辑是跑了几天程序一点点整理的,由于不是常规的程序增强,涉及了标准表的修改,强烈建议做自建表创建增强的控制,避免影响标准业务。
## 3.1交货单允许再次POD
交货单在做完销售开票以后需要再次POD,当前状态C是不允许进行再次POD确认的,所以需要将交货相关开票状态、公司间开票状态、交付证明状态都改成B。
### 3.1.1POD数据保存业务逻辑
多次POD需要统计每个行项目的确认数量,在完全确认之后不再修改POD状态,即不允许再次POD。所以需要一个自建表来保存POD数据。
#### 3.1.1.2增强逻辑
创建一个自建表ZTVPOD统计POD确认的数量来判断是否完全交货。在POD确认完之后,获取物料移动凭证判断当前POD是冲销还是确认,从TVPOD表中获取数据保存到自建表ZTVPOD。
#### 3.1.1.3 增强实施(代码)
代码实例:
DATA:gt_ztvpod LIKE TABLE OF ztvpod WITH HEADER LINE.DATA:lt_tvpod LIKE TABLE OF zyy_tvpod WITH HEADER LINE. DATA:g_message_id TYPE guid_32. "定义消息idIF SY-tcode = 'VLPOD'.WAIT UP TO '0.5' SECONDS. LOOP AT xlips.*=============================将TVPOD的数据保存到自建表============================================================= *获取TVPOD表的数据 SELECT SINGLE * INTO CORRESPONDING FIELDS OF gt_ztvpod FROM tvpod WHERE vbeln = xlips-vbeln AND posnr = xlips-posnr. *保存tvpod数据到临时表,冲销时需要恢复tvpod表 SELECT SINGLE * INTO CORRESPONDING FIELDS OF lt_tvpod FROM tvpod WHERE vbeln = xlips-vbeln AND posnr = xlips-posnr. MODIFY zyy_tvpod FROM lt_tvpod. *获取交货单最新的物料移动凭证,判断执行的是POD冲销还是POD确认 SELECT SHKZG , CPUDT_MKPF , CPUTM_MKPF FROM MSEG INTO TABLE @DATA(LT_MSEG) WHERE XBLNR_MKPF = @xlips-vbeln. SORT LT_MSEG BY CPUDT_MKPF DESCENDING CPUTM_MKPF DESCENDING. READ TABLE LT_MSEG INTO DATA(LS_MSEG) INDEX 1.IF LS_MSEG-shkzg = 'S'. gt_ztvpod-podmg = gt_ztvpod-podmg * -1. ENDIF.gt_ztvpod-datum = sy-datum. gt_ztvpod-uzeit = sy-uzeit. gt_ztvpod-uname = sy-uname. CALL FUNCTION 'GUID_CREATE' "调用方法创建信息id IMPORTING ev_guid_32 = g_message_id. "需要保存的信息id gt_ztvpod-guid = g_message_id.DELETE gt_ztvpod WHERE LFIMG = 0. MODIFY ZTVPOD FROM gt_ztvpod.
*================================第二次POD修改POD状态================================================================= SELECT COUNT(*) FROM ztvpod WHERE vbeln = @xlips-vbeln AND posnr = @xlips-posnr. IF sy-subrc EQ 0.
SELECT SINGLE * INTO @DATA(ls_lips) FROM lips WHERE vbeln = @xlips-vbeln AND posnr = @xlips-posnr. SELECT SINGLE * INTO @DATA(ls_likp) FROM likp WHERE vbeln = @xlips-vbeln.IF ls_likp-fkstk = 'C' AND ls_lips-fksta = 'C'. ls_lips-fksta = 'A'. "交货相关开票状态 ls_lips-gbsta = 'B'. "总体状态 * LS_LIPS-pdsta = 'B'. "交付证明状态 ls_lips-fkivp = 'A'. "公司间开票状态ls_likp-fkstk = 'A'. "交货相关开票状态 ls_likp-gbstk = 'B'. "总体状态 * LS_LIKP-pdstk = 'B'. "交付证明状态 ls_likp-fkivk = 'A'. "公司间开票状态 ELSE.IF ls_likp-fkstk <> '' AND ls_lips-fksta <> ''. ls_lips-fksta = 'A'. "交货相关开票状态 ls_lips-gbsta = 'B'. "总体状态 * LS_LIPS-PDSTA = 'B'. "交付证明状态 ls_lips-fkivp = 'A'. "公司间开票状态ls_likp-fkstk = 'A'. "交货相关的开票状态 ls_likp-gbstk = 'B'. "总体状态 * LS_LIKP-PDSTK = 'B'. "交货证明状态 ls_likp-fkivk = 'A'. "公司间开票状态 ELSE. ls_lips-fksta = 'B'. "交货相关开票状态 ls_lips-gbsta = 'B'. "总体状态 ls_likp-fkstk = 'B'. "交货相关的开票状态 ls_likp-gbstk = 'B'. "总体状态 ENDIF. ENDIF. MODIFY likp FROM LS_LIKP. MODIFY lips FROM LS_LIPS.ENDIF. ENDLOOP. ENDIF.### 3.1.2第二次POD确认修改POD状态
第二次POD确认的状态全都会变成C,要将开票相关状态改成A或B才可以开票可。如下
#### 3.1.2.1 增强实施(代码)
已写在3.1.1.3部分POD数据保存的增强代码中,如下部分:
*================================第二次POD修改POD状态================================================================= SELECT COUNT(*) FROM ztvpod WHERE vbeln = @xlips-vbeln AND posnr = @xlips-posnr. IF sy-subrc EQ 0.
SELECT SINGLE * INTO @DATA(ls_lips) FROM lips WHERE vbeln = @xlips-vbeln AND posnr = @xlips-posnr. SELECT SINGLE * INTO @DATA(ls_likp) FROM likp WHERE vbeln = @xlips-vbeln.IF ls_likp-fkstk = 'C' AND ls_lips-fksta = 'C'. ls_lips-fksta = 'A'. "交货相关开票状态 ls_lips-gbsta = 'B'. "总体状态 * LS_LIPS-pdsta = 'B'. "交付证明状态 ls_lips-fkivp = 'A'. "公司间开票状态ls_likp-fkstk = 'A'. "交货相关开票状态 ls_likp-gbstk = 'B'. "总体状态 * LS_LIKP-pdstk = 'B'. "交付证明状态 ls_likp-fkivk = 'A'. "公司间开票状态 ELSE.IF ls_likp-fkstk <> '' AND ls_lips-fksta <> ''. ls_lips-fksta = 'A'. "交货相关开票状态 ls_lips-gbsta = 'B'. "总体状态 * LS_LIPS-PDSTA = 'B'. "交付证明状态 ls_lips-fkivp = 'A'. "公司间开票状态ls_likp-fkstk = 'A'. "交货相关的开票状态 ls_likp-gbstk = 'B'. "总体状态 * LS_LIKP-PDSTK = 'B'. "交货证明状态 ls_likp-fkivk = 'A'. "公司间开票状态 ELSE. ls_lips-fksta = 'B'. "交货相关开票状态 ls_lips-gbsta = 'B'. "总体状态 ls_likp-fkstk = 'B'. "交货相关的开票状态 ls_likp-gbstk = 'B'. "总体状态 ENDIF. ENDIF. MODIFY likp FROM LS_LIKP. MODIFY lips FROM LS_LIPS.ENDIF.### 3.1.3开票修改POD状态
开票时从ZTVPOD表获取POD确认数量,根据行项目统计总数小于交货单交货数量则修改交货单状态来允许下一次POD确认。
#### 3.1.3.1增强逻辑
判断发票类型以及是否完全交货,如果为完全交货则进行修改,如果公司间开票有值则在第二次开票(公司间开票)时做修改。在修改之后需要删除TVPOD的数据(否则POD会报错已交付)。
#### 3.1.3.2增强实施(代码)
代码示例
...