Files
shanxia2.0/backend/app/crud/crm/supplier_info.py
T
2026-07-26 21:06:09 +08:00

239 lines
7.0 KiB
Python

"""CRM 供方信息 CRUD — 对照 CrmSupplierInfoServiceImpl.java"""
from __future__ import annotations
import math
from datetime import datetime
from typing import Any, Dict, List, Optional, Tuple
from sqlalchemy.orm import Session
from app.core.delete_guard import assert_row_deletable_by_creator
from app.core.utils import generate_uuid
from app.crud.crm.data_scope_helpers import (
apply_crm_create_by_scope,
ensure_crm_create_by_row_in_scope,
)
from app.models.crm_models import CrmSupplierInfo
_FMT = "%Y-%m-%d %H:%M:%S"
_WRITABLE_FIELDS = (
"supplier_name",
"short_name",
"supplier_code",
"supplier_address",
"legal_person",
"agent",
"phone_fax",
"bank_name",
"bank_account",
"allow_toxic",
"allow_explosive",
"status",
"order_num",
"remark",
)
def total_pages(total: int, page_size: int) -> int:
if page_size <= 0:
return 0
return math.ceil(total / page_size)
def _row_to_dict(row: CrmSupplierInfo) -> Dict[str, Any]:
"""ORM → camelCase(单点真相)"""
return {
"id": row.id,
"supplierName": row.supplier_name or "",
"shortName": row.short_name or "",
"supplierCode": row.supplier_code or "",
"supplierAddress": row.supplier_address or "",
"legalPerson": row.legal_person or "",
"agent": row.agent or "",
"phoneFax": row.phone_fax or "",
"bankName": row.bank_name or "",
"bankAccount": row.bank_account or "",
"allowToxic": int(row.allow_toxic or 0),
"allowExplosive": int(row.allow_explosive or 0),
"status": row.status 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 _apply_list_filters(q, *, supplier_name: str = None, status: str = None):
"""Java: buildQueryWrapper"""
if supplier_name and supplier_name.strip():
q = q.filter(CrmSupplierInfo.supplier_name.like(f"%{supplier_name.strip()}%"))
if status is not None and str(status).strip() != "":
q = q.filter(CrmSupplierInfo.status == str(status).strip())
return q
def list_supplier_info(
db: Session,
tenant_no: str,
*,
page: int = 1,
page_size: int = 10,
supplier_name: str = None,
status: str = None,
user_info=None,
) -> Tuple[List[Dict[str, Any]], int]:
"""Java: queryPageList"""
q = db.query(CrmSupplierInfo).filter(
CrmSupplierInfo.tenant_no == tenant_no,
CrmSupplierInfo.del_flag == 0,
)
if user_info:
q = apply_crm_create_by_scope(q, CrmSupplierInfo, user_info, db, tenant_no)
q = _apply_list_filters(q, supplier_name=supplier_name, status=status)
total = q.count()
rows = (
q.order_by(CrmSupplierInfo.create_time.desc())
.offset((page - 1) * page_size)
.limit(page_size)
.all()
)
return [_row_to_dict(r) for r in rows], total
def list_all_supplier_info(
db: Session,
tenant_no: str,
*,
supplier_name: str = None,
status: str = None,
user_info=None,
) -> List[Dict[str, Any]]:
"""Java: queryList(不分页,报价单下拉)"""
q = db.query(CrmSupplierInfo).filter(
CrmSupplierInfo.tenant_no == tenant_no,
CrmSupplierInfo.del_flag == 0,
)
if user_info:
q = apply_crm_create_by_scope(q, CrmSupplierInfo, user_info, db, tenant_no)
q = _apply_list_filters(q, supplier_name=supplier_name, status=status)
rows = q.order_by(CrmSupplierInfo.create_time.desc()).all()
return [_row_to_dict(r) for r in rows]
def get_supplier_info(
db: Session,
supplier_id: str,
*,
tenant_no: str = None,
) -> Optional[CrmSupplierInfo]:
"""Java: queryById"""
q = db.query(CrmSupplierInfo).filter(
CrmSupplierInfo.id == supplier_id,
CrmSupplierInfo.del_flag == 0,
)
if tenant_no:
q = q.filter(CrmSupplierInfo.tenant_no == tenant_no)
return q.first()
def create_supplier_info(
db: Session,
*,
tenant_no: str,
user_id: str = None,
dept_id: str = "",
**kwargs,
) -> CrmSupplierInfo:
"""Java: insertByBo"""
supplier_name = (kwargs.get("supplier_name") or "").strip()
if not supplier_name:
raise ValueError("供方名称不能为空")
obj = CrmSupplierInfo(
id=generate_uuid(),
supplier_name=supplier_name,
short_name=kwargs.get("short_name") or "",
supplier_code=kwargs.get("supplier_code") or "",
supplier_address=kwargs.get("supplier_address") or "",
legal_person=kwargs.get("legal_person") 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 "",
allow_toxic=kwargs.get("allow_toxic", 0) or 0,
allow_explosive=kwargs.get("allow_explosive", 0) or 0,
status=kwargs.get("status") or "0",
tenant_no=tenant_no,
order_num=kwargs.get("order_num"),
remark=kwargs.get("remark"),
create_by=user_id,
create_dept_id=dept_id or "",
del_flag=0,
)
db.add(obj)
db.commit()
db.refresh(obj)
return obj
def update_supplier_info(
db: Session,
supplier_id: str,
*,
tenant_no: str = None,
user_id: str = None,
user_info=None,
**kwargs,
) -> CrmSupplierInfo:
"""Java: updateByBo"""
obj = get_supplier_info(db, supplier_id, tenant_no=tenant_no)
if not obj:
raise ValueError("供方信息不存在")
ensure_crm_create_by_row_in_scope(
db, obj, user_info, obj.tenant_no, message="无权访问该供方信息"
)
if "supplier_name" in kwargs and kwargs["supplier_name"] is not None:
name = (kwargs["supplier_name"] or "").strip()
if not name:
raise ValueError("供方名称不能为空")
obj.supplier_name = name
for field in _WRITABLE_FIELDS:
if field == "supplier_name":
continue
if field in kwargs and kwargs[field] is not None:
setattr(obj, field, kwargs[field])
obj.update_by = user_id
obj.update_time = datetime.now()
db.commit()
db.refresh(obj)
return obj
def soft_delete_supplier_info(
db: Session,
supplier_id: str,
*,
tenant_no: str = None,
user_id: str = None,
user_info=None,
) -> bool:
"""Java: deleteWithValidByIds(门户软删)"""
obj = get_supplier_info(db, supplier_id, tenant_no=tenant_no)
if not obj:
raise ValueError("供方信息不存在")
ensure_crm_create_by_row_in_scope(
db, obj, user_info, obj.tenant_no, message="无权访问该供方信息"
)
assert_row_deletable_by_creator(obj, user_info, user_id=user_id)
obj.del_flag = 1
obj.update_by = user_id
obj.update_time = datetime.now()
db.commit()
return True