发起校验能识别已删除、他租户和他人账户,编辑账户不会改掉 create_by。 Co-authored-by: Cursor <cursoragent@cursor.com>
228 lines
6.9 KiB
Python
228 lines
6.9 KiB
Python
"""OA 收款账户 CRUD(oa_receive_account)"""
|
||
from __future__ import annotations
|
||
|
||
from datetime import datetime
|
||
from typing import Any, Dict, List, Optional, Tuple
|
||
|
||
from sqlalchemy import func, or_
|
||
from sqlalchemy.orm import Session
|
||
|
||
from app.core.utils import generate_uuid
|
||
from app.models.models import OaReceiveAccount, SysUser
|
||
|
||
|
||
def row_to_dict(r: OaReceiveAccount) -> Dict[str, Any]:
|
||
return {
|
||
"id": r.id,
|
||
"accountType": r.account_type,
|
||
"accountName": r.account_name,
|
||
"accountNo": r.account_no,
|
||
"bankName": r.bank_name or "",
|
||
"bankProvince": r.bank_province or "",
|
||
"bankCity": r.bank_city or "",
|
||
"bankBranch": r.bank_branch or "",
|
||
"tenantNo": r.tenant_no,
|
||
"orderNum": r.order_num if r.order_num is not None else 0,
|
||
"remark": r.remark or "",
|
||
"createTime": r.create_time.strftime("%Y-%m-%d %H:%M:%S") if r.create_time else "",
|
||
"updateTime": r.update_time.strftime("%Y-%m-%d %H:%M:%S") if r.update_time else "",
|
||
"ownerUserId": (r.create_by or "").strip(),
|
||
}
|
||
|
||
|
||
def _owner_name_map(db: Session, user_ids: List[str]) -> Dict[str, str]:
|
||
ids = [item for item in {uid.strip() for uid in user_ids if uid and uid.strip()}]
|
||
if not ids:
|
||
return {}
|
||
rows = db.query(SysUser.id, SysUser.nick_name).filter(SysUser.id.in_(ids)).all()
|
||
return {row.id: (row.nick_name or "").strip() for row in rows}
|
||
|
||
|
||
def _attach_owner_names(db: Session, items: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
||
names = _owner_name_map(db, [item.get("ownerUserId") or "" for item in items])
|
||
for item in items:
|
||
uid = item.get("ownerUserId") or ""
|
||
item["ownerName"] = names.get(uid) or "—"
|
||
return items
|
||
|
||
|
||
def _filtered_query(
|
||
db: Session,
|
||
*,
|
||
tenant_no: str,
|
||
keyword: Optional[str] = None,
|
||
account_type: Optional[str] = None,
|
||
):
|
||
q = db.query(OaReceiveAccount).filter(
|
||
OaReceiveAccount.tenant_no == tenant_no,
|
||
OaReceiveAccount.del_flag == 0,
|
||
)
|
||
kw = (keyword or "").strip()
|
||
if kw:
|
||
like = f"%{kw}%"
|
||
q = q.filter(
|
||
or_(
|
||
OaReceiveAccount.account_name.like(like),
|
||
OaReceiveAccount.account_no.like(like),
|
||
OaReceiveAccount.bank_name.like(like),
|
||
)
|
||
)
|
||
if account_type:
|
||
q = q.filter(OaReceiveAccount.account_type == account_type.strip())
|
||
return q
|
||
|
||
|
||
def list_accounts(
|
||
db: Session,
|
||
*,
|
||
tenant_no: str,
|
||
keyword: Optional[str] = None,
|
||
account_type: Optional[str] = None,
|
||
page: int = 1,
|
||
page_size: int = 10,
|
||
) -> Tuple[List[Dict[str, Any]], int]:
|
||
base = _filtered_query(db, tenant_no=tenant_no, keyword=keyword, account_type=account_type)
|
||
total = base.order_by(None).with_entities(func.count(OaReceiveAccount.id)).scalar() or 0
|
||
page = max(1, page)
|
||
page_size = min(max(1, page_size), 100)
|
||
rows = (
|
||
base.order_by(OaReceiveAccount.create_time.desc())
|
||
.offset((page - 1) * page_size)
|
||
.limit(page_size)
|
||
.all()
|
||
)
|
||
return _attach_owner_names(db, [row_to_dict(x) for x in rows]), int(total)
|
||
|
||
|
||
def list_options(db: Session, *, tenant_no: str, user_id: str) -> List[Dict[str, Any]]:
|
||
owner_id = (user_id or "").strip()
|
||
if not owner_id:
|
||
return []
|
||
rows = (
|
||
db.query(OaReceiveAccount)
|
||
.filter(
|
||
OaReceiveAccount.tenant_no == tenant_no,
|
||
OaReceiveAccount.del_flag == 0,
|
||
func.trim(OaReceiveAccount.create_by) == owner_id,
|
||
)
|
||
.order_by(OaReceiveAccount.create_time.desc())
|
||
.all()
|
||
)
|
||
return _attach_owner_names(db, [row_to_dict(x) for x in rows])
|
||
|
||
|
||
def get_account(db: Session, account_id: str, tenant_no: str) -> Optional[Dict[str, Any]]:
|
||
row = (
|
||
db.query(OaReceiveAccount)
|
||
.filter(
|
||
OaReceiveAccount.id == account_id,
|
||
OaReceiveAccount.tenant_no == tenant_no,
|
||
OaReceiveAccount.del_flag == 0,
|
||
)
|
||
.first()
|
||
)
|
||
return _attach_owner_names(db, [row_to_dict(row)])[0] if row else None
|
||
|
||
|
||
def create_account(
|
||
db: Session,
|
||
*,
|
||
tenant_no: str,
|
||
user_id: Optional[str],
|
||
dept_id: str,
|
||
fields: Dict[str, Any],
|
||
) -> Dict[str, Any]:
|
||
now = datetime.now()
|
||
obj = OaReceiveAccount(
|
||
id=generate_uuid(),
|
||
account_type=fields["account_type"],
|
||
account_name=fields["account_name"],
|
||
account_no=fields["account_no"],
|
||
bank_name=fields.get("bank_name") or None,
|
||
bank_province=fields.get("bank_province") or None,
|
||
bank_city=fields.get("bank_city") or None,
|
||
bank_branch=fields.get("bank_branch") or None,
|
||
tenant_no=tenant_no,
|
||
order_num=fields.get("order_num") if fields.get("order_num") is not None else 0,
|
||
remark=(fields.get("remark") or "").strip() or None,
|
||
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(obj)
|
||
db.commit()
|
||
db.refresh(obj)
|
||
return _attach_owner_names(db, [row_to_dict(obj)])[0]
|
||
|
||
|
||
def update_account(
|
||
db: Session,
|
||
account_id: str,
|
||
tenant_no: str,
|
||
user_id: Optional[str],
|
||
fields: Dict[str, Any],
|
||
) -> Optional[Dict[str, Any]]:
|
||
obj = (
|
||
db.query(OaReceiveAccount)
|
||
.filter(
|
||
OaReceiveAccount.id == account_id,
|
||
OaReceiveAccount.tenant_no == tenant_no,
|
||
OaReceiveAccount.del_flag == 0,
|
||
)
|
||
.first()
|
||
)
|
||
if not obj:
|
||
return None
|
||
obj.account_type = fields["account_type"]
|
||
obj.account_name = fields["account_name"]
|
||
obj.account_no = fields["account_no"]
|
||
obj.bank_name = fields.get("bank_name") or None
|
||
obj.bank_province = fields.get("bank_province") or None
|
||
obj.bank_city = fields.get("bank_city") or None
|
||
obj.bank_branch = fields.get("bank_branch") or None
|
||
if fields.get("order_num") is not None:
|
||
obj.order_num = fields["order_num"]
|
||
if fields.get("remark") is not None:
|
||
obj.remark = (fields.get("remark") or "").strip() or None
|
||
obj.update_by = user_id
|
||
obj.update_time = datetime.now()
|
||
db.add(obj)
|
||
db.commit()
|
||
db.refresh(obj)
|
||
return _attach_owner_names(db, [row_to_dict(obj)])[0]
|
||
|
||
|
||
def soft_delete_account(
|
||
db: Session, account_id: str, tenant_no: str, user_id: Optional[str]
|
||
) -> bool:
|
||
obj = (
|
||
db.query(OaReceiveAccount)
|
||
.filter(
|
||
OaReceiveAccount.id == account_id,
|
||
OaReceiveAccount.tenant_no == tenant_no,
|
||
OaReceiveAccount.del_flag == 0,
|
||
)
|
||
.first()
|
||
)
|
||
if not obj:
|
||
return False
|
||
obj.del_flag = 1
|
||
obj.update_by = user_id
|
||
obj.update_time = datetime.now()
|
||
db.add(obj)
|
||
db.commit()
|
||
return True
|
||
|
||
|
||
def soft_delete_accounts(
|
||
db: Session, ids: List[str], tenant_no: str, user_id: Optional[str]
|
||
) -> int:
|
||
count = 0
|
||
for account_id in ids:
|
||
if soft_delete_account(db, account_id, tenant_no, user_id):
|
||
count += 1
|
||
return count
|