diff --git a/User/utils.py b/User/utils.py
index 76da499..a5993fa 100644
--- a/User/utils.py
+++ b/User/utils.py
@@ -592,9 +592,10 @@ def process_approval_flow(approval, business_record, current_approver, state,
approval.content = approval.content + ",已抄送财务部"
approval.save(update_fields=['state', 'personincharge', 'content'])
- if business_record and hasattr(business_record, 'state'):
- business_record.state = "待财务处理"
- business_record.save(update_fields=['state'])
+ if business_record and hasattr(business_record, 'state'):
+ # 抄送财务时就已经审核通过,财务只是查看
+ business_record.state = "已通过"
+ business_record.save(update_fields=['state'])
return False, None
# 有审核人列表(多人团队),按顺序流转
@@ -636,10 +637,11 @@ def process_approval_flow(approval, business_record, current_approver, state,
approval.save(update_fields=['state', 'personincharge', 'content'])
if business_record and hasattr(business_record, 'state'):
- business_record.state = "待财务处理"
+ # 抄送财务时就已经审核通过,财务只是查看
+ business_record.state = "已通过"
business_record.save(update_fields=['state'])
- logger.info(f"process_approval_flow: 已抄送财务部,personincharge=%s, state=已抄送财务", approval.personincharge)
+ logger.info(f"process_approval_flow: 已抄送财务部,personincharge=%s, state=已抄送财务,业务记录状态=已通过", approval.personincharge)
return False, None
@@ -756,9 +758,9 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
user_id=str(user_id)
)
- # 更新业务记录状态
+ # 更新业务记录状态:抄送财务时就已经审核通过,财务只是查看
if business_record:
- business_record.state = "待财务处理"
+ business_record.state = "已通过"
business_record.save(update_fields=['state'])
return approval, None, False
@@ -837,9 +839,9 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
user_id=str(user_id)
)
- # 更新业务记录状态
+ # 更新业务记录状态:抄送财务时就已经审核通过,财务只是查看
if business_record:
- business_record.state = "待财务处理"
+ business_record.state = "已通过"
business_record.save(update_fields=['state'])
return approval, None, False
\ No newline at end of file
diff --git a/User/views.py b/User/views.py
index bf2a7a6..4658479 100644
--- a/User/views.py
+++ b/User/views.py
@@ -1160,16 +1160,17 @@ class approvalProcessing(APIView):
# 检查当前是否已经是财务审核
if is_finance_personincharge(approval.personincharge) and approval.state == "已抄送财务":
- # 财务部审核逻辑:财务部只需要一个人审核完即可完成
- if state == "已通过":
- approval.state = "已通过"
- income.state = "已通过"
- else:
+ # 财务部只是查看,不需要审核,状态已经是"已通过"
+ # 如果财务标记为未通过,则更新状态
+ if state == "未通过":
approval.state = "未通过"
income.state = "未通过"
- income.save(update_fields=['state'])
- approval.save(update_fields=['state'])
- return Response({'message': '处理成功', 'code': 0}, status=status.HTTP_200_OK)
+ income.save(update_fields=['state'])
+ approval.save(update_fields=['state'])
+ return Response({'message': '处理成功', 'code': 0}, status=status.HTTP_200_OK)
+ else:
+ # 财务查看通过,状态保持"已通过"(已经是"已通过")
+ return Response({'message': '处理成功', 'code': 0}, status=status.HTTP_200_OK)
# 负责人填写收入分配
allocate = request.data.get('allocate') # 收入分配(负责人必须填写)
@@ -1185,7 +1186,8 @@ class approvalProcessing(APIView):
# 更新收入分配
income.allocate = allocate
- income.state = "待财务处理" # 更新状态为待财务处理
+ # 负责人填写收入分配后,抄送财务时就已经审核通过,财务只是查看
+ income.state = "已通过"
# 更新审批内容,添加分配信息
if "收入分配:待负责人指定" in approval.content:
@@ -1199,7 +1201,7 @@ class approvalProcessing(APIView):
from User.utils import get_finance_personincharge_value
finance_personincharge = get_finance_personincharge_value()
- # 更新审批记录,抄送给财务
+ # 更新审批记录,抄送给财务(状态已经是"已通过")
approval.personincharge = finance_personincharge
approval.state = "已抄送财务"
approval.content = approval.content + ",已抄送财务部"
diff --git a/收入确认接口文档.md b/收入确认接口文档.md
new file mode 100644
index 0000000..072422d
--- /dev/null
+++ b/收入确认接口文档.md
@@ -0,0 +1,399 @@
+# 收入确认接口文档
+
+## 目录
+1. [新增收入确认](#1-新增收入确认)
+2. [收入确认列表](#2-收入确认列表)
+3. [编辑收入确认](#3-编辑收入确认)
+4. [删除收入确认](#4-删除收入确认)
+5. [获取审核人列表](#5-获取审核人列表)
+
+---
+
+## 1. 新增收入确认
+
+**接口地址:** `POST /finance/confirm`
+
+**接口描述:** 创建收入确认记录,支持通过案件ID或合同号关联案件,自动同步案件信息,并创建审核待办。
+
+### 请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| token | String | 是 | 用户认证token(请求头) |
+| times | String | 是 | 收款日期(格式:YYYY-MM-DD) |
+| amount | String | 是 | 收款金额 |
+| case_id | Integer | 否 | 案件管理ID(Case表),与project_id、ContractNo三选一 |
+| project_id | Integer | 否 | 立项登记ID(ProjectRegistration表),与case_id、ContractNo三选一 |
+| ContractNo | String | 否 | 合同号,与case_id、project_id三选一 |
+| CustomerID | String | 否 | 客户名称(如果通过案件ID或合同号找到案件则自动同步) |
+| allocate | String | 否 | 收入分配(财务提交时不填写,由负责人填写,默认:"待负责人指定") |
+| approvers | Array/String | 否 | 审核人列表(多人团队时需要)
- 推荐格式:用户ID数组,如 `[1, 2, 3]` 或 `["1", "2", "3"]`
- 兼容格式:用户名数组,如 `["张三", "李四"]`
- 字符串格式:逗号分隔,如 `"1,2,3"` 或 `"张三,李四"` |
+| personincharge | String | 否 | 兼容旧接口,会自动转换为approvers |
+
+### 请求示例
+
+```json
+{
+ "case_id": 123,
+ "times": "2024-01-15",
+ "amount": "10000",
+ "allocate": "待负责人指定"
+}
+```
+
+或
+
+```json
+{
+ "project_id": 456,
+ "times": "2024-01-15",
+ "amount": "10000"
+}
+```
+
+或
+
+```json
+{
+ "ContractNo": "HT2024001",
+ "times": "2024-01-15",
+ "amount": "10000",
+ "approvers": [1, 2, 3]
+}
+```
+
+### 返回数据
+
+**成功响应:**
+```json
+{
+ "message": "提交成功",
+ "code": 0,
+ "data": {
+ "id": 1,
+ "ContractNo": "HT2024001",
+ "CustomerID": "某某公司",
+ "responsible_person": "张三",
+ "state": "审核中",
+ "approval_id": 10,
+ "needs_approval": true
+ }
+}
+```
+
+**失败响应:**
+```json
+{
+ "status": "error",
+ "message": "缺少必填参数: times(收款日期), amount(收款金额)",
+ "code": 1
+}
+```
+
+### 字段说明
+
+- **case_id / project_id / ContractNo**:三选一,优先级:case_id > project_id > ContractNo
+- **自动同步字段**:如果通过案件ID或合同号找到案件,会自动同步:
+ - `ContractNo`:合同号
+ - `CustomerID`:客户名称
+ - `responsible_person`:负责人信息
+- **审核流程**:
+ - 个人团队:直接抄送财务,状态为"已通过"(财务只是查看)
+ - 团队类型:需要审核人审核,状态为"审核中"
+ - 如果传入了`approvers`,使用传入的审核人
+ - 如果没有传入,使用团队配置的审核人
+ - **重要**:抄送财务时状态已经是"已通过",财务只是查看,不需要再次审核
+
+---
+
+## 2. 收入确认列表
+
+**接口地址:** `POST /finance/confirmdisplay`
+
+**接口描述:** 分页查询收入确认列表,支持按时间范围、客户名称筛选。权限控制:律师只能看自己的数据,管委会和财务部能查看所有。
+
+### 请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| token | String | 是 | 用户认证token(请求头) |
+| page | Integer | 是 | 页码(从1开始) |
+| per_page | Integer | 是 | 每页数量 |
+| times | String | 否 | 开始日期(格式:YYYY-MM-DD) |
+| end_time | String | 否 | 结束日期(格式:YYYY-MM-DD) |
+| CustomerID | String | 否 | 客户名称(模糊搜索) |
+
+### 请求示例
+
+```json
+{
+ "page": 1,
+ "per_page": 10,
+ "times": "2024-01-01",
+ "end_time": "2024-01-31",
+ "CustomerID": "某某公司"
+}
+```
+
+### 返回数据
+
+**成功响应:**
+```json
+{
+ "message": "展示成功",
+ "total": 50,
+ "code": 0,
+ "data": [
+ {
+ "id": 1,
+ "times": "2024-01-15",
+ "ContractNo": "HT2024001",
+ "CustomerID": "某某公司",
+ "amount": "10000",
+ "allocate": "待负责人指定",
+ "state": "审核中",
+ "submit": "张三",
+ "submit_tiem": "2024-01-15"
+ }
+ ]
+}
+```
+
+### 字段说明
+
+- **权限控制**:
+ - 管委会角色、财务部角色、财务部部门:可以查看所有数据
+ - 其他用户:只能查看自己提交的数据(`submit`字段等于当前用户名)
+- **state状态值**:
+ - `"审核中"`:正在审核中
+ - `"待负责人填写分配"`:待负责人填写收入分配
+ - `"已通过"`:审核通过(抄送财务时就已经是"已通过",财务只是查看)
+ - `"未通过"`:审核未通过
+
+---
+
+## 3. 编辑收入确认
+
+**接口地址:** `POST /finance/editIncome`
+
+**接口描述:** 编辑收入确认记录,只能修改部分字段。
+
+### 请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| token | String | 是 | 用户认证token(请求头) |
+| id | Integer | 是 | 收入确认记录ID |
+| times | String | 否 | 收款日期(格式:YYYY-MM-DD) |
+| ContractNo | String | 否 | 合同号 |
+| CustomerID | String | 否 | 客户名称 |
+| amount | String | 否 | 收款金额 |
+| allocate | String | 否 | 收入分配 |
+
+### 请求示例
+
+```json
+{
+ "id": 1,
+ "times": "2024-01-20",
+ "amount": "15000",
+ "allocate": "50%分配给A,50%分配给B"
+}
+```
+
+### 返回数据
+
+**成功响应:**
+```json
+{
+ "message": "编辑成功",
+ "code": 0
+}
+```
+
+**失败响应:**
+```json
+{
+ "status": "error",
+ "message": "缺少参数id",
+ "code": 1
+}
+```
+
+---
+
+## 4. 删除收入确认
+
+**接口地址:** `POST /finance/deleteIncome`
+
+**接口描述:** 软删除收入确认记录。
+
+### 请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| token | String | 是 | 用户认证token(请求头) |
+| id | Integer | 是 | 收入确认记录ID |
+
+### 请求示例
+
+```json
+{
+ "id": 1
+}
+```
+
+### 返回数据
+
+**成功响应:**
+```json
+{
+ "message": "删除成功",
+ "code": 0
+}
+```
+
+**失败响应:**
+```json
+{
+ "status": "error",
+ "message": "收入确认不存在",
+ "code": 1
+}
+```
+
+---
+
+## 5. 获取审核人列表
+
+**接口地址:** `POST /finance/approvers-list-for-income-confirm`
+
+**接口描述:** 获取收入确认时可选的审核人列表,返回所有未删除的用户列表,格式简洁,适合下拉选择。
+
+### 请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| token | String | 是 | 用户认证token(请求头) |
+| username | String | 否 | 用户名搜索(模糊匹配) |
+
+### 请求示例
+
+```json
+{
+ "username": "张"
+}
+```
+
+### 返回数据
+
+**成功响应:**
+```json
+{
+ "message": "获取审核人列表成功",
+ "code": 0,
+ "total": 20,
+ "data": [
+ {
+ "id": 1,
+ "username": "张三",
+ "account": "zhangsan",
+ "position": "律师"
+ },
+ {
+ "id": 2,
+ "username": "李四",
+ "account": "lisi",
+ "position": "律师"
+ }
+ ]
+}
+```
+
+### 字段说明
+
+- 自动排除admin用户(超级管理员)
+- 按用户名排序
+- 支持用户名模糊搜索
+
+---
+
+## 数据模型
+
+### Income 模型字段
+
+| 字段名 | 类型 | 说明 |
+|--------|------|------|
+| id | Integer | 主键ID |
+| times | String | 收款日期 |
+| ContractNo | String | 合同号 |
+| CustomerID | String | 客户名称 |
+| amount | String | 收款金额 |
+| allocate | String | 收入分配 |
+| submit | String | 提交人用户名 |
+| submit_tiem | String | 提交时间 |
+| state | String | 状态(审核中/待财务处理/待负责人填写分配/已通过/未通过) |
+| approvers_order | Text | 审核人顺序(JSON格式,如:`["张三","李四","王五"]`) |
+| is_deleted | Boolean | 软删除标记 |
+
+---
+
+## 审核流程说明
+
+### 审核状态流转
+
+1. **提交阶段**:
+ - 个人团队:状态为`"已通过"`,直接抄送财务(财务只是查看)
+ - 团队类型:状态为`"审核中"`,创建待办事项
+
+2. **审核阶段**:
+ - 审核人依次审核(按`approvers_order`顺序)
+ - 如果审核未通过,状态变为`"未通过"`
+ - 如果所有审核人通过,状态变为`"待负责人填写分配"`
+
+3. **负责人填写分配**:
+ - 负责人填写`allocate`字段(收入分配)
+ - 状态变为`"已通过"`,抄送财务(财务只是查看,不需要再次审核)
+
+4. **财务查看**:
+ - 抄送财务时状态已经是`"已通过"`,财务只是查看
+ - 如果财务发现问题,可以标记为`"未通过"`,状态变为`"未通过"`
+
+### 金额统计规则
+
+- 在案件分页接口中,收入确认金额只统计`state="已通过"`的记录
+- 只有审核通过的收入确认才会计入案件的收入确认金额统计
+
+---
+
+## 错误码说明
+
+| 错误码 | 说明 |
+|--------|------|
+| 0 | 成功 |
+| 1 | 失败(具体错误信息在message字段中) |
+
+---
+
+## 注意事项
+
+1. **案件关联**:
+ - 优先使用`case_id`(案件管理ID)
+ - 其次使用`project_id`(立项登记ID)
+ - 最后使用`ContractNo`(合同号)
+ - 如果通过案件ID或合同号找到案件,会自动同步合同号、客户名称、负责人信息
+
+2. **审核人参数**:
+ - 推荐使用用户ID数组格式:`[1, 2, 3]`
+ - 兼容用户名数组格式:`["张三", "李四"]`
+ - 如果未传入审核人且团队类型为团队,会使用团队配置的审核人
+
+3. **权限控制**:
+ - 收入确认列表接口有权限控制
+ - 管委会、财务部可以查看所有数据
+ - 其他用户只能查看自己提交的数据
+
+4. **软删除**:
+ - 删除操作是软删除,只更新`is_deleted`字段
+ - 已删除的记录不会在列表中显示
+ - 已删除的记录不会计入金额统计