diff --git a/finance/views.py b/finance/views.py index cdb9a44..399093e 100644 --- a/finance/views.py +++ b/finance/views.py @@ -960,8 +960,8 @@ class confirm(APIView): """ 收入确认 优化后: - 1. 通过合同号关联案件(ContractNo必填) - 2. 从案件管理中同步:客户名称、负责人 + 1. 支持通过案件ID(case_id或project_id)或合同号(ContractNo)关联案件 + 2. 从案件管理中同步:合同号、客户名称、负责人 3. 手动填写:收款日期、收款金额 4. 按照团队审核逻辑处理审核流程(与其他审核待办一致) :param request: @@ -969,15 +969,17 @@ class confirm(APIView): :param kwargs: :return: """ - # 必填参数:合同号 - ContractNo = request.data.get('ContractNo') # 合同号(必填,用于关联案件) + # 案件选择(三选一:case_id、project_id、ContractNo) + case_id = request.data.get('case_id') # 案件管理ID(Case表) + project_id = request.data.get('project_id') # 立项登记ID(ProjectRegistration表) + ContractNo = request.data.get('ContractNo') # 合同号(可选,如果提供了case_id或project_id则自动同步) # 手动填写信息 times = request.data.get('times') # 收款日期 amount = request.data.get('amount') # 收款金额 - # 可选字段(如果通过合同号找到了案件,将从案件管理中同步) - CustomerID = request.data.get('CustomerID') # 客户名称(可选,如果通过合同号找到案件则自动同步) + # 可选字段(如果通过案件ID或合同号找到了案件,将从案件管理中同步) + CustomerID = request.data.get('CustomerID') # 客户名称(可选,如果通过案件ID或合同号找到案件则自动同步) # 审核人列表(可选,多人团队时需要,推荐:用户ID数组如[1,2,3],兼容:用户名数组) approvers = request.data.get('approvers') @@ -1000,8 +1002,10 @@ class confirm(APIView): missing_params.append('times(收款日期)') if not amount: missing_params.append('amount(收款金额)') - if not ContractNo: - missing_params.append('ContractNo(合同号)') + + # 必须提供case_id、project_id或ContractNo之一 + if not case_id and not project_id and not ContractNo: + missing_params.append('case_id或project_id或ContractNo(案件ID或合同号)') if missing_params: return Response({ @@ -1020,96 +1024,159 @@ class confirm(APIView): except Team.DoesNotExist: pass - # 通过合同号从案件管理中提取信息 + # 通过案件ID或合同号从案件管理中提取信息 from business.models import Case, ProjectRegistration import json responsible_person = None # 负责人姓名(用于抄送) responsible_person_username = None # 负责人用户名(用于抄送) case_info = None + responsiblefor = None - # 优先从Case(案件管理)中查找 - try: - case = Case.objects.select_related('project').get(contract_no=ContractNo, is_deleted=False) - - # 获取客户名称 - CustomerID = CustomerID or case.client_name - - # 获取负责人信息 - responsiblefor = case.responsiblefor - - # 如果案件信息不完整,从关联的ProjectRegistration获取 - if case.project: - project = case.project - CustomerID = CustomerID or project.client_info - responsiblefor = responsiblefor or project.responsiblefor - - # 解析负责人信息 + # 优先通过案件ID查找 + if case_id: + # 从Case(案件管理)中查找 try: - if responsiblefor: - if isinstance(responsiblefor, str): - responsiblefor_dict = json.loads(responsiblefor) - else: - responsiblefor_dict = responsiblefor - responsible_person = responsiblefor_dict.get('responsible_person', '') - # 查找负责人用户名 - if responsible_person: - try: - responsible_user = User.objects.get(username=responsible_person, is_deleted=False) - responsible_person_username = responsible_user.username - except User.DoesNotExist: - pass - except (json.JSONDecodeError, TypeError, AttributeError): - responsible_person = str(responsiblefor) if responsiblefor else '' - - case_info = { - 'id': case.id, - 'type': 'case', - 'contract_no': ContractNo, - 'customer_name': CustomerID, - 'responsible_person': responsible_person - } - - except Case.DoesNotExist: - # 如果Case中找不到,尝试从ProjectRegistration(立项登记)中查找 - try: - project = ProjectRegistration.objects.get(ContractNo=ContractNo, is_deleted=False) - - CustomerID = CustomerID or project.client_info - responsiblefor = project.responsiblefor - - # 解析负责人信息 + # 转换case_id为整数(如果可能) try: - if responsiblefor: - if isinstance(responsiblefor, str): - responsiblefor_dict = json.loads(responsiblefor) - else: - responsiblefor_dict = responsiblefor - responsible_person = responsiblefor_dict.get('responsible_person', '') - # 查找负责人用户名 - if responsible_person: - try: - responsible_user = User.objects.get(username=responsible_person, is_deleted=False) - responsible_person_username = responsible_user.username - except User.DoesNotExist: - pass - except (json.JSONDecodeError, TypeError, AttributeError): - responsible_person = str(responsiblefor) if responsiblefor else '' + case_id_int = int(case_id) + except (ValueError, TypeError): + case_id_int = case_id + + case = Case.objects.select_related('project').get(id=case_id_int, is_deleted=False) + + # 获取合同号 + ContractNo = ContractNo or case.contract_no + + # 获取客户名称 + CustomerID = CustomerID or case.client_name + + # 获取负责人信息 + responsiblefor = case.responsiblefor + + # 如果案件信息不完整,从关联的ProjectRegistration获取 + if case.project: + project = case.project + ContractNo = ContractNo or project.ContractNo + CustomerID = CustomerID or project.client_info + responsiblefor = responsiblefor or project.responsiblefor + + case_info = { + 'id': case.id, + 'type': 'case', + 'contract_no': ContractNo, + 'customer_name': CustomerID, + } + + except Case.DoesNotExist: + return Response({ + 'status': 'error', + 'message': f'案件不存在或已被删除(case_id: {case_id})', + 'code': 1 + }, status=status.HTTP_404_NOT_FOUND) + + elif project_id: + # 从ProjectRegistration(立项登记)中查找 + try: + # 转换project_id为整数(如果可能) + try: + project_id_int = int(project_id) + except (ValueError, TypeError): + project_id_int = project_id + + project = ProjectRegistration.objects.get(id=project_id_int, is_deleted=False) + + # 获取合同号 + ContractNo = ContractNo or project.ContractNo + + # 获取客户名称 + CustomerID = CustomerID or project.client_info + + # 获取负责人信息 + responsiblefor = project.responsiblefor case_info = { 'id': project.id, 'type': 'project', 'contract_no': ContractNo, 'customer_name': CustomerID, - 'responsible_person': responsible_person } except ProjectRegistration.DoesNotExist: return Response({ 'status': 'error', - 'message': f'未找到合同号为"{ContractNo}"的案件或立项登记,请检查合同号是否正确', + 'message': f'立项登记不存在或已被删除(project_id: {project_id})', 'code': 1 }, status=status.HTTP_404_NOT_FOUND) + + else: + # 通过合同号查找(保持向后兼容) + # 优先从Case(案件管理)中查找 + try: + case = Case.objects.select_related('project').get(contract_no=ContractNo, is_deleted=False) + + # 获取客户名称 + CustomerID = CustomerID or case.client_name + + # 获取负责人信息 + responsiblefor = case.responsiblefor + + # 如果案件信息不完整,从关联的ProjectRegistration获取 + if case.project: + project = case.project + CustomerID = CustomerID or project.client_info + responsiblefor = responsiblefor or project.responsiblefor + + case_info = { + 'id': case.id, + 'type': 'case', + 'contract_no': ContractNo, + 'customer_name': CustomerID, + } + + except Case.DoesNotExist: + # 如果Case中找不到,尝试从ProjectRegistration(立项登记)中查找 + try: + project = ProjectRegistration.objects.get(ContractNo=ContractNo, is_deleted=False) + + CustomerID = CustomerID or project.client_info + responsiblefor = project.responsiblefor + + case_info = { + 'id': project.id, + 'type': 'project', + 'contract_no': ContractNo, + 'customer_name': CustomerID, + } + + except ProjectRegistration.DoesNotExist: + return Response({ + 'status': 'error', + 'message': f'未找到合同号为"{ContractNo}"的案件或立项登记,请检查合同号是否正确', + 'code': 1 + }, status=status.HTTP_404_NOT_FOUND) + + # 解析负责人信息 + if responsiblefor: + try: + if isinstance(responsiblefor, str): + responsiblefor_dict = json.loads(responsiblefor) + else: + responsiblefor_dict = responsiblefor + responsible_person = responsiblefor_dict.get('responsible_person', '') + # 查找负责人用户名 + if responsible_person: + try: + responsible_user = User.objects.get(username=responsible_person, is_deleted=False) + responsible_person_username = responsible_user.username + except User.DoesNotExist: + pass + except (json.JSONDecodeError, TypeError, AttributeError): + responsible_person = str(responsiblefor) if responsiblefor else '' + + # 更新case_info中的负责人信息 + if case_info: + case_info['responsible_person'] = responsible_person # 验证合同号、客户名称是否获取成功 if not ContractNo: