提交
This commit is contained in:
1 parent
e6072457fd
commit
be4fab78e1
578 files changed
+174415
-214
No files matched your search
@@ -1,11 +1,12 @@
|
||||
"""细胞存储 — 采集协议单 / 审核 / 财务确认 / 分期预警 API"""
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from sqlalchemy import and_ as sa_and
|
||||
from sqlalchemy import and_ as sa_and, func as sa_func, or_ as sa_or
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.core.menu_guard import require_admin_or_super_admin
|
||||
@@ -13,7 +14,14 @@ from app.core.response import error_response, success_response
|
||||
from app.core.utils import parse_datetime
|
||||
from app.crud import collection_protocol as cp_svc
|
||||
from app.crud import customer as customer_crud
|
||||
from app.models.models import BizCollectionProtocol, BizCustomer, SysUser
|
||||
from app.models.models import (
|
||||
BizCollectionProtocol,
|
||||
BizCustomer,
|
||||
BizProtocolPartyCustomer,
|
||||
BizProtocolSample,
|
||||
BizProtocolStorageCert,
|
||||
SysUser,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/web/admin", tags=["细胞存储"])
|
||||
|
||||
@@ -657,3 +665,253 @@ async def post_refund_confirm(
|
||||
except ValueError as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 储存证明管理 / 满月待办
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@router.get("/storage-certs")
|
||||
async def list_storage_certs(
|
||||
page: int = Query(1, ge=1),
|
||||
pageSize: int = Query(10, ge=1, le=100, alias="pageSize"),
|
||||
keyword: Optional[str] = None,
|
||||
makeStatus: Optional[str] = Query(None, alias="makeStatus"),
|
||||
user: dict = Depends(require_admin_or_super_admin),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
q = (
|
||||
db.query(BizCollectionProtocol)
|
||||
.filter(
|
||||
BizCollectionProtocol.del_flag == 0,
|
||||
BizCollectionProtocol.tenant_no == tenant_no,
|
||||
BizCollectionProtocol.protocol_status == "sxz",
|
||||
)
|
||||
)
|
||||
kw = (keyword or "").strip()
|
||||
if kw:
|
||||
like = f"%{kw}%"
|
||||
q = q.filter(BizCollectionProtocol.protocol_no.like(like))
|
||||
|
||||
protocol_ids_sub = q.with_entities(BizCollectionProtocol.id).subquery()
|
||||
|
||||
sample_exists = (
|
||||
db.query(BizProtocolSample)
|
||||
.filter(
|
||||
BizProtocolSample.collection_protocol_id == protocol_ids_sub.c.id,
|
||||
BizProtocolSample.del_flag == 0,
|
||||
BizProtocolSample.sample_status == "yrk",
|
||||
)
|
||||
.limit(1)
|
||||
.exists()
|
||||
)
|
||||
|
||||
q = q.filter(sample_exists)
|
||||
rows_all = q.order_by(BizCollectionProtocol.create_time.desc()).all()
|
||||
|
||||
protocol_ids = [r.id for r in rows_all]
|
||||
pc_map: Dict[str, Any] = {}
|
||||
sc_map: Dict[str, Any] = {}
|
||||
sample_map: Dict[str, List[Dict[str, Any]]] = {}
|
||||
if protocol_ids:
|
||||
pc_rows = (
|
||||
db.query(BizProtocolPartyCustomer)
|
||||
.filter(
|
||||
BizProtocolPartyCustomer.collection_protocol_id.in_(protocol_ids),
|
||||
BizProtocolPartyCustomer.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
for pc in pc_rows:
|
||||
pc_map[pc.collection_protocol_id] = pc
|
||||
|
||||
sc_rows = (
|
||||
db.query(BizProtocolStorageCert)
|
||||
.filter(
|
||||
BizProtocolStorageCert.collection_protocol_id.in_(protocol_ids),
|
||||
BizProtocolStorageCert.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
for sc in sc_rows:
|
||||
sc_map[sc.collection_protocol_id] = sc
|
||||
|
||||
s_rows = (
|
||||
db.query(BizProtocolSample)
|
||||
.filter(
|
||||
BizProtocolSample.collection_protocol_id.in_(protocol_ids),
|
||||
BizProtocolSample.del_flag == 0,
|
||||
BizProtocolSample.sample_status == "yrk",
|
||||
)
|
||||
.all()
|
||||
)
|
||||
for s in s_rows:
|
||||
sample_map.setdefault(s.collection_protocol_id, []).append(
|
||||
cp_svc._sample_to_dict(s)
|
||||
)
|
||||
|
||||
items: List[Dict[str, Any]] = []
|
||||
for r in rows_all:
|
||||
sc = sc_map.get(r.id)
|
||||
ms = (sc.make_status or "0") if sc else "0"
|
||||
if makeStatus and makeStatus.strip() and ms != makeStatus.strip():
|
||||
continue
|
||||
pc = pc_map.get(r.id)
|
||||
d: Dict[str, Any] = {
|
||||
"id": r.id,
|
||||
"protocolNo": r.protocol_no or "",
|
||||
"protocolStatus": r.protocol_status or "",
|
||||
"motherName": (pc.mother_name or "") if pc else "",
|
||||
"newbornDeliveryTime": cp_svc._fmt_dt(pc.newborn_delivery_time) if pc else "",
|
||||
"samples": sample_map.get(r.id, []),
|
||||
"makeStatus": ms,
|
||||
"certImageUrls": (sc.cert_image_urls or "") if sc else "",
|
||||
"makeDate": ((sc.make_date or "").strip() if sc.make_date else "") if sc else "",
|
||||
}
|
||||
items.append(d)
|
||||
|
||||
total = len(items)
|
||||
page_safe = max(1, page)
|
||||
page_size_safe = min(max(1, pageSize), 100)
|
||||
start = (page_safe - 1) * page_size_safe
|
||||
page_items = items[start : start + page_size_safe]
|
||||
tp = cp_svc.total_pages(total, page_size_safe)
|
||||
return success_response(
|
||||
{"list": page_items, "total": total, "page": page_safe, "pageSize": page_size_safe, "totalPages": tp}
|
||||
)
|
||||
|
||||
|
||||
@router.get("/fullmoon-todos")
|
||||
async def list_fullmoon_todos(
|
||||
page: int = Query(1, ge=1),
|
||||
pageSize: int = Query(10, ge=1, le=100, alias="pageSize"),
|
||||
keyword: Optional[str] = None,
|
||||
todoStatus: Optional[str] = Query(None, alias="todoStatus"),
|
||||
user: dict = Depends(require_admin_or_super_admin),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
q = (
|
||||
db.query(BizCollectionProtocol, BizProtocolPartyCustomer)
|
||||
.join(
|
||||
BizProtocolPartyCustomer,
|
||||
sa_and(
|
||||
BizProtocolPartyCustomer.collection_protocol_id == BizCollectionProtocol.id,
|
||||
BizProtocolPartyCustomer.del_flag == 0,
|
||||
),
|
||||
)
|
||||
.filter(
|
||||
BizCollectionProtocol.del_flag == 0,
|
||||
BizCollectionProtocol.tenant_no == tenant_no,
|
||||
BizCollectionProtocol.protocol_status == "sxz",
|
||||
BizProtocolPartyCustomer.tenant_no == tenant_no,
|
||||
)
|
||||
)
|
||||
kw = (keyword or "").strip()
|
||||
if kw:
|
||||
like = f"%{kw}%"
|
||||
q = q.filter(
|
||||
sa_or(
|
||||
BizCollectionProtocol.protocol_no.like(like),
|
||||
BizProtocolPartyCustomer.mother_name.like(like),
|
||||
)
|
||||
)
|
||||
|
||||
rows = q.order_by(BizCollectionProtocol.create_time.desc()).all()
|
||||
|
||||
protocol_ids = [r.id for r, _ in rows]
|
||||
ft_map: Dict[str, Any] = {}
|
||||
if protocol_ids:
|
||||
from app.models.models import BizProtocolFullmoonTodo
|
||||
ft_rows = (
|
||||
db.query(BizProtocolFullmoonTodo)
|
||||
.filter(
|
||||
BizProtocolFullmoonTodo.collection_protocol_id.in_(protocol_ids),
|
||||
BizProtocolFullmoonTodo.tenant_no == tenant_no,
|
||||
BizProtocolFullmoonTodo.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
for ft in ft_rows:
|
||||
ft_map[ft.collection_protocol_id] = ft
|
||||
|
||||
now = datetime.now()
|
||||
items: List[Dict[str, Any]] = []
|
||||
for proto, pc in rows:
|
||||
dt = pc.newborn_delivery_time
|
||||
if not dt:
|
||||
continue
|
||||
fullmoon_date = dt + timedelta(days=30)
|
||||
if fullmoon_date > now:
|
||||
continue
|
||||
ft = ft_map.get(proto.id)
|
||||
ts = (ft.todo_status or "0") if ft else "0"
|
||||
if todoStatus and todoStatus.strip() and ts != todoStatus.strip():
|
||||
continue
|
||||
d: Dict[str, Any] = {
|
||||
"id": proto.id,
|
||||
"protocolNo": proto.protocol_no or "",
|
||||
"protocolStatus": proto.protocol_status or "",
|
||||
"motherName": pc.mother_name or "",
|
||||
"motherPhone": pc.mother_phone or "",
|
||||
"newbornName": pc.newborn_name or "",
|
||||
"newbornDeliveryTime": cp_svc._fmt_dt(dt),
|
||||
"fullmoonDate": fullmoon_date.strftime("%Y-%m-%d"),
|
||||
}
|
||||
if ft:
|
||||
d["fullmoonTodo"] = cp_svc._fullmoon_todo_to_dict(ft)
|
||||
else:
|
||||
d["fullmoonTodo"] = None
|
||||
items.append(d)
|
||||
|
||||
total = len(items)
|
||||
page_safe = max(1, page)
|
||||
page_size_safe = min(max(1, pageSize), 100)
|
||||
start = (page_safe - 1) * page_size_safe
|
||||
page_items = items[start : start + page_size_safe]
|
||||
tp = cp_svc.total_pages(total, page_size_safe)
|
||||
return success_response(
|
||||
{"list": page_items, "total": total, "page": page_safe, "pageSize": page_size_safe, "totalPages": tp}
|
||||
)
|
||||
|
||||
|
||||
class FullmoonTodoInsuranceBody(BaseModel):
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
|
||||
insurance_company_id: Optional[str] = Field(None, alias="insuranceCompanyId")
|
||||
insurance_company_name: Optional[str] = Field(None, alias="insuranceCompanyName")
|
||||
insurance_type: Optional[str] = Field(None, alias="insuranceType")
|
||||
insurance_policy_no: Optional[str] = Field(None, alias="insurancePolicyNo")
|
||||
insurance_effective_date: Optional[str] = Field(None, alias="insuranceEffectiveDate")
|
||||
insurance_expiry_date: Optional[str] = Field(None, alias="insuranceExpiryDate")
|
||||
insurance_subscribed: Optional[str] = Field(None, alias="insuranceSubscribed")
|
||||
insurance_fee: Optional[float] = Field(None, alias="insuranceFee")
|
||||
insurance_attachments: Optional[str] = Field(None, alias="insuranceAttachments")
|
||||
todo_status: Optional[str] = Field(None, alias="todoStatus")
|
||||
handle_date: Optional[str] = Field(None, alias="handleDate")
|
||||
handle_remark: Optional[str] = Field(None, alias="handleRemark")
|
||||
|
||||
|
||||
@router.put("/fullmoon-todos/{protocol_id}/insurance")
|
||||
async def update_fullmoon_todo_insurance(
|
||||
protocol_id: str,
|
||||
body: FullmoonTodoInsuranceBody,
|
||||
user: dict = Depends(require_admin_or_super_admin),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
user_id = _get_current_user_id(user)
|
||||
try:
|
||||
payload = body.model_dump(exclude_unset=True, by_alias=False)
|
||||
ft = cp_svc.upsert_fullmoon_todo(
|
||||
db,
|
||||
protocol_id,
|
||||
tenant_no,
|
||||
user_id,
|
||||
**payload,
|
||||
)
|
||||
return success_response(cp_svc._fullmoon_todo_to_dict(ft), message="更新成功")
|
||||
except ValueError as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
Reference in new issue
Block a user