Compare commits
10 Commits
b016e5ed55
...
9b19987387
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b19987387 | ||
|
|
f2aff9add8 | ||
|
|
149d18f72e | ||
|
|
ca512b9626 | ||
|
|
a03ef1cde8 | ||
|
|
5db0af8360 | ||
|
|
609b66fe8a | ||
|
|
dcbf5bb829 | ||
|
|
f187a4939a | ||
|
|
54372a3c2c |
@@ -826,9 +826,9 @@ def process_approval_flow(approval, business_record, current_approver, state,
|
||||
logger.info(f"process_approval_flow: 已更新审批记录,personincharge={next_approver}, state=审核中")
|
||||
return False, None
|
||||
else:
|
||||
# 最后一个审核人已通过:投标/立项/案件变更转申请人待查看,其他类型抄送财务
|
||||
# 最后一个审核人已通过:投标/立项/案件变更/结案申请转申请人待查看,其他类型抄送财务
|
||||
applicant = getattr(approval, 'applicant', None)
|
||||
if approval_type in ("投标登记", "立项登记", "案件变更") and applicant:
|
||||
if approval_type in ("投标登记", "立项登记", "案件变更", "结案申请") and applicant:
|
||||
logger.info(f"process_approval_flow: 最后一个审核人已审核,流转到申请人待查看: {applicant}")
|
||||
approval.personincharge = applicant
|
||||
approval.state = "待查看"
|
||||
@@ -867,7 +867,7 @@ def process_approval_flow(approval, business_record, current_approver, state,
|
||||
|
||||
|
||||
def create_approval_with_team_logic(team_name, approvers, title, content, approval_type, user_id,
|
||||
business_record=None, today=None, applicant=None):
|
||||
business_record=None, today=None, applicant=None, force_approval=False):
|
||||
"""
|
||||
根据团队类型创建审批记录(统一逻辑)
|
||||
|
||||
@@ -876,6 +876,7 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
|
||||
- 投标登记/立项登记:最后一步给申请人,生成「待查看」待办,申请人查看后完成(不再给财务部)
|
||||
- 其他类型:团队(team)需要审核人,按顺序审核,最后抄送财务
|
||||
- 无团队:直接抄送财务
|
||||
- 强制审批模式(force_approval=True):即使是个人团队也需要审批,用于付款申请、报销、工资/奖金变更等
|
||||
|
||||
注意:personincharge字段统一使用财务部ID(优先)或回退到"财务"字符串
|
||||
|
||||
@@ -889,6 +890,7 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
|
||||
business_record: 业务记录对象(可选)
|
||||
today: 日期字符串(可选,格式:YYYY-MM-DD)
|
||||
applicant: 申请人用户名(可选,投标/立项时填,最后一步生成待查看待办给申请人)
|
||||
force_approval: 是否强制审批(默认False)。设为True时,即使是个人团队也需要审批(如付款申请、报销、工资/奖金变更)
|
||||
|
||||
Returns:
|
||||
tuple: (approval对象, approvers_order_json, 是否需要审核)
|
||||
@@ -941,8 +943,8 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
|
||||
# 创建审批记录,第一个审核人
|
||||
first_approver = approvers_list[0]
|
||||
approvers_str = ' → '.join(approvers_list) # 使用箭头表示顺序
|
||||
# 投标登记/立项登记/案件变更:最后一步给申请人(待查看),不再给财务部
|
||||
if approval_type in ("投标登记", "立项登记", "案件变更") and applicant:
|
||||
# 投标登记/立项登记/案件变更/结案申请:最后一步给申请人(待查看),不再给财务部
|
||||
if approval_type in ("投标登记", "立项登记", "案件变更", "结案申请") and applicant:
|
||||
flow_suffix = " → 申请人(待查看)"
|
||||
else:
|
||||
flow_suffix = " → 财务部(按顺序审批)"
|
||||
@@ -970,8 +972,49 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
|
||||
# 如果没有传入审核人,则根据团队类型判断
|
||||
# 判断团队类型
|
||||
if not team_name or not team or (team and team.team_type == 'personal'):
|
||||
# 投标登记/立项登记/案件变更且传入了申请人:最后一步给申请人,生成待查看待办(不再给财务部)
|
||||
if approval_type in ("投标登记", "立项登记", "案件变更") and applicant:
|
||||
# 强制审批模式(付款申请、报销、工资/奖金变更等):即使是个人团队也需要审批
|
||||
if force_approval:
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.info(f"create_approval_with_team_logic: 强制审批模式 - 审批类型={approval_type}, 团队={team_name}")
|
||||
|
||||
# 尝试获取默认审核人:优先律所负责人,然后管委会成员
|
||||
default_approver = get_law_firm_leader(team_name)
|
||||
if not default_approver:
|
||||
# 如果找不到默认审核人,返回错误
|
||||
logger.warning(f"create_approval_with_team_logic: 强制审批模式下找不到默认审核人")
|
||||
return None, None, True # needs_approval = True,表示需要审批但缺少审核人
|
||||
|
||||
# 使用默认审核人创建审批
|
||||
approvers_list = [default_approver]
|
||||
approvers_order_json = json.dumps(approvers_list, ensure_ascii=False)
|
||||
|
||||
# 存储到业务记录
|
||||
if business_record and hasattr(business_record, 'approvers_order'):
|
||||
business_record.approvers_order = approvers_order_json
|
||||
business_record.state = "审核中"
|
||||
business_record.save(update_fields=['approvers_order', 'state'])
|
||||
|
||||
# 创建审批流程内容
|
||||
content_with_flow = f"{content},审批流程:{default_approver} → 财务部(按顺序审批),当前审批人:{default_approver}"
|
||||
|
||||
logger.info(f"create_approval_with_team_logic: 强制审批 - 使用默认审核人 {default_approver}")
|
||||
|
||||
approval = Approval.objects.create(
|
||||
title=title,
|
||||
content=content_with_flow,
|
||||
times=today,
|
||||
personincharge=default_approver,
|
||||
state="审核中",
|
||||
type=approval_type,
|
||||
user_id=str(user_id),
|
||||
applicant=applicant
|
||||
)
|
||||
|
||||
return approval, approvers_order_json, True
|
||||
|
||||
# 投标登记/立项登记/案件变更/结案申请且传入了申请人:最后一步给申请人,生成待查看待办(不再给财务部)
|
||||
if approval_type in ("投标登记", "立项登记", "案件变更", "结案申请") and applicant:
|
||||
content_to_save = content + ",待申请人查看"
|
||||
approval = Approval.objects.create(
|
||||
title=title,
|
||||
@@ -1056,7 +1099,7 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
|
||||
# 创建审批记录,第一个审核人
|
||||
first_approver = approvers_list[0]
|
||||
approvers_str = ' → '.join(approvers_list)
|
||||
if approval_type in ("投标登记", "立项登记", "案件变更") and applicant:
|
||||
if approval_type in ("投标登记", "立项登记", "案件变更", "结案申请") and applicant:
|
||||
flow_suffix = " → 申请人(待查看)"
|
||||
else:
|
||||
flow_suffix = " → 财务部(按顺序审批)"
|
||||
|
||||
@@ -1774,7 +1774,17 @@ class approvalProcessing(APIView):
|
||||
}
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
# 兼容旧流程:如果负责人未填写分配,但审批人指定了分配方案
|
||||
# 审批人审批时必须填写收入分配
|
||||
# 如果收入分配还是"待负责人指定",且审批人要通过审批,则必须填写收入分配
|
||||
if state == "已通过" and income.allocate == "待负责人指定":
|
||||
if not allocate:
|
||||
return Response({
|
||||
'status': 'error',
|
||||
'message': '请填写收入分配后再通过审批',
|
||||
'code': 1
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 如果审批人填写了收入分配,更新到记录中
|
||||
if allocate:
|
||||
income.allocate = allocate
|
||||
# 更新审批内容,添加分配信息
|
||||
@@ -1785,8 +1795,9 @@ class approvalProcessing(APIView):
|
||||
else:
|
||||
approval.content = approval.content + f",收入分配:{allocate}"
|
||||
income.save(update_fields=['allocate'])
|
||||
approval.save(update_fields=['content'])
|
||||
|
||||
# 使用统一的审核流程处理函数(兼容旧流程)
|
||||
# 使用统一的审核流程处理函数
|
||||
# 非财务查看时,state参数是必填的
|
||||
if not state:
|
||||
return Response({'status': 'error', 'message': '缺少参数state(审核状态:已通过/未通过)', 'code': 1}, status=status.HTTP_400_BAD_REQUEST)
|
||||
@@ -2280,8 +2291,8 @@ class approvalProcessing(APIView):
|
||||
return Response({'message': '处理成功', 'code': 0}, status=status.HTTP_200_OK)
|
||||
|
||||
if type == "结案申请":
|
||||
from business.models import Schedule, Case
|
||||
try:
|
||||
from business.models import Schedule
|
||||
schedule = Schedule.objects.get(id=approval.user_id, is_deleted=False)
|
||||
except Schedule.DoesNotExist:
|
||||
return Response({'status': 'error', 'message': '结案申请记录不存在或已被删除', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
|
||||
@@ -2302,6 +2313,31 @@ class approvalProcessing(APIView):
|
||||
if error:
|
||||
return Response({'status': 'error', 'message': error, 'code': 1}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 审批通过后,更新 Case.Closingapplication 字段
|
||||
# 刷新 schedule 和 approval 以获取最新状态
|
||||
schedule.refresh_from_db()
|
||||
approval.refresh_from_db()
|
||||
if schedule.state == "已完成" or approval.state == "已通过":
|
||||
try:
|
||||
import json
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
# 从 schedule.remark 中获取 case_id 和 closing_application_files
|
||||
remark_data = json.loads(schedule.remark) if schedule.remark else {}
|
||||
case_id = remark_data.get('case_id')
|
||||
closing_files = remark_data.get('closing_application_files', [])
|
||||
|
||||
if case_id and closing_files:
|
||||
case = Case.objects.filter(id=case_id, is_deleted=False).first()
|
||||
if case:
|
||||
case.Closingapplication = json.dumps(closing_files, ensure_ascii=False)
|
||||
case.save(update_fields=['Closingapplication'])
|
||||
logger.info(f"结案申请审批通过,已更新 Case(id={case_id}) 的 Closingapplication 字段")
|
||||
except Exception as e:
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.error(f"结案申请审批通过后更新 Case.Closingapplication 失败: {str(e)}")
|
||||
|
||||
return Response({'message': '处理成功', 'code': 0}, status=status.HTTP_200_OK)
|
||||
|
||||
return Response({'message': '处理成功', 'code': 0}, status=status.HTTP_200_OK)
|
||||
@@ -2747,8 +2783,8 @@ class ApprovalStatusCheck(APIView):
|
||||
is_finance_view = True
|
||||
approval.state = "已通过"
|
||||
approval.save(update_fields=['state'])
|
||||
# 投标/立项/案件变更:当前为「待查看」且当前用户是申请人时,调用本接口即视为申请人已查看,消除待查看状态
|
||||
elif type in ("投标登记", "立项登记", "案件变更") and approval.state == "待查看" and getattr(approval, 'applicant', None) and approval.personincharge == approval.applicant and current_user.username == approval.applicant:
|
||||
# 投标/立项/案件变更/结案申请:当前为「待查看」且当前用户是申请人时,调用本接口即视为申请人已查看,消除待查看状态
|
||||
elif type in ("投标登记", "立项登记", "案件变更", "结案申请") and approval.state == "待查看" and getattr(approval, 'applicant', None) and approval.personincharge == approval.applicant and current_user.username == approval.applicant:
|
||||
is_applicant_view = True
|
||||
approval.state = "已通过"
|
||||
update_fields = ['state', 'content']
|
||||
@@ -2913,6 +2949,37 @@ class ApprovalStatusCheck(APIView):
|
||||
is_approved = (schedule.state == "已完成")
|
||||
except Schedule.DoesNotExist:
|
||||
pass
|
||||
elif type == "结案申请":
|
||||
# 结案申请类型:使用 Schedule 作为承载对象
|
||||
from business.models import Schedule, Case
|
||||
try:
|
||||
schedule = Schedule.objects.get(id=approval.user_id, is_deleted=False)
|
||||
business_state = schedule.state
|
||||
is_approved = (schedule.state == "已完成" or approval.state == "已通过")
|
||||
# 申请人通过本接口查看后,消除待查看并更新业务记录为已完成,同时更新 Case.Closingapplication
|
||||
if is_applicant_view:
|
||||
if schedule.state != "已完成":
|
||||
schedule.state = "已完成"
|
||||
schedule.save(update_fields=['state'])
|
||||
business_state = "已完成"
|
||||
is_approved = True
|
||||
# 更新 Case.Closingapplication 字段
|
||||
try:
|
||||
import json
|
||||
remark_data = json.loads(schedule.remark) if schedule.remark else {}
|
||||
case_id = remark_data.get('case_id')
|
||||
closing_files = remark_data.get('closing_application_files', [])
|
||||
if case_id and closing_files:
|
||||
case = Case.objects.filter(id=case_id, is_deleted=False).first()
|
||||
if case:
|
||||
case.Closingapplication = json.dumps(closing_files, ensure_ascii=False)
|
||||
case.save(update_fields=['Closingapplication'])
|
||||
except Exception as e:
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.error(f"结案申请待查看确认后更新 Case.Closingapplication 失败: {str(e)}")
|
||||
except Schedule.DoesNotExist:
|
||||
pass
|
||||
# 可以根据需要添加其他类型
|
||||
except Exception as e:
|
||||
import logging
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.urls import path
|
||||
|
||||
from .models import Schedule
|
||||
from .views import registration,registrationDetail,Project,Projectquerytype,ProjectDetail,EditProject,BidRegistration,BidDetail,registrationList,caseManagement,caseManagementDetail,CaseAttachmentUpload,CaseAttachmentUpdate,Uploadinvoice,InvoiceDetail,Log,LogDetail,accumulate,preFilingLinkedCases,Application,ApplicationDetail,WarehousingRegistration,WarehousingDetail,PlatformRegistration,PlatformDetail,EditPlatformDetail,DeletePlatformDetail,bulletin,BulletinDetail,EditBulletin,deleteBulletin,Lawyersdocuments,LawyersdocumentsDetail,LwaDetail,CreateSchedule,DeleteSchedule,ScheduleDetail,handleSchedule,AddRermission,DisplayRermission,DeleteRermission,EditRermission,addRole,DeleteRole,EditRole,displayRole,modifypermissions,getRolePermissions,DeleteRegistration,EditRegistration,DeleteProject,EditBid,DeleteBid,EditCase,DeleteCase,EditApplication,DeleteApplication,EditWarehousing,DeleteWarehousing,EditLawyerFlie,EditSchedule,TransferCase,CaseChangeRequestCreate,CaseChangeRequestList,CaseChangeRequestDetail,ProjectDropdownList,CaseDropdownList,ConflictSearch,CreateCaseTag,CaseTagList,CaseTagDetail,EditCaseTag,DeleteCaseTag,CaseTagDropdownList,CaseListByTag,SetCaseTags,PropagandaEit,addSystem,SystemList,eitSystem,deleteSystem
|
||||
from .views import registration,registrationDetail,Project,Projectquerytype,ProjectDetail,EditProject,BidRegistration,BidDetail,registrationList,caseManagement,caseManagementDetail,CaseAttachmentUpload,CaseAttachmentUpdate,Uploadinvoice,InvoiceDetail,Log,LogDetail,accumulate,preFilingLinkedCases,Application,ApplicationDetail,WarehousingRegistration,WarehousingDetail,PlatformRegistration,PlatformDetail,EditPlatformDetail,DeletePlatformDetail,bulletin,BulletinDetail,EditBulletin,deleteBulletin,Lawyersdocuments,LawyersdocumentsDetail,LwaDetail,CreateSchedule,DeleteSchedule,ScheduleDetail,handleSchedule,AddRermission,DisplayRermission,DeleteRermission,EditRermission,addRole,DeleteRole,EditRole,displayRole,modifypermissions,getRolePermissions,DeleteRegistration,EditRegistration,DeleteProject,EditBid,DeleteBid,EditCase,DeleteCase,EditApplication,DeleteApplication,EditWarehousing,DeleteWarehousing,EditLawyerFlie,EditSchedule,TransferCase,CaseChangeRequestCreate,CaseChangeRequestList,CaseChangeRequestDetail,ProjectDropdownList,CaseDropdownList,ConflictSearch,CreateCaseTag,CaseTagList,CaseTagDetail,EditCaseTag,DeleteCaseTag,CaseTagDropdownList,CaseListByTag,SetCaseTags,PropagandaEit,addSystem,SystemList,eitSystem,deleteSystem,ExportCaseLogExcel
|
||||
urlpatterns = [
|
||||
|
||||
path('register',registration.as_view(),name='register'),
|
||||
@@ -85,5 +85,7 @@ urlpatterns = [
|
||||
path('addSystem',addSystem.as_view(),name='addSystem'),
|
||||
path('SystemList',SystemList.as_view(),name='SystemList'),
|
||||
path('eitSystem',eitSystem.as_view(),name='eitSystem'),
|
||||
path('deleteSystem',deleteSystem.as_view(),name='deleteSystem')
|
||||
path('deleteSystem',deleteSystem.as_view(),name='deleteSystem'),
|
||||
# 案件日志导出Excel
|
||||
path('export-case-log-excel',ExportCaseLogExcel.as_view(),name='export-case-log-excel'),
|
||||
]
|
||||
@@ -1598,16 +1598,18 @@ class CaseAttachmentUpdate(APIView):
|
||||
case.Contractreturn = Contractreturn
|
||||
update_fields = ['Contractreturn']
|
||||
elif upload_type == "Closingapplication":
|
||||
case.Closingapplication = json.dumps(file_urls, ensure_ascii=False)
|
||||
update_fields = ['Closingapplication']
|
||||
# 结案申请需要审批通过后才更新 Case.Closingapplication 字段
|
||||
# 这里不直接更新,文件URL保存在 Schedule.remark 中,审批通过后再更新到 Case
|
||||
pass
|
||||
elif upload_type == "AgencyContract":
|
||||
case.AgencyContract = json.dumps(file_urls, ensure_ascii=False)
|
||||
update_fields = ['AgencyContract']
|
||||
|
||||
case.save(update_fields=update_fields)
|
||||
if update_fields:
|
||||
case.save(update_fields=update_fields)
|
||||
|
||||
# 结案申请:加入审批流程(独立于“案件管理”审批,避免覆盖 Case.approvers_order / Case.state)
|
||||
if upload_type == "Closingapplication" and case.state == "结案":
|
||||
if upload_type == "Closingapplication": # 审批通过后才更新 Case.Closingapplication 字段
|
||||
try:
|
||||
token = request.META.get('token')
|
||||
submitter = User.objects.get(token=token, is_deleted=False)
|
||||
@@ -1646,7 +1648,8 @@ class CaseAttachmentUpdate(APIView):
|
||||
approval_type="结案申请",
|
||||
user_id=schedule.id,
|
||||
business_record=schedule,
|
||||
today=today
|
||||
today=today,
|
||||
applicant=submitter.username if submitter else None # 传入申请人,用于"待查看"流程
|
||||
)
|
||||
|
||||
if approval is None and needs_approval:
|
||||
@@ -5146,3 +5149,97 @@ class deleteSystem(APIView):
|
||||
except System.DoesNotExist:
|
||||
return Response({'status': 'error', 'message': '系统公告不存在', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
|
||||
class ExportCaseLogExcel(APIView):
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
导出指定案件的日志到Excel,上传到OSS并返回下载链接
|
||||
必填参数:case_id(案件ID)
|
||||
可选参数:start_time(开始时间)、end_time(结束时间)
|
||||
返回:下载链接
|
||||
"""
|
||||
import pandas as pd
|
||||
import oss2
|
||||
import uuid
|
||||
from io import BytesIO
|
||||
|
||||
case_id = request.data.get('case_id')
|
||||
start_time = request.data.get('start_time')
|
||||
end_time = request.data.get('end_time')
|
||||
|
||||
if not case_id:
|
||||
return Response({'status': 'error', 'message': '缺少参数case_id', 'code': 1}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 获取案件信息
|
||||
try:
|
||||
case = Case.objects.get(id=case_id, is_deleted=False)
|
||||
except Case.DoesNotExist:
|
||||
return Response({'status': 'error', 'message': '案件不存在', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# 构建查询条件
|
||||
Q_obj = Q(is_deleted=False, case_id=case_id)
|
||||
if start_time:
|
||||
Q_obj &= Q(times__gte=start_time)
|
||||
if end_time:
|
||||
Q_obj &= Q(times__lte=end_time)
|
||||
|
||||
# 查询日志
|
||||
logs = Caselog.objects.filter(Q_obj).order_by('-times', '-id')
|
||||
|
||||
if not logs.exists():
|
||||
return Response({'status': 'error', 'message': '该案件没有日志记录', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# 构建Excel数据(只保留:记录人、记录时间、工作内容)
|
||||
excel_data = []
|
||||
for log in logs:
|
||||
excel_data.append({
|
||||
'记录人': log.username or '',
|
||||
'记录时间': log.times or '',
|
||||
'工作内容': log.content or '',
|
||||
})
|
||||
|
||||
# 生成Excel文件
|
||||
df = pd.DataFrame(excel_data)
|
||||
output = BytesIO()
|
||||
with pd.ExcelWriter(output, engine='openpyxl') as writer:
|
||||
df.to_excel(writer, index=False, sheet_name='案件日志')
|
||||
ws = writer.sheets['案件日志']
|
||||
for idx, col in enumerate(df.columns):
|
||||
width = min(max(df[col].astype(str).map(len).max(), len(col)) + 2, 50)
|
||||
ws.column_dimensions[chr(65 + idx) if idx < 26 else chr(64 + idx // 26) + chr(65 + idx % 26)].width = width
|
||||
|
||||
output.seek(0)
|
||||
|
||||
# 上传到阿里云OSS
|
||||
try:
|
||||
endpoint = 'https://oss-cn-beijing.aliyuncs.com'
|
||||
access_key_id = "LTAI5tRMxrM95Pi8JEEmqRcg"
|
||||
access_key_secret = "8vueGCsRVeFyQMcAA7sysO7LSnuJDG"
|
||||
bucket_name = 'oss-bucket-yj'
|
||||
|
||||
auth = oss2.Auth(access_key_id, access_key_secret)
|
||||
bucket = oss2.Bucket(auth, endpoint, bucket_name)
|
||||
|
||||
# 生成唯一文件名
|
||||
contract_no_safe = (case.contract_no or f'case{case_id}').replace('/', '_').replace('\\', '_')
|
||||
filename = f'{uuid.uuid4().hex[:12]}_{contract_no_safe}_日志_{datetime.now().strftime("%Y%m%d%H%M%S")}.xlsx'
|
||||
|
||||
# 上传文件
|
||||
result = bucket.put_object(filename, output.getvalue())
|
||||
|
||||
if result.status == 200:
|
||||
# 生成下载链接
|
||||
download_url = f'http://{bucket_name}.{endpoint.replace("https://", "")}/{filename}'
|
||||
return Response({
|
||||
'message': '导出成功',
|
||||
'code': 0,
|
||||
'data': {
|
||||
'url': download_url,
|
||||
'filename': f'{case.contract_no or f"案件{case_id}"}_日志.xlsx'
|
||||
}
|
||||
}, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response({'status': 'error', 'message': '文件上传失败', 'code': 1}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
except Exception as e:
|
||||
return Response({'status': 'error', 'message': f'文件上传失败: {str(e)}', 'code': 1}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
|
||||
@@ -1059,7 +1059,7 @@ class confirm(APIView):
|
||||
personincharge = request.data.get('personincharge')
|
||||
approvers = normalize_approvers_param(approvers, personincharge)
|
||||
|
||||
allocate = request.data.get('allocate') # 收入分配(财务提交时不填写,由负责人填写)
|
||||
# 收入分配由审批人(负责人)在审批时填写,新增时不接收此参数
|
||||
token = request.META.get('token')
|
||||
|
||||
try:
|
||||
@@ -1274,12 +1274,13 @@ class confirm(APIView):
|
||||
initial_state = "审核中" if (team and team.team_type == 'team') else "待财务处理"
|
||||
|
||||
# 创建收入确认记录
|
||||
# 收入分配由审批人(负责人)在审批时填写
|
||||
income = Income.objects.create(
|
||||
times=times,
|
||||
ContractNo=ContractNo,
|
||||
CustomerID=CustomerID,
|
||||
amount=amount,
|
||||
allocate=allocate if allocate else "待负责人指定", # 如果未提供,设为"待负责人指定"
|
||||
allocate="待负责人指定", # 收入分配由审批人在审批时填写
|
||||
submit=user.username,
|
||||
submit_tiem=date_string,
|
||||
state=initial_state
|
||||
@@ -2277,9 +2278,8 @@ class PaymentRequest(APIView):
|
||||
# 如果团队不存在,默认按团队类型处理(需要审批)
|
||||
pass
|
||||
|
||||
# 根据团队类型决定初始状态
|
||||
# 如果是团队类型且需要审核,状态为"审核中";否则为"已通过"(直接抄送财务)
|
||||
initial_state = "审核中" if (team and team.team_type == 'team') else "已通过"
|
||||
# 付款申请统一都需要审批(无论团队类型)
|
||||
initial_state = "审核中"
|
||||
|
||||
# 创建付款申请记录
|
||||
pay = Payment.objects.create(
|
||||
@@ -2315,7 +2315,7 @@ class PaymentRequest(APIView):
|
||||
content_parts.insert(3, f"付款日期:{times}")
|
||||
content = ",".join(content_parts)
|
||||
|
||||
# 使用统一的审核流程函数(与离职逻辑一样)
|
||||
# 使用统一的审核流程函数(付款申请统一需要审批,force_approval=True)
|
||||
from User.utils import create_approval_with_team_logic
|
||||
|
||||
approval, approvers_order_json, needs_approval = create_approval_with_team_logic(
|
||||
@@ -2326,7 +2326,8 @@ class PaymentRequest(APIView):
|
||||
approval_type="付款申请",
|
||||
user_id=str(pay.id),
|
||||
business_record=pay,
|
||||
today=date_string
|
||||
today=date_string,
|
||||
force_approval=True # 付款申请统一需要审批
|
||||
)
|
||||
|
||||
# 如果返回None且需要审核,说明缺少审核人
|
||||
@@ -2366,7 +2367,7 @@ class PaymentRequest(APIView):
|
||||
'id': pay.id,
|
||||
'state': pay.state,
|
||||
'approval_id': approval.id if approval else None,
|
||||
'needs_approval': team is None or team.team_type != 'personal', # 是否需要审批(前端用这个字段判断是团队还是个人)
|
||||
'needs_approval': True, # 付款申请统一都需要审批
|
||||
'team_type': team.team_type if team else None, # 团队类型:personal/team(前端用这个字段判断)
|
||||
'team_name': team_name # 团队名称
|
||||
}
|
||||
@@ -2652,9 +2653,8 @@ class reimbursement(APIView):
|
||||
now = datetime.now()
|
||||
date_string = now.strftime("%Y-%m-%d")
|
||||
|
||||
# 根据团队类型决定初始状态
|
||||
# 如果是团队类型且需要审核,状态为"审核中";否则为"已通过"(直接抄送财务)
|
||||
initial_state = "审核中" if (team and team.team_type == 'team') else "已通过"
|
||||
# 报销统一都需要审批(无论团队类型)
|
||||
initial_state = "审核中"
|
||||
|
||||
reim = Reimbursement.objects.create(
|
||||
person=person,
|
||||
@@ -2666,7 +2666,7 @@ class reimbursement(APIView):
|
||||
state=initial_state
|
||||
)
|
||||
|
||||
# 使用统一的审核流程函数
|
||||
# 使用统一的审核流程函数(报销统一需要审批,force_approval=True)
|
||||
from User.utils import create_approval_with_team_logic
|
||||
|
||||
content = f"{person}在{times}提交了报销申请,报销理由:{reason},报销金额:{amount},报销日期:{times},费用说明:{FeeDescription}"
|
||||
@@ -2679,7 +2679,8 @@ class reimbursement(APIView):
|
||||
approval_type="报销申请",
|
||||
user_id=str(reim.id),
|
||||
business_record=reim,
|
||||
today=date_string
|
||||
today=date_string,
|
||||
force_approval=True # 报销统一需要审批
|
||||
)
|
||||
|
||||
# 如果返回None且需要审核,说明缺少审核人
|
||||
@@ -2717,7 +2718,7 @@ class reimbursement(APIView):
|
||||
'id': reim.id,
|
||||
'state': reim.state,
|
||||
'approval_id': approval.id if approval else None,
|
||||
'needs_approval': team is None or team.team_type != 'personal', # 是否需要审批(前端用这个字段判断是团队还是个人)
|
||||
'needs_approval': True, # 报销统一都需要审批
|
||||
'team_type': team.team_type if team else None, # 团队类型:personal/team(前端用这个字段判断)
|
||||
'team_name': team_name # 团队名称
|
||||
}
|
||||
@@ -2917,9 +2918,8 @@ class Change(APIView):
|
||||
except Team.DoesNotExist:
|
||||
pass
|
||||
|
||||
# 根据团队类型决定初始状态
|
||||
# 如果是团队类型且需要审核,状态为"审核中";否则为"已通过"(直接抄送财务)
|
||||
initial_state = "审核中" if (team and team.team_type == 'team') else "已通过"
|
||||
# 工资/奖金变更统一都需要审批(无论团队类型)
|
||||
initial_state = "审核中"
|
||||
|
||||
bonus = BonusChange.objects.create(
|
||||
username=username,
|
||||
@@ -2934,7 +2934,7 @@ class Change(APIView):
|
||||
|
||||
content = f"{submitter}在{date_string}提交了工资/奖金变更,类型:{type},调整说明:{Instructions}"
|
||||
|
||||
# 使用统一的审核流程函数(与付款申请、报销申请逻辑一样)
|
||||
# 使用统一的审核流程函数(工资/奖金变更统一需要审批,force_approval=True)
|
||||
approval, approvers_order_json, needs_approval = create_approval_with_team_logic(
|
||||
team_name=team_name,
|
||||
approvers=approvers,
|
||||
@@ -2943,7 +2943,8 @@ class Change(APIView):
|
||||
approval_type="工资/奖金变更",
|
||||
user_id=str(bonus.id),
|
||||
business_record=bonus,
|
||||
today=date_string
|
||||
today=date_string,
|
||||
force_approval=True # 工资/奖金变更统一需要审批
|
||||
)
|
||||
|
||||
# 如果返回None且需要审核,说明缺少审核人
|
||||
@@ -2982,7 +2983,7 @@ class Change(APIView):
|
||||
'submitter': bonus.submitter, # 提交人(明确是谁提交的申请)
|
||||
'state': bonus.state,
|
||||
'approval_id': approval.id if approval else None,
|
||||
'needs_approval': team is None or team.team_type != 'personal', # 是否需要审批(前端用这个字段判断是团队还是个人)
|
||||
'needs_approval': True, # 工资/奖金变更统一都需要审批
|
||||
'team_type': team.team_type if team else None, # 团队类型:personal/team(前端用这个字段判断)
|
||||
'team_name': team_name # 团队名称
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user