# Batch Master Record

> **API 名称**: Batch Master Record
> **服务标识**: `API_BATCH_SRV`
> **版本**: 1.3.0
> **状态**: ACTIVE
> **协议**: OData V2
> **API 地址**: [API_BATCH_SRV](https://api.sap.com/api/API_BATCH_SRV/overview)
> **通信场景**: Batch Management OData Integration (SAP_COM_0337)
> **业务对象**: Batch

---

## 功能说明

This synchronous inbound API enables you to create, change and read batches. Additionally, it is possible to retrieve and edit the related classification data. The service is based on the OData protocol and can be consumed by external systems and user interfaces.

此同步入站 API 允许您创建、更改和读取批次。此外，还可以检索和编辑相关的分类数据。

**主要业务场景:**
- 查询批次主记录（按物料、工厂、批次号）
- 创建新批次（含基本数据和分类数据）
- 更新批次属性（有效期、供应商、原产地等）
- 管理批次分类特征值
- 管理批次文本
- 批次库存状态管理

---

## 实体定义

### 实体概览

| # | 实体 | 描述 | 类型 |
|---|------|------|------|
| 1 | `A_Batch` | 批次主记录 | 核心实体 |
| 2 | `A_BatchCharacteristic` | 批次特征（分类数据） | 依赖实体 |
| 3 | `A_BatchCharacteristicValue` | 批次特征值 | 依赖实体 |
| 4 | `A_BatchClass` | 批次分类分配 | 依赖实体 |
| 5 | `A_BatchPlant` | 批次工厂数据 | 依赖实体 |
| 6 | `A_BatchText` | 批次文本 | 依赖实体 |

### 实体关系图 (ERD)

```
A_Batch (1)
    ├── A_BatchCharacteristic (N)
    │      └── A_BatchCharacteristicValue (N)
    ├── A_BatchClass (1)
    ├── A_BatchPlant (N)
    └── A_BatchText (N)
```

**导航属性:**

| 源实体 | 导航属性 | 目标实体 | 多重性 |
|--------|----------|----------|--------|
| `A_Batch` | `to_BatchCharc` | `A_BatchCharacteristic` | 0..N |
| `A_Batch` | `to_BatchClass` | `A_BatchClass` | 0..1 |
| `A_Batch` | `to_BatchPlant` | `A_BatchPlant` | 0..N |
| `A_Batch` | `to_BatchText` | `A_BatchText` | 0..N |
| `A_BatchCharacteristic` | `to_BatchCharcValue` | `A_BatchCharacteristicValue` | 0..N |
| `A_BatchCharacteristic` | `to_Batch` | `A_Batch` | 1 |
| `A_BatchCharacteristicValue` | `to_BatchCharc` | `A_BatchCharacteristic` | 1 |
| `A_BatchClass` | `to_Batch` | `A_Batch` | 1 |

---

### 1. A_Batch（批次主记录）

**主键:** `Material`, `BatchIdentifyingPlant`, `Batch`

> SAP EDM 实体类型: `BatchType` | 集合: `A_Batch`

| 字段 | 描述 | 类型 | 长度 | 可空 | 示例 |
|------|------|------|------|------|------|
| `Material` | 物料号 | `Edm.String` | 18 | N | `TG21` |
| `BatchIdentifyingPlant` | 工厂（批次标识工厂） | `Edm.String` | 4 | N | `PL01` |
| `Batch` | 批次号 | `Edm.String` | 10 | N | `0000000003` |
| `BatchIsMarkedForDeletion` | 删除标记 | `Edm.Boolean` | - | Y | `false` |
| `MatlBatchIsInRstrcdUseStock` | 限制使用库存标记 | `Edm.Boolean` | - | Y | `false` |
| `Supplier` | 供应商编号 | `Edm.String` | 10 | Y | `10000001` |
| `BatchBySupplier` | 供应商批次号 | `Edm.String` | 15 | Y | `SUPP-BATCH-001` |
| `CountryOfOrigin` | 原产国 | `Edm.String` | 3 | Y | `DE` |
| `RegionOfOrigin` | 原产地（地区） | `Edm.String` | 3 | Y | `BW` |
| `MatlBatchAvailabilityDate` | 批次可用日期 | `Edm.DateTimeOffset` | - | Y | `2024-01-15T00:00:00Z` |
| `ShelfLifeExpirationDate` | 保质期到期日 | `Edm.DateTimeOffset` | - | Y | `2025-01-15T00:00:00Z` |
| `ManufactureDate` | 生产日期 | `Edm.DateTimeOffset` | - | Y | `2024-01-10T00:00:00Z` |
| `FreeDefinedDate1` | 自定义日期 1 | `Edm.DateTimeOffset` | - | Y | `2024-06-01T00:00:00Z` |
| `FreeDefinedDate2` | 自定义日期 2 | `Edm.DateTimeOffset` | - | Y | `2024-12-01T00:00:00Z` |
| `FreeDefinedDate3` | 自定义日期 3 | `Edm.DateTimeOffset` | - | Y | `2025-06-01T00:00:00Z` |
| `FreeDefinedDate4` | 自定义日期 4 | `Edm.DateTimeOffset` | - | Y | `2025-12-01T00:00:00Z` |
| `FreeDefinedDate5` | 自定义日期 5 | `Edm.DateTimeOffset` | - | Y | `2026-01-01T00:00:00Z` |
| `FreeDefinedDate6` | 自定义日期 6 | `Edm.DateTimeOffset` | - | Y | `2026-06-01T00:00:00Z` |
| `CreationDateTime` | 创建日期时间 | `Edm.DateTimeOffset` | - | Y | `2024-01-10T10:30:00Z` |
| `LastChangeDateTime` | 最后更改日期时间 | `Edm.DateTimeOffset` | - | Y | `2024-01-15T14:00:00Z` |
| `BatchExtWhseMgmtInternalId` | 外部仓库管理内部 ID | `Edm.Guid` | - | Y | `a1b2c3d4-e5f6-7890-abcd-ef1234567890` |

**导航属性:**
- `to_BatchCharc` → `A_BatchCharacteristic[]`
- `to_BatchClass` → `A_BatchClass`
- `to_BatchPlant` → `A_BatchPlant[]`
- `to_BatchText` → `A_BatchText[]`

---

### 2. A_BatchCharacteristic（批次特征）

**主键:** `Material`, `BatchIdentifyingPlant`, `Batch`, `CharcInternalID`

> SAP EDM 实体类型: `BatchCharcType` | 集合: `A_BatchCharc`

| 字段 | 描述 | 类型 | 长度 | 可空 |
|------|------|------|------|------|
| `Material` | 物料号 | `Edm.String` | 18 | N |
| `BatchIdentifyingPlant` | 工厂 | `Edm.String` | 4 | N |
| `Batch` | 批次号 | `Edm.String` | 10 | N |
| `CharcInternalID` | 特征内部 ID | `Edm.String` | 10 | N |
| `CharcName` | 特征名称 | `Edm.String` | 40 | Y |
| `CharcDescription` | 特征描述 | `Edm.String` | 60 | Y |
| `CharcValueUnit` | 特征值单位 | `Edm.String` | 3 | Y |
| `CharcDataType` | 特征数据类型 | `Edm.String` | 3 | Y |

**导航属性:**
- `to_BatchCharcValue` → `A_BatchCharacteristicValue[]`
- `to_Batch` → `A_Batch`

---

### 3. A_BatchCharacteristicValue（批次特征值）

**主键:** `Material`, `BatchIdentifyingPlant`, `Batch`, `CharcInternalID`, `CharcValuePositionNumber`

> SAP EDM 实体类型: `BatchCharcValueType` | 集合: `A_BatchCharcValue`

| 字段 | 描述 | 类型 | 长度 | 可空 |
|------|------|------|------|------|
| `Material` | 物料号 | `Edm.String` | 18 | N |
| `BatchIdentifyingPlant` | 工厂 | `Edm.String` | 4 | N |
| `Batch` | 批次号 | `Edm.String` | 10 | N |
| `CharcInternalID` | 特征内部 ID | `Edm.String` | 10 | N |
| `CharcValuePositionNumber` | 特征值位置编号 | `Edm.String` | 3 | N |
| `CharcValue` | 特征值 | `Edm.String` | 60 | Y |
| `CharcValueDesc` | 特征值描述 | `Edm.String` | 60 | Y |
| `CharcValueCode` | 特征值代码 | `Edm.String` | 10 | Y |
| `CharcValueCodeDesc` | 特征值代码描述 | `Edm.String` | 60 | Y |
| `CharcValueNumericFrom` | 数值从 | `Edm.Decimal` | - | Y |
| `CharcValueNumericTo` | 数值到 | `Edm.Decimal` | - | Y |
| `CharcValueCurrency` | 特征值货币 | `Edm.String` | 5 | Y |

**导航属性:**
- `to_BatchCharc` → `A_BatchCharacteristic`

---

### 4. A_BatchClass（批次分类分配）

**主键:** `Material`, `BatchIdentifyingPlant`, `Batch`

> SAP EDM 实体类型: `BatchClassType` | 集合: `A_BatchClass`

| 字段 | 描述 | 类型 | 长度 | 可空 |
|------|------|------|------|------|
| `Material` | 物料号 | `Edm.String` | 18 | N |
| `BatchIdentifyingPlant` | 工厂 | `Edm.String` | 4 | N |
| `Batch` | 批次号 | `Edm.String` | 10 | N |
| `ClassNumber` | 分类号 | `Edm.String` | 18 | Y |
| `ClassType` | 分类类型 | `Edm.String` | 3 | Y |
| `ClassTypeDesc` | 分类类型描述 | `Edm.String` | 60 | Y |
| `StandardClass` | 标准分类 | `Edm.Boolean` | - | Y |
| `ClassStatus` | 分类状态 | `Edm.String` | 2 | Y |
| `ClassStatusDesc` | 分类状态描述 | `Edm.String` | 60 | Y |

**导航属性:**
- `to_Batch` → `A_Batch`

---

### 5. A_BatchPlant（批次工厂数据）

**主键:** `Material`, `Batch`, `Plant`

> SAP EDM 实体类型: `BatchPlantType` | 集合: `A_BatchPlant`

| 字段 | 描述 | 类型 | 长度 | 可空 |
|------|------|------|------|------|
| `Material` | 物料号 | `Edm.String` | 18 | N |
| `Batch` | 批次号 | `Edm.String` | 10 | N |
| `Plant` | 工厂 | `Edm.String` | 4 | N |
| `BatchStockTotal` | 批次库存总量 | `Edm.Decimal` | - | Y |
| `BatchStockInUnrestrictedUse` | 非限制使用库存 | `Edm.Decimal` | - | Y |
| `BatchStockInQualityInspection` | 质检库存 | `Edm.Decimal` | - | Y |
| `BatchStockInBlockedStock` | 冻结库存 | `Edm.Decimal` | - | Y |
| `IsMarkedForDeletion` | 删除标记 | `Edm.Boolean` | - | Y |

**导航属性:**
- `to_Batch` → `A_Batch`

---

### 6. A_BatchText（批次文本）

**主键:** `Material`, `BatchIdentifyingPlant`, `Batch`, `Language`, `LongTextID`

> SAP EDM 实体类型: `BatchTextType` | 集合: `A_BatchText`

| 字段 | 描述 | 类型 | 长度 | 可空 |
|------|------|------|------|------|
| `Material` | 物料号 | `Edm.String` | 18 | N |
| `BatchIdentifyingPlant` | 工厂 | `Edm.String` | 4 | N |
| `Batch` | 批次号 | `Edm.String` | 10 | N |
| `Language` | 语言代码 | `Edm.String` | 2 | N |
| `LongTextID` | 长文本 ID | `Edm.String` | 4 | N |
| `BatchDescription` | 批次描述 | `Edm.String` | 40 | Y |
| `LongText` | 长文本内容 | `Edm.String` | - | Y |
| `ChangeNumber` | 变更号 | `Edm.String` | 10 | Y |

**导航属性:**
- `to_Batch` → `A_Batch`

---

## API 端点

### 基本 URL

```
https://<server>:<port>/sap/opu/odata/SAP/API_BATCH_SRV/
```

### A_Batch 操作

| 方法 | 端点 | 描述 |
|------|------|------|
| `GET` | `/A_Batch` | 查询批次列表 |
| `GET` | `/A_Batch(Material='{Material}',BatchIdentifyingPlant='{Plant}',Batch='{Batch}')` | 查询单个批次 |
| `POST` | `/A_Batch` | 创建批次（支持 Deep Insert） |
| `PATCH` | `/A_Batch(Material='{Material}',BatchIdentifyingPlant='{Plant}',Batch='{Batch}')` | 更新批次 |

**GET 查询参数:**

| 参数 | 描述 | 示例 |
|------|------|------|
| `$top` | 限制返回条数 | `$top=10` |
| `$skip` | 跳过条数 | `$skip=20` |
| `$filter` | 筛选条件 | `$filter=ShelfLifeExpirationDate ge datetime'2024-01-01T00:00:00'` |
| `$orderby` | 排序 | `$orderby=CreationDateTime desc` |
| `$select` | 选择字段 | `$select=Batch,Material,Supplier` |
| `$expand` | 展开导航属性 | `$expand=to_BatchCharc,to_BatchText` |

**创建批次示例:**
```json
POST /A_Batch
{
  "Material": "TG21",
  "BatchIdentifyingPlant": "PL01",
  "Batch": "0000000003",
  "Supplier": "10000001",
  "BatchBySupplier": "SUPP-BATCH-001",
  "CountryOfOrigin": "DE",
  "ShelfLifeExpirationDate": "2025-01-15T00:00:00Z",
  "ManufactureDate": "2024-01-10T00:00:00Z"
}
```

**更新批次示例:**
```json
PATCH /A_Batch(Material='TG21',BatchIdentifyingPlant='PL01',Batch='0000000003')
{
  "ShelfLifeExpirationDate": "2025-06-15T00:00:00Z",
  "Supplier": "10000002"
}
```

### A_BatchCharacteristic 操作

| 方法 | 端点 | 描述 |
|------|------|------|
| `GET` | `/A_BatchCharc` | 查询批次特征列表 |
| `GET` | `/A_BatchCharc(Material='{M}',BatchIdentifyingPlant='{P}',Batch='{B}',CharcInternalID='{ID}')` | 查询单个特征 |
| `POST` | `/A_BatchCharc` | 创建特征 |
| `PATCH` | `/A_BatchCharc(...)` | 更新特征 |

### A_BatchCharacteristicValue 操作

| 方法 | 端点 | 描述 |
|------|------|------|
| `GET` | `/A_BatchCharcValue` | 查询特征值列表 |
| `POST` | `/A_BatchCharcValue` | 创建特征值 |
| `PATCH` | `/A_BatchCharcValue(...)` | 更新特征值 |
| `DELETE` | `/A_BatchCharcValue(...)` | 删除特征值 |

### A_BatchClass 操作

| 方法 | 端点 | 描述 |
|------|------|------|
| `GET` | `/A_BatchClass` | 查询批次分类分配 |
| `GET` | `/A_BatchClass(Material='{M}',BatchIdentifyingPlant='{P}',Batch='{B}')` | 查询单个分类 |
| `POST` | `/A_BatchClass` | 创建分类分配 |
| `DELETE` | `/A_BatchClass(...)` | 删除分类分配 |

### A_BatchPlant 操作

| 方法 | 端点 | 描述 |
|------|------|------|
| `GET` | `/A_BatchPlant` | 查询批次工厂数据 |
| `GET` | `/A_BatchPlant(Material='{M}',Batch='{B}',Plant='{P}')` | 查询单个工厂数据 |
| `PATCH` | `/A_BatchPlant(...)` | 更新批次工厂数据 |

### A_BatchText 操作

| 方法 | 端点 | 描述 |
|------|------|------|
| `GET` | `/A_BatchText` | 查询批次文本 |
| `GET` | `/A_BatchText(Material='{M}',BatchIdentifyingPlant='{P}',Batch='{B}',Language='EN',LongTextID='{ID}')` | 查询单个文本 |
| `POST` | `/A_BatchText` | 创建批次文本 |
| `PATCH` | `/A_BatchText(...)` | 更新批次文本 |
| `DELETE` | `/A_BatchText(...)` | 删除批次文本 |

**创建批次文本（通过导航属性）:**
```
POST /A_Batch(Material='TG21',BatchIdentifyingPlant='PL01',Batch='0000000003')/to_BatchText
```
```json
{
  "Language": "EN",
  "LongTextID": "BATCH",
  "BatchDescription": "Sample batch for material TG21"
}
```

---

## 注意事项

### 1. 认证与授权
- 支持 Basic Auth、OAuth 2.0、x509 证书认证
- 需要通信场景 `SAP_COM_0337` 和相应权限

### 2. Deep Insert（深插入）
- 创建批次时可通过导航属性同时创建分类数据
- 示例：在 `POST /A_Batch` 中包含 `to_BatchCharc`、`to_BatchText`

### 3. 字段约束
- `Material` 最大长度 18（外部视图）或 40（内部视图）
- `Batch` 最大长度 10
- `BatchIdentifyingPlant` 最大长度 4
- `Supplier` 最大长度 10
- `CountryOfOrigin` 使用 ISO 3 位代码

### 4. 批次删除
- 批次删除为逻辑删除（标记 `BatchIsMarkedForDeletion = true`）
- 实际删除通过归档处理

### 5. 特征分类
- 批次特征通过分类系统管理（类类型 023）
- 使用 `A_BatchCharc` 和 `A_BatchCharcValue` 管理特征值
- 特征值可参考表字段或自定义

### 6. HTTP 状态码

| 状态码 | 说明 |
|--------|------|
| `200 OK` | 请求成功 |
| `201 Created` | 创建成功 |
| `204 No Content` | 更新/删除成功 |
| `400 Bad Request` | 请求参数错误 |
| `401 Unauthorized` | 未授权 |
| `403 Forbidden` | 权限不足 |
| `404 Not Found` | 资源未找到 |
| `500 Internal Server Error` | 服务器内部错误 |

---

## PHP SDK: be-lenka/sap-batch

GitHub: [be-lenka/sap-batch](https://github.com/be-lenka/sap-batch)

Composer:
```json
{
  "repositories": [
    {
      "type": "vcs",
      "url": "https://github.com/be-lenka/sap-batch.git"
    }
  ],
  "require": {
    "be-lenka/sap-batch": "dev-master"
  }
}
```

使用示例:
```php
<?php
require_once __DIR__ . '/vendor/autoload.php';

$config = BeLenka\SAP\Batch\Configuration::getDefaultConfiguration()
    ->setUsername('YOUR_USERNAME')
    ->setPassword('YOUR_PASSWORD');

$apiInstance = new BeLenka\SAP\Batch\Api\BatchApi(
    new GuzzleHttp\Client(),
    $config
);

// 查询批次
$result = $apiInstance->aBatchGet();
print_r($result);

// 按主键查询
$result = $apiInstance->aBatchGet(
    'TG21',    // Material
    'PL01',    // BatchIdentifyingPlant
    '0000000003'  // Batch
);
```

---

## SAP Cloud SDK VDM

Java VDM 类: `com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.batch.Batch`

Maven:
```xml
<dependency>
  <groupId>com.sap.cloud.sdk.s4hana</groupId>
  <artifactId>s4hana-api-odata</artifactId>
  <version>4.7.0</version>
</dependency>
```

使用示例:
```java
BatchService service = new DefaultBatchService();
Batch batch = service.getBatchByKey("TG21", "PL01", "0000000003").execute();
```

---

## 更多信息

- **SAP API Business Hub**: [API_BATCH_SRV](https://api.sap.com/api/API_BATCH_SRV/overview)
- **SAP Help Portal**: [Batch Master Record](https://help.sap.com/docs/SAP_S4HANA_CLOUD/9ce855c709ce4f5c99b685903461106e/48b3c2ac60154137bb1d6411c7047e16.html)
- **OData V2 规范**: [https://www.odata.org/documentation/odata-version-2-0/](https://www.odata.org/documentation/odata-version-2-0/)