Bladeren bron

feat(crm): implement quote approver setting model and upsert CRUD

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 3 maanden geleden
bovenliggende
commit
ffbb5e36b3

+ 93 - 0
backend/app/crud/crm/quote_approver_setting.py

@@ -32,3 +32,96 @@ def prefill_approver_ids(
     if valid_ids is not None:
         ids = [i for i in ids if str(i) in valid_ids]
     return [str(i) for i in ids if str(i).strip()]
+
+
+from datetime import datetime
+
+from sqlalchemy.orm import Session
+
+from app.core.utils import generate_uuid
+from app.models.crm_models import CrmQuoteApproverSetting
+from app.models.models import SysUser
+
+
+def _row_to_dict(row: CrmQuoteApproverSetting) -> Dict[str, Any]:
+    return {
+        "id": row.id,
+        "approverIds": parse_approver_ids(row.approver_ids),
+        "status": row.status or "0",
+        "tenantNo": row.tenant_no,
+        "updateTime": row.update_time.isoformat(sep=" ") if row.update_time else None,
+    }
+
+
+def get_setting(db: Session, *, tenant_no: str) -> Optional[Dict[str, Any]]:
+    row = (
+        db.query(CrmQuoteApproverSetting)
+        .filter(
+            CrmQuoteApproverSetting.tenant_no == tenant_no,
+            CrmQuoteApproverSetting.del_flag == 0,
+        )
+        .order_by(CrmQuoteApproverSetting.update_time.desc())
+        .first()
+    )
+    return _row_to_dict(row) if row else None
+
+
+def _assert_users_exist(db: Session, *, tenant_no: str, approver_ids: List[str]) -> None:
+    ids = [str(i).strip() for i in approver_ids if str(i).strip()]
+    if not ids:
+        return
+    rows = (
+        db.query(SysUser.id)
+        .filter(SysUser.id.in_(ids), SysUser.del_flag == 0)
+        .all()
+    )
+    found = {str(r[0]) for r in rows}
+    missing = [i for i in ids if i not in found]
+    if missing:
+        raise ValueError(f"审批人无效或不存在:{','.join(missing)}")
+
+
+def save_setting(
+    db: Session,
+    *,
+    tenant_no: str,
+    approver_ids: List[str],
+    status: str,
+    user_id: str = None,
+    dept_id: str = "",
+) -> Dict[str, Any]:
+    status_norm = "1" if str(status) == "1" else "0"
+    ids = [str(i).strip() for i in (approver_ids or []) if str(i).strip()]
+    _assert_users_exist(db, tenant_no=tenant_no, approver_ids=ids)
+
+    row = (
+        db.query(CrmQuoteApproverSetting)
+        .filter(
+            CrmQuoteApproverSetting.tenant_no == tenant_no,
+            CrmQuoteApproverSetting.del_flag == 0,
+        )
+        .first()
+    )
+    now = datetime.now()
+    if row:
+        row.approver_ids = join_approver_ids(ids)
+        row.status = status_norm
+        row.update_by = user_id
+        row.update_time = now
+    else:
+        row = CrmQuoteApproverSetting(
+            id=generate_uuid(),
+            approver_ids=join_approver_ids(ids),
+            status=status_norm,
+            tenant_no=tenant_no,
+            create_by=user_id,
+            create_dept_id=dept_id or "",
+            create_time=now,
+            update_by=user_id,
+            update_time=now,
+            del_flag=0,
+        )
+        db.add(row)
+    db.commit()
+    db.refresh(row)
+    return _row_to_dict(row)

+ 19 - 0
backend/app/models/crm_models.py

@@ -848,6 +848,25 @@ class CrmQuoteProduct(Base):
     del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记")
 
 
+class CrmQuoteApproverSetting(Base):
+    """CRM-报价单审批人设置(租户级)"""
+
+    __tablename__ = "crm_quote_approver_setting"
+
+    id = Column(String(64), primary_key=True, comment="主键ID(UUID)")
+    approver_ids = Column(String(1000), nullable=False, default="", comment="有序审批人用户ID,逗号分隔")
+    status = Column(String(1), nullable=False, default="0", comment="0启用 1停用")
+    tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
+    order_num = Column(Integer, nullable=True, comment="排序号")
+    remark = Column(String(500), nullable=True, comment="备注")
+    create_by = Column(String(64), nullable=True, comment="创建者")
+    create_dept_id = Column(String(64), nullable=False, default="", comment="创建部门")
+    create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
+    update_by = Column(String(64), nullable=True, comment="更新者")
+    update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
+    del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记")
+
+
 class CrmQuoteApproval(Base):
     """CRM-报价单审批记录表"""
 

+ 10 - 0
backend/app/schemas/crm/quote_approver_setting.py

@@ -0,0 +1,10 @@
+from typing import List
+
+from pydantic import BaseModel, ConfigDict, Field
+
+
+class QuoteApproverSettingSaveBody(BaseModel):
+    model_config = ConfigDict(populate_by_name=True)
+
+    approverIds: List[str] = Field(default_factory=list)
+    status: str = Field(default="0")  # 0启用 1停用