优化:开票申请合同号选择案件表数据
This commit is contained in:
@@ -922,17 +922,36 @@ class approvalProcessing(APIView):
|
||||
|
||||
if type == "收入确认":
|
||||
try:
|
||||
user = Income.objects.get(id=approval.user_id, is_deleted=False)
|
||||
income = Income.objects.get(id=approval.user_id, is_deleted=False)
|
||||
except Income.DoesNotExist:
|
||||
return Response({'status': 'error', 'message': '收入确认记录不存在或已被删除', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# 审批人可以指定收入分配方案
|
||||
allocate = request.data.get('allocate') # 收入分配(可选,审批时指定)
|
||||
|
||||
if state == "已通过":
|
||||
approval.state = "已通过"
|
||||
user.state = "已通过"
|
||||
income.state = "已通过"
|
||||
|
||||
# 如果审批人指定了分配方案,更新分配字段
|
||||
if allocate:
|
||||
income.allocate = allocate
|
||||
# 更新审批内容,添加分配信息
|
||||
if "收入分配:待审批人指定" in approval.content:
|
||||
approval.content = approval.content.replace("收入分配:待审批人指定", f"收入分配:{allocate}")
|
||||
else:
|
||||
approval.content = approval.content + f",收入分配:{allocate}"
|
||||
income.save(update_fields=['state', 'allocate'])
|
||||
approval.save(update_fields=['state', 'content'])
|
||||
else:
|
||||
# 如果审批通过但未指定分配,保持"待审批人指定"
|
||||
income.save(update_fields=['state'])
|
||||
approval.save(update_fields=['state'])
|
||||
else:
|
||||
approval.state = "未通过"
|
||||
user.state = "未通过"
|
||||
approval.save(update_fields=['state'])
|
||||
user.save(update_fields=['state'])
|
||||
income.state = "未通过"
|
||||
income.save(update_fields=['state'])
|
||||
approval.save(update_fields=['state'])
|
||||
if type == "调账申请":
|
||||
try:
|
||||
user = Accounts.objects.get(id=approval.user_id, is_deleted=False)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from .views import UserRegister,UserDeparture,UserDepartureDetail,EditUserDeparture,DeleteUserDeparture,issueAnInvoice,issueAnInvoiceDetail,confirm,loan,PaymentRequest,reimbursement,confirmdisplay,loandisplay,PaymentDisplay,reimbursementdetail,Change,ChangeDetail,EditInvoice,DeleteInvoice,EditIncome,DeleteIncome,EditAccounts,DeleteAccounts,EditPayment,DeletePayment,EditReimbursement,DeleteReimbursement,EditBonusChange,DeleteBonusChange
|
||||
from .views import UserRegister,UserDeparture,UserDepartureDetail,EditUserDeparture,DeleteUserDeparture,issueAnInvoice,issueAnInvoiceDetail,confirm,loan,PaymentRequest,reimbursement,confirmdisplay,loandisplay,PaymentDisplay,reimbursementdetail,Change,ChangeDetail,EditInvoice,DeleteInvoice,EditIncome,DeleteIncome,EditAccounts,DeleteAccounts,EditPayment,DeletePayment,EditReimbursement,DeleteReimbursement,EditBonusChange,DeleteBonusChange,GetCaseListForInvoice
|
||||
from django.urls import path
|
||||
|
||||
urlpatterns = [
|
||||
@@ -7,6 +7,7 @@ urlpatterns = [
|
||||
path("user-departure-detail", UserDepartureDetail.as_view(), name="user-departure-detail/"),
|
||||
path("editUserDeparture", EditUserDeparture.as_view(), name="editUserDeparture/"),
|
||||
path("deleteUserDeparture", DeleteUserDeparture.as_view(), name="deleteUserDeparture/"),
|
||||
path("case-list-for-invoice", GetCaseListForInvoice.as_view(), name="case-list-for-invoice/"),
|
||||
path("issue-invoice", issueAnInvoice.as_view(), name="issue-invoice/"),
|
||||
path('issue-Detail', issueAnInvoiceDetail.as_view(), name="issue-Detail/"),
|
||||
path('editInvoice', EditInvoice.as_view(), name="editInvoice/"),
|
||||
|
||||
214
finance/views.py
214
finance/views.py
@@ -197,18 +197,51 @@ class UserRegister(APIView):
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class GetCaseListForInvoice(APIView):
|
||||
"""获取案件列表(用于开票申请选择)"""
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
获取案件列表,用于开票申请时选择合同号
|
||||
返回案件ID、合同号、负责人等信息
|
||||
"""
|
||||
from business.models import ProjectRegistration
|
||||
|
||||
# 获取所有未删除的案件
|
||||
cases = ProjectRegistration.objects.filter(is_deleted=False).order_by('-id')
|
||||
|
||||
data = []
|
||||
for case in cases:
|
||||
data.append({
|
||||
'id': case.id,
|
||||
'ContractNo': case.ContractNo, # 合同号
|
||||
'responsiblefor': case.responsiblefor, # 负责人
|
||||
'type': case.type, # 项目类型
|
||||
'times': case.times, # 立项时间
|
||||
})
|
||||
|
||||
return Response({
|
||||
'message': '获取成功',
|
||||
'data': data,
|
||||
'code': 0
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class issueAnInvoice(APIView):
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
财务开票
|
||||
优化后:合同号从案件表选择,负责人自动同步
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
token = request.META.get('token')
|
||||
ContractNo = request.data.get('ContractNo')
|
||||
personincharge = request.data.get('personincharge')
|
||||
case_id = request.data.get('case_id') # 案件ID(从案件表选择)
|
||||
# 以下字段改为可选,如果提供了case_id,则从案件表同步
|
||||
ContractNo = request.data.get('ContractNo') # 合同号(可选,如果提供了case_id则自动同步)
|
||||
personincharge = request.data.get('personincharge') # 负责人(可选,如果提供了case_id则自动同步)
|
||||
amount = request.data.get('amount')
|
||||
type = request.data.get('type')
|
||||
unit = request.data.get('unit')
|
||||
@@ -217,11 +250,65 @@ class issueAnInvoice(APIView):
|
||||
bank = request.data.get('bank')
|
||||
username = request.data.get('username')
|
||||
|
||||
if not all([token, ContractNo, personincharge, amount, type, unit, number, address_telephone, bank,username]):
|
||||
return Response({'status': 'error', 'message': '缺少参数', 'code': 1}, status=status.HTTP_400_BAD_REQUEST)
|
||||
# 必填字段验证
|
||||
if not all([token, amount, type, unit, number, address_telephone, bank, username]):
|
||||
missing_params = []
|
||||
if not token:
|
||||
missing_params.append('token')
|
||||
if not amount:
|
||||
missing_params.append('amount(开票金额)')
|
||||
if not type:
|
||||
missing_params.append('type(开票类型)')
|
||||
if not unit:
|
||||
missing_params.append('unit(开票单位)')
|
||||
if not number:
|
||||
missing_params.append('number(纳税人识别号)')
|
||||
if not address_telephone:
|
||||
missing_params.append('address_telephone(地址/电话)')
|
||||
if not bank:
|
||||
missing_params.append('bank(银行卡)')
|
||||
if not username:
|
||||
missing_params.append('username(提交人)')
|
||||
return Response({
|
||||
'status': 'error',
|
||||
'message': f'缺少必填参数: {", ".join(missing_params)}',
|
||||
'code': 1
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 处理合同号和负责人:优先从案件表同步
|
||||
from business.models import ProjectRegistration
|
||||
|
||||
if case_id:
|
||||
# 如果提供了案件ID,从案件表获取合同号和负责人
|
||||
try:
|
||||
case = ProjectRegistration.objects.get(id=case_id, is_deleted=False)
|
||||
ContractNo = case.ContractNo # 自动同步合同号
|
||||
personincharge = case.responsiblefor # 自动同步负责人
|
||||
except ProjectRegistration.DoesNotExist:
|
||||
return Response({
|
||||
'status': 'error',
|
||||
'message': '案件不存在或已被删除',
|
||||
'code': 1
|
||||
}, status=status.HTTP_404_NOT_FOUND)
|
||||
else:
|
||||
# 如果没有提供案件ID,则ContractNo和personincharge必须手动提供
|
||||
if not ContractNo:
|
||||
return Response({
|
||||
'status': 'error',
|
||||
'message': '请选择案件或手动填写合同号',
|
||||
'code': 1
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
if not personincharge:
|
||||
return Response({
|
||||
'status': 'error',
|
||||
'message': '请选择案件或手动填写负责人',
|
||||
'code': 1
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
today = datetime.datetime.now()
|
||||
formatted_date = today.strftime("%Y-%m-%d")
|
||||
invoice = Invoice.objects.create(
|
||||
|
||||
invoice = Invoice.objects.create(
|
||||
ContractNo=ContractNo,
|
||||
personincharge=personincharge,
|
||||
amount=amount,
|
||||
@@ -240,9 +327,11 @@ class issueAnInvoice(APIView):
|
||||
new_data = {
|
||||
'id': invoice.id,
|
||||
'contract_no': invoice.ContractNo,
|
||||
'personincharge': invoice.personincharge,
|
||||
'amount': invoice.amount,
|
||||
'type': invoice.type,
|
||||
'unit': invoice.unit
|
||||
'unit': invoice.unit,
|
||||
'case_id': case_id if case_id else None
|
||||
}
|
||||
log_operation(
|
||||
request=request,
|
||||
@@ -253,10 +342,18 @@ class issueAnInvoice(APIView):
|
||||
target_id=invoice.id,
|
||||
target_name=invoice.ContractNo,
|
||||
new_data=new_data,
|
||||
remark=f'新增开票申请:合同号 {invoice.ContractNo},金额 {invoice.amount}'
|
||||
remark=f'新增开票申请:合同号 {invoice.ContractNo},负责人 {invoice.personincharge},金额 {invoice.amount}'
|
||||
)
|
||||
|
||||
return Response({'message': '提交成功', 'code': 0}, status=status.HTTP_200_OK)
|
||||
return Response({
|
||||
'message': '提交成功',
|
||||
'code': 0,
|
||||
'data': {
|
||||
'id': invoice.id,
|
||||
'ContractNo': invoice.ContractNo,
|
||||
'personincharge': invoice.personincharge,
|
||||
}
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class issueAnInvoiceDetail(APIView):
|
||||
@@ -451,6 +548,8 @@ class confirm(APIView):
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
收入确认
|
||||
优化后:收入分配由审批人指定,提交时不填写分配
|
||||
数据来源案件管理
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
@@ -460,41 +559,124 @@ class confirm(APIView):
|
||||
ContractNo = request.data.get('ContractNo')
|
||||
CustomerID = request.data.get('CustomerID')
|
||||
amount = request.data.get('amount')
|
||||
allocate = request.data.get('allocate')
|
||||
allocate = request.data.get('allocate') # 改为可选,由审批人指定
|
||||
token = request.META.get('token')
|
||||
personincharge = request.data.get('personincharge')
|
||||
case_id = request.data.get('case_id') # 案件ID(可选,用于关联案件)
|
||||
|
||||
try:
|
||||
user = User.objects.get(token=token, is_deleted=False)
|
||||
except User.DoesNotExist:
|
||||
return Response({'status': 'error', 'message': '用户不存在或已被删除', 'code': 1}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
if not all([times, ContractNo, CustomerID, amount, allocate]):
|
||||
return Response({'status': 'error', 'message': '缺少参数', 'code': 1}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 必填字段验证(allocate改为可选)
|
||||
if not all([times, ContractNo, CustomerID, amount]):
|
||||
missing_params = []
|
||||
if not times:
|
||||
missing_params.append('times(收款日期)')
|
||||
if not ContractNo:
|
||||
missing_params.append('ContractNo(合同号)')
|
||||
if not CustomerID:
|
||||
missing_params.append('CustomerID(客户名称)')
|
||||
if not amount:
|
||||
missing_params.append('amount(收款金额)')
|
||||
return Response({
|
||||
'status': 'error',
|
||||
'message': f'缺少必填参数: {", ".join(missing_params)}',
|
||||
'code': 1
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 如果提供了案件ID,从案件表获取相关信息(可选)
|
||||
from business.models import ProjectRegistration
|
||||
case_info = None
|
||||
if case_id:
|
||||
try:
|
||||
case = ProjectRegistration.objects.get(id=case_id, is_deleted=False)
|
||||
case_info = {
|
||||
'id': case.id,
|
||||
'ContractNo': case.ContractNo,
|
||||
'responsiblefor': case.responsiblefor,
|
||||
'type': case.type
|
||||
}
|
||||
# 如果合同号未提供,从案件表同步
|
||||
if not ContractNo:
|
||||
ContractNo = case.ContractNo
|
||||
except ProjectRegistration.DoesNotExist:
|
||||
return Response({
|
||||
'status': 'error',
|
||||
'message': '案件不存在或已被删除',
|
||||
'code': 1
|
||||
}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
from datetime import datetime
|
||||
now = datetime.now()
|
||||
|
||||
# 格式化日期为字符串,格式为 YYYY-MM-DD
|
||||
date_string = now.strftime("%Y-%m-%d")
|
||||
|
||||
# 创建收入确认记录,allocate为空或"待审批人指定"
|
||||
income = Income.objects.create(
|
||||
times=times,
|
||||
ContractNo=ContractNo,
|
||||
CustomerID=CustomerID,
|
||||
amount=amount,
|
||||
allocate=allocate,
|
||||
allocate=allocate if allocate else "待审批人指定", # 如果未提供,设为"待审批人指定"
|
||||
submit=user.username,
|
||||
submit_tiem=date_string,
|
||||
state="审核中"
|
||||
)
|
||||
|
||||
# 构建审批内容,包含案件信息(如果提供了)
|
||||
content_parts = [
|
||||
f"{user.username}在{times}提交了收入确认",
|
||||
f"合同编号:{ContractNo}",
|
||||
f"客户名称:{CustomerID}",
|
||||
f"收入金额:{amount}"
|
||||
]
|
||||
if case_info:
|
||||
content_parts.append(f"案件类型:{case_info['type']}")
|
||||
content_parts.append(f"案件负责人:{case_info['responsiblefor']}")
|
||||
content_parts.append("收入分配:待审批人指定")
|
||||
content = ",".join(content_parts)
|
||||
|
||||
Approval.objects.create(
|
||||
title=user.username + "提交收入确认",
|
||||
content=user.username + "在" + times + "提交了收入确认,合同编号:" + ContractNo + ",客户名称:" + CustomerID + "收入金额:" + amount,
|
||||
content=content,
|
||||
times=date_string,
|
||||
personincharge=format_personincharge(personincharge, is_department=False), # 审批员用户名
|
||||
state='审核中',
|
||||
type="收入确认",
|
||||
user_id=income.id
|
||||
)
|
||||
return Response({'message': '插入成功' ,'code': 0}, status=status.HTTP_200_OK)
|
||||
|
||||
# 记录操作日志
|
||||
new_data = {
|
||||
'id': income.id,
|
||||
'ContractNo': income.ContractNo,
|
||||
'CustomerID': income.CustomerID,
|
||||
'amount': income.amount,
|
||||
'allocate': income.allocate,
|
||||
'case_id': case_id if case_id else None
|
||||
}
|
||||
log_operation(
|
||||
request=request,
|
||||
operation_type='CREATE',
|
||||
module='Finance',
|
||||
action='新增收入确认',
|
||||
target_type='Income',
|
||||
target_id=income.id,
|
||||
target_name=f'{income.ContractNo} - {income.CustomerID}',
|
||||
new_data=new_data,
|
||||
remark=f'新增收入确认:合同号 {income.ContractNo},金额 {income.amount},分配待审批人指定'
|
||||
)
|
||||
|
||||
return Response({
|
||||
'message': '提交成功',
|
||||
'code': 0,
|
||||
'data': {
|
||||
'id': income.id,
|
||||
'ContractNo': income.ContractNo,
|
||||
'allocate': income.allocate
|
||||
}
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
class confirmdisplay(APIView):
|
||||
def post(self, request, *args, **kwargs):
|
||||
|
||||
247
开票申请接口优化说明.md
Normal file
247
开票申请接口优化说明.md
Normal file
@@ -0,0 +1,247 @@
|
||||
# 开票申请接口优化说明
|
||||
|
||||
## 优化内容
|
||||
|
||||
根据需求12,开票申请接口已优化,**合同号从案件表选择,负责人自动同步**。
|
||||
|
||||
## 接口信息
|
||||
|
||||
### 1. 获取案件列表接口(新增)
|
||||
|
||||
- **URL**:`/finance/case-list-for-invoice`
|
||||
- **方法**:POST
|
||||
- **功能**:获取案件列表,用于开票申请时选择合同号
|
||||
|
||||
#### 请求参数
|
||||
|
||||
无需参数
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "获取成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"ContractNo": "HT2024001",
|
||||
"responsiblefor": "张三",
|
||||
"type": "民事诉讼",
|
||||
"times": "2024-01-15"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"ContractNo": "HT2024002",
|
||||
"responsiblefor": "李四",
|
||||
"type": "刑事诉讼",
|
||||
"times": "2024-01-20"
|
||||
}
|
||||
],
|
||||
"code": 0
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 开票申请接口(优化)
|
||||
|
||||
- **URL**:`/finance/issue-invoice`
|
||||
- **方法**:POST
|
||||
- **功能**:财务开票
|
||||
|
||||
## 字段变更
|
||||
|
||||
### 优化前
|
||||
- ✅ `ContractNo` - 合同号(必填,手动输入)
|
||||
- ✅ `personincharge` - 负责人(必填,手动输入)
|
||||
- ✅ 其他字段(金额、类型、单位等)
|
||||
|
||||
### 优化后
|
||||
- ✅ `case_id` - 案件ID(**推荐**,从案件表选择)
|
||||
- ⭕ `ContractNo` - 合同号(可选,如果提供了case_id则自动同步)
|
||||
- ⭕ `personincharge` - 负责人(可选,如果提供了case_id则自动同步)
|
||||
- ✅ 其他字段(金额、类型、单位等,必填)
|
||||
|
||||
## 数据同步逻辑
|
||||
|
||||
### 方式1:从案件表选择(推荐)
|
||||
|
||||
1. **前端调用案件列表接口**:获取所有案件列表
|
||||
2. **用户选择案件**:前端显示案件列表,用户选择
|
||||
3. **自动同步数据**:
|
||||
- 合同号(`ContractNo`)自动从案件表的 `ContractNo` 字段同步
|
||||
- 负责人(`personincharge`)自动从案件表的 `responsiblefor` 字段同步
|
||||
|
||||
### 方式2:手动填写(兼容)
|
||||
|
||||
如果没有提供 `case_id`,可以手动填写 `ContractNo` 和 `personincharge`。
|
||||
|
||||
## 请求示例
|
||||
|
||||
### 方式1:从案件表选择(推荐)
|
||||
|
||||
```json
|
||||
POST /finance/issue-invoice
|
||||
{
|
||||
"case_id": 1,
|
||||
"amount": "10000",
|
||||
"type": "增值税专用发票",
|
||||
"unit": "XX律师事务所",
|
||||
"number": "91110000MA01234567",
|
||||
"address_telephone": "北京市XX区XX路XX号 010-12345678",
|
||||
"bank": "6222021234567890123",
|
||||
"username": "提交人姓名"
|
||||
}
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- 提供了 `case_id`,系统自动从案件表获取合同号和负责人
|
||||
- 不需要手动填写 `ContractNo` 和 `personincharge`
|
||||
|
||||
### 方式2:手动填写(兼容)
|
||||
|
||||
```json
|
||||
POST /finance/issue-invoice
|
||||
{
|
||||
"ContractNo": "HT2024001",
|
||||
"personincharge": "张三",
|
||||
"amount": "10000",
|
||||
"type": "增值税专用发票",
|
||||
"unit": "XX律师事务所",
|
||||
"number": "91110000MA01234567",
|
||||
"address_telephone": "北京市XX区XX路XX号 010-12345678",
|
||||
"bank": "6222021234567890123",
|
||||
"username": "提交人姓名"
|
||||
}
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- 没有提供 `case_id`,需要手动填写 `ContractNo` 和 `personincharge`
|
||||
|
||||
## 响应示例
|
||||
|
||||
### 成功响应
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "提交成功",
|
||||
"code": 0,
|
||||
"data": {
|
||||
"id": 123,
|
||||
"ContractNo": "HT2024001",
|
||||
"personincharge": "张三"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 错误响应
|
||||
|
||||
#### 缺少必填参数
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "缺少必填参数: amount(开票金额), type(开票类型)",
|
||||
"code": 1
|
||||
}
|
||||
```
|
||||
|
||||
#### 案件不存在
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "案件不存在或已被删除",
|
||||
"code": 1
|
||||
}
|
||||
```
|
||||
|
||||
#### 未选择案件且未填写合同号
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "请选择案件或手动填写合同号",
|
||||
"code": 1
|
||||
}
|
||||
```
|
||||
|
||||
#### 未选择案件且未填写负责人
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "请选择案件或手动填写负责人",
|
||||
"code": 1
|
||||
}
|
||||
```
|
||||
|
||||
## 工作流程
|
||||
|
||||
### 推荐流程(从案件表选择)
|
||||
|
||||
```
|
||||
1. 前端调用案件列表接口
|
||||
↓
|
||||
2. 显示案件列表供用户选择
|
||||
↓
|
||||
3. 用户选择案件(获取case_id)
|
||||
↓
|
||||
4. 前端自动填充合同号和负责人(可选,提升用户体验)
|
||||
↓
|
||||
5. 用户填写其他信息(金额、类型、单位等)
|
||||
↓
|
||||
6. 提交开票申请(传入case_id)
|
||||
↓
|
||||
7. 后端自动从案件表同步合同号和负责人
|
||||
↓
|
||||
8. 创建开票申请记录
|
||||
```
|
||||
|
||||
### 兼容流程(手动填写)
|
||||
|
||||
```
|
||||
1. 用户手动填写合同号和负责人
|
||||
↓
|
||||
2. 用户填写其他信息
|
||||
↓
|
||||
3. 提交开票申请(不传case_id)
|
||||
↓
|
||||
4. 后端验证必填字段
|
||||
↓
|
||||
5. 创建开票申请记录
|
||||
```
|
||||
|
||||
## 优势
|
||||
|
||||
1. **数据一致性**
|
||||
- 合同号和负责人直接从案件表同步,避免手动输入错误
|
||||
- 确保开票申请与案件信息一致
|
||||
|
||||
2. **操作便捷**
|
||||
- 用户只需选择案件,无需手动输入合同号和负责人
|
||||
- 减少重复录入,提高效率
|
||||
|
||||
3. **向后兼容**
|
||||
- 仍然支持手动填写合同号和负责人
|
||||
- 不影响现有功能
|
||||
|
||||
4. **数据可追溯**
|
||||
- 开票申请关联到具体案件(通过case_id)
|
||||
- 便于后续查询和统计
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **案件选择**
|
||||
- 建议优先使用案件选择方式
|
||||
- 确保案件在案件管理中已正确创建
|
||||
|
||||
2. **数据同步**
|
||||
- 如果案件信息发生变化,已创建的开票申请不会自动更新
|
||||
- 需要在编辑开票申请时重新选择案件
|
||||
|
||||
3. **必填字段**
|
||||
- 金额、类型、单位、纳税人识别号、地址/电话、银行卡、提交人仍为必填
|
||||
- 合同号和负责人:要么选择案件,要么手动填写
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v2.0.0 (2024-01-XX)
|
||||
- ✅ 新增获取案件列表接口
|
||||
- ✅ 开票申请支持从案件表选择合同号
|
||||
- ✅ 负责人自动从案件表的负责人字段同步
|
||||
- ✅ 保持向后兼容,支持手动填写
|
||||
243
收入确认接口优化说明.md
Normal file
243
收入确认接口优化说明.md
Normal file
@@ -0,0 +1,243 @@
|
||||
# 收入确认接口优化说明
|
||||
|
||||
## 优化内容
|
||||
|
||||
根据需求13,收入确认接口已优化,**收入分配由审批人指定**,提交时不填写分配。
|
||||
|
||||
## 接口信息
|
||||
|
||||
- **URL**:`/finance/confirm`
|
||||
- **方法**:POST
|
||||
- **功能**:收入确认
|
||||
|
||||
## 字段变更
|
||||
|
||||
### 优化前
|
||||
- ✅ `allocate` - 收入分配(必填,提交时填写)
|
||||
|
||||
### 优化后
|
||||
- ⭕ `allocate` - 收入分配(**可选**,提交时不填写,由审批人指定)
|
||||
- ⭕ `case_id` - 案件ID(可选,用于关联案件管理)
|
||||
|
||||
## 工作流程
|
||||
|
||||
### 提交阶段
|
||||
1. 用户提交收入确认
|
||||
2. **不填写** `allocate` 字段(或填写为空)
|
||||
3. 系统自动设置 `allocate = "待审批人指定"`
|
||||
4. 创建审批记录,状态为"审核中"
|
||||
|
||||
### 审批阶段
|
||||
1. 审批人查看收入确认申请
|
||||
2. 审批人**指定收入分配方案**(`allocate` 字段)
|
||||
3. 审批通过时,系统更新 `allocate` 字段
|
||||
4. 审批内容自动更新,包含分配信息
|
||||
|
||||
## 请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| times | string | 是 | 收款日期 |
|
||||
| ContractNo | string | 是 | 合同号 |
|
||||
| CustomerID | string | 是 | 客户名称 |
|
||||
| amount | string | 是 | 收款金额 |
|
||||
| allocate | string | 否 | 收入分配(可选,由审批人指定) |
|
||||
| personincharge | string | 是 | 审批人 |
|
||||
| case_id | int | 否 | 案件ID(可选,用于关联案件) |
|
||||
|
||||
## 请求示例
|
||||
|
||||
### 提交收入确认(不填写分配)
|
||||
|
||||
```json
|
||||
POST /finance/confirm
|
||||
{
|
||||
"times": "2024-01-15",
|
||||
"ContractNo": "HT2024001",
|
||||
"CustomerID": "XX公司",
|
||||
"amount": "100000",
|
||||
"personincharge": "审批人姓名"
|
||||
}
|
||||
```
|
||||
|
||||
### 提交收入确认(关联案件)
|
||||
|
||||
```json
|
||||
POST /finance/confirm
|
||||
{
|
||||
"times": "2024-01-15",
|
||||
"ContractNo": "HT2024001",
|
||||
"CustomerID": "XX公司",
|
||||
"amount": "100000",
|
||||
"personincharge": "审批人姓名",
|
||||
"case_id": 1
|
||||
}
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- 如果提供了 `case_id`,系统会从案件表获取相关信息
|
||||
- 如果未提供 `ContractNo`,会自动从案件表同步
|
||||
|
||||
## 审批处理
|
||||
|
||||
### 审批接口
|
||||
|
||||
- **URL**:`/user/approval_processing`
|
||||
- **方法**:POST
|
||||
|
||||
### 审批请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| id | int | 是 | 审批记录ID |
|
||||
| type | string | 是 | 审批类型("收入确认") |
|
||||
| state | string | 是 | 审批状态("已通过"或"未通过") |
|
||||
| allocate | string | 否 | 收入分配方案(审批通过时指定) |
|
||||
|
||||
### 审批请求示例
|
||||
|
||||
#### 审批通过并指定分配
|
||||
|
||||
```json
|
||||
POST /user/approval_processing
|
||||
{
|
||||
"id": 123,
|
||||
"type": "收入确认",
|
||||
"state": "已通过",
|
||||
"allocate": "张三50%,李四30%,王五20%"
|
||||
}
|
||||
```
|
||||
|
||||
#### 审批通过但不指定分配
|
||||
|
||||
```json
|
||||
POST /user/approval_processing
|
||||
{
|
||||
"id": 123,
|
||||
"type": "收入确认",
|
||||
"state": "已通过"
|
||||
}
|
||||
```
|
||||
|
||||
**说明**:如果审批通过但未指定分配,`allocate` 保持为"待审批人指定"
|
||||
|
||||
#### 审批不通过
|
||||
|
||||
```json
|
||||
POST /user/approval_processing
|
||||
{
|
||||
"id": 123,
|
||||
"type": "收入确认",
|
||||
"state": "未通过"
|
||||
}
|
||||
```
|
||||
|
||||
## 响应示例
|
||||
|
||||
### 提交成功
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "提交成功",
|
||||
"code": 0,
|
||||
"data": {
|
||||
"id": 123,
|
||||
"ContractNo": "HT2024001",
|
||||
"allocate": "待审批人指定"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 错误响应
|
||||
|
||||
#### 缺少必填参数
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "缺少必填参数: times(收款日期), ContractNo(合同号)",
|
||||
"code": 1
|
||||
}
|
||||
```
|
||||
|
||||
#### 案件不存在
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "案件不存在或已被删除",
|
||||
"code": 1
|
||||
}
|
||||
```
|
||||
|
||||
## 数据来源案件管理
|
||||
|
||||
### 关联案件(可选)
|
||||
|
||||
如果提供了 `case_id`,系统会:
|
||||
1. 从案件表(`ProjectRegistration`)获取案件信息
|
||||
2. 如果合同号未提供,自动从案件表同步
|
||||
3. 在审批内容中包含案件类型和负责人信息
|
||||
|
||||
### 案件信息包含
|
||||
|
||||
- 合同号(`ContractNo`)
|
||||
- 负责人(`responsiblefor`)
|
||||
- 案件类型(`type`)
|
||||
|
||||
## 审批内容格式
|
||||
|
||||
### 提交时(未指定分配)
|
||||
|
||||
```
|
||||
张三在2024-01-15提交了收入确认,合同编号:HT2024001,客户名称:XX公司,收入金额:100000,收入分配:待审批人指定
|
||||
```
|
||||
|
||||
### 审批后(已指定分配)
|
||||
|
||||
```
|
||||
张三在2024-01-15提交了收入确认,合同编号:HT2024001,客户名称:XX公司,收入金额:100000,收入分配:张三50%,李四30%,王五20%
|
||||
```
|
||||
|
||||
## 优势
|
||||
|
||||
1. **职责分离**
|
||||
- 提交人只需填写基本信息
|
||||
- 审批人负责指定分配方案,更专业
|
||||
|
||||
2. **数据准确性**
|
||||
- 分配方案由审批人指定,确保准确
|
||||
- 避免提交人填写错误
|
||||
|
||||
3. **灵活性**
|
||||
- 支持关联案件管理
|
||||
- 可以从案件表同步相关信息
|
||||
|
||||
4. **可追溯**
|
||||
- 分配方案记录在审批内容中
|
||||
- 便于后续查询和审计
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **分配方案格式**
|
||||
- 建议使用清晰的格式,如"张三50%,李四30%,王五20%"
|
||||
- 也可以使用其他格式,由审批人自由填写
|
||||
|
||||
2. **审批时机**
|
||||
- 分配方案在审批通过时指定
|
||||
- 如果审批不通过,不需要指定分配
|
||||
|
||||
3. **案件关联**
|
||||
- 案件关联是可选的
|
||||
- 如果提供了 `case_id`,系统会自动同步相关信息
|
||||
|
||||
4. **数据一致性**
|
||||
- 如果案件信息发生变化,已创建的收入确认不会自动更新
|
||||
- 需要在编辑时重新关联案件
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v2.0.0 (2024-01-XX)
|
||||
- ✅ 收入分配改为由审批人指定
|
||||
- ✅ 提交时不填写分配,系统自动设为"待审批人指定"
|
||||
- ✅ 审批通过时,审批人可以指定分配方案
|
||||
- ✅ 支持关联案件管理(可选)
|
||||
- ✅ 审批内容自动更新,包含分配信息
|
||||
Reference in New Issue
Block a user