通过代码实现以指定用户名创建消耗物料凭证,并获取对应财务凭证。
关键BAPI:
BAPI_GOODSMVT_CREATE 物料凭证创建
BAPI_GOODSMVT_CANCEL 反向货物移动
代码如下:
DATA:gv_ypwl type matnr, "对应物料号
lr_werks type range of werks_d, "工厂
gv_lgort type lgort_d value 'xxxx'. "库存地点
* 获取库存
SELECT * INTO TABLE @DATA(lt_mard)
FROM mard
WHERE matnr EQ @gv_ypwl
AND werks IN @lr_werks
AND lgort EQ @gv_lgort.
* 获取到对应的库存字段值(labst)与即将消耗量进行对比
* 消耗大于库存,不允许记账
DATA: lv_bukrs TYPE bukrs,
lv_year TYPE t001b-frye1,
lv_monf TYPE t001b-frpe1,
lv_oper TYPE t001b-frpe1.
CALL FUNCTION 'FI_PERIOD_CHECK'
EXPORTING
i_bukrs = lv_bukrs
i_gjahr = lv_year
i_koart = '+'
i_monat = lv_monf
IMPORTING
e_oper = lv_oper
EXCEPTIONS
error_period = 1
error_period_acc = 2
invalid_input = 3
OTHERS = 4.
IF sy-subrc <> 0.
* Implement suitable error handling here
gs_data-status = 'E'.
gs_data-err_reason = '财务账期未开,请检查'.
ENDIF.
代码如下:
DATA:lw_goodsmvt_header TYPE bapi2017_gm_head_01,
pv_goodsmvt_code TYPE bapi2017_gm_code,
cv_materialdoc_fjy TYPE bapi2017_gm_head_ret-mat_doc
lv_year TYPE bapi2017_gm_head_ret-doc_year,
lt_goodsmvt_item TYPE TABLE OF bapi2017_gm_item_create,
ls_goodsmvt_item TYPE bapi2017_gm_item_create,
lv_pdate TYPE dats,
lv_edate TYPE dats,
lv_err_flag TYPE char01,
lv_err_reason TYPE char255,
lv_str TYPE string,
lv_awkey TYPE awkey.
CLEAR:lv_err_flag.
*表配置T158G 03为MB1A
pv_goodsmvt_code = '03'.
*过账日期
lv_edate = sy-datum.
* header
CLEAR:lw_goodsmvt_header,lv_year,lt_goodsmvt_item,lt_goodsmvt_item.
lw_goodsmvt_header-pstng_date = lv_edate.
lw_goodsmvt_header-doc_date = lv_edate.
lw_goodsmvt_header-pr_uname = 'HELPDESK'.
lw_goodsmvt_header-header_txt = text-001.
* item
ls_goodsmvt_item-plant = lv_werks.
ls_goodsmvt_item-stge_loc = gv_lgort.
ls_goodsmvt_item-move_type = lv_movty. "移动类型(库存管理)
ls_goodsmvt_item-costcenter = lv_kostl. "成本中心
* 同移动类型支持多条
LOOP I_ITEM.
ls_goodsmvt_item-entry_qnt = I_ITEM-XH. "消耗量
ls_goodsmvt_item-material = I_ITEM-MATNR. "物料号
APPEND ls_goodsmvt_item TO lt_goodsmvt_item.
ENDLOOP.
lv_year = sy-datum(4).
CALL FUNCTION 'ZBAPI_GOODSMVT_CREATE'
DESTINATION 'ZDEST_FOR_RFC'
EXPORTING
goodsmvt_header = lw_goodsmvt_header
goodsmvt_code = pv_goodsmvt_code
IMPORTING
materialdocument = cv_materialdoc_fjy
matdocumentyear = lv_year
TABLES
goodsmvt_item = lt_goodsmvt_item[]
return = lt_return[].
LOOP AT lt_return[] INTO DATA(ls_return) WHERE type EQ 'E' OR type EQ 'A'.
lv_err_flag = abap_true.
lv_err_reason = lv_err_reason && ls_return-message.
ENDLOOP.
* 获取财务凭证
IF cv_materialdoc_fjy IS NOT INITIAL AND lv_err_flag IS INITIAL.
lv_awkey = cv_materialdoc_fjy && lv_year.
CONDENSE lv_awkey NO-GAPS.
SELECT SINGLE bukrs,belnr,gjahr INTO @DATA(ls_bkpf)
FROM bkpf
WHERE bukrs EQ @lv_bukrs
AND gjahr EQ @lv_year
AND awkey EQ @lv_awkey.
ENDIF.
即使在lw_goodsmvt_header中设置了指定用户名,但是程序记账依然是使用当前登录用户,财务凭证也是,所以我们用远程调用RFC的方式来执行记账BAPI
由于是新开进程执行记账BAPI
所以要对执行结果在新建的RFC内进行COMMIT或者ROLLBACK
具体请看代码
关于DESTINATION的配置可见文章
指定用户名执行
FUNCTION zbapi_goodsmvt_create.
*"----------------------------------------------------------------------
*"*"本地接口:
*" IMPORTING
*" VALUE(GOODSMVT_HEADER) LIKE BAPI2017_GM_HEAD_01 STRUCTURE
*" BAPI2017_GM_HEAD_01
*" VALUE(GOODSMVT_CODE) LIKE BAPI2017_GM_CODE STRUCTURE
*" BAPI2017_GM_CODE
*" VALUE(TESTRUN) LIKE BAPI2017_GM_GEN-TESTRUN DEFAULT SPACE
*" VALUE(GOODSMVT_REF_EWM) LIKE /SPE/BAPI2017_GM_REF_EWM STRUCTURE
*" /SPE/BAPI2017_GM_REF_EWM OPTIONAL
*" EXPORTING
*" VALUE(GOODSMVT_HEADRET) LIKE BAPI2017_GM_HEAD_RET STRUCTURE
*" BAPI2017_GM_HEAD_RET
*" VALUE(MATERIALDOCUMENT) TYPE BAPI2017_GM_HEAD_RET-MAT_DOC
*" VALUE(MATDOCUMENTYEAR) TYPE BAPI2017_GM_HEAD_RET-DOC_YEAR
*" TABLES
*" GOODSMVT_ITEM STRUCTURE BAPI2017_GM_ITEM_CREATE
*" GOODSMVT_SERIALNUMBER STRUCTURE BAPI2017_GM_SERIALNUMBER
*" OPTIONAL
*" RETURN STRUCTURE BAPIRET2
*" GOODSMVT_SERV_PART_DATA STRUCTURE
*" /SPE/BAPI2017_SERVICEPART_DATA OPTIONAL
*" EXTENSIONIN STRUCTURE BAPIPAREX OPTIONAL
*" GOODSMVT_ITEM_CWM STRUCTURE /CWM/BAPI2017_GM_ITEM_CREATE
*" OPTIONAL
*"----------------------------------------------------------------------
DATA:lv_err_flag TYPE char01.
CALL FUNCTION 'BAPI_GOODSMVT_CREATE'
EXPORTING
goodsmvt_header = goodsmvt_header
goodsmvt_code = goodsmvt_code
IMPORTING
materialdocument = materialdocument
matdocumentyear = matdocumentyear
TABLES
goodsmvt_item = goodsmvt_item[]
return = return[].
CLEAR:lv_err_flag.
LOOP AT return[] INTO DATA(ls_return) WHERE type EQ 'E' OR type EQ 'A'.
lv_err_flag = 'X'.
ENDLOOP.
IF lv_err_flag IS INITIAL.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'
* IMPORTING
* RETURN =
.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'
* IMPORTING
* RETURN =
.
ENDIF.
ENDFUNCTION.
如果发现数据有调整需要重新记账时,我们可以先反向移动,再进行记账
CALL FUNCTION 'BAPI_GOODSMVT_CANCEL'
EXPORTING
materialdocument = lv_mblnr
matdocumentyear = lv_mjahr
goodsmvt_pstng_date = lv_date
goodsmvt_pr_uname = 'HELPDESK'
IMPORTING
goodsmvt_headret = ls_headret
TABLES
return = lt_return[]
* GOODSMVT_MATDOCITEM =
.
以上,希望对你有所帮助