| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- """客户详情:关联协议与同单家庭成员聚合。"""
- from __future__ import annotations
- from datetime import datetime
- from typing import Any, Dict, List, Optional, Tuple
- from sqlalchemy import or_
- from sqlalchemy.orm import Session
- from app.crud import customer as customer_crud
- from app.models.models import BizCollectionProtocol, BizProtocolPartyCustomer
- from app.models.research_donation import BizResearchDonation, BizResearchDonationParty
- _ROLE_SPECS = (
- {
- "role": "mother",
- "id_attr": "customer_id",
- "name_attr": "mother_name",
- "phone_attr": "mother_phone",
- "id_card_attr": "mother_id_card",
- },
- {
- "role": "father",
- "id_attr": "father_customer_id",
- "name_attr": "father_name",
- "phone_attr": "father_phone",
- "id_card_attr": "father_id_card",
- },
- {
- "role": "newborn",
- "id_attr": "newborn_customer_id",
- "name_attr": "newborn_name",
- "phone_attr": None,
- "id_card_attr": "newborn_id_card",
- },
- )
- def resolve_my_role(party: Any, customer_id: str) -> str:
- cid = (customer_id or "").strip()
- if not cid:
- return ""
- if (getattr(party, "customer_id", None) or "").strip() == cid:
- return "mother"
- if (getattr(party, "father_customer_id", None) or "").strip() == cid:
- return "father"
- if (getattr(party, "newborn_customer_id", None) or "").strip() == cid:
- return "newborn"
- return ""
- def party_members(party: Any) -> List[Dict[str, str]]:
- out: List[Dict[str, str]] = []
- for spec in _ROLE_SPECS:
- name = (getattr(party, spec["name_attr"], None) or "").strip()
- if not name:
- continue
- phone_attr = spec["phone_attr"]
- phone = (getattr(party, phone_attr, None) or "").strip() if phone_attr else ""
- out.append(
- {
- "role": spec["role"],
- "customerId": (getattr(party, spec["id_attr"], None) or "").strip(),
- "name": name,
- "phone": phone,
- "idCardNo": (getattr(party, spec["id_card_attr"], None) or "").strip(),
- }
- )
- return out
- def _fmt_date(val: Any) -> str:
- if val is None:
- return ""
- if isinstance(val, datetime):
- return val.strftime("%Y%m%d")
- return str(val).strip()
- def _group_sort_key(group: Dict[str, Any]) -> datetime:
- ct = group.get("_createTime")
- if isinstance(ct, datetime):
- return ct
- return datetime.min
- def _storage_group(party: Any, protocol: Any, customer_id: str) -> Dict[str, Any]:
- return {
- "bizType": "cell_storage",
- "protocolId": protocol.id,
- "protocolNo": (protocol.protocol_no or "").strip(),
- "protocolStatus": (protocol.protocol_status or "").strip(),
- "registerDate": _fmt_date(protocol.register_date),
- "myRole": resolve_my_role(party, customer_id),
- "members": party_members(party),
- "_createTime": protocol.create_time,
- }
- def _donation_group(party: Any, donation: Any, customer_id: str) -> Dict[str, Any]:
- return {
- "bizType": "research_donation",
- "protocolId": donation.id,
- "protocolNo": (donation.donation_no or "").strip(),
- "protocolStatus": (donation.donation_status or "").strip(),
- "registerDate": _fmt_date(donation.donation_date),
- "myRole": resolve_my_role(party, customer_id),
- "members": party_members(party),
- "_createTime": donation.create_time,
- }
- def _fetch_storage_party_rows(
- db: Session, customer_id: str, tenant_no: str
- ) -> List[Tuple[Any, Any]]:
- cid = (customer_id or "").strip()
- rows = (
- db.query(BizProtocolPartyCustomer, BizCollectionProtocol)
- .join(
- BizCollectionProtocol,
- BizCollectionProtocol.id == BizProtocolPartyCustomer.collection_protocol_id,
- )
- .filter(
- BizProtocolPartyCustomer.tenant_no == tenant_no,
- BizProtocolPartyCustomer.del_flag == 0,
- BizCollectionProtocol.tenant_no == tenant_no,
- BizCollectionProtocol.del_flag == 0,
- or_(
- BizProtocolPartyCustomer.customer_id == cid,
- BizProtocolPartyCustomer.father_customer_id == cid,
- BizProtocolPartyCustomer.newborn_customer_id == cid,
- ),
- )
- .all()
- )
- return list(rows)
- def _fetch_donation_party_rows(
- db: Session, customer_id: str, tenant_no: str
- ) -> List[Tuple[Any, Any]]:
- cid = (customer_id or "").strip()
- rows = (
- db.query(BizResearchDonationParty, BizResearchDonation)
- .join(
- BizResearchDonation,
- BizResearchDonation.id == BizResearchDonationParty.research_donation_id,
- )
- .filter(
- BizResearchDonationParty.tenant_no == tenant_no,
- BizResearchDonationParty.del_flag == 0,
- BizResearchDonation.tenant_no == tenant_no,
- BizResearchDonation.del_flag == 0,
- or_(
- BizResearchDonationParty.customer_id == cid,
- BizResearchDonationParty.father_customer_id == cid,
- BizResearchDonationParty.newborn_customer_id == cid,
- ),
- )
- .all()
- )
- return list(rows)
- def build_customer_relations(
- db: Session, customer_id: str, tenant_no: str
- ) -> Optional[Dict[str, Any]]:
- customer = customer_crud.get_customer(db, customer_id, tenant_no=tenant_no)
- if not customer:
- return None
- groups: List[Dict[str, Any]] = []
- for party, protocol in _fetch_storage_party_rows(db, customer_id, tenant_no):
- groups.append(_storage_group(party, protocol, customer_id))
- for party, donation in _fetch_donation_party_rows(db, customer_id, tenant_no):
- groups.append(_donation_group(party, donation, customer_id))
- groups.sort(key=_group_sort_key, reverse=True)
- related_groups: List[Dict[str, Any]] = []
- protocols: List[Dict[str, Any]] = []
- for g in groups:
- related_groups.append(
- {
- "bizType": g["bizType"],
- "protocolId": g["protocolId"],
- "protocolNo": g["protocolNo"],
- "protocolStatus": g["protocolStatus"],
- "registerDate": g["registerDate"],
- "myRole": g["myRole"],
- "members": g["members"],
- }
- )
- protocols.append(
- {
- "bizType": g["bizType"],
- "protocolId": g["protocolId"],
- "protocolNo": g["protocolNo"],
- "protocolStatus": g["protocolStatus"],
- "registerDate": g["registerDate"],
- "myRole": g["myRole"],
- }
- )
- return {
- "customer": customer_crud._row_to_dict(customer),
- "relatedGroups": related_groups,
- "protocols": protocols,
- }
|