sample_customer_service.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. """样本客户服务扩展 CRUD。"""
  2. from __future__ import annotations
  3. from datetime import date, datetime
  4. from typing import Any, Dict, List, Optional
  5. from sqlalchemy.orm import Session
  6. from app.core.utils import generate_uuid
  7. from app.crud.customer_service_dict import ensure_dict_value
  8. from app.models.models import BizSampleCustomerService
  9. from app.services.sample_customer_service_register import (
  10. CUSTOMER_SERVICE_FIELD_KEYS,
  11. merge_customer_service_fields,
  12. normalize_dict_value,
  13. )
  14. DICT_TYPE_BY_FIELD = {
  15. "sms_send_status": "sms_send_status",
  16. "microbe_followup_status": "microbe_followup_status",
  17. "fullmoon_followup_status": "fullmoon_followup_status",
  18. "household_registered": "household_registered",
  19. }
  20. def _format_date(value: Optional[date]) -> Optional[str]:
  21. if value is None:
  22. return None
  23. if isinstance(value, datetime):
  24. return value.strftime("%Y-%m-%d")
  25. return value.strftime("%Y-%m-%d")
  26. def _format_datetime(value: Optional[datetime]) -> Optional[str]:
  27. if value is None:
  28. return None
  29. return value.strftime("%Y-%m-%d %H:%M:%S")
  30. def _row_field_dict(row: BizSampleCustomerService) -> Dict[str, Any]:
  31. return {key: getattr(row, key) for key in CUSTOMER_SERVICE_FIELD_KEYS}
  32. def get_by_sample_code(
  33. db: Session, tenant_no: str, sample_code: str
  34. ) -> Optional[BizSampleCustomerService]:
  35. code = (sample_code or "").strip()
  36. if not code:
  37. return None
  38. return (
  39. db.query(BizSampleCustomerService)
  40. .filter(
  41. BizSampleCustomerService.tenant_no == tenant_no,
  42. BizSampleCustomerService.sample_code == code,
  43. BizSampleCustomerService.del_flag == 0,
  44. )
  45. .first()
  46. )
  47. def get_map_by_sample_codes(
  48. db: Session, tenant_no: str, sample_codes: List[str]
  49. ) -> Dict[str, BizSampleCustomerService]:
  50. codes = list({(c or "").strip() for c in sample_codes if (c or "").strip()})
  51. if not codes:
  52. return {}
  53. rows = (
  54. db.query(BizSampleCustomerService)
  55. .filter(
  56. BizSampleCustomerService.tenant_no == tenant_no,
  57. BizSampleCustomerService.sample_code.in_(codes),
  58. BizSampleCustomerService.del_flag == 0,
  59. )
  60. .all()
  61. )
  62. return {row.sample_code: row for row in rows}
  63. def row_to_dict(row: BizSampleCustomerService) -> Dict[str, Any]:
  64. return {
  65. "id": row.id,
  66. "sampleCode": row.sample_code,
  67. "collectionProtocolId": row.collection_protocol_id,
  68. "smsSendDate": _format_date(row.sms_send_date),
  69. "smsSendStatus": row.sms_send_status,
  70. "microbeFollowupDate": _format_date(row.microbe_followup_date),
  71. "microbeFollowupStatus": row.microbe_followup_status,
  72. "fullmoonFollowupDate": _format_date(row.fullmoon_followup_date),
  73. "fullmoonFollowupStatus": row.fullmoon_followup_status,
  74. "householdRegistered": row.household_registered,
  75. "einvoiceSendTime": _format_datetime(row.einvoice_send_time),
  76. "effectiveAddress": row.effective_address,
  77. }
  78. def upsert_by_sample_code(
  79. db: Session,
  80. *,
  81. tenant_no: str,
  82. sample_code: str,
  83. collection_protocol_id: Optional[str],
  84. user_id: Optional[str],
  85. incoming: Dict[str, Any],
  86. ) -> BizSampleCustomerService:
  87. code = (sample_code or "").strip()
  88. if not code:
  89. raise ValueError("sample_code is required")
  90. row = get_by_sample_code(db, tenant_no, code)
  91. now = datetime.now()
  92. if row is None:
  93. row = BizSampleCustomerService(
  94. id=generate_uuid(),
  95. sample_code=code,
  96. collection_protocol_id=collection_protocol_id,
  97. tenant_no=tenant_no,
  98. create_by=user_id,
  99. create_dept_id="",
  100. create_time=now,
  101. update_by=user_id,
  102. update_time=now,
  103. del_flag=0,
  104. )
  105. db.add(row)
  106. else:
  107. if collection_protocol_id and not row.collection_protocol_id:
  108. row.collection_protocol_id = collection_protocol_id
  109. row.update_by = user_id
  110. row.update_time = now
  111. existing = _row_field_dict(row)
  112. merged = merge_customer_service_fields(existing, incoming)
  113. for field, dict_type in DICT_TYPE_BY_FIELD.items():
  114. if field not in merged:
  115. continue
  116. value = merged[field]
  117. if value is None or normalize_dict_value(value) is None:
  118. continue
  119. merged[field] = ensure_dict_value(
  120. db, tenant_no, dict_type, value, user_id=user_id
  121. )
  122. for key in CUSTOMER_SERVICE_FIELD_KEYS:
  123. if key in merged:
  124. setattr(row, key, merged[key])
  125. db.flush()
  126. return row