|
|
@@ -22,6 +22,7 @@ from app.models.models import (
|
|
|
BizProtocolCollectionInfo,
|
|
|
BizProtocolPartyCustomer,
|
|
|
BizProtocolSample,
|
|
|
+ BizProtocolSampleTransport,
|
|
|
BizSampleCode,
|
|
|
SysUser,
|
|
|
)
|
|
|
@@ -30,6 +31,7 @@ from app.models.research_donation import (
|
|
|
BizResearchDonationCollection,
|
|
|
BizResearchDonationParty,
|
|
|
BizResearchDonationSample,
|
|
|
+ BizResearchDonationSampleTransport,
|
|
|
)
|
|
|
from app.schemas.market_mobile import MarketProtocolBody
|
|
|
from app.services.market_field_scope import (
|
|
|
@@ -39,7 +41,7 @@ from app.services.market_field_scope import (
|
|
|
assert_cell_protocol_access,
|
|
|
assert_donation_access,
|
|
|
)
|
|
|
-from app.services.market_support import validate_attachment_refs
|
|
|
+from app.services.market_support import allowed_actions, validate_attachment_refs
|
|
|
|
|
|
SOURCE_CELL = 'cell_storage'
|
|
|
SOURCE_DONATION = 'research_donation'
|
|
|
@@ -405,6 +407,203 @@ def _party_name_donation(db: Session, ids: List[str], tenant_no: str) -> dict:
|
|
|
return {row.research_donation_id: row.mother_name or '' for row in rows}
|
|
|
|
|
|
|
|
|
+def _enrich_protocol_cards(
|
|
|
+ db: Session, items: List[dict], tenant_no: str
|
|
|
+) -> None:
|
|
|
+ """批量补齐与 Web 列表一致的移动卡片字段,避免逐行查询。"""
|
|
|
+ cell_ids = [item['id'] for item in items if item['source'] == SOURCE_CELL]
|
|
|
+ donation_ids = [
|
|
|
+ item['id'] for item in items if item['source'] == SOURCE_DONATION
|
|
|
+ ]
|
|
|
+ collection_map = {}
|
|
|
+ sample_map = {}
|
|
|
+ party_map = {}
|
|
|
+ if cell_ids:
|
|
|
+ for row in db.query(BizProtocolCollectionInfo).filter(
|
|
|
+ BizProtocolCollectionInfo.collection_protocol_id.in_(cell_ids),
|
|
|
+ BizProtocolCollectionInfo.tenant_no == tenant_no,
|
|
|
+ BizProtocolCollectionInfo.del_flag == 0,
|
|
|
+ ).order_by(BizProtocolCollectionInfo.create_time.desc()).all():
|
|
|
+ collection_map.setdefault((SOURCE_CELL, row.collection_protocol_id), row)
|
|
|
+ for row in db.query(BizProtocolSample).filter(
|
|
|
+ BizProtocolSample.collection_protocol_id.in_(cell_ids),
|
|
|
+ BizProtocolSample.tenant_no == tenant_no,
|
|
|
+ BizProtocolSample.del_flag == 0,
|
|
|
+ ).order_by(BizProtocolSample.create_time.asc()).all():
|
|
|
+ sample_map.setdefault((SOURCE_CELL, row.collection_protocol_id), row)
|
|
|
+ for row in db.query(BizProtocolPartyCustomer).filter(
|
|
|
+ BizProtocolPartyCustomer.collection_protocol_id.in_(cell_ids),
|
|
|
+ BizProtocolPartyCustomer.tenant_no == tenant_no,
|
|
|
+ BizProtocolPartyCustomer.del_flag == 0,
|
|
|
+ ).order_by(BizProtocolPartyCustomer.create_time.desc()).all():
|
|
|
+ party_map.setdefault((SOURCE_CELL, row.collection_protocol_id), row)
|
|
|
+ if donation_ids:
|
|
|
+ for row in db.query(BizResearchDonationCollection).filter(
|
|
|
+ BizResearchDonationCollection.research_donation_id.in_(donation_ids),
|
|
|
+ BizResearchDonationCollection.tenant_no == tenant_no,
|
|
|
+ BizResearchDonationCollection.del_flag == 0,
|
|
|
+ ).order_by(BizResearchDonationCollection.create_time.desc()).all():
|
|
|
+ collection_map.setdefault((SOURCE_DONATION, row.research_donation_id), row)
|
|
|
+ for row in db.query(BizResearchDonationSample).filter(
|
|
|
+ BizResearchDonationSample.research_donation_id.in_(donation_ids),
|
|
|
+ BizResearchDonationSample.tenant_no == tenant_no,
|
|
|
+ BizResearchDonationSample.del_flag == 0,
|
|
|
+ ).order_by(BizResearchDonationSample.create_time.asc()).all():
|
|
|
+ sample_map.setdefault((SOURCE_DONATION, row.research_donation_id), row)
|
|
|
+ for row in db.query(BizResearchDonationParty).filter(
|
|
|
+ BizResearchDonationParty.research_donation_id.in_(donation_ids),
|
|
|
+ BizResearchDonationParty.tenant_no == tenant_no,
|
|
|
+ BizResearchDonationParty.del_flag == 0,
|
|
|
+ ).order_by(BizResearchDonationParty.create_time.desc()).all():
|
|
|
+ party_map.setdefault((SOURCE_DONATION, row.research_donation_id), row)
|
|
|
+ region_ids = {
|
|
|
+ row.region_id for row in collection_map.values() if row.region_id
|
|
|
+ }
|
|
|
+ hospital_ids = {
|
|
|
+ row.hospital_id for row in collection_map.values() if row.hospital_id
|
|
|
+ }
|
|
|
+ user_ids = {
|
|
|
+ value
|
|
|
+ for row in collection_map.values()
|
|
|
+ for value in (row.sales_user_id, row.region_manager_user_id)
|
|
|
+ if value
|
|
|
+ }
|
|
|
+ user_ids.update(
|
|
|
+ item.get('collectorUserId')
|
|
|
+ for item in items
|
|
|
+ if item.get('collectorUserId')
|
|
|
+ )
|
|
|
+ type_ids = {
|
|
|
+ row.sample_type_id for row in sample_map.values() if row.sample_type_id
|
|
|
+ }
|
|
|
+ region_names = {
|
|
|
+ row.id: row.region_name or ''
|
|
|
+ for row in db.query(BizCollectionRegion).filter(
|
|
|
+ BizCollectionRegion.id.in_(region_ids or ['']),
|
|
|
+ BizCollectionRegion.tenant_no == tenant_no,
|
|
|
+ BizCollectionRegion.del_flag == 0,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ hospital_names = {
|
|
|
+ row.id: row.hospital_name or ''
|
|
|
+ for row in db.query(BizCollectionHospital).filter(
|
|
|
+ BizCollectionHospital.id.in_(hospital_ids or ['']),
|
|
|
+ BizCollectionHospital.tenant_no == tenant_no,
|
|
|
+ BizCollectionHospital.del_flag == 0,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ user_names = {
|
|
|
+ row.id: row.nick_name or ''
|
|
|
+ for row in db.query(SysUser).filter(
|
|
|
+ SysUser.id.in_(user_ids or ['']),
|
|
|
+ SysUser.tenant_no == tenant_no,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ type_names = {
|
|
|
+ row.id: row.type_name or ''
|
|
|
+ for row in db.query(BizCellSampleType).filter(
|
|
|
+ BizCellSampleType.id.in_(type_ids or ['']),
|
|
|
+ BizCellSampleType.del_flag == 0,
|
|
|
+ or_(
|
|
|
+ BizCellSampleType.tenant_no == tenant_no,
|
|
|
+ BizCellSampleType.tenant_no == '',
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ }
|
|
|
+ sample_ids = [row.id for row in sample_map.values()]
|
|
|
+ transport_by_sample = {}
|
|
|
+ if sample_ids:
|
|
|
+ for row in db.query(BizProtocolSampleTransport).filter(
|
|
|
+ BizProtocolSampleTransport.sample_id.in_(sample_ids),
|
|
|
+ BizProtocolSampleTransport.tenant_no == tenant_no,
|
|
|
+ BizProtocolSampleTransport.del_flag == 0,
|
|
|
+ ).all():
|
|
|
+ transport_by_sample.setdefault(row.sample_id, row)
|
|
|
+ for row in db.query(BizResearchDonationSampleTransport).filter(
|
|
|
+ BizResearchDonationSampleTransport.sample_id.in_(sample_ids),
|
|
|
+ BizResearchDonationSampleTransport.tenant_no == tenant_no,
|
|
|
+ BizResearchDonationSampleTransport.del_flag == 0,
|
|
|
+ ).all():
|
|
|
+ transport_by_sample.setdefault(row.sample_id, row)
|
|
|
+ lab_by_key = {}
|
|
|
+ from app.crud import sample_reception as reception_crud
|
|
|
+
|
|
|
+ for source in SOURCES:
|
|
|
+ codes = [
|
|
|
+ row.sample_code
|
|
|
+ for (item_source, _), row in sample_map.items()
|
|
|
+ if item_source == source and row.sample_code
|
|
|
+ ]
|
|
|
+ for code, lab_code in reception_crud.get_lab_storage_code_map_by_sample_codes(
|
|
|
+ db, tenant_no, codes, reception_source=source
|
|
|
+ ).items():
|
|
|
+ lab_by_key[(source, code)] = lab_code
|
|
|
+ payment_summaries = {}
|
|
|
+ if cell_ids:
|
|
|
+ from app.services.qc_work_order_fee_summary import (
|
|
|
+ build_protocol_payment_summaries,
|
|
|
+ )
|
|
|
+
|
|
|
+ payment_summaries = build_protocol_payment_summaries(
|
|
|
+ db, cell_ids, tenant_no
|
|
|
+ )
|
|
|
+ transport_labels = {'kdys': '快递运输', 'ryxd': '人员携带'}
|
|
|
+ for item in items:
|
|
|
+ key = (item['source'], item['id'])
|
|
|
+ collection = collection_map.get(key)
|
|
|
+ sample = sample_map.get(key)
|
|
|
+ party = party_map.get(key)
|
|
|
+ payment_summary = payment_summaries.get(item['id']) or {}
|
|
|
+ transport = transport_by_sample.get(getattr(sample, 'id', ''))
|
|
|
+ sample_code = getattr(sample, 'sample_code', '') or ''
|
|
|
+ region_manager_name = user_names.get(
|
|
|
+ getattr(collection, 'region_manager_user_id', ''), ''
|
|
|
+ )
|
|
|
+ item.update(
|
|
|
+ motherName=item.get('customerName', ''),
|
|
|
+ motherPhone=getattr(party, 'mother_phone', '') or '',
|
|
|
+ motherIdCard=getattr(party, 'mother_id_card', '') or '',
|
|
|
+ fatherName=getattr(party, 'father_name', '') or '',
|
|
|
+ newbornSex=getattr(party, 'newborn_sex', '') or '',
|
|
|
+ deliveryMode=getattr(party, 'delivery_mode', '') or '',
|
|
|
+ newbornWeightGram=getattr(party, 'newborn_weight_gram', None),
|
|
|
+ birthOrder=getattr(party, 'birth_order', None),
|
|
|
+ newbornDeliveryTime=_fmt_dt(
|
|
|
+ getattr(party, 'newborn_delivery_time', None)
|
|
|
+ ),
|
|
|
+ protocolStatus=item.get('status', ''),
|
|
|
+ donationStatus=item.get('status', ''),
|
|
|
+ regionName=region_names.get(getattr(collection, 'region_id', ''), ''),
|
|
|
+ hospitalName=hospital_names.get(
|
|
|
+ getattr(collection, 'hospital_id', ''), ''
|
|
|
+ ),
|
|
|
+ sampleCollectTime=_fmt_dt(
|
|
|
+ getattr(collection, 'sample_collect_time', None)
|
|
|
+ ),
|
|
|
+ maternalBloodCollectTime=_fmt_dt(
|
|
|
+ getattr(collection, 'maternal_blood_collect_time', None)
|
|
|
+ ),
|
|
|
+ salesUserName=user_names.get(
|
|
|
+ getattr(collection, 'sales_user_id', ''), ''
|
|
|
+ ),
|
|
|
+ collectorUserName=user_names.get(item.get('collectorUserId', ''), ''),
|
|
|
+ managerName=region_manager_name,
|
|
|
+ regionManagerUserName=region_manager_name,
|
|
|
+ sampleCode=sample_code,
|
|
|
+ sampleTypeName=type_names.get(
|
|
|
+ getattr(sample, 'sample_type_id', ''), ''
|
|
|
+ ),
|
|
|
+ coStored=bool(getattr(sample, 'is_special', 0)),
|
|
|
+ labStorageCode=lab_by_key.get((item['source'], sample_code), ''),
|
|
|
+ payMode=payment_summary.get('payMode', ''),
|
|
|
+ firstPayTime=payment_summary.get('firstPayTransferTime', ''),
|
|
|
+ transportMode=getattr(transport, 'transport_type', '') or '',
|
|
|
+ transportModeLabel=transport_labels.get(
|
|
|
+ getattr(transport, 'transport_type', '') or '', ''
|
|
|
+ ),
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
def list_protocols(
|
|
|
db: Session,
|
|
|
*,
|
|
|
@@ -426,7 +625,26 @@ def list_protocols(
|
|
|
db.query(BizCollectionProtocol), db, ctx, user_info=user_info
|
|
|
)
|
|
|
if search:
|
|
|
- query = query.filter(BizCollectionProtocol.protocol_no.like(f'%{search}%'))
|
|
|
+ like = f'%{search}%'
|
|
|
+ party_ids = db.query(
|
|
|
+ BizProtocolPartyCustomer.collection_protocol_id
|
|
|
+ ).filter(
|
|
|
+ BizProtocolPartyCustomer.tenant_no == ctx.tenant_no,
|
|
|
+ BizProtocolPartyCustomer.del_flag == 0,
|
|
|
+ BizProtocolPartyCustomer.mother_name.like(like),
|
|
|
+ )
|
|
|
+ sample_ids = db.query(BizProtocolSample.collection_protocol_id).filter(
|
|
|
+ BizProtocolSample.tenant_no == ctx.tenant_no,
|
|
|
+ BizProtocolSample.del_flag == 0,
|
|
|
+ BizProtocolSample.sample_code.like(like),
|
|
|
+ )
|
|
|
+ query = query.filter(
|
|
|
+ or_(
|
|
|
+ BizCollectionProtocol.protocol_no.like(like),
|
|
|
+ BizCollectionProtocol.id.in_(party_ids),
|
|
|
+ BizCollectionProtocol.id.in_(sample_ids),
|
|
|
+ )
|
|
|
+ )
|
|
|
total += int(
|
|
|
query.order_by(None)
|
|
|
.with_entities(func.count(BizCollectionProtocol.id))
|
|
|
@@ -451,6 +669,10 @@ def list_protocols(
|
|
|
'code': row.protocol_no or '',
|
|
|
'protocolNo': row.protocol_no or '',
|
|
|
'status': row.protocol_status or '',
|
|
|
+ 'collectDate': row.register_date or '',
|
|
|
+ 'registerDate': row.register_date or '',
|
|
|
+ 'protocolTotalAmount': str(row.protocol_total_amount or ''),
|
|
|
+ 'collectorUserId': row.collector_user_id or '',
|
|
|
'customerName': names.get(row.id, ''),
|
|
|
'createTime': _fmt_dt(row.create_time),
|
|
|
'_created': row.create_time or datetime.min,
|
|
|
@@ -462,7 +684,28 @@ def list_protocols(
|
|
|
db.query(BizResearchDonation), db, ctx, user_info=user_info
|
|
|
)
|
|
|
if search:
|
|
|
- query = query.filter(BizResearchDonation.donation_no.like(f'%{search}%'))
|
|
|
+ like = f'%{search}%'
|
|
|
+ party_ids = db.query(
|
|
|
+ BizResearchDonationParty.research_donation_id
|
|
|
+ ).filter(
|
|
|
+ BizResearchDonationParty.tenant_no == ctx.tenant_no,
|
|
|
+ BizResearchDonationParty.del_flag == 0,
|
|
|
+ BizResearchDonationParty.mother_name.like(like),
|
|
|
+ )
|
|
|
+ sample_ids = db.query(
|
|
|
+ BizResearchDonationSample.research_donation_id
|
|
|
+ ).filter(
|
|
|
+ BizResearchDonationSample.tenant_no == ctx.tenant_no,
|
|
|
+ BizResearchDonationSample.del_flag == 0,
|
|
|
+ BizResearchDonationSample.sample_code.like(like),
|
|
|
+ )
|
|
|
+ query = query.filter(
|
|
|
+ or_(
|
|
|
+ BizResearchDonation.donation_no.like(like),
|
|
|
+ BizResearchDonation.id.in_(party_ids),
|
|
|
+ BizResearchDonation.id.in_(sample_ids),
|
|
|
+ )
|
|
|
+ )
|
|
|
total += int(
|
|
|
query.order_by(None)
|
|
|
.with_entities(func.count(BizResearchDonation.id))
|
|
|
@@ -486,9 +729,19 @@ def list_protocols(
|
|
|
'source': SOURCE_DONATION,
|
|
|
'code': row.donation_no or '',
|
|
|
'protocolNo': row.donation_no or '',
|
|
|
+ 'donationNo': row.donation_no or '',
|
|
|
'status': row.donation_status or '',
|
|
|
+ 'collectDate': row.donation_date or '',
|
|
|
+ 'donationDate': row.donation_date or '',
|
|
|
'customerName': names.get(row.id, ''),
|
|
|
+ 'collectorUserId': row.collector_user_id or '',
|
|
|
'createTime': _fmt_dt(row.create_time),
|
|
|
+ 'monthlyVerifyNo': row.monthly_verify_no or '',
|
|
|
+ 'voidDesc': row.void_desc or '',
|
|
|
+ 'consentFormUrls': row.consent_form_urls or '',
|
|
|
+ 'infectiousDiseaseReportUrls': row.infectious_disease_report_urls or '',
|
|
|
+ 'attachmentUrls': row.attachment_urls or '',
|
|
|
+ 'remark': row.remark or '',
|
|
|
'_created': row.create_time or datetime.min,
|
|
|
}
|
|
|
for row in donation_rows
|
|
|
@@ -501,22 +754,42 @@ def list_protocols(
|
|
|
page_rows = rows[(safe_page - 1) * safe_size : safe_page * safe_size]
|
|
|
for item in page_rows:
|
|
|
item.pop('_created', None)
|
|
|
+ _enrich_protocol_cards(db, page_rows, ctx.tenant_no)
|
|
|
return page_rows, total
|
|
|
|
|
|
|
|
|
+def _attach_sample_eta(
|
|
|
+ sample_dicts: List[dict],
|
|
|
+ transport_by_sample_id: dict,
|
|
|
+) -> List[dict]:
|
|
|
+ for item in sample_dicts:
|
|
|
+ transport = transport_by_sample_id.get(str(item.get('id') or ''))
|
|
|
+ eta = ''
|
|
|
+ if transport is not None:
|
|
|
+ eta = cell_crud._fmt_dt(getattr(transport, 'eta_time', None))
|
|
|
+ item['etaTime'] = eta
|
|
|
+ item['transport'] = {'etaTime': eta} if eta else None
|
|
|
+ return sample_dicts
|
|
|
+
|
|
|
+
|
|
|
def _cell_detail(db: Session, row: BizCollectionProtocol, tenant_no: str) -> dict:
|
|
|
party = cell_crud.get_party_customer(db, row.id, tenant_no)
|
|
|
collection = cell_crud.get_collection_info(db, row.id, tenant_no)
|
|
|
samples = cell_crud.list_samples(db, row.id, tenant_no)
|
|
|
payment = cell_crud.get_payment_by_protocol_id(db, row.id, tenant_no)
|
|
|
- return {
|
|
|
+ transports = cell_crud.list_sample_transports(db, row.id, tenant_no)
|
|
|
+ transport_by_sample_id = {str(t.sample_id): t for t in transports}
|
|
|
+ detail = {
|
|
|
'source': SOURCE_CELL,
|
|
|
'basic': cell_crud._protocol_to_dict(row),
|
|
|
'collection': cell_crud._collection_info_to_dict(collection)
|
|
|
if collection
|
|
|
else None,
|
|
|
'customer': cell_crud._party_customer_to_dict(party) if party else None,
|
|
|
- 'samples': [cell_crud._sample_to_dict(item) for item in samples],
|
|
|
+ 'samples': _attach_sample_eta(
|
|
|
+ [cell_crud._sample_to_dict(item) for item in samples],
|
|
|
+ transport_by_sample_id,
|
|
|
+ ),
|
|
|
'payment': cell_crud._payment_to_dict(payment) if payment else None,
|
|
|
'attachments': {
|
|
|
'protocolAttachments': row.protocol_attachments or '',
|
|
|
@@ -524,6 +797,8 @@ def _cell_detail(db: Session, row: BizCollectionProtocol, tenant_no: str) -> dic
|
|
|
'healthSurveyFormUrls': row.health_survey_form_urls or '',
|
|
|
},
|
|
|
}
|
|
|
+ _enrich_protocol_detail_labels(db, detail, tenant_no)
|
|
|
+ return detail
|
|
|
|
|
|
|
|
|
def _donation_detail(
|
|
|
@@ -532,14 +807,19 @@ def _donation_detail(
|
|
|
party = donation_crud.get_party(db, row.id, tenant_no)
|
|
|
collection = donation_crud.get_collection(db, row.id, tenant_no)
|
|
|
samples = donation_crud.list_samples(db, row.id, tenant_no)
|
|
|
- return {
|
|
|
+ transports = donation_crud.list_sample_transports(db, row.id, tenant_no)
|
|
|
+ transport_by_sample_id = {str(t.sample_id): t for t in transports}
|
|
|
+ detail = {
|
|
|
'source': SOURCE_DONATION,
|
|
|
'basic': donation_crud._donation_to_dict(row),
|
|
|
'collection': donation_crud._collection_to_dict(collection)
|
|
|
if collection
|
|
|
else None,
|
|
|
'customer': donation_crud._party_to_dict(party) if party else None,
|
|
|
- 'samples': [donation_crud._sample_to_dict(item) for item in samples],
|
|
|
+ 'samples': _attach_sample_eta(
|
|
|
+ [donation_crud._sample_to_dict(item) for item in samples],
|
|
|
+ transport_by_sample_id,
|
|
|
+ ),
|
|
|
'attachments': {
|
|
|
'consentFormUrls': row.consent_form_urls or '',
|
|
|
'attachmentUrls': row.attachment_urls or '',
|
|
|
@@ -547,6 +827,99 @@ def _donation_detail(
|
|
|
or '',
|
|
|
},
|
|
|
}
|
|
|
+ _enrich_protocol_detail_labels(db, detail, tenant_no)
|
|
|
+ return detail
|
|
|
+
|
|
|
+
|
|
|
+def _enrich_protocol_detail_labels(
|
|
|
+ db: Session, detail: dict, tenant_no: str
|
|
|
+) -> None:
|
|
|
+ """补齐 Web 详情使用的主数据名称,移动端不直接展示内部 ID。"""
|
|
|
+ basic = detail.get('basic') or {}
|
|
|
+ collection = detail.get('collection') or {}
|
|
|
+ samples = detail.get('samples') or []
|
|
|
+
|
|
|
+ region_id = str(collection.get('regionId') or '').strip()
|
|
|
+ hospital_id = str(collection.get('hospitalId') or '').strip()
|
|
|
+ if region_id:
|
|
|
+ region = (
|
|
|
+ db.query(BizCollectionRegion)
|
|
|
+ .filter(
|
|
|
+ BizCollectionRegion.id == region_id,
|
|
|
+ BizCollectionRegion.tenant_no == tenant_no,
|
|
|
+ )
|
|
|
+ .first()
|
|
|
+ )
|
|
|
+ collection['regionName'] = region.region_name if region else ''
|
|
|
+ if hospital_id:
|
|
|
+ hospital = (
|
|
|
+ db.query(BizCollectionHospital)
|
|
|
+ .filter(
|
|
|
+ BizCollectionHospital.id == hospital_id,
|
|
|
+ BizCollectionHospital.tenant_no == tenant_no,
|
|
|
+ )
|
|
|
+ .first()
|
|
|
+ )
|
|
|
+ collection['hospitalName'] = hospital.hospital_name if hospital else ''
|
|
|
+
|
|
|
+ user_ids = {
|
|
|
+ str(value or '').strip()
|
|
|
+ for value in (
|
|
|
+ basic.get('collectorUserId'),
|
|
|
+ collection.get('salesUserId'),
|
|
|
+ collection.get('regionManagerUserId'),
|
|
|
+ )
|
|
|
+ if str(value or '').strip()
|
|
|
+ }
|
|
|
+ user_names = {
|
|
|
+ row.id: row.nick_name or ''
|
|
|
+ for row in db.query(SysUser).filter(
|
|
|
+ SysUser.id.in_(user_ids or ['']),
|
|
|
+ SysUser.tenant_no == tenant_no,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ basic['collectorUserName'] = user_names.get(
|
|
|
+ str(basic.get('collectorUserId') or ''), ''
|
|
|
+ )
|
|
|
+ collection['salesUserName'] = user_names.get(
|
|
|
+ str(collection.get('salesUserId') or ''), ''
|
|
|
+ )
|
|
|
+ collection['regionManagerUserName'] = user_names.get(
|
|
|
+ str(collection.get('regionManagerUserId') or ''), ''
|
|
|
+ )
|
|
|
+
|
|
|
+ type_ids = {
|
|
|
+ str(item.get('sampleTypeId') or '').strip()
|
|
|
+ for item in samples
|
|
|
+ if str(item.get('sampleTypeId') or '').strip()
|
|
|
+ }
|
|
|
+ type_names = {
|
|
|
+ row.id: row.type_name or ''
|
|
|
+ for row in db.query(BizCellSampleType).filter(
|
|
|
+ BizCellSampleType.id.in_(type_ids or ['']),
|
|
|
+ or_(
|
|
|
+ BizCellSampleType.tenant_no == tenant_no,
|
|
|
+ BizCellSampleType.tenant_no == '',
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ }
|
|
|
+ unit_ids = {
|
|
|
+ str(item.get('unitId') or '').strip()
|
|
|
+ for item in samples
|
|
|
+ if str(item.get('unitId') or '').strip()
|
|
|
+ }
|
|
|
+ unit_names = {
|
|
|
+ row.id: row.unit_name or ''
|
|
|
+ for row in db.query(BizItemUnit).filter(
|
|
|
+ BizItemUnit.id.in_(unit_ids or ['']),
|
|
|
+ BizItemUnit.tenant_no == tenant_no,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ for item in samples:
|
|
|
+ item['sampleTypeName'] = type_names.get(
|
|
|
+ str(item.get('sampleTypeId') or ''), ''
|
|
|
+ )
|
|
|
+ item['unitName'] = unit_names.get(str(item.get('unitId') or ''), '')
|
|
|
|
|
|
|
|
|
def get_protocol(
|
|
|
@@ -588,6 +961,72 @@ def get_protocol(
|
|
|
raise ValueError('不支持的协议来源')
|
|
|
|
|
|
|
|
|
+def audit_protocol(
|
|
|
+ db: Session,
|
|
|
+ *,
|
|
|
+ source: str,
|
|
|
+ protocol_id: str,
|
|
|
+ audit_status: str,
|
|
|
+ audit_remark: Optional[str],
|
|
|
+ ctx: MarketFieldContext,
|
|
|
+ user_info: dict,
|
|
|
+) -> dict:
|
|
|
+ if source == SOURCE_CELL:
|
|
|
+ row = assert_cell_protocol_access(db, protocol_id, ctx, user_info=user_info)
|
|
|
+ if 'audit' not in allowed_actions('protocol', status=row.protocol_status or ''):
|
|
|
+ raise ValueError('当前状态不可审核')
|
|
|
+ cell_crud.create_audit(
|
|
|
+ db,
|
|
|
+ collection_protocol_id=protocol_id,
|
|
|
+ audit_status=audit_status,
|
|
|
+ audit_remark=audit_remark,
|
|
|
+ tenant_no=ctx.tenant_no,
|
|
|
+ user_id=ctx.user_id,
|
|
|
+ )
|
|
|
+ return {'id': protocol_id, 'source': source, 'protocolNo': row.protocol_no or ''}
|
|
|
+ if source == SOURCE_DONATION:
|
|
|
+ row = assert_donation_access(db, protocol_id, ctx, user_info=user_info)
|
|
|
+ if 'audit' not in allowed_actions('protocol', status=row.donation_status or ''):
|
|
|
+ raise ValueError('当前状态不可审核')
|
|
|
+ donation_crud.submit_audit(
|
|
|
+ db,
|
|
|
+ protocol_id,
|
|
|
+ audit_status=audit_status,
|
|
|
+ audit_remark=audit_remark,
|
|
|
+ tenant_no=ctx.tenant_no,
|
|
|
+ user_id=ctx.user_id,
|
|
|
+ )
|
|
|
+ return {'id': protocol_id, 'source': source, 'donationNo': row.donation_no or ''}
|
|
|
+ raise ValueError('不支持的协议来源')
|
|
|
+
|
|
|
+
|
|
|
+def delete_protocol(
|
|
|
+ db: Session,
|
|
|
+ *,
|
|
|
+ source: str,
|
|
|
+ protocol_id: str,
|
|
|
+ ctx: MarketFieldContext,
|
|
|
+ user_info: dict,
|
|
|
+) -> None:
|
|
|
+ if source == SOURCE_CELL:
|
|
|
+ row = assert_cell_protocol_access(db, protocol_id, ctx, user_info=user_info)
|
|
|
+ if 'delete' not in allowed_actions('protocol', status=row.protocol_status or ''):
|
|
|
+ raise ValueError('当前状态不可删除')
|
|
|
+ cell_crud.soft_delete_collection_protocol(
|
|
|
+ db, protocol_id, ctx.tenant_no, user_id=ctx.user_id
|
|
|
+ )
|
|
|
+ return
|
|
|
+ if source == SOURCE_DONATION:
|
|
|
+ row = assert_donation_access(db, protocol_id, ctx, user_info=user_info)
|
|
|
+ if 'delete' not in allowed_actions('protocol', status=row.donation_status or ''):
|
|
|
+ raise ValueError('当前状态不可删除')
|
|
|
+ donation_crud.delete_donation(
|
|
|
+ db, protocol_id, ctx.tenant_no, user_id=ctx.user_id
|
|
|
+ )
|
|
|
+ return
|
|
|
+ raise ValueError('不支持的协议来源')
|
|
|
+
|
|
|
+
|
|
|
def create_protocol(
|
|
|
db: Session,
|
|
|
*,
|