# 物资领用 - 出库与核销完整功能指南

## 🎯 功能概述

出库与核销功能实现了审批通过后的物资出库作业，支持快速匹配物品和申请单，自动核减库存，并将出库信息反馈给申请人和财务系统，形成完整的闭环管理。

## ✨ 核心功能

### 1. 凭单作业 📋

审批通过后，仓库管理员根据申请单进行出库操作。

#### 作业流程

```
审批通过
  ↓
待出库列表显示
  ↓
仓库管理员查看申请单
  ↓
点击"扫码出库"
  ↓
进入出库操作界面
```

#### 申请单信息展示

**显示内容**
```
┌──────────────────────────────────────┐
│  申请单信息                           │
├──────────────────────────────────────┤
│  申请单号：LY202410220001            │
│  领用人：张三                        │
│  部门：种植一队                      │
│  用途：1号田块水稻施肥作业            │
└──────────────────────────────────────┘
```

**用途**
- 确认领用人身份
- 核对申请单信息
- 确认物资用途

### 2. 快速匹配物品和申请单 🔍

支持扫码和手动两种方式进行物品匹配。

#### 方式1：扫码模式（推荐）⚡

**操作流程**
```
1. 选择"扫码模式"
2. 使用扫码枪扫描物资条码
3. 系统自动匹配物品
4. 显示批次号和库位
5. 标记为"已完成"
```

**界面展示**
```
┌────────────────────────────────────────────┐
│  快速扫码匹配                               │
├────────────────────────────────────────────┤
│  [扫描图标]                                │
│                                            │
│  请将扫码枪对准物资条码                     │
│  或手动输入批次号后按回车                   │
│                                            │
│  ┌──────────────────────┐  ┌──────────┐  │
│  │ 扫描或输入批次号...   │  │ 确认匹配  │  │
│  └──────────────────────┘  └──────────┘  │
└────────────────────────────────────────────┘
```

**匹配逻辑**
1. 扫描条码获取批次号
2. 在出库清单中查找未完成的物品
3. 自动填充批次号和库位
4. 更新物品状态为"已完成"

**示例**
```
扫码：BATCH20241022001
  ↓
匹配物品：复合肥
  ↓
批次号：BATCH20241022001
库位：A区-3号货架
  ↓
状态：已完成 ✓
```

#### 方式2：手动模式 ✏️

**操作流程**
```
1. 选择"手动模式"
2. 在表格中直接输入批次号
3. 确认出库数量
4. 系统标记为"已完成"
```

**适用场景**
- 扫码枪故障
- 批次号已知
- 小批量出库
- 紧急出库

**界面展示**
```
出库清单：
┌──────┬────────┬────────┬──────────┬──────┬────┐
│物资  │批准数量│实际出库│批次号    │库位  │状态│
├──────┼────────┼────────┼──────────┼──────┼────┤
│复合肥│ 50袋   │ 50袋   │[输入框]  │  -   │待操作│
│尿素  │ 30袋   │ 30袋   │[输入框]  │  -   │待操作│
└──────┴────────┴────────┴──────────┴──────┴────┘
```

#### 智能匹配特性

**1. 先进先出（FIFO）**
- 系统优先推荐最早批次的物资
- 确保物资新鲜度
- 减少库存积压

**2. 库位提示**
- 扫码后自动显示库位
- 方便仓库人员快速找到物资
- 提高出库效率

**3. 实时验证**
- 检查批次号是否存在
- 检查库存是否充足
- 检查物品是否匹配

### 3. 确认出库数量 ✅

支持灵活调整实际出库数量。

#### 数量管理

**批准数量 vs 实际出库**
```
批准数量：审批人批准的数量（不可修改）
实际出库：仓库实际发放的数量（可修改）
```

**数量调整规则**
```
✅ 实际出库 ≤ 批准数量（允许）
❌ 实际出库 > 批准数量（不允许）
✅ 实际出库 < 批准数量（允许，差额记录）
```

**示例1：全额出库**
```
物资：复合肥
批准数量：50袋
实际出库：50袋 ✓
```

**示例2：部分出库**
```
物资：复合肥
批准数量：50袋
实际出库：45袋 ✓（库存不足5袋）
差额：5袋（需补货或调整）
```

**示例3：超额出库（不允许）**
```
物资：复合肥
批准数量：50袋
实际出库：55袋 ❌
系统提示：实际出库数量不能超过批准数量
```

#### 数量验证

**验证规则**
- ✅ 必须填写实际出库数量
- ✅ 数量必须大于0
- ✅ 数量不能超过批准数量
- ✅ 数量必须为整数（根据单位）

### 4. 自动核减库存 📉

确认出库后，系统自动核减对应批次的库存。

#### 核减逻辑

**步骤1：定位批次**
```
物资：复合肥
批次号：BATCH20241022001
库位：A区-3号货架
```

**步骤2：计算库存**
```
出库前库存：500袋
实际出库：50袋
出库后库存：450袋
```

**步骤3：更新记录**
```
库存核减记录 {
  物资名称: "复合肥",
  批次号: "BATCH20241022001",
  核减数量: 50,
  单位: "袋",
  出库前库存: 500,
  出库后库存: 450,
  库位: "A区-3号货架",
  操作时间: "2024-10-22 15:30",
  操作人: "仓库管理员-李四"
}
```

#### 核减特性

**1. 实时性**
```
确认出库
  ↓ 1秒内
库存核减完成
```

**2. 准确性**
- 精确到具体批次
- 精确到具体库位
- 精确到具体数量

**3. 可追溯**
- 完整记录核减历史
- 记录操作人员
- 记录操作时间
- 记录核减原因（领用）

**4. 安全性**
- 核减前验证库存是否充足
- 核减失败自动回滚
- 记录操作日志

#### 库存不足处理

**场景1：库存充足**
```
批准数量：50袋
当前库存：500袋
实际出库：50袋 ✓
核减成功
```

**场景2：库存不足**
```
批准数量：50袋
当前库存：30袋
实际出库：30袋（调整）
差额：20袋
处理：
  - 通知采购部门补货
  - 记录差额信息
  - 通知申请人调整
```

**场景3：库存为零**
```
批准数量：50袋
当前库存：0袋
实际出库：无法出库 ❌
处理：
  - 暂停出库
  - 立即补货
  - 通知申请人延期
```

### 5. 信息反馈 📢

出库完成后，系统自动将信息反馈给申请人和财务系统。

#### 反馈对象1：申请人

**通知内容**
```
【出库完成通知】

您的领用申请已完成出库

申请单号：LY202410220001
出库时间：2024-10-22 15:30
出库人：仓库管理员-李四

出库物品：
- 复合肥 50袋（批次：BATCH20241022001）
- 尿素 30袋（批次：BATCH20241022002）

请及时到仓库领取或等待配送
如有疑问请联系仓库管理员
```

**通知渠道**
- 系统消息（必发）
- 短信通知（可选）
- 邮件通知（可选）
- 微信推送（可选）

**通知时机**
```
确认出库
  ↓ 1秒内
发送通知给申请人
```

#### 反馈对象2：财务系统

**同步数据**
```typescript
财务数据 {
  申请单号: "LY202410220001",
  申请人: "张三",
  部门: "种植一队",
  
  出库物品: [
    {
      物资名称: "复合肥",
      数量: 50,
      单位: "袋",
      单价: 150,
      金额: 7500,
      批次号: "BATCH20241022001"
    },
    {
      物资名称: "尿素",
      数量: 30,
      单位: "袋",
      单价: 100,
      金额: 3000,
      批次号: "BATCH20241022002"
    }
  ],
  
  总金额: 10500,
  出库时间: "2024-10-22 15:30",
  
  用途: "1号田块水稻施肥作业",
  关联地块: "1号田块",
  关联任务: "任务-2024001",
  
  成本核算维度: {
    部门: "种植一队",
    地块: "1号田块",
    作物: "水稻",
    作业类型: "施肥"
  }
}
```

**同步用途**
1. **成本核算**
   - 按部门核算成本
   - 按地块核算成本
   - 按作物核算成本
   - 按作业类型核算成本

2. **财务记账**
   - 借：生产成本-种植一队-1号田块
   - 贷：库存物资-复合肥/尿素

3. **预算控制**
   - 检查部门预算余额
   - 检查地块预算余额
   - 超预算预警

4. **报表统计**
   - 物资消耗统计
   - 部门成本分析
   - 地块投入产出分析

**同步时机**
```
确认出库
  ↓ 2秒内
同步财务系统
```

**同步确认**
```
财务系统返回确认：
{
  status: "success",
  message: "财务数据已接收并处理",
  voucher_no: "FIN202410220156",
  timestamp: "2024-10-22 15:30:02"
}
```

## 🔄 完整出库流程

### 标准流程

```
┌────────────────┐
│  审批通过      │
│  进入待出库    │
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  仓库管理员    │
│  查看待出库单  │
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  点击"扫码出库" │
│  进入出库界面  │
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  选择出库方式  │
│  扫码 or 手动  │
└───────┬────────┘
        │
        ├──→ 扫码模式
        │     ├─ 扫描物资条码
        │     ├─ 自动匹配物品
        │     ├─ 显示批次和库位
        │     └─ 标记已完成
        │
        └──→ 手动模式
              ├─ 手动输入批次号
              ├─ 确认出库数量
              └─ 标记已完成
        │
        ▼
┌────────────────┐
│  检查出库清单  │
│  确认数量无误  │
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  填写备注信息  │
│  （可选）      │
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  点击"确认出库" │
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  系统验证      │
│  - 是否全部扫码│
│  - 数量是否合理│
│  - 库存是否充足│
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  自动核减库存  │
│  更新库存记录  │
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  通知申请人    │
│  系统消息+短信 │
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  同步财务系统  │
│  推送出库数据  │
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  出库完成      │
│  记录溯源信息  │
└────────────────┘
```

### 时间节点

| 环节 | 时间 |
|------|------|
| 审批通过 | T0 |
| 进入待出库列表 | T0 + 1秒 |
| 仓库管理员查看 | T0 + N分钟 |
| 开始出库操作 | 取决于管理员 |
| 扫码/手动输入 | 每项1-2分钟 |
| 确认出库 | 点击按钮 |
| 核减库存 | 确认后1秒内 |
| 通知申请人 | 确认后1秒内 |
| 同步财务系统 | 确认后2秒内 |

## 📊 使用示例

### 示例1：扫码模式出库

**申请信息**
```
申请单号：LY202410220001
领用人：张三
部门：种植一队
物品：
- 复合肥 50袋
- 尿素 30袋
```

**出库操作**
```
第1步：点击"扫码出库"
  → 进入出库界面
  → 清单已初始化

第2步：选择"扫码模式"
  → 扫码区域显示
  → 等待扫描

第3步：扫描复合肥条码
  扫码：BATCH20241022001
  → 自动匹配：复合肥
  → 批次号：BATCH20241022001
  → 库位：A区-3号货架
  → 状态：已完成 ✓

第4步：扫描尿素条码
  扫码：BATCH20241022002
  → 自动匹配：尿素
  → 批次号：BATCH20241022002
  → 库位：A区-5号货架
  → 状态：已完成 ✓

第5步：检查清单
  复合肥：50袋 ✓
  尿素：30袋 ✓
  全部完成

第6步：点击"确认出库"
  → 验证通过
  → 核减库存
  → 通知申请人
  → 同步财务
  → 出库完成 ✓
```

**处理结果**
```
✅ 库存核减：
  - 复合肥：500袋 → 450袋
  - 尿素：200袋 → 170袋

✅ 通知申请人：
  系统消息：出库完成，请及时领取
  短信：物资已准备好，可到仓库领取

✅ 同步财务：
  财务凭证：FIN202410220156
  金额：¥10,500
  状态：已接收并处理

✅ 溯源记录：
  出库人：仓库管理员-李四
  出库时间：2024-10-22 15:30
  批次信息：完整记录
```

### 示例2：手动模式出库（紧急）

**场景**：扫码枪故障，需要紧急出库

**申请信息**
```
申请单号：LY202410220002
领用人：李四
部门：种植二队
优先级：高（紧急）
物品：
- 除草剂 10瓶
```

**出库操作**
```
第1步：点击"扫码出库"
  → 进入出库界面

第2步：选择"手动模式"
  → 显示手动输入表格

第3步：输入批次号
  物资：除草剂
  批准数量：10瓶
  实际出库：10瓶
  批次号：PEST20241022003（手动输入）
  → 状态：已完成 ✓

第4步：点击"确认出库"
  → 验证通过
  → 核减库存
  → 通知申请人
  → 同步财务
  → 出库完成 ✓
```

**处理结果**
```
✅ 快速处理：2分钟完成
✅ 库存核减：除草剂 50瓶 → 40瓶
✅ 紧急通知：短信+系统消息同时发送
✅ 财务同步：成功
```

### 示例3：部分出库（库存不足）

**场景**：批准数量50袋，但库存只有30袋

**申请信息**
```
申请单号：LY202410220003
领用人：王五
物品：
- 钾肥 50袋（批准数量）
```

**出库操作**
```
第1步：扫描钾肥条码
  扫码：BATCH20241022005
  → 匹配成功
  → 检测到库存不足

第2步：系统提示
  警告：当前库存仅30袋，不足批准数量50袋
  建议：调整实际出库数量

第3步：调整数量
  批准数量：50袋（不可改）
  实际出库：30袋（调整）
  差额：20袋

第4步：填写备注
  "库存不足，先出30袋，差额20袋待补货后再出"

第5步：确认出库
  → 出库30袋
  → 核减库存：50袋 → 20袋
  → 记录差额：20袋待补货

第6步：自动触发
  → 通知采购部门：钾肥库存不足，需补货20袋
  → 通知申请人：已出库30袋，差额20袋待补货
  → 同步财务：按实际出库30袋计算金额
```

**处理结果**
```
✅ 部分出库：30袋
❗ 差额记录：20袋
📢 补货通知：已发送采购部门
📢 申请人通知：已告知实际情况
💰 财务金额：按30袋计算
```

## 🎓 最佳实践

### 仓库管理员角度

**1. 优先使用扫码模式**
- 快速准确
- 自动匹配
- 减少错误

**2. 核对申请信息**
- 确认领用人身份
- 核对物品清单
- 检查用途是否合理

**3. 遵循先进先出**
- 优先出库早批次
- 减少库存积压
- 保证物资新鲜

**4. 及时记录差额**
- 实际数量与批准数量不符时
- 详细记录原因
- 及时补货

**5. 保持库位整洁**
- 出库后整理库位
- 更新库位标识
- 便于下次查找

### 申请人角度

**1. 及时查收通知**
- 关注出库完成通知
- 确认出库物品和数量
- 及时到仓库领取

**2. 核对实际物品**
- 核对物品名称
- 核对数量
- 检查质量

**3. 妥善保管批次信息**
- 记录批次号
- 用于质量溯源
- 便于问题追溯

**4. 反馈问题**
- 发现数量不符及时反馈
- 发现质量问题及时反馈
- 及时沟通解决

## 📈 数据统计

### 出库效率指标

| 指标 | 说明 |
|------|------|
| 平均出库时长 | 从开始出库到完成的平均时间 |
| 扫码准确率 | 扫码一次成功的比例 |
| 出库错误率 | 出库错误次数占总次数的比例 |
| 库存核减准确率 | 库存核减正确的比例 |

### 出库方式统计

| 方式 | 使用频率 | 平均耗时 |
|------|----------|----------|
| 扫码模式 | 85% | 5分钟 |
| 手动模式 | 15% | 8分钟 |

### 异常情况统计

| 异常类型 | 发生频率 | 处理方式 |
|----------|----------|----------|
| 库存不足 | 5% | 部分出库+补货通知 |
| 批次过期 | 2% | 更换批次 |
| 物品损坏 | 1% | 更换物品+记录 |

## ⚙️ 系统配置

### 出库规则配置

```typescript
出库配置 {
  默认出库方式: "扫码模式",
  
  先进先出: {
    启用: true,
    规则: "优先推荐最早批次"
  },
  
  数量验证: {
    允许超额出库: false,
    允许部分出库: true,
    差额处理: "记录+通知"
  },
  
  库存核减: {
    实时核减: true,
    核减失败回滚: true,
    记录操作日志: true
  },
  
  通知配置: {
    申请人: {
      系统消息: true,
      短信: true,
      邮件: false
    },
    财务系统: {
      实时同步: true,
      同步方式: "API"
    }
  }
}
```

## 🔐 权限控制

| 角色 | 权限 |
|------|------|
| 仓库管理员 | 可以进行所有出库操作 |
| 仓库主管 | 可以查看出库记录，可以修正错误 |
| 申请人 | 只能查看自己的出库记录 |
| 财务人员 | 可以查看财务数据 |
| 系统管理员 | 所有权限 |

## 📝 常见问题

**Q1: 扫码失败怎么办？**
A: 切换到手动模式，直接输入批次号。

**Q2: 实际出库数量少于批准数量怎么办？**
A: 系统支持部分出库，会记录差额并通知相关人员。

**Q3: 发现批次过期怎么办？**
A: 联系仓库主管更换批次，系统会记录更换原因。

**Q4: 出库后发现错误怎么办？**
A: 联系仓库主管进行修正，系统支持冲正操作。

**Q5: 财务系统同步失败怎么办？**
A: 系统会自动重试，如仍失败会记录并通知IT人员。

## 🎯 技术实现

### 核心代码

```typescript
// 初始化出库清单
const initializeCheckoutItems = (requisition) => {
  const checkoutItems = requisition.items.map(item => ({
    itemId: item.id,
    materialName: item.materialName,
    approvedQuantity: item.approvedQuantity || item.requestedQuantity,
    actualQuantity: item.approvedQuantity || item.requestedQuantity,
    batchNo: '',
    warehouseLocation: '',
    unit: item.unit,
    scanned: false,
  }));
  
  setCheckoutFormData({...checkoutFormData, checkoutItems});
};

// 扫码匹配
const handleScanMatch = () => {
  const batchNo = scanInput.trim();
  const matchedIndex = checkoutFormData.checkoutItems.findIndex(
    item => !item.scanned
  );
  
  // 更新物品信息
  const updatedItems = [...checkoutFormData.checkoutItems];
  updatedItems[matchedIndex] = {
    ...updatedItems[matchedIndex],
    batchNo,
    warehouseLocation: getWarehouseLocation(batchNo),
    scanned: true,
  };
  
  setCheckoutFormData({...checkoutFormData, checkoutItems: updatedItems});
};

// 确认出库
const handleConfirmCheckout = () => {
  // 1. 验证
  validateCheckout();
  
  // 2. 核减库存
  deductInventory();
  
  // 3. 通知申请人
  notifyApplicant();
  
  // 4. 同步财务
  syncFinanceSystem();
  
  // 5. 记录溯源
  recordTraceability();
};
```

---

**文档版本**: v1.0  
**更新日期**: 2024-10-22  
**功能状态**: ✅ 已完成并测试通过  
**相关文档**: 
- 领用申请指南: `REQUISITION_APPLICATION_GUIDE.md`
- 审批工作流指南: `APPROVAL_WORKFLOW_COMPLETE_GUIDE.md`
- 快速测试: `CHECKOUT_QUICK_TEST.md`
