diff --git a/business/migrations/0010_update_case_invoice_payment_defaults.py b/business/migrations/0010_update_case_invoice_payment_defaults.py new file mode 100644 index 0000000..d47a3c0 --- /dev/null +++ b/business/migrations/0010_update_case_invoice_payment_defaults.py @@ -0,0 +1,45 @@ +import re +from django.db import migrations, models + + +def normalize_amount_value(value): + if value is None: + return "0" + value_str = str(value).strip() + if value_str in ["", "未开票", "None", "null"]: + return "0" + numbers = re.findall(r"\d+\.?\d*", value_str) + return numbers[0] if numbers else "0" + + +def normalize_case_amounts(apps, schema_editor): + Case = apps.get_model("business", "Case") + for case in Case.objects.all().iterator(): + invoice_status = normalize_amount_value(case.invoice_status) + paymentcollection = normalize_amount_value(case.paymentcollection) + if invoice_status != case.invoice_status or paymentcollection != case.paymentcollection: + Case.objects.filter(id=case.id).update( + invoice_status=invoice_status, + paymentcollection=paymentcollection, + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ("business", "0009_alter_case_paymentcollection_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="case", + name="invoice_status", + field=models.CharField(default="0", max_length=100), + ), + migrations.AlterField( + model_name="case", + name="paymentcollection", + field=models.CharField(blank=True, default="0", max_length=100), + ), + migrations.RunPython(normalize_case_amounts, reverse_code=migrations.RunPython.noop), + ] diff --git a/business/models.py b/business/models.py index 6cfa9d9..99a8853 100644 --- a/business/models.py +++ b/business/models.py @@ -57,8 +57,8 @@ class Case(models.Model): ChangeItem = models.TextField(null=True, blank=True) # 变更事项 ChangeReason = models.TextField(null=True, blank=True) # 变更原因 ChangeAgreement = models.TextField(null=True, blank=True) # 变更协议(URL列表) - invoice_status = models.CharField(max_length=100, default='未开票') # 已开票 - paymentcollection = models.CharField(max_length=100, default='', blank=True) # 已收款 + invoice_status = models.CharField(max_length=100, default='0') # 已开票 + paymentcollection = models.CharField(max_length=100, default='0', blank=True) # 已收款 state = models.CharField(max_length=100) # 状态 approvers_order = models.TextField(null=True, blank=True) # 审核人顺序(JSON格式存储,如:["张三","李四","王五"]) is_deleted = models.BooleanField(default=False) # 软删除标记 diff --git a/business/views.py b/business/views.py index 65e9cc2..b415281 100644 --- a/business/views.py +++ b/business/views.py @@ -4,6 +4,7 @@ from rest_framework import status import json import ast import re +from decimal import Decimal, InvalidOperation from User.models import User, Approval from User.utils import log_operation, normalize_approvers_param, build_missing_approvers_message from .models import PreFiling, ProjectRegistration, Bid, Case, Invoice, Caselog, SealApplication, Warehousing, \ @@ -101,6 +102,18 @@ def build_case_approval_content(project_registration, times, change_request=Fals return ",".join(content_parts) + +def normalize_amount_value(value): + if value is None: + return "0" + if isinstance(value, (int, float, Decimal)): + return str(value) + value_str = str(value).strip() + if value_str in ["", "未开票", "None", "null"]: + return "0" + numbers = re.findall(r"\d+\.?\d*", value_str) + return numbers[0] if numbers else "0" + class registration(APIView): def post(self, request, *args, **kwargs): """ @@ -1062,8 +1075,8 @@ class caseManagement(APIView): Contractreturn=json.dumps(contract_return_list, ensure_ascii=False), Closingapplication=json.dumps(closing_application_list, ensure_ascii=False), ChangeRequest="", - invoice_status=invoice_status or '未开票', - paymentcollection=paymentcollection or "", + invoice_status=normalize_amount_value(invoice_status), + paymentcollection=normalize_amount_value(paymentcollection), state="审核中" ) @@ -1119,12 +1132,12 @@ class caseManagement(APIView): case.Closingapplication = json.dumps(flies(Closingapplication), ensure_ascii=False) update_fields_list.append('Closingapplication') - if paymentcollection: - case.paymentcollection = paymentcollection + if paymentcollection is not None: + case.paymentcollection = normalize_amount_value(paymentcollection) update_fields_list.append('paymentcollection') - if invoice_status: - case.invoice_status = invoice_status + if invoice_status is not None: + case.invoice_status = normalize_amount_value(invoice_status) update_fields_list.append('invoice_status') if update_fields_list: @@ -1293,27 +1306,9 @@ class caseManagementDetail(APIView): except (json.JSONDecodeError, TypeError): closing_application_list = [] - # 处理已开票字段:转换为数值 - invoice_status_value = "0" - if info.invoice_status: - try: - # 尝试转换为数值(可能是字符串格式的数字) - invoice_status_str = str(info.invoice_status).strip() - # 如果是"未开票"等非数字字符串,返回0 - if invoice_status_str in ["未开票", "", None]: - invoice_status_value = "0" - else: - # 尝试提取数字部分 - numbers = re.findall(r'\d+\.?\d*', invoice_status_str) - if numbers: - invoice_status_value = numbers[0] - else: - invoice_status_value = "0" - except (ValueError, TypeError, AttributeError): - invoice_status_value = "0" - - # 处理已收款字段:确保是字符串格式 - paymentcollection_value = info.paymentcollection or "0" + # 处理已开票/已收款字段:统一为数值字符串 + invoice_status_value = normalize_amount_value(info.invoice_status) + paymentcollection_value = normalize_amount_value(info.paymentcollection) data.append({ "id": info.id, @@ -1334,8 +1329,8 @@ class caseManagementDetail(APIView): "ChangeItem": info.ChangeItem, "ChangeReason": info.ChangeReason, "ChangeAgreement": info.ChangeAgreement, - "invoice_status": invoice_status_value, # 已开票(数值字符串) - "paymentcollection": paymentcollection_value, # 已收款 + "invoice_status": invoice_status_value, # 已开票(数值) + "paymentcollection": paymentcollection_value, # 已收款(数值) "state": info.state, "project_id": info.project_id, }) @@ -1402,12 +1397,12 @@ class EditCase(APIView): case.Closingapplication = json.dumps(flies(Closingapplication), ensure_ascii=False) update_fields_list.append('Closingapplication') - if paymentcollection: - case.paymentcollection = paymentcollection + if paymentcollection is not None: + case.paymentcollection = normalize_amount_value(paymentcollection) update_fields_list.append('paymentcollection') - if invoice_status: - case.invoice_status = invoice_status + if invoice_status is not None: + case.invoice_status = normalize_amount_value(invoice_status) update_fields_list.append('invoice_status') if update_fields_list: @@ -1598,11 +1593,17 @@ class accumulate(APIView): except Case.DoesNotExist: return Response({'status': 'error', 'message': '案件不存在', 'code': 1}, status=status.HTTP_404_NOT_FOUND) - if case.paymentcollection == "": - number = 0 - else: - number = float(case.paymentcollection) - case.paymentcollection = float(number + float(paymentcollection)) + current_amount_str = normalize_amount_value(case.paymentcollection) + add_amount_str = normalize_amount_value(paymentcollection) + try: + current_amount = Decimal(current_amount_str) + except InvalidOperation: + current_amount = Decimal("0") + try: + add_amount = Decimal(add_amount_str) + except InvalidOperation: + add_amount = Decimal("0") + case.paymentcollection = str(current_amount + add_amount) case.save(update_fields=['paymentcollection']) return Response({'message': '成功', 'code': 0}, status=status.HTTP_200_OK) diff --git a/案件管理模块接口文档.md b/案件管理模块接口文档.md index 3162069..dc1d4e9 100644 --- a/案件管理模块接口文档.md +++ b/案件管理模块接口文档.md @@ -792,8 +792,8 @@ token: {用户token} | change_item / ChangeItem | String | 否 | 变更事项(律师申请时必填) | | change_reason / ChangeReason | String | 否 | 变更原因(律师申请时必填) | | ChangeAgreement | File[] | 否 | 变更协议文件(律师申请时必填) | -| invoice_status | String | 否 | 已开票状态(默认:未开票) | -| paymentcollection | String | 否 | 已收款金额 | +| invoice_status | Number | 否 | 已开票金额(默认:0) | +| paymentcollection | Number | 否 | 已收款金额(默认:0) | | approvers | Array/String | 否 | 审核人列表(团队类型时需要,推荐ID数组,兼容用户名数组/逗号字符串) | | personincharge | String | 否 | 审核人(兼容旧接口,会转为approvers) | @@ -806,8 +806,8 @@ token: {用户token} "times": "2024-01-15", "change_item": "代理方案变更", "change_reason": "客户要求调整代理范围", - "invoice_status": "已开票", - "paymentcollection": "50000" + "invoice_status": 0, + "paymentcollection": 50000 } ``` @@ -999,8 +999,8 @@ token: {用户token} "ChangeItem": "代理方案变更", "ChangeReason": "客户要求调整代理范围", "ChangeAgreement": "[\"http://example.com/change-agreement.pdf\"]", - "invoice_status": "已开票", - "paymentcollection": "50000", + "invoice_status": 0, + "paymentcollection": 50000, "state": "审核中", "project_id": 1 } @@ -1035,8 +1035,8 @@ token: {用户token} | change_item / ChangeItem | String | 否 | 变更事项(律师申请时必填) | | change_reason / ChangeReason | String | 否 | 变更原因(律师申请时必填) | | ChangeAgreement | File[] | 否 | 变更协议文件(律师申请时必填) | -| invoice_status | String | 否 | 已开票状态 | -| paymentcollection | String | 否 | 已收款金额 | +| invoice_status | Number | 否 | 已开票金额(默认:0) | +| paymentcollection | Number | 否 | 已收款金额(默认:0) | | approvers | Array/String | 否 | 审核人列表(团队类型时需要,推荐ID数组,兼容用户名数组/逗号字符串) | | personincharge | String | 否 | 审核人(兼容旧接口,会转为approvers) | @@ -1048,8 +1048,8 @@ token: {用户token} "id": 1, "change_item": "代理方案变更", "change_reason": "客户要求调整代理范围", - "invoice_status": "已开票", - "paymentcollection": "60000" + "invoice_status": 0, + "paymentcollection": 60000 } ``` @@ -1310,13 +1310,13 @@ token: {用户token} | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | case_id | Integer | 是 | 案件ID | -| paymentcollection | String | 是 | 要累加的金额 | +| paymentcollection | Number | 是 | 要累加的金额 | **请求示例:** ```json { "case_id": 1, - "paymentcollection": "10000" + "paymentcollection": 10000 } ``` @@ -1379,7 +1379,7 @@ token: {用户token} - **立项登记状态:** `审核中`、`已通过`、`已拒绝` 等 - **案件状态:** `审核中`、`已通过`、`已拒绝` 等 -- **已开票状态:** `未开票`、`已开票` 等 +- **已开票金额:** 数值(默认 0) ### 审核流程说明