问题背景
有客户提出需求,由于业务管理要求,希望在创建外向交货单时能够自动检查交货单行项目物料的库存数量是否充足。具体来说,当外向交货单创建保存时,需要检查交货单对应的销售订单行项目物料数量是否大于物料库存数量,如果库存数量不足,则增加一个 Warning 提示该物料库存数量不足。同时,客户希望在使用 API 创建外向交货单时,也能看到对应的 Message。
解决方案
尝试通过自定义逻辑,使用两个 BAdI 的组合方案来满足需求。
分析步骤
1. 确认适用的 BAdI 增强点
首先,我们需要找到合适的 BAdI 增强点来实现库存检查功能。经过分析,发现增强点 LE_SHP_DELIVERY_FINAL_CHECK 可以在交货单保存之前执行最终检查。因此,可以通过这个 BAdI 实现在前台 APP 创建外向交货单时,如果库存数量不足,返回 Warning 消息提醒。
2. 实现前台 APP 的 Warning 提醒
在 BAdI LE_SHP_DELIVERY_FINAL_CHECK 中实现基本的库存检查逻辑:
CONSTANTS:
lc_plant TYPE werks_d VALUE '1310',
lc_vkorg TYPE vkorg VALUE '1310',
lc_vtweg TYPE vtweg VALUE '20',
lc_spart TYPE spart VALUE '00'.
DATA:
lv_so_qty TYPE menge_d,
lv_stock TYPE menge_d.
IF documentprocessingmode="CREATE".
LOOP AT delivery_document_items_in INTO DATA(ls_item) .
IF ls_item-plant = lc_plant.
" 读取销售订单行项目的订单数量
SELECT SINGLE orderquantity
FROM i_salesorderitem
WHERE salesorder = @LS_item-referencesddocument
AND salesorderitem = @LS_item-referencesddocumentitem
INTO @LV_so_qty.
" 读取物料的库存数量
SELECT SINGLE MATLWRHSSTKQTYINMATLBASEUNIT
FROM I_STOCKQUANTITYCURRENTVALUE_2( P_DisplayCurrency = 'CNY' )
WHERE PRODUCT = @LS_item-MATERIAL
INTO @LV_stock.
IF sy-subrc <> 0.
CONTINUE. " No SO item found – skip this delivery item
ENDIF.
IF lv_stock < lv_so_qty.
message-messagetype="W". " saving of the delivery document will be warned
message-messagetext = |Warning: 该物料库存数量不足|.
EXIT.
ENDIF.
ENDIF.
ENDLOOP.
ENDIF.3. 发现 API 场景的局限性
但是这里的 Warning Message 只能在前台 APP 显示,API 创建的情况下无法看到 Message。因此需要通过替代方案实现。
4. 实现 API 场景的消息提示
为了让 API 创建场景也能看到提示信息,我们采用以下方案:
方案说明:
– 创建一个自定义字段,这个字段可以在 API Response 里看到。我们创建了一个自定义字段
– 使用 BAdI LE_SHP_SAVE_DOCUMENT_PREPARE,这个 BAdI 可以修改表头和行项目级别的标准字段和自定义字段
– 该 BAdI 将在交货单保存到数据库之前被调用
实现代码:
IF DOCUMENTPROCESSINGMODE = 'CREATE'.
CONSTANTS:
lc_plant TYPE werks_d VALUE '1310',
lc_vkorg TYPE vkorg VALUE '1310',
lc_vtweg TYPE vtweg VALUE '20',
lc_spart TYPE spart VALUE '00'.
DATA:
lv_so_qty TYPE menge_d,
lv_stock TYPE menge_d.
" -------------------------------------------------------
" Step 1: 必须先将输入完整复制到输出(Cloud BAdI 标准做法)
" -------------------------------------------------------
move-corresponding delivery_document_in to delivery_document_out.
delivery_document_items_out = delivery_document_items_in.
" -------------------------------------------------------
" Step 2: 表头组织数据过滤
" 仅对 Sales Org 1310 / DC 20 / Division 00 生效
" -------------------------------------------------------
*CHECK delivery_document_in-salesorganization = lc_vkorg.
" -------------------------------------------------------
" Step 3: 遍历交货单行项目
" -------------------------------------------------------
LOOP AT delivery_document_items_in INTO DATA(ls_item).
" 跳过无参考销售订单的行项目
* CHECK ls_item-referencesddocument IS NOT INITIAL.
* CHECK ls_item-referencesddocumentitem IS NOT INITIAL.
" 读取销售订单行项目的订单数量
SELECT SINGLE orderquantity
FROM i_salesorderitem
WHERE salesorder = @LS_item-referencesddocument
AND salesorderitem = @LS_item-referencesddocumentitem
INTO @LV_so_qty.
" 读取物料的库存数量
SELECT SINGLE MATLWRHSSTKQTYINMATLBASEUNIT
FROM I_STOCKQUANTITYCURRENTVALUE_2( P_DisplayCurrency = 'CNY' )
WHERE PRODUCT = @LS_item-MATERIAL
INTO @LV_stock.
IF sy-subrc <> 0.
CONTINUE. " 未找到对应销售订单行项目,跳过
ENDIF.
" 比较库存数量与销售订单数量
IF lv_stock < lv_so_qty.
" 更新自定义字段
DELIVERY_DOCUMENT_OUT-yy1_message_dlh="Warning: 该物料库存数量不足。".
ENDIF.
ENDLOOP.
ENDIF.5. 使用到的 CDS View
在实现过程中,我们使用了以下 CDS View 来获取所需的数据:
– I_SalesOrderItem: 用于获取销售订单行项目的订单数量,通过销售订单号和行项目号进行查询
– I_StockQuantityCurrentValue_2: 用于获取物料的当前库存数量,提供了物料在不同存储地点的实时库存信息,非常适合用于库存检查场景
6. 测试验证
测试后,上述代码可以满足需求:
– 在前台 APP 创建外向交货单时,如果库存不足,会显示 Warning 消息
– 通过 API 创建外向交货单时,自定义字段的值被更改,可以在 Response 的自定义字段中看到库存不足的提示信息
结语
通过阅读本文以及之前写过的几篇相似场景的 Blog,希望您已知晓在创建外向交货单时,如何通过自定义逻辑来实现库存数量检查并在不同场景下返回相应的提示消息。
关注以下链接可以看到更多有关 SAP S/4HANA Cloud 销售相关的问题和博文:SAP S/4HANA Cloud Public Edition Sales – SAP Community
如果您对本文有任何的建议和想法,欢迎在评论区提出,期待与您一起交流。也欢迎您关注我的个人账号,期待我们在下一篇博文再见!



