补全 PR3 Phase 2.4–2.7,列表 apply_data_scope、详情/CUD assert_row_in_data_scope,合同/报价主表支持 owner_user_id。 Co-authored-by: Cursor <cursoragent@cursor.com>
254 lines
7.1 KiB
Python
254 lines
7.1 KiB
Python
"""CRM 客户开票信息 CRUD"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.utils import generate_uuid
|
|
from app.crud.crm.data_scope_helpers import (
|
|
ensure_crm_customer_linked_row_in_scope,
|
|
ensure_crm_owner_row_in_scope,
|
|
)
|
|
from app.models.crm_models import CrmInvoiceInfo
|
|
|
|
|
|
_FMT = "%Y-%m-%d %H:%M:%S"
|
|
|
|
|
|
def _row_to_dict(row: CrmInvoiceInfo) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"customerId": row.customer_id or "",
|
|
"companyName": row.company_name or "",
|
|
"taxNo": row.tax_no or "",
|
|
"companyAddress": row.company_address or "",
|
|
"legalRepresentative": row.legal_representative or "",
|
|
"agent": row.agent or "",
|
|
"phoneFax": row.phone_fax or "",
|
|
"bankName": row.bank_name or "",
|
|
"bankAccount": row.bank_account or "",
|
|
"isDefault": row.is_default or "0",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createBy": row.create_by or "",
|
|
"createTime": row.create_time.strftime(_FMT) if row.create_time else "",
|
|
"updateBy": row.update_by or "",
|
|
"updateTime": row.update_time.strftime(_FMT) if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_invoice_info_by_customer(
|
|
db: Session,
|
|
tenant_no: str,
|
|
customer_id: str,
|
|
*,
|
|
user_info=None,
|
|
) -> List[Dict[str, Any]]:
|
|
if user_info:
|
|
from app.crud.crm.customer import get_customer
|
|
|
|
customer = get_customer(db, customer_id)
|
|
if not customer or customer.tenant_no != tenant_no:
|
|
raise ValueError("客户不存在")
|
|
ensure_crm_owner_row_in_scope(
|
|
db, customer, user_info, tenant_no, message="无权访问该客户"
|
|
)
|
|
rows = (
|
|
db.query(CrmInvoiceInfo)
|
|
.filter(
|
|
CrmInvoiceInfo.tenant_no == tenant_no,
|
|
CrmInvoiceInfo.customer_id == customer_id,
|
|
CrmInvoiceInfo.del_flag == 0,
|
|
)
|
|
.order_by(CrmInvoiceInfo.is_default.desc(), CrmInvoiceInfo.create_time.desc())
|
|
.all()
|
|
)
|
|
return [_row_to_dict(r) for r in rows]
|
|
|
|
|
|
def get_invoice_info(db: Session, invoice_id: str) -> Optional[CrmInvoiceInfo]:
|
|
return (
|
|
db.query(CrmInvoiceInfo)
|
|
.filter(
|
|
CrmInvoiceInfo.id == invoice_id,
|
|
CrmInvoiceInfo.del_flag == 0,
|
|
)
|
|
.first()
|
|
)
|
|
|
|
|
|
def _clear_default_for_customer(
|
|
db: Session,
|
|
tenant_no: str,
|
|
customer_id: str,
|
|
exclude_id: str = None,
|
|
) -> None:
|
|
q = db.query(CrmInvoiceInfo).filter(
|
|
CrmInvoiceInfo.tenant_no == tenant_no,
|
|
CrmInvoiceInfo.customer_id == customer_id,
|
|
CrmInvoiceInfo.del_flag == 0,
|
|
CrmInvoiceInfo.is_default == "1",
|
|
)
|
|
if exclude_id:
|
|
q = q.filter(CrmInvoiceInfo.id != exclude_id)
|
|
q.update({"is_default": "0"})
|
|
|
|
|
|
def create_invoice_info(
|
|
db: Session,
|
|
*,
|
|
tenant_no: str,
|
|
user_id: str = None,
|
|
dept_id: str = "",
|
|
user_info=None,
|
|
**kwargs,
|
|
) -> CrmInvoiceInfo:
|
|
customer_id = kwargs.get("customer_id")
|
|
if not customer_id:
|
|
raise ValueError("缺少客户ID")
|
|
if user_info:
|
|
from app.crud.crm.customer import get_customer
|
|
|
|
customer = get_customer(db, customer_id)
|
|
if not customer or customer.tenant_no != tenant_no:
|
|
raise ValueError("客户不存在")
|
|
ensure_crm_owner_row_in_scope(
|
|
db, customer, user_info, tenant_no, message="无权访问该客户"
|
|
)
|
|
|
|
company_name = (kwargs.get("company_name") or "").strip()
|
|
if not company_name:
|
|
raise ValueError("单位名称不能为空")
|
|
|
|
is_default = kwargs.get("is_default") or "0"
|
|
if is_default == "1":
|
|
_clear_default_for_customer(db, tenant_no, customer_id)
|
|
|
|
obj = CrmInvoiceInfo(
|
|
id=generate_uuid(),
|
|
customer_id=customer_id,
|
|
company_name=company_name,
|
|
tax_no=kwargs.get("tax_no") or "",
|
|
company_address=kwargs.get("company_address") or "",
|
|
legal_representative=kwargs.get("legal_representative") or "",
|
|
agent=kwargs.get("agent") or "",
|
|
phone_fax=kwargs.get("phone_fax") or "",
|
|
bank_name=kwargs.get("bank_name") or "",
|
|
bank_account=kwargs.get("bank_account") or "",
|
|
is_default=is_default,
|
|
tenant_no=tenant_no,
|
|
order_num=kwargs.get("order_num"),
|
|
remark=kwargs.get("remark"),
|
|
create_by=user_id,
|
|
create_dept_id=dept_id,
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_invoice_info(
|
|
db: Session,
|
|
invoice_id: str,
|
|
*,
|
|
tenant_no: str = None,
|
|
user_id: str = None,
|
|
user_info=None,
|
|
**kwargs,
|
|
) -> CrmInvoiceInfo:
|
|
obj = get_invoice_info(db, invoice_id)
|
|
if not obj:
|
|
raise ValueError("开票信息不存在")
|
|
|
|
if tenant_no and obj.tenant_no != tenant_no:
|
|
raise ValueError("开票信息不存在")
|
|
ensure_crm_customer_linked_row_in_scope(
|
|
db, obj, user_info, obj.tenant_no, message="无权访问该开票信息"
|
|
)
|
|
|
|
_updatable = (
|
|
"company_name",
|
|
"tax_no",
|
|
"company_address",
|
|
"legal_representative",
|
|
"agent",
|
|
"phone_fax",
|
|
"bank_name",
|
|
"bank_account",
|
|
"is_default",
|
|
"order_num",
|
|
"remark",
|
|
)
|
|
for field in _updatable:
|
|
if field in kwargs and kwargs[field] is not None:
|
|
setattr(obj, field, kwargs[field])
|
|
|
|
if kwargs.get("is_default") == "1":
|
|
_clear_default_for_customer(
|
|
db,
|
|
obj.tenant_no,
|
|
obj.customer_id,
|
|
exclude_id=invoice_id,
|
|
)
|
|
obj.is_default = "1"
|
|
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def set_default_invoice_info(
|
|
db: Session,
|
|
invoice_id: str,
|
|
customer_id: str,
|
|
*,
|
|
tenant_no: str,
|
|
user_id: str = None,
|
|
user_info=None,
|
|
) -> CrmInvoiceInfo:
|
|
obj = get_invoice_info(db, invoice_id)
|
|
if not obj or obj.tenant_no != tenant_no:
|
|
raise ValueError("开票信息不存在")
|
|
if obj.customer_id != customer_id:
|
|
raise ValueError("开票信息与客户不匹配")
|
|
ensure_crm_customer_linked_row_in_scope(
|
|
db, obj, user_info, tenant_no, message="无权访问该开票信息"
|
|
)
|
|
|
|
_clear_default_for_customer(db, tenant_no, customer_id, exclude_id=invoice_id)
|
|
obj.is_default = "1"
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_invoice_info(
|
|
db: Session,
|
|
invoice_id: str,
|
|
user_id: str = None,
|
|
*,
|
|
tenant_no: str = None,
|
|
user_info=None,
|
|
) -> bool:
|
|
obj = get_invoice_info(db, invoice_id)
|
|
if not obj:
|
|
raise ValueError("开票信息不存在")
|
|
if tenant_no and obj.tenant_no != tenant_no:
|
|
raise ValueError("开票信息不存在")
|
|
ensure_crm_customer_linked_row_in_scope(
|
|
db, obj, user_info, obj.tenant_no, message="无权访问该开票信息"
|
|
)
|
|
obj.del_flag = 1
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.commit()
|
|
return True
|