| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- """样本信息列表快捷登记写入。"""
- from __future__ import annotations
- from datetime import datetime
- from typing import Any, Dict, List, Optional
- from sqlalchemy.orm import Session
- from app.core.utils import generate_uuid
- from app.crud import sample_customer_service as sample_customer_service_crud
- from app.crud import sample_insurance as sample_insurance_crud
- from app.crud import sample_storage_cert as sample_storage_cert_crud
- from app.crud.storage_release_review import _get_user_name
- from app.services.sample_customer_service_register import has_any_customer_service_payload
- from app.models.models import (
- BizCollectionProtocol,
- BizProtocolSample,
- BizStorageReleaseReview,
- )
- from app.models.research_donation import BizResearchDonation, BizResearchDonationSample
- from app.services.sample_info_quick_register import (
- apply_quick_storage_payload,
- unique_sample_items,
- )
- def _protocol_accessible(db: Session, protocol_id: str, tenant_no: str) -> bool:
- """登记写入只校验本租户协议存在,不再按数据权限拦截。"""
- row = (
- db.query(BizCollectionProtocol.id)
- .filter(
- BizCollectionProtocol.id == protocol_id,
- BizCollectionProtocol.del_flag == 0,
- BizCollectionProtocol.tenant_no == tenant_no,
- )
- .first()
- )
- return row is not None
- def _donation_accessible(db: Session, donation_id: str, tenant_no: str) -> bool:
- """登记写入只校验本租户捐赠单存在,不再按数据权限拦截。"""
- row = (
- db.query(BizResearchDonation.id)
- .filter(
- BizResearchDonation.id == donation_id,
- BizResearchDonation.del_flag == 0,
- BizResearchDonation.tenant_no == tenant_no,
- )
- .first()
- )
- return row is not None
- def _pick_latest_review(
- rows: List[BizStorageReleaseReview],
- ) -> Optional[BizStorageReleaseReview]:
- best = None
- best_t = None
- for rev in rows:
- cur_t = rev.storage_time or rev.update_time or rev.create_time
- if best is None:
- best, best_t = rev, cur_t
- continue
- if cur_t is None:
- continue
- if best_t is None or cur_t > best_t:
- best, best_t = rev, cur_t
- return best
- def batch_handle_storage_certs(
- db: Session,
- *,
- items: List[Dict[str, str]],
- tenant_no: str,
- user_id: str,
- handle_time: Optional[datetime],
- handler_user_id: Optional[str],
- attachments: str,
- remark: str,
- mail_cert_time: Optional[datetime] = None,
- update_mail_cert_time: bool = False,
- do_commit: bool = True,
- ) -> Dict[str, int]:
- pairs = unique_sample_items(items)
- if not pairs:
- raise ValueError("请选择样本")
- success = 0
- fail = 0
- for sample_code, protocol_id in pairs:
- if not protocol_id or not _protocol_accessible(db, protocol_id, tenant_no):
- fail += 1
- continue
- try:
- sample_storage_cert_crud.upsert_handle(
- db,
- tenant_no=tenant_no,
- sample_code=sample_code,
- collection_protocol_id=protocol_id,
- user_id=user_id,
- handle_time=handle_time,
- handler_user_id=handler_user_id,
- cert_image_urls=attachments,
- remark=remark,
- mail_cert_time=mail_cert_time,
- update_mail_cert_time=update_mail_cert_time,
- )
- success += 1
- except ValueError:
- fail += 1
- if do_commit:
- db.commit()
- return {"success": success, "fail": fail}
- def batch_handle_insurance(
- db: Session,
- *,
- items: List[Dict[str, str]],
- tenant_no: str,
- user_id: str,
- handle_time: Optional[datetime],
- handler_user_id: Optional[str],
- attachments: str,
- remark: str,
- policy_send_time: Optional[datetime] = None,
- update_policy_send_time: bool = False,
- do_commit: bool = True,
- ) -> Dict[str, int]:
- pairs = unique_sample_items(items)
- if not pairs:
- raise ValueError("请选择样本")
- success = 0
- fail = 0
- for sample_code, protocol_id in pairs:
- if not protocol_id or not _protocol_accessible(db, protocol_id, tenant_no):
- fail += 1
- continue
- try:
- sample_insurance_crud.upsert_handle(
- db,
- tenant_no=tenant_no,
- sample_code=sample_code,
- collection_protocol_id=protocol_id,
- user_id=user_id,
- handle_time=handle_time,
- handler_user_id=handler_user_id,
- insurance_attachments=attachments,
- handle_remark=remark,
- policy_send_time=policy_send_time,
- update_policy_send_time=update_policy_send_time,
- )
- success += 1
- except ValueError:
- fail += 1
- if do_commit:
- db.commit()
- return {"success": success, "fail": fail}
- def batch_register_customer_service(
- db: Session,
- *,
- items: List[Dict[str, str]],
- tenant_no: str,
- user_id: str,
- incoming: Dict[str, Any],
- do_commit: bool = True,
- ) -> Dict[str, int]:
- if not has_any_customer_service_payload(incoming):
- raise ValueError("请至少填写一项客户服务信息")
- pairs = unique_sample_items(items)
- if not pairs:
- raise ValueError("请选择样本")
- success = 0
- fail = 0
- for sample_code, protocol_id in pairs:
- if not protocol_id or not _protocol_accessible(db, protocol_id, tenant_no):
- fail += 1
- continue
- try:
- sample_customer_service_crud.upsert_by_sample_code(
- db,
- tenant_no=tenant_no,
- sample_code=sample_code,
- collection_protocol_id=protocol_id,
- user_id=user_id,
- incoming=incoming,
- )
- success += 1
- except ValueError:
- fail += 1
- if do_commit:
- db.commit()
- return {"success": success, "fail": fail}
- def batch_quick_register_storage(
- db: Session,
- *,
- items: List[Dict[str, str]],
- reception_source: str,
- tenant_no: str,
- user_id: str,
- handle_time: Optional[datetime],
- handler_user_id: Optional[str],
- attachments: str,
- remark: str,
- do_commit: bool = True,
- ) -> Dict[str, int]:
- source = (reception_source or "").strip()
- if source not in ("cell_storage", "research_donation"):
- raise ValueError("来源无效")
- fields = apply_quick_storage_payload(
- handle_time=handle_time,
- handler_user_id=handler_user_id,
- attachments=attachments,
- remark=remark,
- )
- pairs = unique_sample_items(items)
- if not pairs:
- raise ValueError("请选择样本")
- handler_name = _get_user_name(db, fields["storage_by"] or user_id)
- success = 0
- fail = 0
- now = datetime.now()
- for sample_code, protocol_id in pairs:
- if source == "cell_storage":
- if not protocol_id or not _protocol_accessible(db, protocol_id, tenant_no):
- fail += 1
- continue
- else:
- if not protocol_id or not _donation_accessible(db, protocol_id, tenant_no):
- fail += 1
- continue
- rows = (
- db.query(BizStorageReleaseReview)
- .filter(
- BizStorageReleaseReview.tenant_no == tenant_no,
- BizStorageReleaseReview.del_flag == 0,
- BizStorageReleaseReview.reception_source == source,
- BizStorageReleaseReview.sample_code == sample_code,
- )
- .all()
- )
- rev = _pick_latest_review(rows)
- if rev is None:
- rev = BizStorageReleaseReview(
- id=generate_uuid(),
- sample_code=sample_code,
- reception_source=source,
- protocol_id=protocol_id,
- storage_status="yrk",
- tenant_no=tenant_no,
- create_by=user_id,
- create_dept_id="",
- update_by=user_id,
- create_time=now,
- update_time=now,
- del_flag=0,
- )
- db.add(rev)
- rev.storage_status = fields["storage_status"]
- rev.storage_time = fields["storage_time"]
- rev.storage_by = fields["storage_by"]
- rev.storage_by_name = handler_name
- rev.remark = fields["remark"] or None
- if fields["attachments"]:
- rev.review_attachments = fields["attachments"]
- rev.update_by = user_id
- rev.update_time = now
- db.add(rev)
- ymd = fields["storage_in_date"]
- if source == "cell_storage":
- ps = (
- db.query(BizProtocolSample)
- .filter(
- BizProtocolSample.sample_code == sample_code,
- BizProtocolSample.tenant_no == tenant_no,
- BizProtocolSample.del_flag == 0,
- )
- .first()
- )
- if ps:
- ps.sample_status = "yrk"
- ps.storage_in_date = ymd
- ps.update_time = now
- db.add(ps)
- else:
- ds = (
- db.query(BizResearchDonationSample)
- .filter(
- BizResearchDonationSample.sample_code == sample_code,
- BizResearchDonationSample.tenant_no == tenant_no,
- BizResearchDonationSample.del_flag == 0,
- )
- .first()
- )
- if ds:
- ds.sample_status = "yrk"
- ds.storage_in_date = ymd
- ds.update_time = now
- db.add(ds)
- success += 1
- if do_commit:
- db.commit()
- return {"success": success, "fail": fail}
|