SAP ABAP 交货单的增强,交货单多次POD确认及多次开票

1 篇文章 0 订阅

        一般销售业务中存在多次交货及多次开票的可能.这种情况在SAP中标准功能是实现不了的,所以需要进行增强。POD的抬头状态栏有三个:总体状态,POD状态,开票状态,用来确定交货单目前所处的状态。POD确认之后必须完成销售开票才能再次POD,所以允许再次POD确认的逻辑写在了开票的增强里。

1.先对POD进行增强

1.1创建自建表用于保存TVPOD的数据

        POD确认的数据会保存在TVPOD表里,同时做POD确认以及销售开票的时候会同步修改LIKP、LIPS两张表。需要再次POD确认需要清除标准表TVPOD的数据,所以将需要使用的数据保存到自建表中,用于后续开票以及POD确认操作使用。

1.2POD确认增强逻辑

        因为修改的是标准表的数据,所以要在数据保存到标准表之后才可以进行操作。添加判断如果交货数量和POD数量不一致的时候,并且POD确定总数量小于交货单数量,将TVPOD的数据保存到自建表ZTVPOD以统计累计确定数量并清除标准表tvpod的数据.在自建表ZTVPOD根据交货单取数判断当前是否为第一次POD,不是第一次则需要修改POD状态使得允许再次开票.

1.3代码示例

        等待0.5S,防止数据还没保存到标准表,也可以通过SELECT去判断。

        增强程序:FV50XF0B_BELEG_SICHERN

        增强点: fv50xf0b_beleg_sichern_06

WAIT UP TO '0.5' SECONDS.

    IF sy-tcode = 'VLPOD'.
      DATA:gt_tvpod LIKE TABLE OF tvpod WITH HEADER LINE.
      DATA:l_count TYPE lfimg.
      DATA:gt_ztvpod LIKE TABLE OF ztvpod WITH HEADER LINE.
      DATA:gt_ztvpod1 LIKE TABLE OF ztvpod WITH HEADER LINE.
      DATA:gt_lips LIKE TABLE OF lips WITH HEADER LINE.
      DATA:gt_likp LIKE TABLE OF likp WITH HEADER LINE.
      DATA:i_code.
      DATA:i_code2.

      LOOP AT xlips.
        REFRESH gt_tvpod.
        REFRESH gt_ztvpod.
        REFRESH gt_ztvpod1.
        REFRESH gt_likp.
        REFRESH gt_lips.
        CLEAR:i_code , l_count.

        SELECT * INTO TABLE gt_tvpod FROM tvpod WHERE vbeln = xlips-vbeln AND posnr = xlips-posnr.
        MOVE-CORRESPONDING  gt_tvpod[] TO gt_ztvpod[].

        LOOP AT gt_ztvpod.
          IF xlips-lfimg > gt_ztvpod-podmg.
            i_code = 'X'.
            gt_ztvpod-datum = sy-datum.
            gt_ztvpod-uzeit = sy-uzeit.
            gt_ztvpod-uname = sy-uname.
            DATA:g_message_id TYPE guid_32. "定义消息id
            CALL FUNCTION 'GUID_CREATE'  "调用方法创建信息id
              IMPORTING
                ev_guid_32 = g_message_id.  "需要保存的信息id
            gt_ztvpod-guid = g_message_id.
            MODIFY gt_ztvpod.
          ENDIF.
        ENDLOOP.
        DELETE gt_ztvpod WHERE podmg = 0.

        SELECT COUNT(*) FROM ztvpod WHERE vbeln = xlips-vbeln.
        IF SY-subrc NE 0.
          CLEAR i_code.
        ENDIF.

        MODIFY ztvpod FROM TABLE gt_ztvpod.
        IF i_code = 'X'.
IF i_code = 'X'.
          SELECT * INTO TABLE gt_lips FROM lips WHERE vbeln = xlips-vbeln AND posnr = xlips-posnr.

          SELECT SINGLE * INTO  gt_likp FROM likp WHERE vbeln = xlips-vbeln.

          LOOP AT gt_lips.
            IF gt_likp-fkstk = 'C' AND gt_lips-fksta = 'C'.
              i_code2 = 'A'.
              gt_lips-fksta = 'B'. "交货相关开票状态
              gt_lips-gbsta = 'B'. "总体状态
*             gt_lips-pdsta = 'B'. "交付证明状态
              gt_lips-fkivp = 'B'.  "公司间开票状态
              MODIFY lips FROM gt_lips.

            ENDIF.

            IF gt_likp-fkstk <> 'C' AND gt_lips-fksta <> 'C'.
              IF gt_likp-fkstk <> '' AND gt_lips-fksta <> ''.
                i_code2 = 'B'.
                gt_lips-fksta = 'B'. "交货相关开票状态
                gt_lips-gbsta = 'B'. "总体状态
*                gt_lips-PDSTA = 'B'. "交付证明状态
                gt_lips-fkivp = 'B'.  "公司间开票状态
                MODIFY lips FROM gt_lips.
              ENDIF.
            ENDIF.
          ENDLOOP.

          CASE i_code2.
            WHEN 'A'.
              gt_likp-fkstk = 'B'. "交货相关开票状态
              gt_likp-gbstk = 'B'. "总体状态
*             gt_likp-pdstk = 'B'. "交付证明状态
              gt_likp-fkivk = 'B'.  "公司间开票状态
              MODIFY likp FROM gt_likp.
            WHEN 'B'.
              gt_likp-fkstk = 'B'.  "交货相关的开票状态
              gt_likp-gbstk = 'B'.  "总体状态
*               gt_likp-PDSTK = 'B'. "交货证明状态
              gt_likp-fkivk = 'B'.  "公司间开票状态
              MODIFY likp FROM gt_likp.
            WHEN OTHERS.
          ENDCASE.

        ENDIF.
        ENDIF.
      ENDLOOP.
    ENDIF.

2.销售开票的增强

2.1开票增强逻辑

    修改标准表需要在数据保存完之后再做修改,运行标准程序发现在调用完函数’RV_INVOICE_REFRESH’之后数据会保存到标准表,而这个函数会清空内存里的数据,所以要在调用函数之前保存需要使用的数据在函数之后进行操作。这个函数本身就在一个增强点里,所以直接创建这个增强实现,增强点自带调用函数模块’RV_INVOICE_REFRESH’的代码。所以在调用前保存XVBRK、XVBRP的数据作为后续使用。在自建表ZTVPOD获取累计POD确定数量用来判断是否允许下一次POD。如果自建表获取的累计POD数量小于交货单交货数量则修改POD状态以允许下次POD操作。

2.2代码示例

        函数模块:RV_INVOICE_DOCUMENT_ADD

        增强点: ES_SAPLV60A /  rv_invoice_document_add_02

DATA(lt_vbrk) = xvbrk[].
DATA(lt_vbrp) = xvbrp[].
DATA l_xvbrp TYPE vbrpvb.
DATA:l_count TYPE lfimg.
DATA:l_lfimg TYPE lfimg.
DATA lv_used TYPE char1.

CALL FUNCTION 'RV_INVOICE_REFRESH'
  EXPORTING
    with_posting = kom-posting
  TABLES
    xkomfk       = xkomfk
    xkomv        = xkomv
    xthead       = xthead
    xvbfs        = xvbfs
    xvbss        = xvbss
    xvbpa        = xvbpa
    xvbrk        = xvbrk
    xvbrp        = xvbrp.

IF  sy-tcode = 'VF01'.

  WAIT UP TO '0.5' SECONDS.

  LOOP AT lt_vbrk INTO DATA(ls_vbrk).
    IF ls_vbrk-fkart EQ 'ZF01' OR ls_vbrk-fkart EQ 'ZF02' OR ls_vbrk-fkart EQ 'ZF03' OR ls_vbrk-fkart EQ 'ZF04' OR ls_vbrk-fkart EQ 'ZF10' OR ls_vbrk-fkart EQ 'ZIV'.
      LOOP AT lt_vbrp INTO l_xvbrp.

        SELECT SINGLE * FROM likp INTO @DATA(ls_likp) WHERE vbeln = @l_xvbrp-vgbel.

        SELECT * FROM ztvpod INTO TABLE @DATA(lt_pod) WHERE vbeln = @l_xvbrp-vgbel AND posnr = @l_xvbrp-vgpos.

        IF lt_pod[] IS NOT INITIAL.
          LOOP AT lt_pod INTO DATA(ls_pod).
            l_count = l_count + ls_pod-podmg.
            l_lfimg = ls_pod-lfimg.
          ENDLOOP.
        ENDIF.


        SELECT SINGLE * FROM lips INTO @DATA(ls_lips) WHERE vbeln = @l_xvbrp-vgbel AND posnr = @l_xvbrp-vgpos.

        IF l_count <> l_lfimg.

          IF ls_likp-fkivk = '' AND ls_lips-fkivp = ''.
            I_CODE = 'A'.

            ls_lips-fksta = 'B'.  "交货相关开票状态
            ls_lips-gbsta = 'B'.  "总体状态
            ls_lips-pdsta = 'B'.  "交付证明状态
            MODIFY lips FROM ls_lips.

            SELECT * FROM tvpod INTO TABLE @DATA(lt_tvpod) WHERE vbeln = @ls_lips-vbeln.
            IF lt_tvpod[] IS NOT INITIAL.
              DELETE tvpod FROM TABLE lt_tvpod.
            ENDIF.
          ENDIF.

          IF ls_likp-fkivk = 'C' AND ls_lips-fkivp = 'C' .
            IF ls_vbrk-fkart NE 'ZIV'.
              I_CODE = 'B'.
*              ls_lips-fksta = 'B'.  "交货相关开票状态
              ls_lips-gbsta = 'B'.  "总体状态
*              ls_lips-pdsta = 'B'.  "交付证明状态
              ls_lips-fkivp = 'B'.    "公司间开票状态
              MODIFY lips FROM ls_lips.

            ELSE.
              I_CODE = 'C'.
              ls_lips-fksta = 'B'.  "交货相关开票状态
              ls_lips-gbsta = 'B'.  "总体状态
              ls_lips-pdsta = 'B'.  "交付证明状态
              ls_lips-fkivp = 'B'.    "公司间开票状态
              MODIFY lips FROM ls_lips.

              SELECT * FROM tvpod INTO TABLE @lt_tvpod WHERE vbeln = @ls_lips-vbeln.
              IF lt_tvpod[] IS NOT INITIAL.
                DELETE tvpod FROM TABLE lt_tvpod.
              ENDIF.
            ENDIF.

          ENDIF.
        ELSE.
          IF ls_vbrk-fkart NE 'ZIV' AND ls_likp-fkivk <> '' AND ls_lips-fkivp <> ''.
            I_CODE = 'D'.
*            ls_lips-fksta = 'B'.  "交货相关开票状态
              ls_lips-gbsta = 'B'.  "总体状态
*              ls_lips-pdsta = 'B'.  "交付证明状态
              ls_lips-fkivp = 'B'.    "公司间开票状态
              MODIFY lips FROM ls_lips.

          ENDIF.
        ENDIF.

      ENDLOOP.

      CASE I_CODE.
        WHEN 'A'.
          ls_likp-fkstk = 'B'."交货相关的开票状态
          ls_likp-gbstk = 'B'."总体状态
          ls_likp-pdstk = 'B'."交货证明状态
        WHEN 'B'.
*          ls_likp-fkstk = 'B'."交货相关的开票状态
          ls_likp-gbstk = 'B'."总体状态
*          ls_likp-pdstk = 'B'."交货证明状态
          ls_likp-fkivk = 'B'."公司间开票状态
          MODIFY likp FROM ls_likp.
        WHEN 'C'.
          ls_likp-fkstk = 'B'."交货相关的开票状态
          ls_likp-gbstk = 'B'."总体状态
          ls_likp-pdstk = 'B'."交货证明状态
          ls_likp-fkivk = 'B'."公司间开票状态
        WHEN 'D'.
*          ls_likp-fkstk = 'B'."交货相关的开票状态
          ls_likp-gbstk = 'B'."总体状态
*          ls_likp-pdstk = 'B'."交货证明状态
          ls_likp-fkivk = 'B'."公司间开票状态
      ENDCASE.

      IF I_CODE <> ''.
        MODIFY likp FROM ls_likp.
        CLEAR:I_CODE.
      ENDIF.

    ENDIF.
  ENDLOOP.
ENDIF.

REFRESH: lt_vbrk[],lt_vbrp[].
FREE:ls_vbrk,ls_vbrp.

3.凭证流展示

  • 16
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值