356 lines
9.2 KiB
Markdown
356 lines
9.2 KiB
Markdown
# 财务Excel数据处理系统 - 需求文档
|
||
|
||
## 项目概述
|
||
|
||
本系统用于自动化处理财务Excel数据,提取收款信息并生成标准会计分录表,支持数据验证和异常标记功能。
|
||
|
||
---
|
||
|
||
## 功能模块
|
||
|
||
### 模块一: Excel数据提取 (`process_excel.py`)
|
||
|
||
#### 1.1 数据源
|
||
- **文件路径**: `data/data.xlsx`
|
||
- **工作表**: Sheet1
|
||
- **数据起始行**: 第2行(第1行为表头)
|
||
|
||
#### 1.2 数据提取规则
|
||
|
||
##### 1.2.1 主记录字段
|
||
- **ReceivedAmount** (实收金额)
|
||
- 来源: F列
|
||
- 说明: 支持合并单元格(一行或多行)
|
||
- 处理: 非合并单元格按单行处理
|
||
|
||
- **HandlingFee** (手续费)
|
||
- 来源: G列
|
||
- 处理: 空值自动记为0
|
||
|
||
##### 1.2.2 订单明细字段
|
||
- **Order** (订单列表)
|
||
- 范围: F列合并单元格包含的所有行
|
||
- 包含字段:
|
||
- **OrderNum** (订单号): H列
|
||
- **Amount** (金额): I列
|
||
- **AccountName** (账户名称): O列(支持公式,读取计算结果)
|
||
|
||
##### 1.2.3 数据验证
|
||
- **checkRes** (验证结果): Boolean
|
||
- 计算规则: `ReceivedAmount + HandlingFee ≈ Sum(Order[].Amount)`
|
||
- 容差: 0.01
|
||
- true: 金额匹配
|
||
- false: 金额不匹配,需要人工核对
|
||
|
||
#### 1.3 输出格式
|
||
|
||
**文件**: `res.json`
|
||
|
||
**结构**:
|
||
```json
|
||
[
|
||
{
|
||
"ReceivedAmount": 12125,
|
||
"HandlingFee": 25,
|
||
"Order": [
|
||
{
|
||
"OrderNum": "XLRQD300T25",
|
||
"Amount": 550,
|
||
"AccountName": "24台湾长荣航运"
|
||
},
|
||
{
|
||
"OrderNum": "XLRQD044T25",
|
||
"Amount": 11600,
|
||
"AccountName": "24台湾长荣航运"
|
||
}
|
||
],
|
||
"checkRes": true
|
||
}
|
||
]
|
||
```
|
||
|
||
#### 1.4 特殊处理
|
||
- 跳过订单号为空的行
|
||
- 处理F列合并和非合并单元格混合的情况
|
||
- 读取O列公式计算后的值(data_only=True)
|
||
|
||
---
|
||
|
||
### 模块二: 会计分录生成 (`generate_accounting_entries.py`)
|
||
|
||
#### 2.1 输入输出
|
||
- **输入**: `res.json`
|
||
- **输出**: `AccountingEntries.xlsx`
|
||
|
||
#### 2.2 会计分录规则
|
||
|
||
##### 2.2.1 基本分录
|
||
|
||
每笔 ReceivedAmount 记录生成以下分录:
|
||
|
||
**1) 到账金额 - 借方记录** (每笔记录1条)
|
||
- 科目代码: `1002.02`
|
||
- 科目名称: `银行存款 - 中行USD`
|
||
- 摘要: `美金收款-{OrderNum}`
|
||
- 核算项目: Order[0].AccountName
|
||
- 币别: 美元
|
||
- 汇率: 7.1072 (可配置)
|
||
- 原币金额: ReceivedAmount
|
||
- 金额: ReceivedAmount × 汇率
|
||
|
||
**2) 手续费 - 借方记录** (仅当 HandlingFee > 0)
|
||
- 科目代码: `5603.03`
|
||
- 科目名称: `财务费用-手续费`
|
||
- 摘要: `美金收款-{OrderNum}`
|
||
- 核算项目: 空
|
||
- 币别: 人民币
|
||
- 汇率: 空
|
||
- 原币金额: 空
|
||
- 金额: HandlingFee × 汇率
|
||
|
||
**3) 订单明细 - 贷方记录** (每个Order记录1条)
|
||
- 科目代码: `1122`
|
||
- 科目名称: `应收账款`
|
||
- 应收账款: Order.Amount (显示在"应收账款"列)
|
||
- 摘要: `美金收款-{OrderNum}`
|
||
- 核算项目: Order.AccountName
|
||
- 币别: 美元
|
||
- 汇率: 7.1072 (可配置)
|
||
- 原币金额: Order.Amount
|
||
- 金额: Order.Amount × 汇率
|
||
|
||
##### 2.2.2 特殊规则
|
||
|
||
**空值处理**
|
||
- Order.Amount为null的订单跳过,不生成分录
|
||
|
||
**金额验证**
|
||
- checkRes为false的记录,所有相关分录行标记为粉红色背景(#FAD1D4)
|
||
|
||
#### 2.3 Excel格式设置
|
||
|
||
##### 2.3.1 表头
|
||
- 字段: 到账金额, 手续费, 订单号, 应收账款, 金蝶名称, 摘要, 借/贷, 科目代码(*), 科目名称(*), 核算项目, 币别, 汇率, 原币金额, 金额
|
||
- 样式: 粗体, 蓝色背景(#CCE5FF), 居中对齐
|
||
|
||
##### 2.3.2 单元格合并
|
||
- **到账金额列** (A列): 同一ReceivedAmount的所有分录行合并
|
||
- **手续费列** (B列): 同一ReceivedAmount的所有分录行合并
|
||
- 对齐方式: 垂直居中,水平居中
|
||
|
||
##### 2.3.3 异常标记
|
||
- 条件: 原始记录的 checkRes = false
|
||
- 处理: 该记录产生的所有分录行设置背景色
|
||
- 颜色: #FAD1D4 (粉红色)
|
||
- 目的: 突出显示金额不匹配的记录,便于人工核对
|
||
|
||
##### 2.3.4 列宽设置
|
||
```
|
||
A(到账金额): 12, B(手续费): 10, C(订单号): 18,
|
||
D(应收账款): 12, E(金蝶名称): 25, F(摘要): 25,
|
||
G(借/贷): 8, H(科目代码): 15, I(科目名称): 25,
|
||
J(核算项目): 25, K(币别): 10, L(汇率): 10,
|
||
M(原币金额): 12, N(金额): 15
|
||
```
|
||
|
||
---
|
||
|
||
## 配置参数
|
||
|
||
### 汇率配置
|
||
- **变量名**: `EXCHANGE_RATE`
|
||
- **位置**: `generate_accounting_entries.py` 第12行
|
||
- **默认值**: 7.1072
|
||
- **修改方式**: 直接编辑变量值
|
||
|
||
```python
|
||
# 固定汇率
|
||
EXCHANGE_RATE = 7.1072 # 修改此值
|
||
```
|
||
|
||
---
|
||
|
||
## 数据流程
|
||
|
||
```
|
||
data/data.xlsx (原始数据)
|
||
↓
|
||
[process_excel.py 提取]
|
||
↓
|
||
res.json (中间数据)
|
||
↓
|
||
[generate_accounting_entries.py 生成]
|
||
↓
|
||
AccountingEntries.xlsx (会计分录表)
|
||
```
|
||
|
||
---
|
||
|
||
## 技术要求
|
||
|
||
### 开发语言
|
||
- Python 3.x
|
||
|
||
### 依赖库
|
||
- openpyxl: Excel文件读写
|
||
|
||
### 安装命令
|
||
```bash
|
||
pip install openpyxl --break-system-packages
|
||
```
|
||
|
||
---
|
||
|
||
## 数据示例
|
||
|
||
### 输入示例 (data.xlsx)
|
||
|
||
| 到账金额 | 手续费 | 订单号 | 解款金额 | 金蝶名称 |
|
||
|---------|--------|---------|---------|---------|
|
||
| 12125 | 25 | XLRQD300T25 | 550 | 24台湾长荣航运 |
|
||
| (合并) | (合并) | XLRQD044T25 | 11600 | 24台湾长荣航运 |
|
||
|
||
### 中间数据 (res.json)
|
||
```json
|
||
{
|
||
"ReceivedAmount": 12125,
|
||
"HandlingFee": 25,
|
||
"Order": [
|
||
{"OrderNum": "XLRQD300T25", "Amount": 550, "AccountName": "24台湾长荣航运"},
|
||
{"OrderNum": "XLRQD044T25", "Amount": 11600, "AccountName": "24台湾长荣航运"}
|
||
],
|
||
"checkRes": true
|
||
}
|
||
```
|
||
|
||
### 输出示例 (AccountingEntries.xlsx)
|
||
|
||
| 到账金额 | 手续费 | 订单号 | 应收账款 | 金蝶名称 | 借/贷 | 科目代码 | 科目名称 | 币别 | 原币金额 | 金额 |
|
||
|---------|--------|--------|---------|---------|-------|----------|----------|------|----------|------|
|
||
| 12125 | 25 | XLRQD300T25 | | 24台湾长荣航运 | 借 | 1002.02 | 银行存款 - 中行USD | 美元 | 12125 | 86,174.80 |
|
||
| (合并) | (合并) | XLRQD300T25 | | | 借 | 5603.03 | 财务费用-手续费 | 人民币 | | 177.68 |
|
||
| (合并) | (合并) | XLRQD300T25 | 550 | 24台湾长荣航运 | 贷 | 1122 | 应收账款 | 美元 | 550 | 3,908.96 |
|
||
| (合并) | (合并) | XLRQD044T25 | 11600 | 24台湾长荣航运 | 贷 | 1122 | 应收账款 | 美元 | 11600 | 82,443.52 |
|
||
|
||
---
|
||
|
||
## 验证规则
|
||
|
||
### checkRes计算
|
||
```python
|
||
received_plus_fee = ReceivedAmount + HandlingFee
|
||
order_amount_sum = Sum(Order[].Amount where Amount is not null)
|
||
checkRes = abs(received_plus_fee - order_amount_sum) < 0.01
|
||
```
|
||
|
||
### 异常情况
|
||
- **checkRes = false**: 粉红色背景标记
|
||
- **Order.Amount = null**: 跳过该订单,不生成分录
|
||
- **HandlingFee = null**: 自动记为0
|
||
|
||
---
|
||
|
||
## 测试用例
|
||
|
||
### 测试用例1: 正常单订单
|
||
- 输入: ReceivedAmount=695, HandlingFee=0, Order[0].Amount=695
|
||
- 预期: 2行分录(到账借+订单贷), checkRes=true
|
||
- 应收账款列: 贷方记录显示695
|
||
|
||
### 测试用例2: 正常多订单
|
||
- 输入: ReceivedAmount=12125, HandlingFee=25, Order=[550, 11600]
|
||
- 预期: 4行分录(到账借+手续费借+2个订单贷), checkRes=true
|
||
- 应收账款列: 两条贷方记录分别显示550和11600
|
||
|
||
### 测试用例3: 金额不匹配
|
||
- 输入: ReceivedAmount=17270, HandlingFee=0, Order=[5676, 11450]
|
||
- 预期: checkRes=false, 所有分录行粉红色背景(#FAD1D4)
|
||
|
||
### 测试用例4: 订单金额为空
|
||
- 输入: ReceivedAmount=240, HandlingFee=25, Order[0].Amount=null
|
||
- 预期: 跳过订单明细分录,不报错,只生成到账借方和手续费借方
|
||
|
||
---
|
||
|
||
## 文件清单
|
||
|
||
| 文件名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| data/data.xlsx | 输入 | 原始财务数据 |
|
||
| process_excel.py | 程序 | 数据提取脚本 |
|
||
| res.json | 中间 | 提取的JSON数据 |
|
||
| generate_accounting_entries.py | 程序 | 会计分录生成脚本 |
|
||
| AccountingEntries.xlsx | 输出 | 会计分录表 |
|
||
| analyze_excel.py | 工具 | Excel结构分析工具 |
|
||
| task.md | 文档 | 需求文档(本文件) |
|
||
| User.md | 文档 | 用户使用说明 |
|
||
|
||
---
|
||
|
||
## 性能要求
|
||
|
||
- 支持处理300+行Excel数据
|
||
- 生成500+行会计分录
|
||
- 处理时间 < 10秒
|
||
- 实测: 174条记录生成566条会计分录
|
||
|
||
---
|
||
|
||
## 错误处理
|
||
|
||
### Excel读取错误
|
||
- 文件不存在: 提示并退出
|
||
- Sheet1不存在: 提示并退出
|
||
- 列映射错误: 记录日志,跳过该行
|
||
|
||
### 数据验证错误
|
||
- 空值: 自动处理(HandlingFee=0, 跳过Amount=null)
|
||
- 格式错误: 记录日志,继续处理
|
||
- checkRes=false: 标记但继续处理
|
||
|
||
---
|
||
|
||
## 扩展需求
|
||
|
||
### 未来可能增加的功能
|
||
- [ ] 支持多工作表批量处理
|
||
- [ ] 汇率从配置文件读取
|
||
- [ ] 生成汇总统计报表
|
||
- [ ] 支持导出金蝶格式
|
||
- [ ] 添加数据修正功能
|
||
|
||
---
|
||
|
||
## 版本信息
|
||
|
||
- **版本**: v1.1
|
||
- **最后更新**: 2025-01-17
|
||
- **作者**: Claude Code
|
||
- **状态**: 已完成并测试
|
||
|
||
### 版本历史
|
||
|
||
**v1.1** (2025-01-17)
|
||
- 优化会计分录规则: 移除"到账金额-贷方"记录
|
||
- 每个Order记录都生成对应的贷方分录(无例外)
|
||
- Order生成的贷方记录在"应收账款"列显示Amount金额
|
||
- 简化单订单处理逻辑,移除单订单优化规则
|
||
|
||
**v1.0** (2025-01-17)
|
||
- 初始版本
|
||
- Excel数据提取功能
|
||
- 会计分录生成功能
|
||
- 合并单元格支持
|
||
- 金额验证功能
|
||
- 异常背景色标记
|
||
|
||
---
|
||
|
||
## 备注
|
||
|
||
1. 所有金额计算保留2位小数
|
||
2. 汇率统一使用固定值,不从Excel读取
|
||
3. 合并单元格的值读取左上角单元格
|
||
4. O列公式使用data_only=True读取计算结果
|
||
5. 背景色仅用于标记,不影响数据内容
|