150 lines
4.6 KiB
Python
150 lines
4.6 KiB
Python
"""样本客户服务扩展 CRUD。"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import date, datetime
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.utils import generate_uuid
|
|
from app.crud.customer_service_dict import ensure_dict_value
|
|
from app.models.models import BizSampleCustomerService
|
|
from app.services.sample_customer_service_register import (
|
|
CUSTOMER_SERVICE_FIELD_KEYS,
|
|
merge_customer_service_fields,
|
|
normalize_dict_value,
|
|
)
|
|
|
|
DICT_TYPE_BY_FIELD = {
|
|
"sms_send_status": "sms_send_status",
|
|
"microbe_followup_status": "microbe_followup_status",
|
|
"fullmoon_followup_status": "fullmoon_followup_status",
|
|
"household_registered": "household_registered",
|
|
}
|
|
|
|
|
|
def _format_date(value: Optional[date]) -> Optional[str]:
|
|
if value is None:
|
|
return None
|
|
if isinstance(value, datetime):
|
|
return value.strftime("%Y-%m-%d")
|
|
return value.strftime("%Y-%m-%d")
|
|
|
|
|
|
def _format_datetime(value: Optional[datetime]) -> Optional[str]:
|
|
if value is None:
|
|
return None
|
|
return value.strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
|
|
def _row_field_dict(row: BizSampleCustomerService) -> Dict[str, Any]:
|
|
return {key: getattr(row, key) for key in CUSTOMER_SERVICE_FIELD_KEYS}
|
|
|
|
|
|
def get_by_sample_code(
|
|
db: Session, tenant_no: str, sample_code: str
|
|
) -> Optional[BizSampleCustomerService]:
|
|
code = (sample_code or "").strip()
|
|
if not code:
|
|
return None
|
|
return (
|
|
db.query(BizSampleCustomerService)
|
|
.filter(
|
|
BizSampleCustomerService.tenant_no == tenant_no,
|
|
BizSampleCustomerService.sample_code == code,
|
|
BizSampleCustomerService.del_flag == 0,
|
|
)
|
|
.first()
|
|
)
|
|
|
|
|
|
def get_map_by_sample_codes(
|
|
db: Session, tenant_no: str, sample_codes: List[str]
|
|
) -> Dict[str, BizSampleCustomerService]:
|
|
codes = list({(c or "").strip() for c in sample_codes if (c or "").strip()})
|
|
if not codes:
|
|
return {}
|
|
rows = (
|
|
db.query(BizSampleCustomerService)
|
|
.filter(
|
|
BizSampleCustomerService.tenant_no == tenant_no,
|
|
BizSampleCustomerService.sample_code.in_(codes),
|
|
BizSampleCustomerService.del_flag == 0,
|
|
)
|
|
.all()
|
|
)
|
|
return {row.sample_code: row for row in rows}
|
|
|
|
|
|
def row_to_dict(row: BizSampleCustomerService) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"sampleCode": row.sample_code,
|
|
"collectionProtocolId": row.collection_protocol_id,
|
|
"smsSendDate": _format_date(row.sms_send_date),
|
|
"smsSendStatus": row.sms_send_status,
|
|
"microbeFollowupDate": _format_date(row.microbe_followup_date),
|
|
"microbeFollowupStatus": row.microbe_followup_status,
|
|
"fullmoonFollowupDate": _format_date(row.fullmoon_followup_date),
|
|
"fullmoonFollowupStatus": row.fullmoon_followup_status,
|
|
"householdRegistered": row.household_registered,
|
|
"einvoiceSendTime": _format_datetime(row.einvoice_send_time),
|
|
"effectiveAddress": row.effective_address,
|
|
}
|
|
|
|
|
|
def upsert_by_sample_code(
|
|
db: Session,
|
|
*,
|
|
tenant_no: str,
|
|
sample_code: str,
|
|
collection_protocol_id: Optional[str],
|
|
user_id: Optional[str],
|
|
incoming: Dict[str, Any],
|
|
) -> BizSampleCustomerService:
|
|
code = (sample_code or "").strip()
|
|
if not code:
|
|
raise ValueError("sample_code is required")
|
|
|
|
row = get_by_sample_code(db, tenant_no, code)
|
|
now = datetime.now()
|
|
if row is None:
|
|
row = BizSampleCustomerService(
|
|
id=generate_uuid(),
|
|
sample_code=code,
|
|
collection_protocol_id=collection_protocol_id,
|
|
tenant_no=tenant_no,
|
|
create_by=user_id,
|
|
create_dept_id="",
|
|
create_time=now,
|
|
update_by=user_id,
|
|
update_time=now,
|
|
del_flag=0,
|
|
)
|
|
db.add(row)
|
|
else:
|
|
if collection_protocol_id and not row.collection_protocol_id:
|
|
row.collection_protocol_id = collection_protocol_id
|
|
row.update_by = user_id
|
|
row.update_time = now
|
|
|
|
existing = _row_field_dict(row)
|
|
merged = merge_customer_service_fields(existing, incoming)
|
|
|
|
for field, dict_type in DICT_TYPE_BY_FIELD.items():
|
|
if field not in merged:
|
|
continue
|
|
value = merged[field]
|
|
if value is None or normalize_dict_value(value) is None:
|
|
continue
|
|
merged[field] = ensure_dict_value(
|
|
db, tenant_no, dict_type, value, user_id=user_id
|
|
)
|
|
|
|
for key in CUSTOMER_SERVICE_FIELD_KEYS:
|
|
if key in merged:
|
|
setattr(row, key, merged[key])
|
|
|
|
db.flush()
|
|
return row
|