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`字段 + - 已删除的记录不会在列表中显示 + - 已删除的记录不会计入金额统计