BAPI_GOODSMVT_CREATE to post Goods Movement

使用BAPI处理采购订单收货
本文介绍了一个ABAP程序示例,该程序利用BAPI函数BAPI_GOODSMVT_CREATE来处理从外部系统导入的数据,并针对采购订单完成收货流程。

The following is an abap program making used of the BAPI function BAPI_GOODSMVT_CREATE to do Goods Receipts for Purchase Order after importing the data from an external system.

*
* BAPI TO Upload Inventory Data
*
* GMCODE Table T158G - 01 - MB01 - Goods Receipts for Purchase Order
*                      02 - MB31 - Goods Receipts for Prod Order
*                      03 - MB1A - Goods Issue
*                      04 - MB1B - Transfer Posting
*                      05 - MB1C - Enter Other Goods Receipt
*                      06 - MB11
*
* Domain: KZBEW - Movement Indicator
*      Goods movement w/o reference
*  B - Goods movement for purchase order
*  F - Goods movement for production order
*  L - Goods movement for delivery note
*  K - Goods movement for kanban requirement (WM - internal only)
*  O - Subsequent adjustment of "material-provided" consumption
*  W - Subsequent adjustment of proportion/product unit material
<think>我们正在讨论如何使用ABAP BAPI_GOODSMVT_CREATE创建委外采购订单的收货。根据引用[1]和[2],我们知道BAPI_GOODSMVT_CREATE用于创建货物移动,包括采购订单收货。特别地,引用[2]指出GM_CODE参数为'01'时对应采购订单的过帐收货(TCODE MB01)。委外采购订单的收货也属于采购订单收货的一种,因此我们可以使用相同的BAPI,但需要注意委外加工的特殊性(如消耗的组件和收货的成品)。 委外加工采购订单收货时,通常涉及两个方面的移动: 1. 成品的收货(从委外供应商接收成品) 2. 组件的消耗(消耗发往供应商的组件库存) 在标准SAP中,委外采购订单收货通常使用移动类型101(收货)和相应的反冲移动类型(如543对组件的消耗)。在同一个货物移动中,我们可以同时过账成品的收货和组件的消耗。 使用BAPI_GOODSMVT_CREATE创建委外采购订单收货的步骤: 1. 准备表头数据(GOODSMVT_HEADER) - 必须指定过账日期(PSTNG_DATE)、凭证日期(DOC_DATE)和移动类型(移动类型在行项目中指定,但表头可以指定一些默认值?注意:实际上移动类型在行项目中指定,表头中有一个字段REF_DOC_NO可以填写采购订单号,但并不是必须的,因为行项目会关联采购订单行) - 特别注意:GM_CODE 设置为 '01'(采购订单收货) - 其他字段如BLART(凭证类型)等根据业务需求填写 2. 准备行项目数据(GOODSMVT_ITEM 表) - 对于成品收货: ENTRY_QNT: 收货数量 MOVE_TYPE: 101(标准采购订单收货) PO_NUMBER: 委外采购订单号 PO_ITEM: 采购订单行项目号 MATERIAL: 成品物料号 VENDOR: 供应商(可选,因为采购订单中已有) STGE_LOC: 库存地点(收货) ... 其他必要字段 - 对于组件消耗(反冲): ENTRY_QNT: 消耗数量(负数) MOVE_TYPE: 543(委外加工消耗) MATERIAL: 组件物料号 STGE_LOC: 组件消耗的库存地点(通常为委外加工库存地点) ... 其他必要字段 **注意:** 组件消耗的行需要与成品收货行关联在同一张凭证中,并且需要指定反冲的关联(如通过采购订单行和物料号关联)。在标准委外流程中,组件的消耗是自动根据BOM反冲的,因此我们只需要在BAPI中同时提供这两类行项目即可。 3. 调用BAPI 调用BAPI_GOODSMVT_CREATE,传入表头数据和行项目表,并接收返回的凭证号(MATERIALDOCUMENT)和会计年度(MATDOCUMENTYEAR)。 4. 检查返回值 检查BAPI返回的消息,如果有错误则进行相应处理。 注意:在实际操作中,委外采购订单的收货通常通过移动类型101(收货)和543(消耗)在同一个物料凭证中完成。在调用BAPI时,我们需要为每个移动(成品收货和每个组件的消耗)分别创建一个行项目。 但是,请注意,组件的消耗数量通常由系统根据BOM自动计算。在调用BAPI时,我们是否需要显式指定每个组件的消耗?这取决于系统配置。在标准流程中,我们通常只指定成品的收货数量,系统会自动反冲组件。然而,在BAPI调用中,我们必须明确提供所有行项目(包括组件消耗行)。因此,我们需要在调用BAPI之前计算组件的消耗数量(根据BOM和收货数量)。 另一种做法是使用移动类型101(只针对成品),并让系统自动产生反冲凭证(这通常是在后台配置中设置的)。但根据BAPI_GOODSMVT_CREATE的文档,我们需要在同一个调用中提供所有的行项目,包括组件的消耗行。 因此,步骤总结如下: a. 读取委外采购订单,获取需要收货的成品行项目。 b. 根据BOM计算该成品收货数量对应的组件消耗数量。 c. 构建行项目: - 一行用于成品收货(移动类型101) - 每个组件一行(移动类型543,数量为负,库存地点为委外库存地点) 示例代码结构: ```abap DATA: lt_goodsmvt_item TYPE TABLE OF bapi2017_gm_item_create, ls_goodsmvt_item LIKE LINE OF lt_goodsmvt_item, ls_goodsmvt_header TYPE bapi2017_gm_head_01, ls_goodsmvt_code TYPE bapi2017_gm_code, lv_matdoc TYPE bapi2017_gm_head_ret-mat_doc, lv_matdocyear TYPE bapi2017_gm_head_ret-doc_year, lt_return TYPE TABLE OF bapiret2. * 设置表头数据 ls_goodsmvt_header-pstng_date = sy-datum. "过账日期 ls_goodsmvt_header-doc_date = sy-datum. "凭证日期 ls_goodsmvt_header-ref_doc_no = '委外采购订单号'. "可选 * 设置移动代码(采购订单收货) ls_goodsmvt_code-gm_code = '01'. * 成品收货行 ls_goodsmvt_item-material = '成品物料号'. ls_goodsmvt_item-plant = '工厂'. ls_goodsmvt_item-stge_loc = '库存地点'. "成品收货库存地点 ls_goodsmvt_item-move_type = '101'. "采购订单收货 ls_goodsmvt_item-entry_qnt = 收货数量. ls_goodsmvt_item-po_number = '委外采购订单号'. ls_goodsmvt_item-po_item = '采购订单行项目号'. ls_goodsmvt_item-mvt_ind = 'B'. "采购订单相关移动 APPEND ls_goodsmvt_item TO lt_goodsmvt_item. CLEAR ls_goodsmvt_item. * 组件消耗行(假设有多个组件) LOOP AT 组件列表 INTO 组件. ls_goodsmvt_item-material = 组件-物料号. ls_goodsmvt_item-plant = '工厂'. ls_goodsmvt_item-stge_loc = '组件库存地点'. "通常为委外库存地点 ls_goodsmvt_item-move_type = '543'. "委外加工消耗 ls_goodsmvt_item-entry_qnt = -组件消耗数量. "负数表示消耗 ls_goodsmvt_item-po_number = '委外采购订单号'. ls_goodsmvt_item-po_item = '采购订单行项目号'. "注意:这里通常指向同一个采购订单行(即成品行)?实际上,组件的消耗与成品行关联,但采购订单行项目号应该是成品行的行号。 ls_goodsmvt_item-mvt_ind = 'B'. "采购订单相关移动 APPEND ls_goodsmvt_item TO lt_goodsmvt_item. CLEAR ls_goodsmvt_item. ENDLOOP. * 调用BAPI CALL FUNCTION 'BAPI_GOODSMVT_CREATE' EXPORTING goodsmvt_header = ls_goodsmvt_header goodsmvt_code = ls_goodsmvt_code IMPORTING goodsmvt_headret = ls_headret materialdocument = lv_matdoc matdocumentyear = lv_matdocyear TABLES goodsmvt_item = lt_goodsmvt_item return = lt_return. * 检查返回值 READ TABLE lt_return WITH KEY type = 'E' TRANSPORTING NO FIELDS. IF sy-subrc = 0. "有错误,需要回滚并显示错误 CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. "处理错误消息 ELSE. "提交更改 CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'. "成功,lv_matdoc和lv_matdocyear包含物料凭证号和年度 ENDIF. ``` 注意:上述代码仅为示例,实际应用中需要根据具体业务调整。特别是组件的消耗数量计算需要根据BOM展开,并且确保采购订单是委外类型(具有组件分配)。 另外,在行项目中,我们通过PO_NUMBER和PO_ITEM关联采购订单,并且移动类型101和543都指向同一个采购订单行(即成品行)。在委外采购订单中,组件分配在采购订单的组件分配标签中,因此系统在收货时会自动反冲,但在BAPI中我们需要显式指定这些行。 关于组件的PO_ITEM:实际上,在采购订单中,组件并不在采购订单行项目中,而是在采购订单的组件分配中(如表RESB)。因此,在行项目中,我们仍然使用成品的采购订单行项目号。系统会根据物料和采购订单行自动匹配组件。 最后,务必注意权限和错误处理。 参考文献: [^1]: SAP_ABAP_MM_BAPI清单案例教程——采购订单收货_BAPI_GOODSMVT_CREATE_MIGO [^2]: SAP ABAP BAPI_GOODSMVT_CREATEGOODSMVT_CODE GM_CODE参数 §§相关问题§§ 1. 如何计算委外加工收货时组件的消耗数量? 2. BAPI_GOODSMVT_CREATE调用时出现错误如何排查? 3. 委外采购订单和普通采购订单在收货BAPI调用上有哪些区别?</think>### 使用ABAP BAPI_GOODSMVT_CREATE创建委外采购订单收货 在SAP系统中,委外加工采购订单的收货操作涉及特殊处理,需要同时记录成品收货和组件消耗。以下是使用`BAPI_GOODSMVT_CREATE`创建委外采购订单收货的详细步骤: #### 核心参数说明 1. **GOODSMVT_HEADER**(表头数据): - `PSTNG_DATE`:过账日期(必填) - `DOC_DATE`:凭证日期(必填) - `REF_DOC_NO`:采购订单号(委外订单号) 2. **GOODSMVT_CODE**(移动类型标识): - `GM_CODE = '01'`:对应采购订单收货(MB01事务码)[^2] 3. **GOODSMVT_ITEM**(行项目数据): - **成品收货行**: - `MATERIAL`:成品物料号 - `MOVE_TYPE = '101'`:标准收货移动类型 - `ENTRY_QNT`:收货数量 - `PO_NUMBER`:采购订单号 - `PO_ITEM`:采购订单行号 - **组件消耗行**: - `MATERIAL`:组件物料号 - `MOVE_TYPE = '543'`:委外加工消耗移动类型 - `ENTRY_QNT`:负消耗数量(例如:-100) - `PO_NUMBER`:采购订单号 - `PO_ITEM`:关联的订单行号 #### ABAP代码示例 ```abap DATA: lt_item TYPE TABLE OF bapi2017_gm_item_create, ls_header TYPE bapi2017_gm_head_01, ls_code TYPE bapi2017_gm_code, lt_return TYPE TABLE OF bapiret2. * 设置表头参数 ls_header-pstng_date = sy-datum. "过账日期 ls_header-doc_date = sy-datum. "凭证日期 ls_header-ref_doc_no = '4500001234'. "委外采购订单号 * 设置移动类型标识 ls_code-gm_code = '01'. "采购订单收货 * 成品收货行(移动类型101) APPEND VALUE #( material = 'F-100' "成品物料 plant = '1000' "工厂 stge_loc = '0001' "库存地点 move_type = '101' "收货移动类型 entry_qnt = 100 "收货数量 po_number = '4500001234' po_item = '00010' "采购订单行号 ) TO lt_item. * 组件消耗行(移动类型543) APPEND VALUE #( material = 'C-200' "组件物料 plant = '1000' "工厂 stge_loc = '5000' "委外库存地点 move_type = '543' "委外消耗移动类型 entry_qnt = -100 "消耗数量(负值) po_number = '4500001234' po_item = '00010' "关联的订单行号 ) TO lt_item. * 调用BAPI创建货物移动 CALL FUNCTION 'BAPI_GOODSMVT_CREATE' EXPORTING goodsmvt_header = ls_header goodsmvt_code = ls_code IMPORTING materialdocument = lv_matdoc "返回物料凭证号 TABLES goodsmvt_item = lt_item return = lt_return. * 检查执行结果 IF NOT line_exists( lt_return[ type = 'E' ] ). CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = abap_true. WRITE: '物料凭证', lv_matdoc, '创建成功'. ELSE. CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. "处理错误消息 ENDIF. ``` #### 关键注意事项 1. **组件消耗处理**: - 必须使用移动类型`543`记录组件消耗 - 数量必须为**负值**表示库存减少 - 组件库存地点需设置为委外加工专用库位 2. **凭证一致性**: - 所有行项目的`PO_NUMBER`必须相同 - 组件消耗行的`PO_ITEM`需关联到成品行号 3. **错误处理**: - 始终检查`RETURN`表内的消息 - 错误时调用`BAPI_TRANSACTION_ROLLBACK`回滚 4. **特殊配置**: - 确保工厂的委外加工标识已激活 - 组件物料需维护反冲标志 > 注:委外加工收货需同时处理成品和组件,这与普通采购订单(仅需移动类型101)有本质区别[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值