ABAP BAPI_ACC_DOCUMENT_POST创建会计凭证

记录下项目过程中用到BAPI_ACC_DOCUMENT_POST时的问题
1.凭证货币与本币 不一致时,在curr_type 里区分本币金额和凭证金额(汇率会自己换算)
如果不区分本币和凭证货币,在处理外币时 报错消息如下:
Inconsistent currency information(货币信息不一致)

2.记账码是供应商类型时,供应商的前导0需要添加处理,报错消息如下:
Vendor 970773 is not defined in company code 1000(公司代码1000中未定义供应商970773)

3.部分字段在标准bapi结构中没有找到,需要增强里去处理,然后传入的结构中增加。
增强:
参考:link
4.传入的客户,填在accountgl里,需要区分清楚供应商和客户(前台过的去,BAPI过不去,搞半天原来是客户,前台双击对应的供应商/客户,跳转后显示供应商/客户)
5.有些字段前台有,在BAPI字段里找,却没有(例如:付款参考,在供应商的字段里有,但是在总账里却没有),这种情况需要在extension2里传进去就OK了
在这里插入图片描述

接口的代码如下。

CLASS zfi_feikong_item DEFINITION FINAL.
  PUBLIC SECTION.
    DATA:gl_account TYPE hkont, "总分类帐帐目
         costcenter TYPE kostl,  "成本中心
         item_text  TYPE sgtxt,  "项目文本
         alloc_nmbr TYPE acpi_zuonr, "分配号
         tr_part_ba TYPE pargb,  "贸易伙伴的业务范围
         amt_doccur TYPE bapidoccur, "本币金额
         wrbtr      TYPE wrbtr,   "凭证金额
         currency   TYPE waers,  "货币码
         rstgr      TYPE rstgr,  "付款原因代码
         bschl      TYPE bschl,  "记帐代码
         umskz      TYPE umskz, "特别总账标识
         quantity   TYPE menge_d,  "数量
         base_uom   TYPE meins,  "基本计量单位
         tax_code   TYPE mwskz,  "销售/购买税代码
         material   TYPE matnr,  "物料编号
         zterm      TYPE dzterm, "付款条件代码
         zfbdt      TYPE dzfbdt, "到期日期计算的起算日期
         zbd1t      TYPE dzbd1t, "现金折扣天数 1
         zbd2t      TYPE dzbd2t, "现金折扣天数 2
         skfbt      TYPE acfbt,  "以货币类型中的货币计的现金折扣金额合法化
         rmvct      TYPE rmvct,  "事务类型
         vendor_no  TYPE lifnr.   "供应商或债权人的帐号
ENDCLASS.

CLASS zfi_feikong_req DEFINITION FINAL.
  PUBLIC SECTION.
    DATA:username   TYPE usnam, "录入用户(必输)
         comp_code  TYPE bukrs, "公司代码(必输)
         doc_date   TYPE bldat, "凭证日期(必输)
         pstng_date TYPE budat, "过账日期(必输)
         doc_type   TYPE blart,  "凭证类型(必输)
         header_txt TYPE bktxt,  "凭证抬头文本
         ppnam      TYPE usnam, "预制人
         lt_item    TYPE STANDARD TABLE OF REF TO zfi_feikong_item.
ENDCLASS.

CLASS zfi_feikong_cl DEFINITION FINAL.

  PUBLIC SECTION.
    DATA:  interfaceid TYPE string.
    DATA:  reqdata TYPE REF TO  zfi_feikong_req.
ENDCLASS.

FUNCTION zfi_feikong.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(INJSON) TYPE  STRING
*"  EXPORTING
*"     VALUE(O_CODE) TYPE  CHAR1
*"     VALUE(O_DESC) TYPE  CHAR100
*"     VALUE(OUTJSON) TYPE  STRING
*"----------------------------------------------------------------------

  DATA tp_input TYPE REF TO  zfi_feikong_cl.


  DATA: gd_documentheader LIKE bapiache09,
        lt_accountgl      LIKE TABLE OF bapiacgl09
                                    WITH HEADER LINE,
        lt_accountpayable	LIKE TABLE OF	bapiacap09
                                    WITH HEADER LINE,
        lt_currencyamount LIKE TABLE OF bapiaccr09
                                    WITH HEADER LINE,
        lt_return         LIKE TABLE OF bapiret2
                                    WITH HEADER LINE.
  DATA: lw_extension TYPE bapiextc,
        lt_extension TYPE STANDARD TABLE OF bapiparex
                                    WITH HEADER LINE.
  DATA: ls_zcos0002 LIKE zcos0002.
  DATA: e_monat LIKE bkpf-monat,
        e_gjahr LIKE bkpf-gjahr.
  DATA: ld_item      TYPE i .
  DATA lv_belnr TYPE belnr_d.

* 传入参数转换判断
  IF injson IS INITIAL.
    o_code = 'E'.
    o_desc = 'Query ParamData is Required!'.
  ELSE.

    /ui2/cl_json=>deserialize( EXPORTING json = injson pretty_name = /ui2/cl_json=>pretty_mode-camel_case CHANGING data = tp_input ).

    IF tp_input IS NOT INITIAL.
      ASSIGN  tp_input->reqdata TO FIELD-SYMBOL(<fs_head>).

      REFRESH : lt_accountgl[],lt_currencyamount[],lt_extension[].
      REFRESH : lt_return[].
      CLEAR : gd_documentheader.

      e_gjahr = <fs_head>->pstng_date+0(4).
      e_monat = <fs_head>->pstng_date+4(2).

      gd_documentheader-username   = <fs_head>->username.   "录入用户(必输)
      gd_documentheader-comp_code  = <fs_head>->comp_code.    "公司代码(必输)
      gd_documentheader-doc_date   = <fs_head>->doc_date.   "凭证日期(必输)
      gd_documentheader-pstng_date = <fs_head>->pstng_date. "过账日期(必输)
      gd_documentheader-doc_type   = <fs_head>->doc_type.       "凭证类型(必输)
      gd_documentheader-fis_period = e_monat.    "过账期间(必输)
      gd_documentheader-fisc_year  = e_gjahr.    "会计年度
      gd_documentheader-header_txt = <fs_head>->header_txt.    "凭证抬头文本
*  GD_DOCUMENTHEADER-BUS_ACT    = 'RMWE'.    "业务事务
*  GD_DOCUMENTHEADER-OBJ_TYPE   = 'BKPFF'.   "参考交易

      LOOP AT <fs_head>->lt_item INTO DATA(ls_item).

        ADD 1 TO ld_item.
        IF ls_item->gl_account IS NOT INITIAL.
          lt_accountgl-itemno_acc = ld_item.        "会计凭证行项目编号
          lt_accountgl-gl_account = ls_item->gl_account.   "总分类帐帐目
          "lt_accountgl-VENDOR_NO = ls_item->gl_account.   "总分类帐帐目
          "lt_accountgl-costcenter = ls_item->costcenter. "成本中心
*    LT_ACCOUNTGL-BUS_AREA   = P_WS_COS-GSBER. "业务范围
          lt_accountgl-item_text  = ls_item->item_text.   "项目文本
          lt_accountgl-alloc_nmbr = ls_item->alloc_nmbr.   "分配
          lt_accountgl-tr_part_ba = ls_item->tr_part_ba.   "贸易伙伴的业务范围
          lt_accountgl-quantity = ls_item->quantity.   "数量
          lt_accountgl-base_uom = ls_item->base_uom.   "基本计量单位
          lt_accountgl-tax_code = ls_item->tax_code.   "销售/购买税代码
          lt_accountgl-material = ls_item->material.   "物料编号
          lt_accountgl-customer = |{ ls_item->customer ALPHA = IN }|.   "客户编号
          APPEND lt_accountgl.
          CLEAR  lt_accountgl.
        ENDIF.

        IF ls_item->vendor_no IS NOT INITIAL.
          lt_accountpayable-itemno_acc = ld_item.
          lt_accountpayable-vendor_no = |{ ls_item->vendor_no ALPHA = IN }|..
          lt_accountpayable-comp_code = <fs_head>->comp_code.
          APPEND lt_accountpayable.
          CLEAR  lt_accountpayable.
        ENDIF.

        "添加金额
        lt_currencyamount-itemno_acc = ld_item.
        lt_currencyamount-amt_doccur = ls_item->amt_doccur.  "本币金额
        lt_currencyamount-curr_type  = '10'.
        lt_currencyamount-currency   = 'CNY'."ls_item->currency.
        APPEND lt_currencyamount.
        CLEAR  lt_currencyamount.

        "添加金额(**重复添加金额就是解决不能冲销的问题**)
        lt_currencyamount-itemno_acc = ld_item.
        lt_currencyamount-amt_doccur = ls_item->wrbtr."amt_doccur.  "凭证货币金额
        lt_currencyamount-curr_type  = '00'.
        lt_currencyamount-currency   = ls_item->currency.
        APPEND lt_currencyamount.
        CLEAR  lt_currencyamount.

        "添加记账码
        ls_zcos0002-posnr = ld_item.  "Item No
        ls_zcos0002-bschl = ls_item->bschl. "记帐码
        ls_zcos0002-umskz = ls_item->umskz. "特别总账标识
        ls_zcos0002-rstgr = ls_item->rstgr. "付款原因代码
        ls_zcos0002-zterm = ls_item->zterm. "付款条件代码
        ls_zcos0002-zfbdt = ls_item->zfbdt. "到期日期计算的起算日期
        ls_zcos0002-zbd1t = ls_item->zbd1t. "现金折扣天数1
        ls_zcos0002-zbd2t = ls_item->zbd2t. "现金折扣天数2
        ls_zcos0002-skfbt = ls_item->skfbt. "以货币类型中的货币计的现金折扣金额合法化
        ls_zcos0002-rmvct = ls_item->rmvct. "事务类型

*是否创建预制凭证,否则凭证直接过账
        lt_extension-structure =  'ZCOS0002'.
        lt_extension-valuepart1 = ls_zcos0002.
        APPEND lt_extension.
        CLEAR : lt_extension,ls_zcos0002.

      ENDLOOP.
    ENDIF.

    CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
      EXPORTING
        documentheader = gd_documentheader
      TABLES
        accountgl      = lt_accountgl
        accountpayable = lt_accountpayable
        currencyamount = lt_currencyamount
        return         = lt_return
        extension2     = lt_extension.

    READ TABLE lt_return WITH KEY type = 'E'.
*  BREAK-POINT.
    IF sy-subrc <> 0.
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
        EXPORTING
          wait = 'X'.
      o_code = 'S'.
      o_desc = 'Acc_Document Create Success!'.

      READ TABLE lt_return INTO DATA(ls_return) INDEX 1.
      lv_belnr = ls_return-message_v2+(10).

      SELECT SINGLE belnr INTO @DATA(lv_c_belnr)
        FROM bkpf
        WHERE belnr = @lv_belnr
        AND gjahr = @e_gjahr.
      IF sy-subrc EQ 0.
        IF <fs_head> IS ASSIGNED.
          UPDATE bkpf SET ppnam = <fs_head>->ppnam WHERE belnr = lv_c_belnr AND gjahr = e_gjahr.
          COMMIT WORK.
        ENDIF.
      ENDIF.

    ELSE.
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
      o_code = 'E'.
      o_desc = 'Acc_Document Create Failed!'.
    ENDIF.
  ENDIF.

* 返回结果数据JSON封装
  outjson = /ui2/cl_json=>serialize( data = lt_return[] pretty_name = /ui2/cl_json=>pretty_mode-none numc_as_string = abap_true ).

  outjson = '{"RETURNCODE":"' && o_code && '", "MESSAGE":"' && o_desc && '", "DATA":' && outjson && '}'.



ENDFUNCTION.

补充一点,一次性客户、一次性供应商BSEC表
内容填在抬头的customercpd里
如下:

          IF ls_item->bschl = '25' or ls_item->bschl = '31'.
            ls_customercpd-name = ls_item->name1.
            ls_customercpd-city = ls_item->ort01.
            ls_customercpd-country = 'CN'.
            ls_customercpd-street = ls_item->name1.
            ls_customercpd-postl_code = '528200'.
            ls_customercpd-title = ls_item->anred.
          ENDIF.
          
      CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
        EXPORTING
          documentheader    = gd_documentheader
          customercpd       = ls_customercpd
        TABLES
          accountgl         = lt_accountgl
          accountreceivable = lt_accountreceivable
          accountpayable    = lt_accountpayable
          currencyamount    = lt_currencyamount
          return            = lt_return
          extension2        = lt_extension.

效果如下:
供应商
在这里插入图片描述
客户
在这里插入图片描述

上面的BAPI执行W类型的过账时会报F5 246的错误。link
在这里插入图片描述
此时,无法使用BAPI_ACC_DOCUMENT_POST创建凭证,
在上面的链接里已经给出解决办法
跟BDC一样,如果找不到字段,直接SHDB执行之后,把对应的字段复制过来就OK


DATA: ls_ftpost TYPE ftpost,
      lt_ftpost TYPE TABLE OF ftpost,
      lt_fttax  TYPE TABLE OF fttax,
      lt_blntab TYPE TABLE OF blntab,
      lv_subrc  TYPE sy-subrc,
      lv_msg    TYPE bapiret2.

DEFINE macro.
  ls_ftpost-fnam = &1.
  ls_ftpost-fval = &2.
  APPEND ls_ftpost TO lt_ftpost.
END-OF-DEFINITION.

CALL FUNCTION 'POSTING_INTERFACE_START'
  EXPORTING
*   I_CLIENT           = SY-MANDT
    i_function         = 'C'
    i_group            = 'ZTESTFIBDC'
*   I_HOLDDATE         = ' '
    i_keep             = 'X'
*   I_MODE             = 'N'
*   I_UPDATE           = 'S'
    i_user             = sy-uname
*   I_XBDCC            = ' '
  EXCEPTIONS
    client_incorrect   = 1
    function_invalid   = 2
    group_name_missing = 3
    mode_invalid       = 4
    update_invalid     = 5
    user_invalid       = 6
    OTHERS             = 7.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.


"header:
ls_ftpost-stype = 'K'.        "Header indicator
ls_ftpost-count = '001'.      "First item
macro: 'BKPF-BLDAT' '20230801',
       'BKPF-BLART' 'SA',
       'BKPF-BUKRS' '1000',
       'BKPF-BUDAT' '20230801'.
*"items:
ls_ftpost-stype = 'P'.
ls_ftpost-count = '001'.

macro: 'RF05A-NEWBS' '19',
       'RF05A-NEWKO' '102361',
       'RF05A-NEWUM' 'W',
       'BSEG-ZFBDT' '20230904',
       'BSEG-WRBTR' '100'.
"macro: 'RF05A-NEWBS' '40',
"       'COBL-PARGB' '0099',
"       'BSEG-RSTGR' 'A10',
"       'BSEG-ZUONR' '20230904',
"       'BSEG-HKONT' '1009010101',
"       'BSEG-WRBTR' '100'.

ls_ftpost-stype = 'P'.
ls_ftpost-count = '002'.

macro: 'RF05A-NEWBS' '25',
       'RF05A-NEWKO' '6',
       'BSEC-ANRED' '标题',
       'BSEC-NAME1' '名称',
       'BSEC-ORT01' '城市',
       'BSEC-LAND1' 'CN',
       'BSEG-WRBTR' '100'.
"macro: 'RF05A-NEWBS' '50',
"       'COBL-GSBER' '0099',
"       'COBL-KOSTL' '1700902',
"       'BSEG-ZUONR' '20230904',
"       'BSEG-WRBTR' '100',
"       'BSEG-HKONT' '6609000101'.

BREAK-POINT.
*
CALL FUNCTION 'POSTING_INTERFACE_DOCUMENT'
  EXPORTING
    i_tcode   = 'FB01'          "Name of t-code for Posting
    i_sgfunct = 'C'            "Batch input session
  IMPORTING
    e_subrc   = lv_subrc
    e_msgid   = lv_msg-id        "Error handling
    e_msgty   = lv_msg-type      "Error handling
    e_msgno   = lv_msg-number    "Error handling
    e_msgv1   = lv_msg-message_v1 "Error handling
    e_msgv2   = lv_msg-message_v2 "Error handling
    e_msgv3   = lv_msg-message_v3 "Error handling
    e_msgv4   = lv_msg-message_v4 "Error handling
  TABLES
    t_ftpost  = lt_ftpost        "Internal table populated in Step 2
    t_fttax   = lt_fttax        "Relevant for Tax calculation manually
    t_blntab  = lt_blntab       "Relevant only for Call Trans…
  EXCEPTIONS
    OTHERS    = 1.


CALL FUNCTION 'POSTING_INTERFACE_END'.

LOOP AT lt_blntab INTO DATA(ls_blntab).
  WRITE: ls_blntab-belnr,
         ls_blntab-gjahr.
ENDLOOP.

SAP链接link

使用内部过账接口
此主题仅针对已在 SAP 系统中生成自己的报表或程序,并且之前一直使用批输入更新数据库数据的应用程序程序员及顾问。

用途
可通过财务会计中的内部过账接口,使用批输入或调用事务来生成过账。

特征
使用此接口时不再需要输入程序名称或屏幕编号。上述两项内容均由接口根据过账数据来确定。这一功能的优势在于即使数据结构发生更改,您也不需要修改程序。

过账接口旨在简化批输入流程。仅在标准功能无法满足需要等例外情况下才使用此接口。

可以通过下列功能模块使用此接口:

|功能模块 | 事务 |
|POSTING_INTERFACE_START-- | |
| POSTING_INTERFACE_DOCUMENT | FB01、FBS1、FB41、ABF1、FBB1、FBVB、FBV1、FBD5 |
| POSTING_INTERFACE_CLEARING | FB05|
| POSTING_INTERFACE_END | |
| POSTING_INTERFACE_RESET_CLEAR | FBRA |
| POSTING_INTERFACE_REVERSE_DOC | FB08|

各功能模块在线记录在 SAP 系统中。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值