BAPI_INCOMINGINVOICE_* 预制正向凭证和贷项凭证

采购订单预制发票其实是对物料凭证进行发票预制,在调用BAPI的时候,由标识:记账发票决定是最后的发票金额是大于0还是小于0,标识为空是小于0,供应商在借方 S,标识为X标识大于0,供应商在贷方。

另外,在预制退货订单的时候,有时候会碰到发票SHKZG为'S',但是手工用MIR7预制是'H',这个都是BAPI在传参的时候错误导致的。

注:无论在金额大于0还是小于0都是,抬头金额 RBKP-WRBTR都是大于0的。

在明细行中,目前看起来可以不使用借贷方标识,仅仅通过金额正负来确定最后 RSEG中的SHKZG的值。

注:发票预制:在ACDOCA,BSEG,BSIK中都不会有数据。


  DATA: lv_mwskz            TYPE ekpo-mwskz,
        lv_lifnr            TYPE matdoc-lifnr,
        lv_hsje             TYPE matdoc-dmbtr,              " 含税金额
        lv_wsje             TYPE matdoc-dmbtr,
        lv_bldat            TYPE mkpf-bldat,                " 输入发票日期
        lv_budat            TYPE mkpf-budat,                " 输入过账日期
        lv_bktxt            TYPE char40,                    " 输入实际发票号
        lv_invoicedocnumber TYPE bapi_incinv_fld-inv_doc_no, " 输出发票号
        lv_fiscalyear       TYPE bapi_incinv_fld-fisc_year, " 输出年份
        lv_return           TYPE bapi_msg VALUE '失败:',

        ls_headerdata       TYPE bapi_incinv_create_header,
        lt_item             TYPE STANDARD TABLE OF bapi_incinv_create_item,
        ls_item             TYPE bapi_incinv_create_item,
        lt_return           TYPE STANDARD TABLE OF bapiret2,
        ls_return           TYPE bapiret2,
        lv_doc_item         TYPE rblgp.
*        lt_rseg             TYPE STANDARD TABLE OF typ_rseg.

  READ TABLE gt_ekbe WITH KEY sel = 'X' INTO gs_ekbe.
  IF sy-subrc <> 0.
    MESSAGE '请选择预制发票的行项目' TYPE 'S' DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.

  LOOP AT gt_fieldcat ASSIGNING FIELD-SYMBOL(<fs_fieldcat>) WHERE fieldname = 'BELNR' .
    <fs_fieldcat>-no_out = ''.
  ENDLOOP.

  DATA(lt_ekbe_tmp) = gt_ekbe.
  DELETE lt_ekbe_tmp WHERE sel <> 'X'.
  SORT lt_ekbe_tmp BY lifnr mwskz ebeln ebelp.

  LOOP AT lt_ekbe_tmp INTO DATA(ls_ekbe_grp) GROUP BY ( lifnr = ls_ekbe_grp-lifnr  mwskz = ls_ekbe_grp-mwskz ).

    CLEAR:lv_hsje,lv_wsje,lt_item.

    LOOP AT GROUP ls_ekbe_grp INTO DATA(ls_ekbe_tmp).

      LOOP AT gt_mir7 INTO gs_mir7 WHERE ebeln = ls_ekbe_tmp-ebeln AND ebelp = ls_ekbe_tmp-ebelp.
        CLEAR:ls_item.
        lv_doc_item = lv_doc_item + 1 .
        ls_item-invoice_doc_item = lv_doc_item.
        ls_item-po_number        = ls_ekbe_tmp-ebeln.
        ls_item-po_item          = ls_ekbe_tmp-ebelp.
        ls_item-ref_doc          = gs_mir7-mblnr.
        ls_item-ref_doc_year     = gs_mir7-mjahr.
        ls_item-ref_doc_it       = gs_mir7-zeile.
        ls_item-item_amount      = gs_mir7-menge * ls_ekbe_tmp-netpr / ls_ekbe_tmp-peinh.
        IF ls_item-item_amount < 0.
          ls_item-quantity       = abs( gs_mir7-menge ).
        ELSE.
          ls_item-quantity       = gs_mir7-menge .
        ENDIF.
        ls_item-item_amount      = abs( ls_item-item_amount ).
        ls_item-po_unit          = ls_ekbe_tmp-meins.
        ls_item-tax_code         = ls_ekbe_tmp-mwskz.
*        IF gs_mir7-menge <  0.
*          ls_item-de_cre_ind       = 'X'.
*        ELSE.
*          ls_item-de_cre_ind       = ''.
*        ENDIF.
        APPEND ls_item TO lt_item.
        lv_hsje = ls_ekbe_tmp-netpr_hs * gs_mir7-menge + lv_hsje.
        lv_wsje = ls_ekbe_tmp-netpr * gs_mir7-menge + lv_wsje.
      ENDLOOP.
    ENDLOOP.

    lv_mwskz = gs_ekbe-mwskz.
    lv_lifnr = gs_ekbe-lifnr.

    ls_headerdata-invoice_ind   = 'X'.
    ls_headerdata-doc_type      = 'RE'.
    ls_headerdata-doc_date      = sy-datum.
    ls_headerdata-pstng_date    = sy-datum.
    ls_headerdata-comp_code     = ls_ekbe_tmp-bukrs.
    ls_headerdata-diff_inv      = ls_ekbe_tmp-lifnr.
    ls_headerdata-currency      = 'CNY'.
    ls_headerdata-return_posting = 'H'.
    ls_headerdata-deliv_posting = 'S'.
    ls_headerdata-calc_tax_ind  = 'X'.

    ls_headerdata-gross_amount  = lv_hsje.
*    ls_headerdata-item_text     = lv_bktxt.
*    ls_headerdata-dsct_amount = lv_hsje - lv_wsje.
    IF ls_headerdata-gross_amount < 0.
      ls_headerdata-invoice_ind = ' '. "贷项凭证
      ls_headerdata-gross_amount = abs( ls_headerdata-gross_amount ).
*      ls_headerdata-dsct_amount = abs( ls_headerdata-dsct_amount ).
    ENDIF.

* 预制发票
    CALL FUNCTION 'BAPI_INCOMINGINVOICE_PARK'
      EXPORTING
        headerdata       = ls_headerdata
      IMPORTING
        invoicedocnumber = lv_invoicedocnumber
        fiscalyear       = lv_fiscalyear
      TABLES
        itemdata         = lt_item
        return           = lt_return.

    LOOP AT lt_return INTO ls_return WHERE type EQ 'E'.
      lv_return = |{ lv_return }  { ls_return-message }|.

* 事务回滚
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    ENDLOOP.
    IF sy-subrc NE 0.

* 事务提交
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
        EXPORTING
          wait = 'X'.

      LOOP AT gt_ekbe INTO gs_ekbe WHERE sel EQ 'X' AND lifnr = ls_ekbe_grp-lifnr AND  mwskz = ls_ekbe_grp-mwskz.
        gs_ekbe-belnr = lv_invoicedocnumber.
        gs_ekbe-message = '预制成功'.
        edit_disabled 'SEL'.
        gs_ekbe-sel = ''.
        gs_ekbe-icon = icon_green_light.
        MODIFY gt_ekbe FROM gs_ekbe.
      ENDLOOP.

    ELSE.
      LOOP AT gt_ekbe INTO gs_ekbe WHERE sel EQ 'X' AND lifnr = ls_ekbe_grp-lifnr AND  mwskz = ls_ekbe_grp-mwskz.
        gs_ekbe-message = lv_return.
        edit_disabled 'SEL'.
        gs_ekbe-sel = ''.
        gs_ekbe-icon = icon_red_light.
        MODIFY gt_ekbe FROM gs_ekbe.

      ENDLOOP.

    ENDIF.
  ENDLOOP.

同样的场景也出现在发票校验上:

前言

同事开发供应商结算功能时,需要把供应商的采购入库,采购退货,及供应商的费用项,返利项等整合到一张发票校验单据中. 

调用BAPI的时候,因为参数填写的原因,报了一些错误.帮忙跟踪了这些报错时. 

总结了发票校验BAPI的参数传递注意事项.

分享给大家.

两个BAPI函数的选择

创建发票校验有两个BAPI函数,二者实现的功能是一致的. 

BAPI_INCOMINGINVOICE_CREATE

BAPI_INCOMINGINVOICE_CREATE1

因为函数

BAPI_INCOMINGINVOICE_CREATE1 

中会检查行项目金额不能为负数,所以无法同时创建正向和反向订单的发票校验.

如果按单张采购订单创建发票校验. 建议选择 BAPI_INCOMINGINVOICE_CREATE1

如果需要在一张发票校验中同时添加采购收获,采购退货或其它费用. 则需要用BAPI_INCOMINGINVOICE_CREATE

后文的介绍以 

BAPI_INCOMINGINVOICE_CREATE 为主

多个BAPI的选择

SPRING

 一般情况下. 我们尽量选择函数名后面带有数字并且数字最大的函数,更大的数字序号往往代表了更新的BAPI函数版本.

比如PO的创建,选择BAPI_PO_CREATE1

函数传入参数简介

 01

抬头部分信息

HEADERDATA:

 02

明细部分

ITEMDATA

采购订单/商品凭证明细部分

根据订单基于收货的出具发票标记EKPO-WEBRE,如果有该标记. 则明细部分必须输入商品凭证信息. 否则,无需输入商品凭证部分

03

总账科目部分

GLACCOUNTDATA

费用/返利等总账科目信息

总账贷方减少应付金额, 借方增加应付金额. 

 04

物料部分

MATERIALDATA

不在采购/商品凭证的商品数据信息(这部分不太常用,一般用来调整商品库存价值,从而影响移动平均价)

05

关键字段

HEADERDATA- INVOICE_IND

抬头-INVOICE_IND = 'X'. 创建正常发票校验

此时明细行中金额ITEM_AMOUNT退货设置负数, 收货设置正数 ,数量QUANTITY始终设置正数

抬头-INVOICE_IND = ''. 创建贷项发票校验

此时明细行中金额退货设置正数, 收货设置负数,数量始终设置为正数

HEADERDATA- INVOICE_IND内容设置方式

通过ITEMDATA 中的采购收获金额加总 + GLACCOUNTDATA借项金额加总 为SUMA

通过ITEMDATA 中的采购退货金额加总 + GLACCOUNTDATA贷项金额加总为SUMB

如果SUMA >= SUMB

INVOICE_IND = 'X' . 此时ITEMDATA中的采购入库金额用正数, 采购退货金额用负数. GLACCOUNTDATA 金额始终用正数

如果SUMA < SUMB

INVOICE_IND = '' 此时ITEMDATA中的采购入库金额用负数, 采购退货金额用正数

GLACCOUNTDATA 金额始终用正数

如果上述规则没有遵守. 系统可能会报错

06

特定报错处理

如果按照上述规则设置了参数,BAPI 还是返回错误 M8 485 现金折扣总额不能过帐。

报错原因: 系统会根据抬头的借项/贷项标记 RBKP-XRECH (从INVOICE_IND传入) = '' 表示贷项 ='X'表示结项 去校验行项目中的收货金额/退货金额总计. 如果收获总计>退货总计 只能做发票 如果退货总计>收获总计 只能做贷项 如果存在总账行,按照之前的规则确定的INVOICE_IND内容, 违背了系统这个检查规则, 就会导致报错M8 485 

可以通过增强跳过这个检查,不影响后续处理逻辑. 

跳过方式:

检查的代码位置: 函数

MRM_CALCULATE_SKONTOBASE  

FORM VERGLEICH_SKONTOBASIS 

开头用隐式增强退出FORM .

总结:

一般前台界面能够录入实现的凭证,都可以通过调用BAPI传递参数实现. 特殊情况下,可以用BAPI做出前台操作无法实现的业务. 尤其是增强跳过BAPI的部分检查逻辑后(需要确保产生的单据的业务正确性). BAPI能够完成更多的业务形态.

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
根据提供的引用内容,可以了解到BAPI_INCOMINGINVOICE_CREATE1是一个用于创建进货发票的标准BAPI。而BAPI_INCOMINGINVOICE_PARK是一个用于将进货发票暂存的标准BAPI。下面是一个简单的示例代码,演示如何使用BAPI_INCOMINGINVOICE_PARK: ```ABAP DATA: lt_invoice_header TYPE STANDARD TABLE OF bapivbrk, lt_invoice_item TYPE STANDARD TABLE OF bapivbrp, ls_invoice_header LIKE LINE OF lt_invoice_header, ls_invoice_item LIKE LINE OF lt_invoice_item, ls_return LIKE bapiret2. * 填充进货发票头信息 ls_invoice_header-companycode = '1000'. ls_invoice_header-docdate = '20220101'. ls_invoice_header-pstngdate = '20220101'. ls_invoice_header-duedate = '20220131'. ls_invoice_header-vendor = '10000001'. APPEND ls_invoice_header TO lt_invoice_header. * 填充进货发票行项目信息 ls_invoice_item-material = 'MATERIAL001'. ls_invoice_item-quantity = 10. ls_invoice_item-netvalue = 1000. APPEND ls_invoice_item TO lt_invoice_item. * 调用BAPI_INCOMINGINVOICE_PARK CALL FUNCTION 'BAPI_INCOMINGINVOICE_PARK' EXPORTING headerdata = ls_invoice_header TABLES itemdata = lt_invoice_item return = lt_return. * 检查返回结果 IF lt_return IS NOT INITIAL. LOOP AT lt_return INTO ls_return. WRITE: / ls_return-type, ls_return-id, ls_return-number, ls_return-message. ENDLOOP. ENDIF. ``` 上述代码中,我们首先定义了进货发票的头信息和行项目信息,并将其填充到对应的表中。然后,我们调用了BAPI_INCOMINGINVOICE_PARK,并将进货发票的头信息作为EXPORTING参数传递给该BAPI,将进货发票的行项目信息作为TABLES参数传递给该BAPI。最后,我们检查了返回结果,如果有错误信息,则将其输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值