787 lines
29 KiB
Python
787 lines
29 KiB
Python
"""CRM 合同 API 路由 — GET/PUT/DELETE/POST 对齐原 Java CRM"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from fastapi import Depends, Query
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.database import get_db
|
|
from app.core.menu_guard import require_admin_or_super_admin
|
|
from app.core.oper_log_decorator import oper_log
|
|
from app.core.response import error_response, success_response
|
|
from app.core.tenant_context import get_tenant_no
|
|
from app.crud.crm.data_scope_helpers import crm_user_info
|
|
from app.crud.crm.contract import (
|
|
batch_assign_owner,
|
|
batch_submit_contract_approval,
|
|
create_contract,
|
|
create_from_opportunity,
|
|
create_from_quote,
|
|
download_contract_pdf,
|
|
export_contracts,
|
|
finish_contract,
|
|
get_contract_detail,
|
|
get_template,
|
|
invalid_contract,
|
|
list_contracts,
|
|
query_expiring,
|
|
renew_contract,
|
|
save_template,
|
|
sign_contract,
|
|
soft_delete_contracts,
|
|
start_execute,
|
|
statistics_by_status,
|
|
statistics_by_type,
|
|
statistics_overview,
|
|
statistics_trend,
|
|
submit_contract_approval,
|
|
total_pages,
|
|
update_contract,
|
|
upload_attachments,
|
|
upload_attachments_with_category,
|
|
upload_file,
|
|
withdraw_contract_approval,
|
|
)
|
|
from app.crud.crm.contract_approval import (
|
|
approve_contract_by_contract_id,
|
|
list_contract_approvals,
|
|
)
|
|
from app.schemas.crm.contract import (
|
|
ContractApprovalActionBody,
|
|
ContractBatchAssignBody,
|
|
ContractBatchSubmitBody,
|
|
ContractCreateBody,
|
|
ContractExportBody,
|
|
ContractInvalidBody,
|
|
ContractListQuery,
|
|
ContractRenewBody,
|
|
ContractSignBody,
|
|
ContractStatisticsOverviewQuery,
|
|
ContractStatisticsTrendQuery,
|
|
ContractStatusBody,
|
|
ContractSubmitBody,
|
|
ContractTemplateSaveBody,
|
|
ContractUpdateBody,
|
|
ContractUploadAttachmentsBody,
|
|
ContractUploadFileBody,
|
|
ContractWithdrawBody,
|
|
)
|
|
from app.utils.crm_export_columns import CONTRACT_EXPORT_COLUMNS
|
|
from app.utils.excel_export import export_rows_to_xlsx_response
|
|
|
|
|
|
def register_contract_routes(router):
|
|
@router.get("/contract/list")
|
|
async def contract_list(
|
|
pageNum: int = Query(1, ge=1),
|
|
pageSize: int = Query(10, ge=1, le=100),
|
|
contractNo: Optional[str] = None,
|
|
contractName: Optional[str] = None,
|
|
customerName: Optional[str] = None,
|
|
customerId: Optional[str] = None,
|
|
opportunityId: Optional[str] = None,
|
|
quoteId: Optional[str] = None,
|
|
contractType: Optional[str] = None,
|
|
status: Optional[str] = None,
|
|
excludeStatus: Optional[str] = None,
|
|
approvalStatus: Optional[str] = None,
|
|
ownerUserId: Optional[str] = None,
|
|
pendingApprovalUserId: Optional[str] = None,
|
|
approvedByUserId: Optional[str] = None,
|
|
minAmount: Optional[float] = None,
|
|
maxAmount: Optional[float] = None,
|
|
signDateBegin: Optional[str] = None,
|
|
signDateEnd: Optional[str] = None,
|
|
beginTime: Optional[str] = None,
|
|
endTime: Optional[str] = None,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
query = ContractListQuery(
|
|
pageNum=pageNum,
|
|
pageSize=pageSize,
|
|
contractNo=contractNo,
|
|
contractName=contractName,
|
|
customerName=customerName,
|
|
customerId=customerId,
|
|
opportunityId=opportunityId,
|
|
quoteId=quoteId,
|
|
contractType=contractType,
|
|
status=status,
|
|
excludeStatus=excludeStatus,
|
|
approvalStatus=approvalStatus,
|
|
ownerUserId=ownerUserId,
|
|
pendingApprovalUserId=pendingApprovalUserId,
|
|
approvedByUserId=approvedByUserId,
|
|
minAmount=minAmount,
|
|
maxAmount=maxAmount,
|
|
signDateBegin=signDateBegin,
|
|
signDateEnd=signDateEnd,
|
|
beginTime=beginTime,
|
|
endTime=endTime,
|
|
)
|
|
filters = query.model_dump(
|
|
by_alias=True,
|
|
exclude={"pageNum", "pageSize"},
|
|
exclude_none=True,
|
|
)
|
|
rows, total = list_contracts(
|
|
db,
|
|
tenant_no,
|
|
user_info=user_info,
|
|
page=query.pageNum,
|
|
page_size=query.pageSize,
|
|
filters=filters,
|
|
current_user_id=user_id,
|
|
)
|
|
tp = total_pages(total, query.pageSize)
|
|
return success_response(
|
|
{
|
|
"list": rows,
|
|
"rows": rows,
|
|
"total": total,
|
|
"pageNum": query.pageNum,
|
|
"pageSize": query.pageSize,
|
|
"totalPages": tp,
|
|
}
|
|
)
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.post("/contract")
|
|
@oper_log(title="CRM合同管理", business_type=1, summary="新增合同【{contractName}】")
|
|
async def contract_add(
|
|
body: ContractCreateBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
dept_id = _user.get("dept_id", "") or _user.get("create_dept_id", "") or ""
|
|
detail = create_contract(
|
|
db,
|
|
tenant_no=tenant_no,
|
|
data=body.model_dump(by_alias=True),
|
|
user_id=user_id,
|
|
dept_id=dept_id,
|
|
)
|
|
return success_response(detail["id"], message="新增成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.put("/contract")
|
|
@oper_log(title="CRM合同管理", business_type=2, summary="修改合同【{contractName}】")
|
|
async def contract_edit(
|
|
body: ContractUpdateBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
dept_id = _user.get("dept_id", "") or _user.get("create_dept_id", "") or ""
|
|
data = body.model_dump(by_alias=True)
|
|
contract_id = data.pop("id")
|
|
detail = update_contract(
|
|
db,
|
|
contract_id,
|
|
tenant_no=tenant_no,
|
|
data=data,
|
|
user_id=user_id,
|
|
dept_id=dept_id,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(detail, message="修改成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.delete("/contract/{ids}")
|
|
@oper_log(title="CRM合同管理", business_type=3, path_param="ids", summary="删除合同")
|
|
async def contract_remove(
|
|
ids: str,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
id_list = [x.strip() for x in ids.split(",") if x.strip()]
|
|
soft_delete_contracts(db, id_list, tenant_no=tenant_no)
|
|
return success_response(None, message="删除成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.put("/contract/submitApproval")
|
|
async def contract_submit_approval(
|
|
body: ContractSubmitBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
dept_id = _user.get("dept_id", "") or _user.get("create_dept_id", "") or ""
|
|
submit_contract_approval(
|
|
db,
|
|
body.id,
|
|
tenant_no=tenant_no,
|
|
approver_ids=body.approverIds,
|
|
remark=body.remark,
|
|
user_id=user_id,
|
|
dept_id=dept_id,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(None, message="提交成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.put("/contract/batchSubmitApproval")
|
|
async def contract_batch_submit_approval(
|
|
body: ContractBatchSubmitBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
dept_id = _user.get("dept_id", "") or _user.get("create_dept_id", "") or ""
|
|
count = batch_submit_contract_approval(
|
|
db,
|
|
body.ids,
|
|
tenant_no=tenant_no,
|
|
approver_ids=body.approverIds,
|
|
remark=body.remark,
|
|
user_id=user_id,
|
|
dept_id=dept_id,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(count, message="批量提交完成")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.put("/contract/withdrawApproval")
|
|
async def contract_withdraw_approval(
|
|
body: ContractWithdrawBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
withdraw_contract_approval(
|
|
db,
|
|
body.id,
|
|
tenant_no=tenant_no,
|
|
remark=body.remark,
|
|
user_id=user_id,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(None, message="撤回成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.put("/contract/startExecute")
|
|
async def contract_start_execute(
|
|
body: ContractStatusBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
start_execute(db, body.id, tenant_no=tenant_no, remark=body.remark, user_id=user_id)
|
|
return success_response(None, message="操作成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.put("/contract/finish")
|
|
async def contract_finish(
|
|
body: ContractStatusBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
finish_contract(db, body.id, tenant_no=tenant_no, remark=body.remark, user_id=user_id)
|
|
return success_response(None, message="操作成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.put("/contract/invalid")
|
|
@oper_log(title="CRM合同管理", business_type=2, summary="作废合同")
|
|
async def contract_invalid(
|
|
body: ContractInvalidBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
invalid_contract(
|
|
db,
|
|
body.id,
|
|
tenant_no=tenant_no,
|
|
invalid_reason=body.invalidReason,
|
|
remark=body.remark,
|
|
user_id=user_id,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(None, message="作废成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.post("/contract/saveTemplate")
|
|
async def contract_save_template(
|
|
body: ContractTemplateSaveBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
save_template(
|
|
db,
|
|
body.id,
|
|
body.templateContent,
|
|
tenant_no=tenant_no,
|
|
settlement_clause_drafts=body.settlementClauseDrafts,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(None, message="保存成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.get("/contract/getTemplate/{contract_id}")
|
|
async def contract_get_template(
|
|
contract_id: str,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
content = get_template(db, contract_id, tenant_no=tenant_no, user_info=user_info)
|
|
return success_response(content or "", message="获取模板成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.post("/contract/uploadFile")
|
|
async def contract_upload_file(
|
|
body: ContractUploadFileBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
upload_file(db, body.id, body.fileUrl, tenant_no=tenant_no)
|
|
return success_response(None, message="上传成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.post("/contract/uploadAttachments")
|
|
async def contract_upload_attachments(
|
|
body: ContractUploadAttachmentsBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
if body.attachments:
|
|
upload_attachments_with_category(
|
|
db, body.id, body.attachments, tenant_no=tenant_no,
|
|
user_info=user_info,
|
|
)
|
|
elif body.ossIds:
|
|
upload_attachments(db, body.id, body.ossIds, tenant_no=tenant_no)
|
|
else:
|
|
return error_response(400, "附件参数不能为空")
|
|
return success_response(None, message="上传成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.post("/contract/export")
|
|
@oper_log(title="CRM合同管理", business_type=5, summary="导出合同列表")
|
|
async def contract_export(
|
|
body: ContractExportBody = None,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
list_body = body or ContractExportBody()
|
|
filters = list_body.model_dump(
|
|
by_alias=True,
|
|
exclude={"pageNum", "pageSize"},
|
|
exclude_none=True,
|
|
)
|
|
rows = export_contracts(db, tenant_no, filters=filters)
|
|
return export_rows_to_xlsx_response(
|
|
db,
|
|
tenant_no=tenant_no,
|
|
sheet_title="合同",
|
|
columns=CONTRACT_EXPORT_COLUMNS,
|
|
rows=rows,
|
|
filename_stem=f"合同_{datetime.now().strftime('%Y%m%d%H%M%S')}",
|
|
include_legacy_filename=False,
|
|
)
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.get("/contract/statistics/overview")
|
|
async def contract_statistics_overview(
|
|
ownerUserId: Optional[str] = None,
|
|
beginTime: Optional[str] = None,
|
|
endTime: Optional[str] = None,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
req = ContractStatisticsOverviewQuery(
|
|
ownerUserId=ownerUserId,
|
|
beginTime=beginTime,
|
|
endTime=endTime,
|
|
)
|
|
data = statistics_overview(
|
|
db,
|
|
tenant_no,
|
|
owner_user_id=req.ownerUserId,
|
|
begin_time=req.beginTime,
|
|
end_time=req.endTime,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(data)
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.get("/contract/statistics/status")
|
|
async def contract_statistics_status(
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
return success_response(statistics_by_status(db, tenant_no))
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.get("/contract/statistics/type")
|
|
async def contract_statistics_type(
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
return success_response(statistics_by_type(db, tenant_no))
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.get("/contract/statistics/trend")
|
|
async def contract_statistics_trend(
|
|
type: str = Query("month"),
|
|
beginTime: Optional[str] = None,
|
|
endTime: Optional[str] = None,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
req = ContractStatisticsTrendQuery(type=type, beginTime=beginTime, endTime=endTime)
|
|
data = statistics_trend(
|
|
db,
|
|
tenant_no,
|
|
period_type=req.type or "month",
|
|
begin_time=req.beginTime,
|
|
end_time=req.endTime,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(data)
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.get("/contract/statistics/expiring")
|
|
async def contract_statistics_expiring(
|
|
days: int = Query(30, ge=1),
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
rows = query_expiring(db, tenant_no, days=days)
|
|
return success_response(rows)
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.post("/contract/renew/{parent_id}")
|
|
async def contract_renew(
|
|
parent_id: str,
|
|
body: ContractRenewBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
dept_id = _user.get("dept_id", "") or _user.get("create_dept_id", "") or ""
|
|
new_id = renew_contract(
|
|
db,
|
|
parent_id,
|
|
tenant_no=tenant_no,
|
|
data=body.model_dump(by_alias=True),
|
|
user_id=user_id,
|
|
dept_id=dept_id,
|
|
)
|
|
return success_response(new_id, message="续签成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.post("/contract/createFromQuote/{quote_id}")
|
|
async def contract_create_from_quote(
|
|
quote_id: str,
|
|
body: ContractCreateBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
dept_id = _user.get("dept_id", "") or _user.get("create_dept_id", "") or ""
|
|
contract_id = create_from_quote(
|
|
db,
|
|
quote_id,
|
|
tenant_no=tenant_no,
|
|
data=body.model_dump(by_alias=True),
|
|
user_id=user_id,
|
|
dept_id=dept_id,
|
|
)
|
|
return success_response(contract_id, message="创建成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.post("/contract/createFromOpportunity/{opportunity_id}")
|
|
async def contract_create_from_opportunity(
|
|
opportunity_id: str,
|
|
body: ContractCreateBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
dept_id = _user.get("dept_id", "") or _user.get("create_dept_id", "") or ""
|
|
contract_id = create_from_opportunity(
|
|
db,
|
|
opportunity_id,
|
|
tenant_no=tenant_no,
|
|
data=body.model_dump(by_alias=True),
|
|
user_id=user_id,
|
|
dept_id=dept_id,
|
|
)
|
|
return success_response(contract_id, message="创建成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.put("/contract/sign")
|
|
async def contract_sign(
|
|
body: ContractSignBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
sign_contract(
|
|
db,
|
|
body.id,
|
|
tenant_no=tenant_no,
|
|
actual_sign_date=body.actualSignDate,
|
|
contract_file=body.contractFile,
|
|
remark=body.remark or "",
|
|
user_id=user_id,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(None, message="签订成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.put("/contract/batch/assign")
|
|
async def contract_batch_assign(
|
|
body: ContractBatchAssignBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
count = batch_assign_owner(
|
|
db,
|
|
body.ids,
|
|
tenant_no=tenant_no,
|
|
owner_user_id=body.ownerUserId,
|
|
remark=body.remark or "",
|
|
user_id=user_id,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(count, message="分配成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.get("/contract/download/{contract_id}")
|
|
async def contract_download(
|
|
contract_id: str,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
file_path = download_contract_pdf(db, contract_id, tenant_no=tenant_no)
|
|
return success_response(file_path)
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.post("/contract/approval")
|
|
async def contract_approval_by_contract_id(
|
|
body: ContractApprovalActionBody,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
approve_contract_by_contract_id(
|
|
db,
|
|
body.id,
|
|
approval_result=body.approvalResult,
|
|
approval_opinion=body.approvalOpinion or "",
|
|
attachments=body.attachments or "",
|
|
remark=body.remark or "",
|
|
user_id=user_id,
|
|
)
|
|
db.commit()
|
|
return success_response(None, message="审批成功")
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.get("/contract/approval/flow/{contract_id}")
|
|
async def contract_approval_flow(
|
|
contract_id: str,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
rows = list_contract_approvals(db, contract_id, tenant_no=tenant_no)
|
|
return success_response(rows)
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|
|
|
|
@router.get("/contract/{contract_id}")
|
|
async def contract_detail(
|
|
contract_id: str,
|
|
_user: dict = Depends(require_admin_or_super_admin),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
try:
|
|
tenant_no = get_tenant_no(db, _user)
|
|
user_info = crm_user_info(_user)
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
detail = get_contract_detail(
|
|
db,
|
|
contract_id,
|
|
tenant_no=tenant_no,
|
|
current_user_id=user_id,
|
|
user_info=user_info,
|
|
)
|
|
return success_response(detail)
|
|
except ValueError as e:
|
|
return error_response(400, str(e))
|
|
except Exception as e:
|
|
return error_response(500, str(e))
|