SAP与WMS之间的数据是一个非常重要且常见的企业系统集成场景。设计一个健壮、高效的WMS与SAP接口是确保后勤和财务数据同步的关键。

下面将为您详细讲解接口设计的核心理念,并以最经典、最可靠的 IDoc (Intermediate Document) 和Web Service技术为例,提供两个完整的、可操作的实例。

 第一部分:接口设计核心理念与技术选型

一个优秀的接口设计应遵循以下原则:

1.  可靠性 (Reliability):保证消息不丢失,即使一方系统宕机,恢复后也能继续处理。

2.  解耦性 (Decoupling):SAP和WMS应能独立运行。SAP的性能问题不应拖垮WMS,反之亦然。这通常意味着异步通信是首选。

3.  标准化 (Standardization):尽可能使用SAP的标准接口(如IDoc, BAPI),这能大大减少开发和维护成本,并获得SAP的支持。

4.  可监控性 (Monitoring):必须有清晰的工具来监控接口状态、追踪数据交换过程,并能轻松定位错误。

5.  错误处理与重试机制 (Error Handling & Reprocessing):必须设计完善的错误处理流程。例如,如果WMS发送的数据在SAP校验失败,如何通知WMS?如何重新发送?

技术选型对比

技术

优点

缺点

适用场景

IDoc

SAP标准、高度可靠、异步处理、支持大批量、监控工具完善(WE02, BD87)、解耦性好

配置相对复杂,需要对IDoc结构有一定了解

核心业务流程,如发货、收货、库存转移等大批量、高可靠性要求的场景。 (本次实例重点)

BAPI/RFC

实时同步调用、逻辑封装在函数中、返回即时结果

强耦合、需要WMS系统主动调用、网络中断会导致事务失败、性能开销大

实时查询或小数据量更新,如:WMS实时查询SAP的物料主数据、校验批次有效性等。

Web Service (SOAP/REST)

基于开放标准(HTTP/XML/JSON)、跨平台兼容性好

相比IDoc,SAP端的标准服务较少,很多需要定制开发。错误处理和监控需额外开发。

与云WMS或非SAP生态系统集成,需要实时交互的场景。

文件传输 (FTP/SFTP)

简单易懂,实现快速

安全性较低、无事务性保证、无标准错误处理机制、非实时

简单的、非关键的主数据批量导入/导出,或作为备用方案。

结论: 对于SAP与WMS之间的核心业务数据交换,IDoc是业界公认的最佳实践。

第二部分:完整实例 - [SAP -> WMS] 发送出库单 (Outbound Delivery)

我们将以最常见的业务场景为例:SAP创建出库单后,通过IDoc自动发送给WMS,通知WMS进行拣货发运。

 业务流程

1.  SAP用户创建销售订单 (SO)。

2.  基于SO创建出库单 (Outbound Delivery)。

3.  出库单保存时,SAP系统自动触发一个IDoc。

4.  IDoc通过中间件(如SAP PO/PI,或直接通过tRFC)发送给WMS系统。

5.  WMS接收IDoc,解析数据,并在其系统中创建相应的拣货任务。

 技术实现步骤

1. 识别标准IDoc类型

对于出库单,SAP的标准IDoc是:

   基本类型 (Basic Type): `DELVRY07` (这是最新的版本,包含了丰富的信息)

   消息类型 (Message Type): `DESADV` (Despatch Advice / 发货通知)

2. SAP系统配置 (由BASIS或顾问完成)

步骤 2.1: 创建逻辑系统 (Logical System) - `BD54`

   为WMS系统创建一个逻辑名称,例如 `WMSCLNT100`。

步骤 2.2: 创建RFC目标地址 (RFC Destination) - `SM59`

   创建一个`TCP/IP`类型的RFC Destination,指向接收IDoc的外部系统(或中间件)。

   需要指定一个`Program ID`,这个ID需要与WMS端(或中间件)的IDoc监听器配置保持一致。

步骤 2.3: 创建端口 (Port) - `WE21`

   创建一个`Transactional RFC (tRFC)`类型的端口,例如 `WMS_PORT`。

   将此端口与上一步创建的RFC目标地址关联起来。

步骤 2.4: 创建伙伴参数 (Partner Profile) - `WE20`

这是最核心的配置,它将业务对象、消息类型、接收方和端口关联起来。

   选择伙伴类型 `LS` (Logical System),创建伙伴 `WMSCLNT100`。

   在 "出站参数 (Outbound parmtrs.)" 部分,点击`+`新增条目:

       消息类型 (Message Type): `DESADV`

       接收方端口 (Receiver Port): `WMS_PORT` (上一步创建的)

       输出模式 (Output Mode): 选择 `立即传输IDoc` (Transfer IDoc immediately)。

       基本类型 (Basic Type): `DELVRY07`

3. 业务触发配置 - 输出确定 (Output Determination)

我们需要配置系统,在创建/更改出库单时自动触发`DESADV`消息。

步骤 3.1: 定义输出类型 (Output Type) - `NACE` -> Application `V2` (Shipping)

   通常使用标准输出类型 `DESA` 或复制一个新的 `ZESA`。

   在处理例程 (Processing routines) 中,指定程序 `RSNASTED` 和 FORM 例程 `EDI_PROCESSING`。这表示该输出将通过EDI/IDoc处理。

步骤 3.2: 分配给输出确定过程

   将输出类型 `DESA` (或`ZESA`) 添加到相应的输出确定过程中。这个过程与你的交货类型 (Delivery Type, e.g., `LF`) 相关联。

步骤 3.3: 创建条件记录 (Condition Record) - `VV21` / `VV22`

   为输出类型 `DESA` 创建条件记录。

   关键设置:

       交货类型 (Delivery Type): `LF` (或你使用的类型)

       合作伙伴功能 (Partner Function): `SH` (Ship-to party)

       传输介质 (Medium): `6` (EDI)

       时间 (Dispatch time): `4` (立即发送)

配置完成!

测试流程

1.  创建一个销售订单 (`VA01`)。

2.  基于该订单创建出库单 (`VL01N`)。

3.  输入所有必填信息(如拣配数量、库位等)后,点击保存。

4.  验证IDoc生成:

       进入出库单显示界面 (`VL03N`),点击 `抬头 -> 输出`,你应该能看到 `DESA` 类型的输出,状态为绿色 (已成功处理)。

       打开IDoc监控器 `WE02` 或 `WE05`。

       输入今天的日期和消息类型 `DESADV`,执行。

       你应该能看到一个新生成的IDoc,最终状态为 `03` (数据传递到端口正常)。如果状态是 `30` (IDoc 已准备好被分派),可以运行程序 `RSEOUT00` 手动发送。

 IDoc结构概览 (`DELVRY07`)

WMS系统收到的IDoc数据是结构化的,主要关注以下段 (Segment):

   `E1EDL20` (交货单抬头): 包含交货单号、交货日期、运输计划点、客户信息等。

   `E1EDL24` (交货单行项目): 包含物料号、数量、单位、批次、库存地点等。

   `E1EDL37` (交货单合作伙伴): 包含售达方、送达方等地址信息。

   `E1EDL44` (包装数据): 如果有打包操作,这里会包含HU(处理单元)信息。

WMS系统需要一个IDoc适配器来接收这个IDoc,然后解析这些段的数据,映射到自己的数据库表中。

第三部分:[WMS -> SAP] 接口设计 (以发货过账为例)

当WMS完成拣货和发货后,需要通知SAP进行库存扣减(发货过账,Goods Issue)。

业务流程

1.  WMS系统确认货物已发出。

2.  WMS系统生成一个IDoc,发送给SAP。

3.  SAP接收此IDoc,并自动对相应的出库单执行发货过账 (PGI)。

 技术实现

   IDoc类型: `SHPCON` (Shipping Confirmation) 或 `WHSCON` (Warehouse Control) 都可以用来做发货确认。`SHPCON` 更常用。

   消息类型: `SHPCON`

   处理逻辑:

       WMS系统填充 `SHPCON` IDoc,其中必须包含原始的SAP出库单号作为参照。

       SAP端的伙伴参数 `WE20` 需要配置 入站参数 (Inbound parmtrs.)。

       消息类型为 `SHPCON`,并指定处理它的 流程代码 (Process Code),例如 `DELV`。

       此流程代码关联一个标准的Function Module (`IDOC_INPUT_DELVRY`),这个FM会读取IDoc数据,并调用 `BAPI_OUTB_DELIVERY_CONFIRM_DEC` 来执行发货过账。

通过这种双向的IDoc接口设计,SAP和WMS之间的数据流形成了一个闭环,确保了业务和库存的实时同步。

下面详细介绍Web Service的集成方案。

Web Service(特别是基于REST/OData的API)是现代系统集成的重要方案,尤其适用于需要实时、跨平台、与云WMS或移动应用集成的场景。

下文会设计一个完整的、贴近实际的例子:WMS系统完成拣货后,实时调用SAP的Web Service接口,以确认出库单中的某个行项目(Picking Confirmation)。

第一部分:场景与架构设计

 业务场景

1.  SAP中已创建出库单 `80012345`,包含两个物料:A和B。

2.  WMS系统接收到该任务,操作员使用移动设备扫描并拣选了物料A。

3.  WMS系统需要立即通知SAP:“出库单`80012345`的`0010`行项目已拣配完毕,数量10个”。

4.  SAP接收此信息,并更新出库单的拣配数量。这个操作必须是实时的,以便销售部门能立即看到订单履行状态。

 技术架构

   通信协议: HTTP/S

   数据格式: JSON

   API风格: RESTful (使用SAP OData)

   SAP端技术: SAP Gateway (OData服务) + ABAP后端逻辑

   WMS端技术: 任何能发送HTTP请求的编程语言 (Python, Java, C, JavaScript等)

 第二部分:SAP端实现 (服务端/Provider)

我们将通过SAP Gateway (T-Code: `SEGW`) 创建一个OData服务来暴露业务功能。

 步骤1: 封装业务逻辑 (创建 BAPI/RFC)

虽然可以直接在OData服务中写逻辑,但最佳实践是先将业务逻辑封装在一个可重用的函数模块中。我们创建一个`Z_WM_CONFIRM_PICKING`的远程函数模块(RFC)。

T-Code: `SE37`

```abap

FUNCTION Z_WM_CONFIRM_PICKING.

"----------------------------------------------------------------------

""Local Interface:

"  IMPORTING

"     VALUE(IV_DELIVERY_NO) TYPE LIKP-VBELN

"     VALUE(IV_ITEM_NO) TYPE LIPS-POSNR

"     VALUE(IV_PICKED_QTY) TYPE LIPS-PIKMG

"  EXPORTING

"     VALUE(ES_RETURN) TYPE BAPIRET2

"----------------------------------------------------------------------

  DATA: ls_vbkok TYPE vbkok,

        lt_prot  TYPE TABLE OF prott,

        lv_vbeln_vl TYPE vbeln_vl.

  " --- 1. 参数校验 ---

  IF iv_delivery_no IS INITIAL OR iv_item_no IS INITIAL.

    es_return-type    = 'E'.

    es_return-message = 'Delivery number and item number cannot be empty'.

    RETURN.

  ENDIF.

  lv_vbeln_vl = iv_delivery_no.

  " --- 2. 锁定交货单,防止并发修改 ---

  CALL FUNCTION 'ENQUEUE_EVVBLKE'

    EXPORTING

      vbeln = lv_vbeln_vl

    EXCEPTIONS

      OTHERS = 2.

  IF sy-subrc <> 0.

    es_return-type = 'E'.

    es_return-message = |Delivery { lv_vbeln_vl } is locked by another user|.

    RETURN.

  ENDIF.

  " --- 3. 调用标准BAPI更新拣配数量 ---

  " 这是SAP中用于更改出库单的核心BAPI

  CALL FUNCTION 'BAPI_OUTB_DELIVERY_CHANGE'

    EXPORTING

      header_data    = VALUE ( deliv_numb = lv_vbeln_vl )

      header_control = VALUE ( deliv_numb = lv_vbeln_vl )

      delivery       = lv_vbeln_vl

    TABLES

      item_data      = VALUE ( ( deliv_numb = lv_vbeln_vl

                                  deliv_item = iv_item_no

                                  pick_qty = iv_picked_qty ) )

      item_control   = VALUE ( ( deliv_item = iv_item_no

                                  chg_pick_qty = 'X' ) )

      return         = es_return.

  " --- 4. 提交工作 ---

  IF es_return-type <> 'E' AND es_return-type <> 'A'.

    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'

      EXPORTING

        wait = 'X'.

    es_return-type = 'S'.

    es_return-message = |Item { iv_item_no } of delivery { lv_vbeln_vl } confirmed successfully|.

  ELSE.

    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

  ENDIF.

  " --- 5. 解锁交货单 ---

  CALL FUNCTION 'DEQUEUE_EVVBLKE'

    EXPORTING

      vbeln = lv_vbeln_vl.

ENDFUNCTION.

```

步骤2: 创建OData服务项目

T-Code: `SEGW`

1.  点击 "创建项目" (Create Project)。

2.  项目名称: `ZGW_WMS_INTEGRATION`,描述: "WMS Integration Services"。

3.  在项目下,右键点击 "数据模型" -> "导入" -> "RFC/BOR 接口"。

4.  创建实体类型 (Entity Type):

       实体类型名称: `PickingConfirmation`

       目标RFC: `Z_WM_CONFIRM_PICKING`

选择所有参数 (`IvDeliveryNo`, `IvItemNo`, `IvPickedQty`) 作为实体属性。

       取消勾选 `EsReturn`,因为我们通常通过HTTP状态码和标准OData错误格式来返回结果。

       将 `IvDeliveryNo` 标记为 Key。

5.  生成运行时对象:

       点击工具栏的 "生成运行时对象" 按钮 (小齿轮图标)。

       系统会为你生成 `_MPC` (模型提供类) 和 `_DPC` (数据提供类) 等ABAP类。

 步骤3: 实现OData服务逻辑 (将请求映射到RFC)

1.  在项目树中,展开 "服务实现" -> "PickingConfirmationSet"。

2.  右键点击 "创建 (Create)" 操作 -> "转到ABAP工作台"。

3.  系统会打开 `_DPC_EXT` 类的 `PICKINGCONFIRMA_CREATE_ENTITY` 方法。在此处编写代码。

选择所有参数 (`IvDeliveryNo`, `IvItemNo`, `IvPickedQty`) 作为实体属性。

       取消勾选 `EsReturn`,因为我们通常通过HTTP状态码和标准OData错误格式来返回结果。

       将 `IvDeliveryNo` 标记为 Key。

5.  生成运行时对象:

       点击工具栏的 "生成运行时对象" 按钮 (小齿轮图标)。

       系统会为你生成 `_MPC` (模型提供类) 和 `_DPC` (数据提供类) 等ABAP类。

 步骤3: 实现OData服务逻辑 (将请求映射到RFC)

1.  在项目树中,展开 "服务实现" -> "PickingConfirmationSet"。

2.  右键点击 "创建 (Create)" 操作 -> "转到ABAP工作台"。

3.  系统会打开 `_DPC_EXT` 类的 `PICKINGCONFIRMA_CREATE_ENTITY` 方法。在此处编写代码。

步骤4: 注册并激活服务

1.  T-Code: `/IWFND/MAINT_SERVICE`

2.  点击 "添加服务" (Add Service)。

3.  系统别名 (System Alias): `LOCAL` (或你的后端系统别名)。

4.  技术服务名称: `ZGW_WMS_INTEGRATION_SRV`。

5.  点击服务,将其添加到服务目录。

6.  返回主屏幕,确认服务已激活(ICF节点状态为绿色)。

 步骤5: 测试服务

1.  在 `/IWFND/MAINT_SERVICE` 中,选择你的服务,点击 "SAP Gateway 客户端" (SAP Gateway Client)。

2.  设置请求:

       HTTP 方法: `POST`

       请求 URI: `/sap/opu/odata/sap/ZGW_WMS_INTEGRATION_SRV/PickingConfirmationSet`

       在 HTTP 请求 body 部分,输入JSON数据:

3.  执行请求。

       成功: 你会收到 `HTTP 201 Created` 状态码,并且响应体中包含成功消息。

       失败: 你会收到 `HTTP 400 Bad Request` 状态码,响应体中包含详细的错误信息。

 第三部分:WMS端实现 (客户端/Consumer)

WMS端的开发人员现在有了一个清晰、标准的REST API可以调用。他们不需要懂任何ABAP知识。

以下是一个Python语言的调用示例:

```python

import requests

import json

from requests.auth import HTTPBasicAuth

 SAP Gateway服务器信息

SAP_HOST = "https://your.sap.gateway.server:port"

SERVICE_URI = "/sap/opu/odata/sap/ZGW_WMS_INTEGRATION_SRV/PickingConfirmationSet"

SAP_USER = "API_USER"   建议为API创建一个专用的系统用户

SAP_PASSWORD = "API_PASSWORD"

 要发送的拣配确认数据

picking_data = {

    "IvDeliveryNo": "0080012345",

    "IvItemNo": "000010",

    "IvPickedQty": "10.000"

}

 设置HTTP请求头

headers = {

    "Content-Type": "application/json",

    "Accept": "application/json",

    "X-CSRF-Token": "Fetch"  第一次请求获取CSRF令牌

}

 构建完整的URL

url = SAP_HOST + SERVICE_URI

try:

     --- Step 1: Fetch CSRF Token for security ---

    token_response = requests.get(

        url,

        auth=HTTPBasicAuth(SAP_USER, SAP_PASSWORD),

        headers=headers,

        verify=False  在生产环境中应使用正确的证书

    )

    token_response.raise_for_status()  检查是否有HTTP错误

    csrf_token = token_response.headers.get("x-csrf-token")

    if not csrf_token:

        raise Exception("Failed to fetch CSRF token.")

    print(f"Successfully fetched CSRF token: {csrf_token}")

     --- Step 2: Send the POST request with the token ---

    headers["X-CSRF-Token"] = csrf_token

    response = requests.post(

        url,

        auth=HTTPBasicAuth(SAP_USER, SAP_PASSWORD),

        headers=headers,

        data=json.dumps(picking_data),

        verify=False

    )

     检查响应状态码

    if response.status_code == 201:  201 Created表示成功

        print("Successfully confirmed picking in SAP.")

        print("Response from SAP:", response.json())

    else:

        print(f"Error occurred. Status Code: {response.status_code}")

        print("Error details:", response.json())

except requests.exceptions.RequestException as e:

    print(f"An error occurred during the HTTP request: {e}")

```

总结与对比

特性

Web Service (OData/REST)

IDoc

通信模式

同步/实时 (请求-响应)

异步/批处理 (发送后不管)

耦合度

较高 (WMS需要等待SAP的即时响应)

极低 (解耦) (SAP和WMS可独立运行)

数据格式

JSON (轻量级,易于Web和移动端解析)

SAP专有格式 (结构化,但对非SAP系统不友好)

协议

HTTP/S (开放、标准、防火墙友好)

tRFC/qRFC (SAP专有)

错误处理

即时返回HTTP错误码和消息体

需要在SAP中监控IDoc状态(WE02),并建立重处理机制

适用场景

需要即时反馈的业务操作,如状态查询、单笔确认、与云/移动应用集成。

大批量、可靠性要求极高、无需即时反馈的核心后台流程,如批量发货、收货。

这个Web Service的例子展示了如何为现代化的WMS系统提供一个标准、实时、易于集成的接口。

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐