# ERP系统改造方案：采购申请与付款申请分离

## 📋 项目背景

**当前问题：**
- 付款申请混合了公司运营支出和项目材料采购
- 项目成本统计不精确
- 库存管理无法关联采购流程
- 商品管理已存在但缺少库存管理

**改造目标：**
- 建立独立的采购申请流程（项目材料/设备）
- 简化付款申请流程（公司运营支出）
- 实现项目成本精确统计
- 建立基础库存管理

---

## 🗂️ 改造范围

### 1. 数据库层
- 新增采购申请表
- 新增采购明细表
- 新增库存记录表
- 修改付款申请表（简化）
- 新增项目成本统计视图

### 2. 后端API层
- 采购申请CRUD API
- 采购审批流程API
- 库存管理API
- 项目成本统计API
- 付款申请简化API

### 3. 前端页面层
- 采购申请管理页面
- 采购申请审批页面
- 库存管理页面
- 项目成本统计页面
- 简化付款申请页面

---

## 🧪 TDD测试策略

### 测试层级
```
1. 单元测试 (Unit Tests)
   - 数据库模型测试
   - API接口测试
   - 业务逻辑测试

2. 集成测试 (Integration Tests)
   - 采购-库存-项目流程测试
   - 审批流程测试

3. 端到端测试 (E2E Tests)
   - 完整业务流程测试
   - 用户场景测试
```

---

## 📊 数据库设计

### 新表1：采购申请表 (purchase_requests)

```sql
CREATE TABLE purchase_requests (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  request_code TEXT UNIQUE NOT NULL,      -- 采购申请编号：PUR-20240324-001
  project_id INTEGER NOT NULL,             -- 关联项目（必填）
  applicant TEXT NOT NULL,                 -- 申请人
  request_date DATE NOT NULL,              -- 申请日期
  supplier_id INTEGER,                     -- 供应商ID（从供应商库选择）
  supplier_name TEXT,                      -- 供应商名称（手动输入或库中选择）
  expense_category TEXT NOT NULL,          -- 支出分类：material/equipment/pole/other
  total_amount REAL NOT NULL DEFAULT 0,    -- 总金额
  currency TEXT DEFAULT 'CNY',             -- 币种
  status TEXT DEFAULT 'pending',           -- 状态：pending/approved/rejected/executed
  remark TEXT,                             -- 备注
  attachments TEXT,                        -- 附件JSON数组
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (project_id) REFERENCES projects(id),
  FOREIGN KEY (supplier_id) REFERENCES suppliers(id)
);
```

### 新表2：采购明细表 (purchase_request_items)

```sql
CREATE TABLE purchase_request_items (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  purchase_request_id INTEGER NOT NULL,    -- 关联采购申请
  product_id INTEGER,                      -- 商品ID（从商品库选择）
  product_name TEXT NOT NULL,              -- 商品名称
  specification TEXT,                      -- 规格型号
  unit TEXT,                               -- 单位
  quantity REAL NOT NULL DEFAULT 0,        -- 数量
  unit_price REAL NOT NULL DEFAULT 0,      -- 单价
  total_price REAL NOT NULL DEFAULT 0,     -- 小计
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (purchase_request_id) REFERENCES purchase_requests(id) ON DELETE CASCADE,
  FOREIGN KEY (product_id) REFERENCES products(id)
);
```

### 新表3：库存记录表 (inventory_records)

```sql
CREATE TABLE inventory_records (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  record_type TEXT NOT NULL,               -- 记录类型：in(入库)/out(出库)
  project_id INTEGER,                      -- 关联项目（出库时必填）
  purchase_request_id INTEGER,             -- 关联采购申请（入库时）
  product_id INTEGER NOT NULL,             -- 商品ID
  quantity REAL NOT NULL DEFAULT 0,        -- 数量（正数）
  unit_price REAL,                         -- 单价
  total_amount REAL,                       -- 总金额
  record_date DATE NOT NULL,               -- 记录日期
  operator TEXT,                           -- 操作人
  remark TEXT,                             -- 备注
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (project_id) REFERENCES projects(id),
  FOREIGN KEY (purchase_request_id) REFERENCES purchase_requests(id),
  FOREIGN KEY (product_id) REFERENCES products(id)
);
```

### 修改表：付款申请表 (payment_requests) - 简化

```sql
-- 保留字段：
-- id, request_code, applicant, payment_date, payee, bank_account, bank_name
-- amount, currency, reason, status, attachments, created_at, updated_at

-- 移除字段：
-- detail_items（不再需要明细）

-- 保留但限制使用范围的字段：
-- expense_type: 只允许 'company'（公司支出）
-- expense_category: 只允许公司支出分类
-- payee_type, payee_id: 保留
-- project_id: 可选，用于关联项目但非采购类支出
```

---

## 🔄 业务流程设计

### 流程1：采购申请流程

```
1. 创建采购申请
   ↓
2. 选择项目（必填）
   ↓
3. 添加商品明细（从商品库选择）
   ↓
4. 选择供应商（从供应商库或手动输入）
   ↓
5. 提交审批
   ↓
6. 审批通过 → 生成采购单
   ↓
7. 货物到货 → 入库操作 → 自动更新库存
   ↓
8. 项目成本自动统计
```

### 流程2：付款申请流程（简化）

```
1. 创建付款申请
   ↓
2. 选择付款类型：
   - 公司运营支出（房租/工资/营销等）
   - 项目其他支出（非采购类）
   - 采购尾款（关联采购单）
   ↓
3. 填写金额和收款信息
   ↓
4. 提交审批
   ↓
5. 审批通过 → 执行付款
```

---

## 📱 页面设计

### 页面1：采购申请管理

**功能：**
- 采购申请列表（按项目筛选）
- 新建采购申请
- 编辑/删除（待审批状态）
- 查看详情
- 提交审批

**表单字段：**
```
- 申请日期
- 关联项目（下拉选择）
- 供应商（二级：从库选择/手动输入）
- 支出分类（材料/设备/电杆/其他）
- 商品明细（多行，从商品库选择）
- 总金额（自动计算）
- 币种
- 附件
- 备注
```

### 页面2：采购申请审批

**功能：**
- 待审批列表
- 审批通过/驳回
- 查看详情（含商品明细）

### 页面3：库存管理

**功能：**
- 库存查询（按商品、按项目）
- 入库记录（采购自动入库）
- 出库记录（项目领用）
- 库存预警

### 页面4：项目成本统计

**功能：**
- 项目列表
- 项目详情页：
  - 合同金额
  - 采购成本（材料/设备/电杆等分类统计）
  - 付款支出（非采购类）
  - 人工成本（预留）
  - 利润计算

### 页面5：付款申请（简化版）

**功能：**
- 付款申请列表
- 新建付款申请（简化表单）
- 审批流程

**简化表单字段：**
```
- 付款日期
- 付款类型（公司支出/项目其他支出/采购尾款）
- 收款单位（简化选择）
- 金额
- 付款事由
- 关联项目（可选）
- 关联采购单（付款类型为采购尾款时）
- 附件
```

---

## 🧪 TDD测试计划

### 阶段1：数据库层测试（第1-2天）

**测试文件：**
- `test-purchase-requests-table.spec.js`
- `test-purchase-request-items-table.spec.js`
- `test-inventory-records-table.spec.js`

**测试内容：**
```javascript
// 示例测试
describe('采购申请表', () => {
  test('应该能创建采购申请', async () => {
    const result = await db.query(
      'INSERT INTO purchase_requests (...) VALUES (...)'
    );
    expect(result.changes).toBe(1);
  });
  
  test('采购申请编号应该唯一', async () => {
    // 测试唯一约束
  });
  
  test('应该能关联项目和供应商', async () => {
    // 测试外键约束
  });
});
```

### 阶段2：后端API测试（第3-5天）

**测试文件：**
- `test-purchase-requests-api.spec.js`
- `test-inventory-api.spec.js`
- `test-project-cost-api.spec.js`

**测试内容：**
```javascript
// 示例测试
describe('采购申请API', () => {
  test('POST /api/purchase-requests - 创建采购申请', async () => {
    const response = await request(app)
      .post('/api/purchase-requests')
      .send({...});
    expect(response.status).toBe(200);
    expect(response.body.success).toBe(true);
  });
  
  test('应该能计算采购总金额', async () => {
    // 测试金额计算逻辑
  });
  
  test('审批通过后应该能入库', async () => {
    // 测试审批-入库流程
  });
});
```

### 阶段3：前端页面测试（第6-8天）

**测试文件：**
- `test-purchase-requests-page.spec.js`
- `test-inventory-page.spec.js`
- `test-project-cost-page.spec.js`

**测试内容：**
```javascript
// 示例测试
describe('采购申请页面', () => {
  test('应该能显示采购申请列表', async () => {
    // 测试页面渲染
  });
  
  test('应该能从商品库选择商品', async () => {
    // 测试商品选择功能
  });
  
  test('应该能自动计算总金额', async () => {
    // 测试金额计算
  });
});
```

### 阶段4：集成测试（第9-10天）

**测试场景：**
1. 完整采购流程：申请→审批→入库→成本统计
2. 付款申请流程：创建→审批→执行
3. 项目成本统计：多笔采购+付款的汇总

---

## 📅 实施计划（10天）

### 第1天：备份与准备
- [ ] 备份现有数据库
- [ ] 备份现有代码
- [ ] 创建新分支
- [ ] 编写数据库迁移脚本

### 第2天：数据库层
- [ ] 创建采购申请表
- [ ] 创建采购明细表
- [ ] 创建库存记录表
- [ ] 修改付款申请表
- [ ] 编写数据库测试

### 第3-4天：后端API - 采购申请
- [ ] 采购申请CRUD API
- [ ] 采购审批流程API
- [ ] 采购明细API
- [ ] 编写API测试

### 第5天：后端API - 库存与统计
- [ ] 库存管理API
- [ ] 项目成本统计API
- [ ] 修改付款申请API（简化）
- [ ] 编写API测试

### 第6天：前端 - 采购申请页面
- [ ] 采购申请列表页
- [ ] 采购申请表单（含商品选择）
- [ ] 采购申请详情页

### 第7天：前端 - 审批与库存
- [ ] 采购审批页面
- [ ] 库存管理页面
- [ ] 入库/出库操作

### 第8天：前端 - 统计与付款
- [ ] 项目成本统计页面
- [ ] 简化付款申请页面
- [ ] 修改现有付款申请页面

### 第9天：集成测试
- [ ] 完整流程测试
- [ ] Bug修复
- [ ] 性能优化

### 第10天：验收与部署
- [ ] 最终测试
- [ ] 用户验收
- [ ] 部署上线

---

## 📦 交付物清单

### 1. 数据库
- [ ] 迁移脚本
- [ ] 表结构文档
- [ ] 测试数据

### 2. 后端
- [ ] 采购申请API
- [ ] 库存管理API
- [ ] 项目统计API
- [ ] 测试用例（覆盖率>80%）

### 3. 前端
- [ ] 采购申请管理页面
- [ ] 采购审批页面
- [ ] 库存管理页面
- [ ] 项目成本统计页面
- [ ] 简化付款申请页面

### 4. 文档
- [ ] API文档
- [ ] 用户操作手册
- [ ] 测试报告

---

## ⚠️ 风险评估

| 风险 | 影响 | 应对措施 |
|------|------|----------|
| 数据迁移失败 | 高 | 完整备份，分步迁移，验证数据 |
| 商品库不完善 | 中 | 允许手动输入商品名称，后续完善商品库 |
| 用户不适应新流程 | 中 | 保留旧付款申请一段时间，并行使用 |
| 项目统计不准确 | 高 | 增加数据校验，提供手动调整功能 |

---

## ✅ 验收标准

1. **功能验收**
   - [ ] 能正常创建采购申请
   - [ ] 能从商品库选择商品
   - [ ] 审批流程正常
   - [ ] 入库后库存正确更新
   - [ ] 项目成本统计准确

2. **性能验收**
   - [ ] 页面加载<2秒
   - [ ] 列表查询<1秒
   - [ ] 报表生成<3秒

3. **测试验收**
   - [ ] 单元测试通过率100%
   - [ ] 集成测试通过率100%
   - [ ] 无严重Bug

---

## 📝 变更记录

| 日期 | 版本 | 变更内容 | 变更人 |
|------|------|----------|--------|
| 2026-03-24 | v1.0 | 初始方案 | AI Assistant |

---

**方案状态：** 已保存，待执行
**备份状态：** 待备份
**开始日期：** 待定
