SAP对于采购发票的校验,MIRO能够直接生成校验凭证和会计凭证,但还有一种用MIR7进行发票预制(Park Incoming Invoice),这种场景很好地适用于业务与财务的分工:业务人员用MIR7预制发票后(不生成会计凭证),经财务人员审核才进行过账操作(生成会计凭证)。
预制凭证的过账有多种方法,常用的有:
用MIR4显示凭证,转换成编辑状态进行过账;
用MIRO调出预制凭证进行编辑及过账。
接下来介绍前台操作流程:
首先ME21N新建一张PO,这里新建的方法我就不多做介绍了:
如下,我们新建了一个采购订单,还没有做过任何收货
然后我们MIGO 101 收货:
我们再进 PO 去看,可以看到 采购订单历史 这个页签已经出来了,并且有了一笔101收货的单据。
另外稍微提一下,这个页签的数据再表 EKBE 里都能找到。
然后采购就会去MIR7去做预制发票:
填入相关信息
然后回车,采购订单的信息以及供应商的银行信息都会被带出来
然后我们点击 模拟
系统提示仍然有问题,五哦一点击保存预制凭证也没有,我们点 X
发现指示灯变红了
点击
告诉我们抬头文本没填,这里是我们的校验增强做的0.0
填上文本后继续操作 , 点击 模拟 -> 保存预制凭证 ,出现如下提示
然后我们再回采购订单去看 采购订单历史 页面多了一个预制发票(提前输入发票)的单据号
然后到财务这边审核发现没问题,就会去把这笔发票过账。
进miro,进来以后点击 更换单据 这个按钮
把对应的预制发票放进去
对应树状结构和信息都出来了
然后点击过账(或者模拟),出现如下提示,证明已经过账
我们再回到PO里去,这时这张发票的描述变成了发票收据,证明预制的发票已经过账了
我们点击进去还能看到凭证流
点击后续凭证就可以看到凭证编号和分类帐了
至此前台操作完毕。
然后作为一个开发者,我们要怎么通过PO得到这些凭证的信息呢?
首先,我们进表 EKBE,获取PO的凭证信息
可以看到 101 和 预制发票的凭证号都在这里面,我们拿到预制发票号
然后进表 BKPF 找这个发票有没有过账
把发票号按照如下形式放到 AWKEY 字段里
会计凭证号就找到了
但是其实大多数时候,用户是不会手动一个一个这样操作的,所以我们开发人员就要用BAPI帮忙做批量预制发票,对应的 BAPI 为 BAPI_INCOMINGINVOICE_PARK,关键代码我放下面,仅供参考:
FORM create_docment .
"BAPI相关
DATA:ts_head TYPE bapi_incinv_create_header,
tt_item TYPE TABLE OF bapi_incinv_create_item,
ts_item TYPE bapi_incinv_create_item,
gt_taxdata TYPE TABLE OF bapi_incinv_create_tax,
gs_taxdata TYPE bapi_incinv_create_tax,
g_belnr LIKE bapi_incinv_fld-inv_doc_no,
g_gjahr LIKE bapi_incinv_fld-fisc_year,
ts_return TYPE bapiret2,
tt_return TYPE TABLE OF bapiret2.
CLEAR: ts_head,tt_item[],gt_taxdata[].
CLEAR:ts_head.
DATA:lv_sum_menge TYPE menge_d,
lv_sum_amount TYPE ZMMT018_1-ZHSJE, "含税金额,
lv_sum_zse TYPE icl_txamt,
lv_sum_wrbtr TYPE wrbtr.
DATA: BEGIN OF ntab OCCURS 0,
ZHBPX TYPE STRING,
LFBNR TYPE MSEG-LFBNR, "参考物料凭证编号
MJAHR TYPE MSEG-MJAHR, "物料凭证的年份
MBLNR TYPE MSEG-MBLNR, "物料凭证编号
ZEILE TYPE MSEG-ZEILE, "物料凭证中的项目
LFBJA TYPE MSEG-LFBJA, "参考物料凭证的年份
LFPOS TYPE MSEG-LFPOS, "参考物料凭证中的项目
tabix LIKE sy-tabix,
END OF ntab.
DATA: g_number TYPE i VALUE 0.
DATA: w_flag TYPE i.
READ TABLE gt_head INTO gs_head WITH KEY sel = 'X'.
"添加表头信息
* IF ZMMS029-zhsje > 0. "发票
ts_head-doc_type = 'RE'. "凭证类型
IF ZMMS029-zhstz > 0. "发票
ts_head-invoice_ind = 'X'. "发票标志
ts_head-gross_amount = ZMMS029-zhstz. "总金额
ELSE.
ts_head-invoice_ind = ''. "发票标志
ts_head-gross_amount = ZMMS029-zhstz * ( -1 ). "总金额
ENDIF.
ts_head-person_ext = sy-uname. "按系统用户输入
* ts_head-bline_date = sy-datum. "到期日期计算的起算日期
ts_head-comp_code = gs_head-bukrs. "公司代码
ts_head-doc_date = ZMMS029-budat. "凭证日期
ts_head-pstng_date = ZMMS029-zdte. "过帐日期
ts_head-calc_tax_ind = ''."计算税额标识
ts_head-currency = zmms029-waers.
* ts_head-currency = 'CNY'. "货币码
"出票方
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = ZMMS029-lifnr
IMPORTING
output = ts_head-diff_inv.
"付款条件
SELECT SINGLE zterm
FROM lfm1
INTO ts_head-pmnttrms
WHERE lifnr = ZMMS029-lifnr.
ts_head-ref_doc_no = ZMMS029-xblnr. "参考凭证
ts_head-item_text = ZMMS029-sgtxt. "项目文本
* ENDIF.
"添加行项目信息
CLEAR:ntab.
REFRESH:ntab[].
LOOP AT gt_item INTO gs_item WHERE sel = 'X'.
MOVE-CORRESPONDING gs_item TO ntab.
ntab-ZHBPX = ntab-LFBJA && ntab-LFBNR && ntab-LFPOS.
ntab-tabix = sy-tabix.
APPEND ntab.
CLEAR ntab.
ENDLOOP.
SORT ntab BY ZHBPX.
CLEAR:g_number.
LOOP AT ntab.
READ TABLE gt_item INTO gs_item INDEX ntab-tabix.
* IF gs_head_1-shkzg = 'S'.
* ADD gs_head_1-amount TO lv_sum_amount."含税总金额
* ADD gs_head_1-zse TO lv_sum_zse. "税额
* ADD gs_head_1-menge TO lv_sum_menge. "数量
* ADD gs_head_1-wrbtr TO lv_sum_wrbtr. "不含税金额
* ELSEIF gs_head_1-shkzg = 'H'.
* SUBTRACT gs_head_1-amount FROM lv_sum_amount. "含税总金额
* SUBTRACT gs_head_1-zse FROM lv_sum_zse. "税额
* SUBTRACT gs_head_1-menge FROM lv_sum_menge. "数量
* SUBTRACT gs_head_1-wrbtr FROM lv_sum_wrbtr. "不含税金额
* ENDIF.
IF sy-subrc = 0.
lv_sum_amount = lv_sum_amount + gs_item-ZHSJE.
lv_sum_zse = lv_sum_zse + gs_item-ZSE.
lv_sum_menge = lv_sum_menge + gs_item-ZRKSL.
lv_sum_wrbtr = lv_sum_wrbtr + gs_item-ZWSJE.
ENDIF.
* IF lv_sum_amount < 0.
** lv_sum_amount = lv_sum_amount * ( -1 ).
* lv_sum_zse = lv_sum_zse * ( -1 ).
* lv_sum_menge = lv_sum_menge * ( -1 ).
* ENDIF.
IF ZMMS029-zhsje < 0. "贷记
lv_sum_wrbtr = lv_sum_wrbtr * ( -1 ).
ENDIF.
AT END OF ZHBPX.
IF lv_sum_amount NE 0.
CLEAR:ts_item.
g_number = g_number + 1.
lv_sum_menge = abs( lv_sum_menge ).
ts_item-invoice_doc_item = g_number.
ts_item-po_number = gs_item-ebeln.
ts_item-po_item = gs_item-ebelp.
ts_item-item_amount = lv_sum_wrbtr.
ts_item-tax_code = gs_item-MWSKZ."税码
gs_taxdata-tax_code = gs_item-MWSKZ."税码
ts_item-ref_doc = gs_item-LFBNR."参考凭证号
ts_item-ref_doc_year = gs_item-LFBJA.
ts_item-ref_doc_it = gs_item-LFPOS.
ts_item-quantity = lv_sum_menge.
ts_item-po_unit = gs_item-meins.
ts_item-po_pr_uom = gs_item-bprme."gs_head_1-meins.
APPEND ts_item TO tt_item.
ENDIF.
CLEAR: lv_sum_amount,lv_sum_menge,lv_sum_wrbtr.
ENDAT.
ENDLOOP.
IF lv_sum_zse <> 0.
gs_taxdata-tax_amount = ZMMS029-ZSETZ.
APPEND gs_taxdata TO gt_taxdata.
CLEAR:gs_taxdata.
ENDIF.
CLEAR:ts_return,w_flag.
CALL FUNCTION 'BAPI_INCOMINGINVOICE_PARK'
EXPORTING
headerdata = ts_head
IMPORTING
invoicedocnumber = g_belnr
fiscalyear = g_gjahr
TABLES
itemdata = tt_item
taxdata = gt_taxdata
return = tt_return.
LOOP AT tt_return INTO ts_return WHERE type = 'E'.
w_flag = 1.
EXIT.
ENDLOOP.
IF w_flag = 0.
CLEAR ts_return.
REFRESH tt_return.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
IF tt_return[] IS INITIAL.
"预制成功更新自建表
LOOP AT GT_ITEM INTO GS_ITEM WHERE SEL = 'X'.
GS_ITEM-belnr = g_belnr.
UPDATE ZMMT017_1 SET BELNR = @g_belnr , GJAHR = @g_gjahr WHERE ZDZDID = @GS_ITEM-ZDZDID.
UPDATE ZMMT018_1 SET BELNR = @g_belnr , GJAHR = @g_gjahr WHERE ZDZDID = @GS_ITEM-ZDZDID.
MODIFY GT_ITEM FROM GS_ITEM.
CLEAR GS_ITEM.
ENDLOOP.
"预制成功提示信息
DATA:t_mess TYPE string.
CONCATENATE '发票' g_belnr '预制成功!' INTO t_mess.
MESSAGE t_mess type 'S'.
LEAVE TO SCREEN 0.
ENDIF.
PERFORM frm_refresh_alv.
ELSE.
LOOP AT tt_return INTO ts_return WHERE type = 'E' AND message_v2 <> '$'.
MESSAGE ts_return-message TYPE 'S' DISPLAY LIKE 'E'.
ENDLOOP.
ENDIF.
ENDFORM.
更详细的信息可以参考博文https://blog.csdn.net/weixin_42646630/article/details/118972822