BAPI测试时发现 item_data_spl塞入库存地运行时无效,这个BAPI需要执行两次才能正确写入库存地,代码实现如下。
DATA:gs_header TYPE ZC80_SDIF006_2_IN_S_HEAD.
"交货单BAPI有关参数
DATA: lv_delivery TYPE bapishpdelivnumb-deliv_numb,
lv_num_deliveries TYPE bapidlvcreateheader-num_deliveries.
DATA: lt_stock_trans_items TYPE TABLE OF bapidlvreftosto,
lt_sales_order_items TYPE TABLE OF bapidlvreftosalesorder,
ls_sales_order_items TYPE bapidlvreftosalesorder,
lt_created_items TYPE TABLE OF bapidlvitemcreated.
DATA: lv_vstel LIKE tvst-vstel. "装运点/接收点
DATA: lt_return TYPE TABLE OF bapiret2 WITH HEADER LINE,
ls_return TYPE bapiret2.
DATA: lv_error TYPE char1,
lv_str TYPE string.
DATA: lt_log TYPE TABLE OF ZC80SDIF005E,
ls_Log TYPE ZC80SDIF005E.
DATA: lt_lips TYPE TABLE OF lips,
ls_lips TYPE lips.
DATA:ls_vbkok TYPE vbkok.
DATA: ls_out TYPE zc80_sdif006_2_out_s.
DATA: lt_header_data LIKE TABLE OF bapiobdlvhdrchg WITH HEADER LINE. "delivery header
DATA: lt_header_control LIKE TABLE OF bapiobdlvhdrctrlchg WITH HEADER LINE. "delivery header control
DATA: i_delivery_no LIKE bapiobdlvhdrchg-deliv_numb. "deliver number
DATA: lt_techn_control LIKE bapidlvcontrol. "lt_techn_control
DATA: lt_item_data LIKE bapiobdlvitemchg OCCURS 0 WITH HEADER LINE. "lt_item_data delivery item
DATA: lt_item_control LIKE bapiobdlvitemctrlchg OCCURS 0 WITH HEADER LINE. "item_control
DATA: lt_item_data_spl LIKE /spe/bapiobdlvitemchg OCCURS 0 WITH HEADER LINE.
DATA: vbkok_wa TYPE vbkok,
vbpok_tab TYPE vbpok OCCURS 0 WITH HEADER LINE,
lt_prot TYPE TABLE OF prott WITH HEADER LINE,
xlips TYPE lips OCCURS 0 WITH HEADER LINE .
DATA: lt_str_msg TYPE TABLE OF string WITH HEADER LINE.
DATA:lv_posnr TYPE lips-posnr VALUE '900000'.
DATA:lv_lfdat TYPE likp-lfdat.
DATA:BEGIN OF lt_vbap OCCURS 0,
vbeln TYPE vbap-vbeln,
posnr TYPE vbap-posnr,
meins TYPE vbap-meins,
END OF lt_vbap.
CHECK gt_header[] IS NOT INITIAL.
SELECT
vbeln
posnr
meins
FROM vbap
INTO TABLE lt_vbap
FOR ALL ENTRIES IN gt_head
WHERE vbeln = gt_head-vbeln.
"根据SO创建交货单
LOOP AT gt_header INTO gs_header.
ls_sales_order_items-ref_doc = gs_header-vbeln. "参考销售订单
ls_sales_order_items-ref_item = gs_header-posnr. "参考销售订单项目
ls_sales_order_items-dlv_qty = gs_header-lfimg. "交货数量
*->获取销售订单单位作为交货单单位
READ TABLE lt_vbap WITH KEY
vbeln = gs_header-vbeln.
IF sy-subrc EQ 0.
ls_sales_order_items-sales_unit = lt_vbap-meins.
ENDIF.
lv_vstel = gs_header-vstel.
lv_lfdat = gs_header-lfdat.
APPEND ls_sales_order_items TO lt_sales_order_items.
ENDLOOP.
"对SO的交货单
CALL FUNCTION 'BAPI_OUTB_DELIVERY_CREATE_SLS'
EXPORTING
ship_point = lv_vstel
due_date = lv_lfdat
* DEBUG_FLG =
* NO_DEQUEUE = ''
IMPORTING
delivery = lv_delivery
num_deliveries = lv_num_deliveries
TABLES
sales_order_items = lt_sales_order_items
* serial_numbers =
* extension_in =
* deliveries =
* created_items =
* extension_out =
return = lt_return.
CLEAR lv_error.
LOOP AT lt_return INTO ls_return
WHERE type CA 'AEX'.
IF sy-subrc EQ 0.
lv_error = 'X'.
ENDIF.
ENDLOOP.
IF lv_error = 'X'.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
LOOP AT lt_return INTO ls_return.
IF lv_str IS INITIAL.
lv_str = ls_return-message.
ELSE.
CONCATENATE lv_str ls_return-message INTO lv_str.
ENDIF.
ENDLOOP.
*->输出消息参数并更新LOG TABLE
LOOP AT gt_header INTO gs_header.
"更新LOG TABLE
MOVE-CORRESPONDING gs_header TO ls_log.
ls_log-type = 'E'.
ls_log-message = lv_str.
ls_log-cssj = sy-uzeit.
ls_log-csrq = sy-datum.
APPEND ls_log TO lt_log.
"输出消息
MOVE-CORRESPONDING gs_header TO ls_out.
ls_out-type = 'E'.
ls_out-message = lv_str.
ls_out-erzet = sy-uzeit.
ls_out-erdat = sy-datum.
APPEND ls_out TO gt_out.
ENDLOOP.
MODIFY zc80sdif005e FROM TABLE lt_log.
IF sy-subrc EQ 0.
COMMIT WORK.
ELSE.
ROLLBACK WORK.
ENDIF.
RETURN.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
WAIT = 'X'.
i_delivery_no = lv_delivery.
SELECT *
INTO TABLE lt_lips
FROM lips
WHERE vbeln = lv_delivery.
*首先做批次拆分,修改批次和库存地点
lt_header_data-deliv_numb = lv_delivery.
lt_header_control-deliv_numb = lv_delivery.
APPEND lt_header_data.
APPEND lt_header_control.
LOOP AT lt_lips INTO ls_lips.
*->原项目
lt_item_data-deliv_numb = ls_lips-vbeln.
lt_item_data-deliv_item = ls_lips-posnr.
lt_item_data-hieraritem = ls_lips-posnr. "the batch split record below delivery item hierary
lt_item_data-usehieritm = '1'.
* lt_item_data-dlv_qty = ls_lips-lfimg.
* lt_item_data-dlv_qty_imunit = 1.
lt_item_data-base_uom = 'Z09'.
lt_item_data-sales_unit = 'Z09'.
lt_item_data-fact_unit_nom = 1.
lt_item_data-fact_unit_denom = 1.
APPEND lt_item_data.
CLEAR lt_item_data.
lt_item_control-deliv_numb = ls_lips-vbeln.
lt_item_control-deliv_item = ls_lips-posnr.
lt_item_control-chg_delqty = 'X'.
APPEND lt_item_control.
CLEAR lt_item_control.
*-》新项目新拆分的批次
LOOP AT gt_header INTO gs_header WHERE vbeln = ls_lips-vgbel
AND posnr = ls_lips-vgpos. "参考的销售订单号与项目
CLEAR lt_item_data.
ADD 1 TO lv_posnr.
lt_item_data-deliv_numb = lv_delivery. "交货单号
lt_item_data-deliv_item = lv_posnr. "拆分后的新行项目
lt_item_data-hieraritem = gs_header-posnr. "上级行项目
lt_item_data-batch = gs_header-charg. "新批次
lt_item_data-dlv_qty = gs_header-lfimg. "自己重新计算拆分后的数量,
* lt_item_data-dlv_qty_imunit = 1.
lt_item_data-fact_unit_nom = 1. "销售数量转换成SKU的分子(因子)
lt_item_data-fact_unit_denom = 1. "销售数量转换为 SKU 的值(除数)
lt_item_data-base_uom = 'Z09'. "基本单位
lt_item_data-sales_unit = 'Z09'. "销售单位
lt_item_data-usehieritm = '1'.
APPEND lt_item_data.
lt_item_control-deliv_numb = lv_delivery.
lt_item_control-deliv_item = lv_posnr.
lt_item_control-chg_delqty = 'X'.
APPEND lt_item_control.
CLEAR lt_item_control.
ENDLOOP.
ENDLOOP.
*->交货单创建成功后需要通过修改写入批次
CALL FUNCTION 'BAPI_OUTB_DELIVERY_CHANGE'
EXPORTING
header_data = lt_header_data
header_control = lt_header_control
delivery = i_delivery_no
techn_control = lt_techn_control
TABLES
item_data = lt_item_data
item_control = lt_item_control
item_data_spl = lt_item_data_spl
RETURN = lt_return.
IF sy-subrc EQ 0.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
WAIT = 'X'.
*->调用成功后需要再次调用BAPI修改库存地点
lv_posnr = '900000'.
*-》新项目新拆分的批次
LOOP AT lt_lips INTO ls_lips.
lt_item_data_spl-deliv_numb = ls_lips-vbeln.
lt_item_data_spl-deliv_item = ls_lips-posnr.
lt_item_data_spl-stge_loc = gs_header-lgort. "库存地点
APPEND lt_item_data_spl.
CLEAR lt_item_data_spl.
LOOP AT gt_header INTO gs_header WHERE vbeln = ls_lips-vgbel
AND posnr = ls_lips-vgpos. "参考的销售订单号与项目
CLEAR lt_item_data.
ADD 1 TO lv_posnr.
lt_item_data_spl-deliv_numb = lv_delivery.
lt_item_data_spl-deliv_item = lv_posnr.
lt_item_data_spl-stge_loc = gs_header-lgort. "库存地点
APPEND lt_item_data_spl.
CLEAR lt_item_data_spl.
ENDLOOP.
ENDLOOP.
CLEAR lt_return[].
CALL FUNCTION 'BAPI_OUTB_DELIVERY_CHANGE'
EXPORTING
header_data = lt_header_data
header_control = lt_header_control
delivery = i_delivery_no
TABLES
item_data = lt_item_data
item_control = lt_item_control
item_data_spl = lt_item_data_spl
RETURN = lt_return.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
WAIT = 'X'.
ELSE.
* LOOP AT lt_return WHERE TYPE CA 'AEX'.
* IF ov_message IS INITIAL.
* ov_message = lt_return-MESSAGE.
* ELSE.
* ov_message = ov_message && '/' && lt_return-MESSAGE.
* ENDIF.
* ENDLOOP.
* ov_error = 'X'.
RETURN.
ENDIF.
ENDIF.