浏览代码

feat: wire party customer sync into storage and donation saves

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 3 周之前
父节点
当前提交
f005370a1e
共有 3 个文件被更改,包括 22 次插入 和 48 次删除
  1. 4 46
      backend/app/api/collection_protocol.py
  2. 4 1
      backend/app/crud/collection_protocol.py
  3. 14 1
      backend/app/crud/research_donation.py

+ 4 - 46
backend/app/api/collection_protocol.py

@@ -13,15 +13,14 @@ from app.core.menu_guard import require_admin_or_super_admin
 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,
     BizProtocolPartyCustomer,
     BizProtocolSample,
     BizProtocolStorageCert,
     SysUser,
 )
+from app.services.party_customer_sync import sync_party_customers
 
 router = APIRouter(prefix="/web/admin", tags=["细胞存储"])
 
@@ -79,49 +78,6 @@ def _parse_datetime_fields(d: dict, camel_keys: list) -> None:
                 d[snake] = None
 
 
-def _ensure_customer_for_mother(db: Session, party_customer: dict, tenant_no: str, user_id: str) -> dict:
-    """If mother info exists but no customerId, create a customer record and link it."""
-    if not party_customer:
-        return party_customer
-    customer_id = party_customer.get("customer_id") or party_customer.get("customerId")
-    mother_name = (party_customer.get("mother_name") or party_customer.get("motherName") or "").strip()
-    if customer_id or not mother_name:
-        return party_customer
-    # Build customer fields from mother info
-    mother_phone = (party_customer.get("mother_phone") or party_customer.get("motherPhone") or "").strip() or None
-    mother_id_card = (party_customer.get("mother_id_card") or party_customer.get("motherIdCard") or "").strip() or None
-
-    # Check if customer with this id_card already exists
-    if mother_id_card and customer_crud.id_card_taken(db, mother_id_card, tenant_no):
-        existing = db.query(BizCustomer).filter(
-            sa_and(
-                BizCustomer.id_card_no == mother_id_card,
-                BizCustomer.tenant_no == tenant_no,
-                BizCustomer.del_flag == 0,
-            )
-        ).first()
-        if existing:
-            party_customer["customer_id"] = existing.id
-            return party_customer
-
-    # Create new customer
-    try:
-        obj = customer_crud.create_customer(
-            db,
-            customer_name=mother_name,
-            sex="1",  # female (mother)
-            id_card_no=mother_id_card,
-            phone_no=mother_phone,
-            tenant_no=tenant_no,
-            user_id=user_id,
-        )
-        party_customer["customer_id"] = obj.id
-    except ValueError:
-        # If creation fails (e.g. duplicate), try to find existing
-        pass
-    return party_customer
-
-
 # ---------------------------------------------------------------------------
 # 采集协议单
 # ---------------------------------------------------------------------------
@@ -286,7 +242,9 @@ def _persist_protocol_sub_resources(
     """
     if party_customer:
         _parse_datetime_fields(party_customer, ["newbornDeliveryTime"])
-        party_customer = _ensure_customer_for_mother(db, party_customer, tenant_no, user_id)
+        party_customer = sync_party_customers(
+            db, party_customer, tenant_no=tenant_no, user_id=user_id
+        )
         cp_svc.upsert_party_customer(db, protocol_id, tenant_no, user_id, **party_customer)
     if collection_info:
         _parse_datetime_fields(collection_info, ["sampleCollectTime", "maternalBloodCollectTime"])

+ 4 - 1
backend/app/crud/collection_protocol.py

@@ -511,6 +511,8 @@ def _party_customer_to_dict(p: BizProtocolPartyCustomer) -> Dict[str, Any]:
         "id": p.id,
         "collectionProtocolId": p.collection_protocol_id,
         "customerId": p.customer_id or "",
+        "fatherCustomerId": p.father_customer_id or "",
+        "newbornCustomerId": p.newborn_customer_id or "",
         "motherName": p.mother_name or "",
         "motherPhone": p.mother_phone or "",
         "motherIdCard": p.mother_id_card or "",
@@ -2526,7 +2528,8 @@ def upsert_party_customer(
     fields = _normalize_fields(fields)
     obj = get_party_customer(db, collection_protocol_id, tenant_no)
     _STR_FIELDS = [
-        "customer_id", "mother_name", "mother_phone", "mother_id_card",
+        "customer_id", "father_customer_id", "newborn_customer_id",
+        "mother_name", "mother_phone", "mother_id_card",
         "mother_birth_ym", "mother_ethnic", "mother_email", "mother_address",
         "father_name", "father_phone", "father_id_card",
         "newborn_name", "newborn_id_card",

+ 14 - 1
backend/app/crud/research_donation.py

@@ -321,6 +321,8 @@ def _party_to_dict(p: BizResearchDonationParty) -> Dict[str, Any]:
         "id": p.id,
         "researchDonationId": p.research_donation_id,
         "customerId": p.customer_id or "",
+        "fatherCustomerId": p.father_customer_id or "",
+        "newbornCustomerId": p.newborn_customer_id or "",
         "motherName": p.mother_name or "",
         "motherPhone": p.mother_phone or "",
         "motherIdCard": p.mother_id_card or "",
@@ -955,7 +957,10 @@ def create_donation(
     donation_id = obj.id
 
     # party
+    from app.services.party_customer_sync import sync_party_customers
+
     party_raw = _normalize_fields(raw.get("party") or {})
+    party_raw = sync_party_customers(db, party_raw, tenant_no=tenant_no, user_id=user_id or "")
     _create_party(db, donation_id, tenant_no, user_id, party_raw, now)
 
     # collection
@@ -1039,8 +1044,11 @@ def update_donation(
 
     # party upsert: 软删旧 → 创建新
     if "party" in raw:
+        from app.services.party_customer_sync import sync_party_customers
+
         _soft_delete_party(db, donation_id, tenant_no, user_id)
         party_raw = _normalize_fields(raw["party"] or {})
+        party_raw = sync_party_customers(db, party_raw, tenant_no=tenant_no, user_id=user_id or "")
         _create_party(db, donation_id, tenant_no, user_id, party_raw, now)
 
     # collection upsert
@@ -1480,6 +1488,8 @@ def convert_from_storage(
             id=generate_uuid(),
             research_donation_id=did,
             customer_id=src_party.customer_id,
+            father_customer_id=getattr(src_party, "father_customer_id", None),
+            newborn_customer_id=getattr(src_party, "newborn_customer_id", None),
             mother_name=src_party.mother_name,
             mother_phone=src_party.mother_phone,
             mother_id_card=src_party.mother_id_card,
@@ -1724,6 +1734,8 @@ def convert_to_storage(
             id=generate_uuid(),
             collection_protocol_id=pid,
             customer_id=src_party.customer_id,
+            father_customer_id=getattr(src_party, "father_customer_id", None),
+            newborn_customer_id=getattr(src_party, "newborn_customer_id", None),
             mother_name=src_party.mother_name,
             mother_phone=src_party.mother_phone,
             mother_id_card=src_party.mother_id_card,
@@ -1863,7 +1875,8 @@ def convert_to_storage(
 # ---------------------------------------------------------------------------
 
 _PARTY_STR_FIELDS = [
-    "customer_id", "mother_name", "mother_phone", "mother_id_card",
+    "customer_id", "father_customer_id", "newborn_customer_id",
+    "mother_name", "mother_phone", "mother_id_card",
     "mother_birth_ym", "mother_ethnic", "mother_email", "mother_address",
     "father_name", "father_phone", "father_id_card",
     "newborn_name", "newborn_id_card", "newborn_sex",